@qwen-code/web-shell 0.26.5 → 0.26.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +32 -0
  2. package/dist/{PierreFilePreview-BqZBliqk.js → PierreFilePreview-CUfIRw63.js} +1 -1
  3. package/dist/{SpreadsheetPreview-Bn-HzKXD.js → SpreadsheetPreview-CFnRo-Yk.js} +2 -2
  4. package/dist/{WorkspaceFileBrowser-BSNZoggH.js → WorkspaceFileBrowser-C0YJRw5U.js} +189 -189
  5. package/dist/{agents-route-B1Ckyab-.js → agents-route-Ce70dXW4.js} +2 -2
  6. package/dist/daemon-react-sdk.js +38 -37
  7. package/dist/{index-minpPSyG.js → index-Bgo2d7hn.js} +56665 -53768
  8. package/dist/index.js +57 -56
  9. package/dist/sw.js +1 -1
  10. package/dist/transcript.js +5959 -5616
  11. package/dist/types/ManagedAgentWebShell.d.ts +13 -2
  12. package/dist/types/components/DaemonConnectionHelp.d.ts +5 -0
  13. package/dist/types/components/RemoteAccessSettingsCard.d.ts +1 -0
  14. package/dist/types/components/artifacts/TokenUsageTrend.d.ts +30 -0
  15. package/dist/types/components/channels/ChannelEventsPage.d.ts +12 -0
  16. package/dist/types/components/channels/channel-editor-state.d.ts +55 -2
  17. package/dist/types/components/channels/channel-events-messages.d.ts +9 -0
  18. package/dist/types/components/channels/channel-platform.d.ts +1 -0
  19. package/dist/types/components/composer/AddMenu.d.ts +3 -1
  20. package/dist/types/components/managed/ManagedSessionsPage.d.ts +2 -1
  21. package/dist/types/components/managed/generated/managed-agent-api.d.ts +19 -0
  22. package/dist/types/components/managed/java-managed-agent-client.d.ts +2 -1
  23. package/dist/types/components/managed/managed-agent-provider.d.ts +1 -1
  24. package/dist/types/components/plugins/PluginManagerPage.d.ts +2 -1
  25. package/dist/types/components/plugins/manager-page.d.ts +1 -0
  26. package/dist/types/components/sidebar/ActivityView.d.ts +41 -0
  27. package/dist/types/components/sidebar/SidebarSectionHeader.d.ts +7 -0
  28. package/dist/types/components/sidebar/WebShellSidebar.d.ts +10 -4
  29. package/dist/types/components/sidebar/activity-messages.d.ts +4 -0
  30. package/dist/types/components/sidebar/activity-model.d.ts +34 -0
  31. package/dist/types/components/sidebar/pinned-session-order.d.ts +2 -0
  32. package/dist/types/components/sidebar/use-activity-catalog.d.ts +31 -0
  33. package/dist/types/components/workflow-mode-control-state.d.ts +43 -0
  34. package/dist/types/components/workflow-mode-messages.d.ts +10 -0
  35. package/dist/types/config/daemon.d.ts +1 -0
  36. package/dist/types/daemon/index.d.ts +2 -2
  37. package/dist/types/daemon/workspace/hooks/index.d.ts +1 -0
  38. package/dist/types/daemon/workspace/hooks/useDaemonChannelEvents.d.ts +31 -0
  39. package/dist/types/daemon/workspace/index.d.ts +2 -2
  40. package/dist/types/daemon/workspace/types.d.ts +7 -1
  41. package/dist/types/daemon-react-sdk.d.ts +2 -0
  42. package/dist/types/utils/navigationUrl.d.ts +1 -1
  43. package/dist/types/utils/standalone-session-routing.d.ts +20 -1
  44. package/dist/{useDaemonMidTurnInjected-CyCL08_O.js → useDaemonMidTurnInjected-Bsza8bIn.js} +5119 -4668
  45. package/package.json +3 -2
  46. package/dist/types/components/WorkflowModeControl.d.ts +0 -8
@@ -1,11 +1,21 @@
1
1
  import './styles/globals.css';
2
- import { type CSSProperties } from 'react';
2
+ import { type ComponentProps, type CSSProperties } from 'react';
3
3
  import { type WebShellBrand } from './brandContext';
4
+ import { ManagedSessionsPage } from './components/managed/ManagedSessionsPage';
4
5
  import { type JavaManagedAgentProviderOptions } from './components/managed/java-managed-agent-provider';
6
+ import type { ManagedAgentProvider } from './components/managed/managed-agent-provider';
5
7
  import { type WebShellLanguage } from './i18n';
6
8
  import { type WebShellTheme } from './themeContext';
9
+ /**
10
+ * 会话列表 portal 到宿主导航槽位所需的 props,直接从 ManagedSessionsPage 的
11
+ * props 推导,避免在入口层维护第二份类型。
12
+ */
13
+ type ManagedSessionsNavigationProps = Pick<ComponentProps<typeof ManagedSessionsPage>, 'navigationTarget' | 'archivedNavigationTarget' | 'onArchivedSessionsStatusChange' | 'navigationActive' | 'navigationSearch'>;
7
14
  /** Change productScope with tenant/actor identity so saved selections and output caches are discarded. */
8
- export interface ManagedAgentWebShellProps extends JavaManagedAgentProviderOptions {
15
+ export interface ManagedAgentWebShellProps extends JavaManagedAgentProviderOptions, ManagedSessionsNavigationProps {
16
+ managedAgentProvider?: ManagedAgentProvider;
17
+ /** Only open the existing Session explicitly selected by the host. */
18
+ hostSessionOnly?: boolean;
9
19
  sessionId?: string;
10
20
  onSessionChange?: (sessionId: string | undefined) => void;
11
21
  language?: WebShellLanguage;
@@ -16,3 +26,4 @@ export interface ManagedAgentWebShellProps extends JavaManagedAgentProviderOptio
16
26
  }
17
27
  /** Managed-only 产品入口,不创建 daemon workspace/session context。 */
18
28
  export declare function ManagedAgentWebShell(props: ManagedAgentWebShellProps): import("react/jsx-runtime").JSX.Element;
29
+ export {};
@@ -0,0 +1,5 @@
1
+ import { type WebShellLanguage } from '../i18n';
2
+ export declare function DaemonConnectionHelp({ language, expanded, }: {
3
+ language: WebShellLanguage;
4
+ expanded?: boolean;
5
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function RemoteAccessSettingsCard(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { DaemonSessionStatsModelMetrics } from '@qwen-code/web-shell/daemon-react-sdk';
7
+ type TimingSample = NonNullable<DaemonSessionStatsModelMetrics['timingSamples']>[number];
8
+ type FailureSample = NonNullable<DaemonSessionStatsModelMetrics['failures']>['recent'][number];
9
+ export interface TrendSeries {
10
+ key: string;
11
+ label: string;
12
+ /** Color slot shared with the model card. */
13
+ color: string;
14
+ samples: TimingSample[];
15
+ failures: FailureSample[];
16
+ }
17
+ export type TrendMetric = 'speed' | 'ttft';
18
+ /** Output tokens per second, or undefined when the window is too short. */
19
+ export declare function sampleSpeed(sample: TimingSample): number | undefined;
20
+ /** Linear-interpolated quantile of an unsorted list; undefined when empty. */
21
+ export declare function quantile(values: number[], q: number): number | undefined;
22
+ export declare function TokenUsageTrend({ series }: {
23
+ series: TrendSeries[];
24
+ }): import("react/jsx-runtime").JSX.Element;
25
+ /** Per-model output-speed spread: every sample as a dot on a shared scale. */
26
+ export declare function SpeedSpread({ samples, scaleMax, }: {
27
+ samples: TimingSample[];
28
+ scaleMax: number;
29
+ }): import("react/jsx-runtime").JSX.Element | null;
30
+ export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { type Ref } from 'react';
7
+ interface ChannelEventsPageProps {
8
+ onClose?: () => void;
9
+ initialFocusRef?: Ref<HTMLHeadingElement>;
10
+ }
11
+ export declare function ChannelEventsPage({ onClose, initialFocusRef, }: ChannelEventsPageProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -19,13 +19,66 @@ export interface ChannelEditorDraft {
19
19
  allowedGroupIds: string;
20
20
  groupSenders: ChannelGroupSenders;
21
21
  groupAllowedUsers: string;
22
+ groupOverrides: Record<string, ChannelGroupOverrideDraft>;
22
23
  }
23
- export type ChannelEditorValidationCode = 'required' | 'credential' | 'duplicate' | 'invalid' | 'invalidGroupId' | 'invalidOption' | 'number' | 'outOfRange' | 'policy';
24
+ /**
25
+ * Per-repository settings. `''` means the key is absent, so the repository
26
+ * inherits from `groups["*"]` and then from the built-in default.
27
+ */
28
+ export interface ChannelGroupOverrideDraft {
29
+ requireMention: '' | 'true' | 'false';
30
+ senders: '' | 'open' | 'allowlist';
31
+ allowedUsers: string;
32
+ }
33
+ export type ChannelEditorValidationCode = 'required' | 'credential' | 'duplicate' | 'invalid' | 'invalidGroupId' | 'invalidOption' | 'invalidRepoId' | 'conflictingRepoAliases' | 'invalidGroupEntry' | 'number' | 'outOfRange' | 'policy';
24
34
  export type ChannelEditorValidationErrors = Record<string, ChannelEditorValidationCode>;
35
+ /** Access fields that only gate direct messages, which repository-only channels never receive. */
36
+ export declare const PRIVATE_ONLY_FIELD_KEYS: Set<string>;
37
+ /**
38
+ * Canonical repository IDs the allowlist currently names, in typing order.
39
+ * Entries that are not `owner/repo` are left out: the save path rejects them,
40
+ * and a row for a half-typed repository would only flicker.
41
+ */
42
+ export declare function repositoryAllowlistIds(value: string): string[];
43
+ export declare function toList(value: string): string[];
25
44
  export declare function hasDescriptorPrivatePolicy(descriptor: DaemonChannelTypeDescriptor): boolean;
26
45
  export declare function hasDescriptorGroupPolicy(descriptor: DaemonChannelTypeDescriptor): boolean;
27
46
  export declare function defaultGroupSenders(): Exclude<ChannelGroupSenders, ''>;
28
47
  export declare function configuredPrivatePolicy(instance?: DaemonChannelInstanceSnapshot): string;
29
48
  export declare function createChannelEditorDraft(descriptor: DaemonChannelTypeDescriptor, instance?: DaemonChannelInstanceSnapshot): ChannelEditorDraft;
30
- export declare function validateChannelEditorDraft(descriptor: DaemonChannelTypeDescriptor, draft: ChannelEditorDraft, existingNames: readonly string[]): ChannelEditorValidationErrors;
49
+ export declare function validateChannelEditorDraft(descriptor: DaemonChannelTypeDescriptor, draft: ChannelEditorDraft, existingNames: readonly string[], instance?: DaemonChannelInstanceSnapshot): ChannelEditorValidationErrors;
50
+ /**
51
+ * Stored repository entries whose value is not an object. The form has no row
52
+ * for them and the store rejects them on every save, so they have to be named
53
+ * rather than silently dropped or passed through to a generic refusal.
54
+ */
55
+ export declare function invalidRepositoryGroupEntries(instance?: DaemonChannelInstanceSnapshot): string[];
56
+ /**
57
+ * Apply one repository's draft over its stored settings. Only a field that
58
+ * differs from the stored reading is written, so an untouched repository keeps
59
+ * every key it had — including ones this form does not model.
60
+ *
61
+ * Exported because the row's helper text must describe what this projection
62
+ * writes, not what the draft happens to hold: deriving the copy from the draft
63
+ * policy alone tells two deliberately-preserved stored shapes the opposite of
64
+ * what the runtime does.
65
+ */
66
+ export declare function projectRepositoryGroup(stored: Record<string, unknown>, override: ChannelGroupOverrideDraft): Record<string, unknown>;
31
67
  export declare function buildChannelUpsertRequest(descriptor: DaemonChannelTypeDescriptor, draft: ChannelEditorDraft, expectedRevision: string, instance?: DaemonChannelInstanceSnapshot): DaemonChannelUpsertRequest;
68
+ export interface RetainedRepositorySetting {
69
+ repositoryId: string;
70
+ /** Whether the entry can still change who is admitted or what is processed. */
71
+ applies: boolean;
72
+ }
73
+ /**
74
+ * The repositories whose settings this save keeps, read back from the request
75
+ * the save actually builds rather than from storage: a repository the operator
76
+ * typed during this visit exists only in the draft, and enumerating stored
77
+ * groups would let the dialog report success without naming it.
78
+ *
79
+ * `applies` follows the runtime, not the shape of the entry. `senderGateFor`
80
+ * builds an allowlist only when the resolved senders policy is `allowlist`, so
81
+ * an `allowedUsers` array beside an inherited `open` policy restricts nobody;
82
+ * and a `requireMention` equal to the inherited value changes nothing either.
83
+ */
84
+ export declare function retainedRepositorySettings(descriptor: DaemonChannelTypeDescriptor, draft: ChannelEditorDraft, instance?: DaemonChannelInstanceSnapshot): RetainedRepositorySetting[];
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ type ChannelEventsMessage = string | ((vars?: Record<string, string | number>) => string);
7
+ export declare const CHANNEL_EVENTS_MESSAGES_EN: Record<string, ChannelEventsMessage>;
8
+ export declare const CHANNEL_EVENTS_MESSAGES_ZH: Record<string, ChannelEventsMessage>;
9
+ export {};
@@ -7,3 +7,4 @@ import type { DaemonChannelTypeDescriptor } from '@qwen-code/sdk/daemon';
7
7
  export declare const PLATFORM_MARKS: Record<string, string>;
8
8
  export declare function isSupportedChannelType(type: unknown): type is 'dingtalk' | 'dws' | 'wecom' | 'wecom-callback' | 'feishu' | 'github' | 'gitlab';
9
9
  export declare function isChannelPlatformAvailable(descriptor: DaemonChannelTypeDescriptor): boolean;
10
+ export declare function isRepositoryOnlyChannelType(type: unknown): boolean;
@@ -3,6 +3,7 @@ import { type SkillInfo } from '../../completions/slashCompletion';
3
3
  import type { CommandDisplayCategoryOrder } from '../../utils/commandDisplay';
4
4
  import type { WebShellComposerTag } from '../../customization';
5
5
  import type { AtMentionWorkspaceActions } from '../../hooks/useAtMentionSources';
6
+ import { type WorkflowModeControlOptions } from '../workflow-mode-control-state';
6
7
  export interface AddMenuProps {
7
8
  disabled?: boolean;
8
9
  availabilityKey: string;
@@ -23,6 +24,7 @@ export interface AddMenuProps {
23
24
  * Omitted when the host has not enabled Plan.
24
25
  */
25
26
  plan?: AddMenuPlanControl;
27
+ workflow?: WorkflowModeControlOptions;
26
28
  btw?: {
27
29
  onSelect: () => void;
28
30
  disabledReason?: string;
@@ -44,4 +46,4 @@ export interface AddMenuPlanControl {
44
46
  disabled?: boolean;
45
47
  onToggle: () => void;
46
48
  }
47
- export declare function AddMenu({ disabled, availabilityKey, addFileAvailable, uploadAvailable, onAddFiles, onFilePickerCancel, onInsertReference, onPrependSkill, getWorkspaceActions, skills, onSkillsOpenChange, skillsLoading, skillsLoadError, skillsLoaded, plan, btw, mobileActions, commandsOnly, simpleMode, }: AddMenuProps): import("react/jsx-runtime").JSX.Element;
49
+ export declare function AddMenu({ disabled, availabilityKey, addFileAvailable, uploadAvailable, onAddFiles, onFilePickerCancel, onInsertReference, onPrependSkill, getWorkspaceActions, skills, onSkillsOpenChange, skillsLoading, skillsLoadError, skillsLoaded, plan, workflow, btw, mobileActions, commandsOnly, simpleMode, }: AddMenuProps): import("react/jsx-runtime").JSX.Element;
@@ -2,7 +2,7 @@ import type { WorkspaceSelectorOption } from '../WorkspaceSelector';
2
2
  import type { ManagedCreationSkillsSource } from './managed-creation-skills';
3
3
  import { type ManagedArchivedSessionsStatus } from './ManagedArchivedSessions';
4
4
  import type { ManagedAgentProvider, ManagedAgentWorkspace } from './managed-agent-provider';
5
- export declare function ManagedSessionsPage({ sessionId, workspaceCreationOpen, onWorkspaceCreationOpenChange, onWorkspaceCreated, onOpenLocalWorkspace, daemonWorkspaces, onSelectDaemonWorkspace, onWorkspacesChange, onSelectSession, onOpenSession, workspaceId, onSelectWorkspace, onSessionWorkspaceChange, managedAgentProvider, navigationTarget, archivedNavigationTarget, onArchivedSessionsStatusChange, interactive, creationSkills, navigationActive, navigationSearch, }: {
5
+ export declare function ManagedSessionsPage({ sessionId, workspaceCreationOpen, onWorkspaceCreationOpenChange, onWorkspaceCreated, onOpenLocalWorkspace, daemonWorkspaces, onSelectDaemonWorkspace, onWorkspacesChange, onSelectSession, onOpenSession, workspaceId, onSelectWorkspace, onSessionWorkspaceChange, managedAgentProvider, hostSessionOnly, navigationTarget, archivedNavigationTarget, onArchivedSessionsStatusChange, interactive, creationSkills, navigationActive, navigationSearch, }: {
6
6
  sessionId?: string;
7
7
  workspaceCreationOpen?: boolean;
8
8
  onWorkspaceCreationOpenChange?: (open: boolean) => void;
@@ -17,6 +17,7 @@ export declare function ManagedSessionsPage({ sessionId, workspaceCreationOpen,
17
17
  onSelectWorkspace?: (workspaceId: string) => void;
18
18
  onSessionWorkspaceChange?: (workspaceId: string | null) => void;
19
19
  managedAgentProvider?: ManagedAgentProvider;
20
+ hostSessionOnly?: boolean;
20
21
  /** Null keeps home layout while its sidebar slot is temporarily unmounted. */
21
22
  navigationTarget?: HTMLElement | null;
22
23
  archivedNavigationTarget?: HTMLElement | null;
@@ -1198,6 +1198,24 @@ export interface components {
1198
1198
  prompts: "complete" | "partial" | "failed" | "stale";
1199
1199
  };
1200
1200
  InputBlock: components["schemas"]["InputTextBlock"] | components["schemas"]["InputFileBlock"] | components["schemas"]["InputImageBlock"];
1201
+ /** @description Immutable Session connection. Requires session-model-config/1, encrypted storage and an endpoint in the control-plane allowlist. UTF-8 limits: model 512 bytes, base_url 2048 bytes, api_key 4096 bytes, complete canonical JSON 8192 bytes. Secrets are never returned in public Session responses. Child Sessions inherit the configuration. Cannot be combined with modelId. */
1202
+ SessionModelConfig: {
1203
+ /** @enum {string} */
1204
+ protocol: "openai" | "openai-responses" | "anthropic" | "gemini";
1205
+ model: string;
1206
+ /** @description Exact allowlisted HTTP(S) base URL without userinfo, query or fragment. */
1207
+ base_url: string;
1208
+ api_key: string;
1209
+ generation_config?: {
1210
+ temperature?: number;
1211
+ top_p?: number;
1212
+ top_k?: number;
1213
+ max_tokens?: number;
1214
+ presence_penalty?: number;
1215
+ frequency_penalty?: number;
1216
+ seed?: number;
1217
+ };
1218
+ };
1201
1219
  PublicArtifact: {
1202
1220
  /** @constant */
1203
1221
  object: "agent.artifact";
@@ -1259,6 +1277,7 @@ export interface components {
1259
1277
  agentId: string;
1260
1278
  /** @description Optional host-catalog model for a bound built-in qwen-code Session. Requires modelSelectionSupported. Persisted atomically before the first Turn and included in creation idempotency; omission preserves the default model and old digest. */
1261
1279
  modelId?: string;
1280
+ modelConfig?: components["schemas"]["SessionModelConfig"];
1262
1281
  /** @description The server enforces the bound in UTF-16 code units (Java String.length()), so an astral character counts as two: a title this schema's code-point maxLength accepts can still exceed the server's 256-unit bound and answer 400 invalid_title. */
1263
1282
  title?: string | null;
1264
1283
  /** @description Text has a 4,000,000-character aggregate budget and per-block 1,000,000-character cap, counted in code points. Hosted also enforces its 64 KiB durable-record limit for text-only inputs and a 32 MiB prepared-snapshot ceiling. A complete canonical input containing file/image attachments must fit within 8 MiB and requires input-attachments/1. */
@@ -37,7 +37,8 @@ export interface JavaManagedAgentClientOptions {
37
37
  export declare class JavaManagedAgentHttpError extends Error {
38
38
  readonly status: number;
39
39
  readonly code: string;
40
- constructor(status: number, code: string, message: string);
40
+ readonly requestId?: string | undefined;
41
+ constructor(status: number, code: string, message: string, requestId?: string | undefined);
41
42
  }
42
43
  export declare class JavaManagedAgentClient {
43
44
  private readonly options;
@@ -430,7 +430,7 @@ export interface ManagedAgentProvider {
430
430
  text: string;
431
431
  input?: ManagedInputBlock[];
432
432
  }, options: ManagedAgentCommandOptions): Promise<ManagedAgentTurnAdmission & {
433
- operationId: string;
433
+ operationId?: string;
434
434
  }>;
435
435
  cancel(sessionId: string, turnId: string, options: ManagedAgentCommandOptions): Promise<{
436
436
  sessionId: string;
@@ -5,6 +5,7 @@ type PluginTab = 'extensions' | 'mcp' | 'skills' | 'agents';
5
5
  interface PluginManagerPageProps {
6
6
  onClose: () => void;
7
7
  onUseSkill: (name: string) => void;
8
+ showBackButton?: boolean;
8
9
  initialFocusRef?: Ref<HTMLButtonElement>;
9
10
  initialTab?: PluginTab;
10
11
  skillsWorkspaceCwd?: string;
@@ -13,5 +14,5 @@ interface PluginManagerPageProps {
13
14
  managedExtensions?: Omit<ManagedExtensionsManagerPageProps, 'onClose'>;
14
15
  managedMcp?: ManagedMcpManagerPageProps;
15
16
  }
16
- export declare function PluginManagerPage({ onClose, onUseSkill, initialFocusRef, initialTab, skillsWorkspaceCwd, onSkillsWorkspaceChange, managedSkills, managedExtensions, managedMcp, }: PluginManagerPageProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function PluginManagerPage({ onClose, onUseSkill, showBackButton, initialFocusRef, initialTab, skillsWorkspaceCwd, onSkillsWorkspaceChange, managedSkills, managedExtensions, managedMcp, }: PluginManagerPageProps): import("react/jsx-runtime").JSX.Element;
17
18
  export {};
@@ -1,4 +1,5 @@
1
1
  export interface EmbeddedManagerPage {
2
2
  onRoot: () => void;
3
3
  onDetailChange: (open: boolean) => void;
4
+ onBack?: () => void;
4
5
  }
@@ -0,0 +1,41 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type ActivityEntry, type ActivityPreferences } from './activity-model';
3
+ export declare const ACTIVITY_PREFERENCES_EVENT = "qwen-code-activity-preferences-changed";
4
+ export declare function readActivityPreferences(): ActivityPreferences;
5
+ interface ActivityOperationState {
6
+ undo?: {
7
+ entries: ActivityEntry[];
8
+ priorityKeys: string[];
9
+ };
10
+ pending: boolean;
11
+ result?: string;
12
+ }
13
+ export declare function useActivityOperations(scope: string): {
14
+ state: ActivityOperationState;
15
+ update: (change: (state: ActivityOperationState) => ActivityOperationState) => void;
16
+ };
17
+ export interface ActivityViewProps {
18
+ operations: ReturnType<typeof useActivityOperations>;
19
+ entries: ActivityEntry[];
20
+ loading: boolean;
21
+ unavailable: boolean;
22
+ hasMore: boolean;
23
+ onLoadMore: () => void | Promise<void>;
24
+ onRetry: () => void;
25
+ renderSession: (entry: ActivityEntry, preview?: string) => ReactNode;
26
+ onMarkRead: (entries: ActivityEntry[]) => Promise<void>;
27
+ onArchive: (entries: ActivityEntry[]) => Promise<{
28
+ succeeded: ActivityEntry[];
29
+ failed: number;
30
+ }>;
31
+ onUndo: (entries: ActivityEntry[]) => Promise<{
32
+ succeeded: ActivityEntry[];
33
+ failed: number;
34
+ }>;
35
+ loadPreview: (entry: ActivityEntry) => Promise<string | undefined>;
36
+ canArchive: boolean;
37
+ pinnedExpanded: boolean;
38
+ onPinnedExpandedChange: (expanded: boolean) => void;
39
+ }
40
+ export declare function ActivityView({ operations, entries, loading, unavailable, hasMore, onLoadMore, onRetry, renderSession, onMarkRead, onArchive, onUndo, loadPreview, canArchive, pinnedExpanded, onPinnedExpandedChange, }: ActivityViewProps): import("react/jsx-runtime").JSX.Element;
41
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare function SidebarSectionHeader({ label, expanded, onToggle, action, }: {
3
+ label: string;
4
+ expanded?: boolean;
5
+ onToggle?: () => void;
6
+ action?: ReactNode;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -17,7 +17,7 @@ export interface WebShellSidebarLockedWorkspace {
17
17
  expanded: boolean;
18
18
  }) => ReactNode;
19
19
  }
20
- export type WebShellSidebarPrimaryNavItem = 'newTask' | 'agents' | 'plugins' | 'channels' | 'live' | 'scheduledTasks' | 'prWatches' | 'workflows' | 'goals' | 'managed';
20
+ export type WebShellSidebarPrimaryNavItem = 'newTask' | 'agents' | 'plugins' | 'channels' | 'channelEvents' | 'live' | 'scheduledTasks' | 'prWatches' | 'workflows' | 'goals' | 'managed';
21
21
  export interface WebShellSidebarPrimaryNavOptions {
22
22
  /** Built-in primary nav entries to show. Embedded hosts default to New session only. */
23
23
  items?: readonly WebShellSidebarPrimaryNavItem[];
@@ -33,7 +33,7 @@ export interface WebShellSidebarFooterOptions {
33
33
  export declare const DEFAULT_FOOTER_ITEMS: readonly WebShellSidebarFooterItem[];
34
34
  export declare const DESKTOP_DEFAULT_FOOTER_ITEMS: readonly WebShellSidebarFooterItem[];
35
35
  export declare const DEFAULT_PRIMARY_NAV_ITEMS: readonly WebShellSidebarPrimaryNavItem[];
36
- export type WebShellSidebarSessionActionItem = 'details' | 'rename' | 'group' | 'export' | 'delete' | 'pin' | 'archive';
36
+ export type WebShellSidebarSessionActionItem = 'details' | 'rename' | 'group' | 'export' | 'delete' | 'pin' | 'split' | 'archive';
37
37
  /** Subset of action items that have working inline (hover-button) handlers. */
38
38
  export type WebShellSidebarSessionInlineActionItem = 'pin' | 'rename' | 'export' | 'delete';
39
39
  export interface WebShellSidebarSessionActionsOptions {
@@ -46,7 +46,7 @@ export interface WebShellSidebarSessionActionsOptions {
46
46
  * archive a session.
47
47
  * Only items that also pass their built-in visibility condition are rendered.
48
48
  * Only items with working inline handlers are accepted
49
- * (details/group/archive are dropdown-only).
49
+ * (details/group/archive/split are dropdown-only).
50
50
  * Recent sessions use dedicated Pin and Archive buttons instead of this
51
51
  * layout; the items policy still controls whether those actions are enabled.
52
52
  * Archived rows use Export and Restore inline, independently of this option.
@@ -73,6 +73,9 @@ interface WebShellSidebarProps {
73
73
  onOpenAgents?: (view?: 'agents' | 'squads' | 'runtime') => void;
74
74
  onOpenPlugins: () => void;
75
75
  onOpenChannels: () => void;
76
+ /** Opens the cross-Channel event timeline; absent when the host does not
77
+ * offer it. */
78
+ onOpenChannelEvents?: () => void;
76
79
  onOpenLive?: () => void;
77
80
  onLiveVoiceSlotChange?: (element: HTMLDivElement | null) => void;
78
81
  onOpenManagedSessions?: () => void;
@@ -92,6 +95,8 @@ interface WebShellSidebarProps {
92
95
  /** Opens the Workspaces overview panel (table of registered workspaces). */
93
96
  onOpenWorkspacesOverview?: () => void;
94
97
  onOpenSplitView: () => void;
98
+ onAddSessionToSplitView?: (sessionId: string) => void;
99
+ splitSessionIds?: readonly string[];
95
100
  /** Whether to offer the in-window split view (large screens only). */
96
101
  canOpenSplitView?: boolean;
97
102
  onNewSession: (workspaceCwd?: string) => Promise<boolean> | boolean;
@@ -104,6 +109,7 @@ interface WebShellSidebarProps {
104
109
  */
105
110
  onOpenHostSession?: (origin: string, sessionId: string, workspaceCwd?: string) => void;
106
111
  onSelectCurrentSession?: () => void;
112
+ onSessionArchived?: (sessionId: string, workspaceCwd: string) => void;
107
113
  onSessionRenameConfirmed?: (workspaceCwd: string | undefined, sessionId: string, displayName: string) => void;
108
114
  /**
109
115
  * `attachedSessionId` is the session this client was attached to when the
@@ -182,4 +188,4 @@ interface WebShellSidebarProps {
182
188
  onLoadStandaloneSession?: (sessionId: string, displayName?: string) => Promise<void> | void;
183
189
  onStandaloneNotice?: (message: string) => void;
184
190
  }
185
- export declare function WebShellSidebar({ collapsed, layout, activePage, containerWidth, onOpenHome, onCollapsedChange, onOpenSettings, canOpenSettings, onOpenAgents, onOpenPlugins, onOpenChannels, onOpenLive, onLiveVoiceSlotChange, onOpenManagedSessions, onOpenDaemonStatus, onOpenScheduledTasks, onOpenPrWatches, onOpenWorkflows, onOpenGoals, onOpenSessions, canOpenSessionsOverview, onOpenWorkspacesOverview, onOpenSplitView, canOpenSplitView, onNewSession, onNewStandaloneSession, onLoadSession, onOpenHostSession, onSelectCurrentSession, onSessionRenameConfirmed, onSessionsDeleted, onError, theme, onThemeChange, mobileOpen, onMobileClose, selectedWorkspaceCwd, onSelectWorkspace, onOpenGitDiff, onOpenCommit, onOpenAddWorkspace, workspaces: providedWorkspaces, lockedWorkspaceCwd, lockedWorkspace: lockedWorkspaceOptions, branding, primaryNav: primaryNavOptions, sessionContent, sessionHeader, managedWorkspaces, managedArchivedSessions, archivedSessionsTarget, onSearchQueryChange, currentSessionActive, showSessionSourceSwitch, showLive, hideProjectHeader, sessionActions: sessionActionsOptions, footer, workspaceOverview, onOpenWorkspaceManagement, onNewWorktreeSession, projectFeaturesEnabled, onLoadStandaloneSession, onStandaloneNotice, }: WebShellSidebarProps): import("react/jsx-runtime").JSX.Element;
191
+ export declare function WebShellSidebar({ collapsed, layout, activePage, containerWidth, onOpenHome, onCollapsedChange, onOpenSettings, canOpenSettings, onOpenAgents, onOpenPlugins, onOpenChannels, onOpenChannelEvents, onOpenLive, onLiveVoiceSlotChange, onOpenManagedSessions, onOpenDaemonStatus, onOpenScheduledTasks, onOpenPrWatches, onOpenWorkflows, onOpenGoals, onOpenSessions, canOpenSessionsOverview, onOpenWorkspacesOverview, onOpenSplitView, onAddSessionToSplitView, splitSessionIds, canOpenSplitView, onNewSession, onNewStandaloneSession, onLoadSession, onOpenHostSession, onSelectCurrentSession, onSessionArchived, onSessionRenameConfirmed, onSessionsDeleted, onError, theme, onThemeChange, mobileOpen, onMobileClose, selectedWorkspaceCwd, onSelectWorkspace, onOpenGitDiff, onOpenCommit, onOpenAddWorkspace, workspaces: providedWorkspaces, lockedWorkspaceCwd, lockedWorkspace: lockedWorkspaceOptions, branding, primaryNav: primaryNavOptions, sessionContent, sessionHeader, managedWorkspaces, managedArchivedSessions, archivedSessionsTarget, onSearchQueryChange, currentSessionActive, showSessionSourceSwitch, showLive, hideProjectHeader, sessionActions: sessionActionsOptions, footer, workspaceOverview, onOpenWorkspaceManagement, onNewWorktreeSession, projectFeaturesEnabled, onLoadStandaloneSession, onStandaloneNotice, }: WebShellSidebarProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ type Message = string | ((vars?: Record<string, string | number>) => string);
2
+ export declare const ACTIVITY_MESSAGES_EN: Record<string, Message>;
3
+ export declare const ACTIVITY_MESSAGES_ZH: Record<string, Message>;
4
+ export {};
@@ -0,0 +1,34 @@
1
+ import type { DaemonSessionSummary } from '@qwen-code/sdk/daemon';
2
+ export interface ActivityEntry {
3
+ key: string;
4
+ session: DaemonSessionSummary;
5
+ unread?: boolean;
6
+ }
7
+ export type ActivityState = 'input' | 'approval' | 'error' | 'unread' | 'active' | 'idle';
8
+ export interface ActivityPreferences {
9
+ priority: boolean;
10
+ pinned: boolean;
11
+ scheduled: boolean;
12
+ }
13
+ export declare const DEFAULT_ACTIVITY_PREFERENCES: ActivityPreferences;
14
+ export interface ActivitySnapshot {
15
+ activatedAt: number;
16
+ priorityKeys: string[];
17
+ recentTimes: ReadonlyMap<string, number>;
18
+ }
19
+ export declare function activityRecency({ session }: ActivityEntry): number;
20
+ export declare function isActivityUnread(entry: ActivityEntry): boolean;
21
+ export declare function activityState(entry: ActivityEntry): ActivityState;
22
+ export declare function activityNeedsAttention(entry: ActivityEntry): boolean;
23
+ export declare function isActivityEligible(entry: ActivityEntry, preferences: ActivityPreferences): boolean;
24
+ export declare function openActivitySnapshot(entries: ActivityEntry[], preferences: ActivityPreferences, now?: number): ActivitySnapshot;
25
+ export declare function updateActivitySnapshot(snapshot: ActivitySnapshot, entries: ActivityEntry[], preferences: ActivityPreferences): ActivitySnapshot;
26
+ export declare function clearReadActivitySnapshot(snapshot: ActivitySnapshot, entries: ActivityEntry[], preferences: ActivityPreferences): ActivitySnapshot;
27
+ export declare function selectActivitySections(snapshot: ActivitySnapshot, entries: ActivityEntry[], preferences: ActivityPreferences): {
28
+ priority: ActivityEntry[];
29
+ pinned: ActivityEntry[];
30
+ recent: {
31
+ dayStart: number;
32
+ entries: ActivityEntry[];
33
+ }[];
34
+ };
@@ -0,0 +1,2 @@
1
+ import type { DaemonSessionSummary } from '@qwen-code/sdk/daemon';
2
+ export declare function comparePinnedSectionSessions(a: DaemonSessionSummary, b: DaemonSessionSummary): number;
@@ -0,0 +1,31 @@
1
+ import type { DaemonClient, DaemonEvent } from '@qwen-code/sdk/daemon';
2
+ import type { ActivityEntry } from './activity-model';
3
+ export declare function activityKey(workspaceCwd: string, sessionId: string): string;
4
+ export declare function activityPreview(events: readonly DaemonEvent[]): string | undefined;
5
+ export declare function activityBatch<T, R>(items: readonly T[], run: (item: T) => Promise<R>): Promise<PromiseSettledResult<R>[]>;
6
+ interface ActivityCatalogOptions {
7
+ client: DaemonClient;
8
+ workspaceCwds: readonly string[];
9
+ enabled: boolean;
10
+ open: boolean;
11
+ liveStateEnabled: boolean;
12
+ currentKey?: string;
13
+ onArchivedCurrent: (entry: ActivityEntry) => void;
14
+ }
15
+ export declare function useActivityCatalog({ client, workspaceCwds, enabled, open, liveStateEnabled, currentKey, onArchivedCurrent, }: ActivityCatalogOptions): {
16
+ entries: ActivityEntry[];
17
+ loading: boolean;
18
+ unavailable: boolean;
19
+ hasMore: boolean;
20
+ archive: (items: ActivityEntry[]) => Promise<{
21
+ succeeded: ActivityEntry[];
22
+ failed: number;
23
+ }>;
24
+ undo: (items: ActivityEntry[]) => Promise<{
25
+ succeeded: ActivityEntry[];
26
+ failed: number;
27
+ }>;
28
+ loadPreview: (entry: ActivityEntry) => Promise<string | undefined>;
29
+ retry: () => void;
30
+ };
31
+ export {};
@@ -0,0 +1,43 @@
1
+ import type { DaemonWorkflowMode, DaemonWorkflowModeStatus } from '@qwen-code/web-shell/daemon-react-sdk';
2
+ import type { WebShellLanguage } from '../i18n';
3
+ export interface WorkflowModeControlOptions {
4
+ workflowMode?: DaemonWorkflowMode;
5
+ workflowModeStatus?: DaemonWorkflowModeStatus;
6
+ workflowModePending?: boolean;
7
+ onWorkflowModeChange?: (requested: boolean) => void;
8
+ }
9
+ export declare function getWorkflowModeControlState({ workflowMode, workflowModeStatus: status, workflowModePending: pending, onWorkflowModeChange, }: WorkflowModeControlOptions, language: WebShellLanguage): {
10
+ mode: DaemonWorkflowMode | undefined;
11
+ disabled: boolean;
12
+ description: string;
13
+ summary: string;
14
+ messages: {
15
+ label: string;
16
+ menuDescription: string;
17
+ short: {
18
+ unbound: string;
19
+ updating: string;
20
+ syncing: string;
21
+ unknown: string;
22
+ onUnavailable: string;
23
+ unavailable: string;
24
+ };
25
+ details: string;
26
+ unbound: string;
27
+ updating: string;
28
+ syncing: string;
29
+ unknown: string;
30
+ on: string;
31
+ off: string;
32
+ onUnavailable: string;
33
+ unavailable: string;
34
+ initializing: string;
35
+ workflowUnavailable: string;
36
+ unsupported: string;
37
+ nextTurn: string;
38
+ updateFailed: string;
39
+ clickToTurnOff: string;
40
+ };
41
+ status: "unknown" | "ready" | "unbound" | "syncing";
42
+ pending: boolean;
43
+ } | null;
@@ -1,6 +1,15 @@
1
1
  import type { WebShellLanguage } from '../i18n';
2
2
  export declare function getWorkflowModeMessages(language: WebShellLanguage): {
3
3
  label: string;
4
+ menuDescription: string;
5
+ short: {
6
+ unbound: string;
7
+ updating: string;
8
+ syncing: string;
9
+ unknown: string;
10
+ onUnavailable: string;
11
+ unavailable: string;
12
+ };
4
13
  details: string;
5
14
  unbound: string;
6
15
  updating: string;
@@ -15,4 +24,5 @@ export declare function getWorkflowModeMessages(language: WebShellLanguage): {
15
24
  unsupported: string;
16
25
  nextTurn: string;
17
26
  updateFailed: string;
27
+ clickToTurnOff: string;
18
28
  };
@@ -51,6 +51,7 @@ export declare function waitForDaemonTokenMessage(timeoutMs?: number): Promise<s
51
51
  export declare function removeDaemonTokenFromUrl(): void;
52
52
  export declare function getDaemonAuthHeaders(): HeadersInit | undefined;
53
53
  export declare function getAllowedDaemonOrigin(raw: string): string;
54
+ export declare function isDaemonMixedContent(daemonOrigin: string): boolean;
54
55
  export declare function buildDaemonConnectionUrl(raw: string, currentHref: string): string | undefined;
55
56
  export declare function confirmDaemonTarget(origin: string): void;
56
57
  export declare function isKnownDaemonTarget(origin: string): boolean;
@@ -5,8 +5,8 @@
5
5
  */
6
6
  export { DaemonSessionProvider, useDaemonActions, useDaemonActiveTodoList, useDaemonConnection, useDaemonPendingPermissions, useDaemonPromptStatus, useDaemonSessionNotices, useDaemonSessionOwnerGuard, useDaemonStreamingState, useDaemonSession, useDaemonTranscriptBlocks, useDaemonTranscriptHistory, useDaemonTranscriptState, useDaemonTranscriptStore, useDaemonTurnNavigationState, useDaemonTurnNavigationStore, useDaemonWorkspaceEventSignals, extractDaemonTodosFromToolBlock, hasDaemonActiveTodos, isDaemonSubAgentToolBlock, parseDaemonTodoItemsFromEntries, selectDaemonActiveTodoList, selectDaemonLatestTodoList, selectDaemonPendingPermissions, selectDaemonSubAgentToolBlocks, selectDaemonStreamingState, selectDaemonTodoLists, selectDaemonTranscriptStreamingState, isMissingSessionHttpStatus, toDaemonPromptContent, } from './session/index.js';
7
7
  export type { DaemonCommandInfo, DaemonConnectionState, DaemonConnectionStatus, DaemonModelInfo, DaemonProductSessionContext, DaemonStandaloneConnectionState, DaemonNoticeCategory, DaemonNoticeOperation, DaemonNoticeSeverity, DaemonPromptFile, DaemonPromptImage, DaemonPromptStatus, DaemonReasoningControls, DaemonWorkflowMode, DaemonWorkflowModeStatus, DaemonSessionActions, DaemonSessionContextValue, DaemonSessionNotice, DaemonSessionOwnerGuard, DaemonSessionOwnerSnapshot, DaemonSessionProviderProps, DaemonTranscriptHistory, DaemonPromptAdmission, DaemonProvisionalTurn, DaemonSelectedTurnState, DaemonTurnIndexPage, DaemonTurnLocation, DaemonTurnNavigationClient, DaemonTurnNavigationError, DaemonTurnNavigationSession, DaemonTurnNavigationSnapshot, DaemonTurnNavigationStore, HistoricalTranscriptPage, HistoricalTranscriptRange, TranscriptBoundary, DaemonTokenUsage, DaemonTodoItem, DaemonTodoList, DaemonTodoPriority, DaemonTodoStatus, DaemonStreamingState, DaemonWorkspaceEventSignals, PendingPromptActionOptions, SendPromptOptions, SubmitPromptOptions, SubmitPromptResult, } from './session/index.js';
8
- export { DaemonWorkspaceProvider, useDaemonWorkspace, useDaemonWorkspaceActions, useOptionalDaemonWorkspace, useDaemonAgents, useDaemonAuth, useDaemonChannels, useDaemonDiagnostics, useDaemonFiles, useDaemonGlob, useDaemonMcp, useDaemonMemory, useDaemonResource, useDaemonSessions, useDaemonSkills, useDaemonStatusReport, useDaemonUsageDashboard, useDaemonTools, useDaemonSettings, useDaemonProviders, } from './workspace/index.js';
9
- export type { DaemonDirectoryEntry, DaemonDirectoryListing, DaemonFileStat, DaemonGlobOptions, DaemonGlobResult, DaemonGoal, DaemonGoalList, DaemonAutofixPrWatch, DaemonAutofixPrWatchList, DaemonScheduledTask, DaemonScheduledTaskGateStatus, DaemonScheduledTaskRun, DaemonCreateScheduledTaskRequest, DaemonUpdateScheduledTaskRequest, DaemonResourceOptions, DaemonChannelPairingActions, DaemonChannelsResource, DaemonStatusReportOptions, DaemonUsageDashboardOptions, DaemonWorkspaceActions, DaemonWorkspaceContextValue, DaemonWorkspaceProviderProps, DaemonWorkspaceStatus, ResourceResult, ResourceState, } from './workspace/index.js';
8
+ export { DaemonWorkspaceProvider, useDaemonWorkspace, useDaemonWorkspaceActions, useOptionalDaemonWorkspace, useDaemonAgents, useDaemonAuth, useDaemonChannels, useDaemonChannelEvents, useDaemonDiagnostics, useDaemonFiles, useDaemonGlob, useDaemonMcp, useDaemonMemory, useDaemonResource, useDaemonSessions, useDaemonSkills, useDaemonStatusReport, useDaemonUsageDashboard, useDaemonTools, useDaemonSettings, useDaemonProviders, } from './workspace/index.js';
9
+ export type { DaemonDirectoryEntry, DaemonDirectoryListing, DaemonFileStat, DaemonGlobOptions, DaemonGlobResult, DaemonGoal, DaemonGoalList, DaemonAutofixPrWatch, DaemonAutofixPrWatchList, DaemonScheduledTask, DaemonScheduledTaskGateStatus, DaemonScheduledTaskRun, DaemonCreateScheduledTaskRequest, DaemonUpdateScheduledTaskRequest, DaemonResourceOptions, DaemonChannelPairingActions, DaemonChannelsResource, DaemonChannelEventEntry, DaemonChannelEventList, DaemonStatusReportOptions, DaemonUsageDashboardOptions, DaemonWorkspaceActions, DaemonWorkspaceContextValue, DaemonWorkspaceProviderProps, DaemonWorkspaceStatus, ResourceResult, ResourceState, } from './workspace/index.js';
10
10
  export { useDaemonFollowupSuggestion, type UseDaemonFollowupSuggestionReturn, } from './useDaemonFollowupSuggestion.js';
11
11
  export { useDaemonMidTurnInjected } from './useDaemonMidTurnInjected.js';
12
12
  export { getPendingPromptVersion, getPendingPromptEvents, consumePendingPromptEvents, subscribePendingPromptEvents, subscribePendingPromptVersion, } from './pendingPromptVersion.js';
@@ -6,6 +6,7 @@
6
6
  export { useDaemonAgents } from './useDaemonAgents.js';
7
7
  export { useDaemonAuth } from './useDaemonAuth.js';
8
8
  export { useDaemonChannels } from './useDaemonChannels.js';
9
+ export { CHANNEL_EVENTS_RELOAD_MS, useDaemonChannelEvents, } from './useDaemonChannelEvents.js';
9
10
  export { useDaemonDiagnostics } from './useDaemonDiagnostics.js';
10
11
  export { useDaemonFiles } from './useDaemonFiles.js';
11
12
  export { useDaemonGlob } from './useDaemonGlob.js';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { DaemonChannelEventEntry, DaemonChannelEventList, DaemonResourceOptions } from '../types.js';
7
+ /** Channels react within seconds; a diagnostic view can lag a little. */
8
+ export declare const CHANNEL_EVENTS_RELOAD_MS = 5000;
9
+ interface DaemonChannelEventsOptions extends DaemonResourceOptions {
10
+ workspaceCwd?: string;
11
+ /** Restrict the timeline to one Channel instance. */
12
+ channel?: string;
13
+ types?: readonly DaemonChannelEventEntry['type'][];
14
+ limit?: number;
15
+ }
16
+ /** A loaded journal together with the query that produced it. */
17
+ interface ChannelEventsSnapshot {
18
+ queryKey: string;
19
+ list: DaemonChannelEventList;
20
+ }
21
+ /**
22
+ * A workspace's Channel event journal, polled while `enabled`. The page can
23
+ * also call `reload` for an explicit refresh.
24
+ */
25
+ export declare function useDaemonChannelEvents(options?: DaemonChannelEventsOptions): {
26
+ data: import("@qwen-code/sdk/daemon").DaemonChannelEventsSnapshot | undefined;
27
+ reload: () => Promise<ChannelEventsSnapshot | undefined>;
28
+ loading: boolean;
29
+ error: Error | undefined;
30
+ };
31
+ export {};