@qwen-code/web-shell 0.25.1-preview.1 → 0.25.1-preview.2
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.
- package/dist/{agents-route-DAa1HKQE.js → agents-route-B3FonPY-.js} +2 -2
- package/dist/daemon-react-sdk.js +1 -1
- package/dist/{index-zUj3SlrB.js → index-BPRuZpl-.js} +45926 -45076
- package/dist/index.js +3 -3
- package/dist/sw.js +1 -1
- package/dist/{toolNames-B_KiYcXs.js → toolNames-CusX912Z.js} +1375 -1334
- package/dist/transcript.js +3775 -3757
- package/dist/types/components/ChatEditor.d.ts +4 -7
- package/dist/types/components/WorkspaceSelector.d.ts +9 -1
- package/dist/types/components/artifacts/artifactUtils.d.ts +9 -0
- package/dist/types/components/managed/generated/managed-agent-api.d.ts +74 -17
- package/dist/types/components/managed/use-managed-actions.d.ts +6 -5
- package/dist/types/components/sidebar/WebShellSidebar.d.ts +7 -1
- package/dist/types/components/sidebar/WorkspaceSection.d.ts +9 -1
- package/dist/types/components/workspaces/HostLabel.d.ts +8 -0
- package/dist/types/components/workspaces/WorkspaceHostProjects.d.ts +11 -4
- package/dist/types/components/workspaces/WorkspaceLocation.d.ts +4 -1
- package/dist/types/config/daemon-target.d.ts +76 -0
- package/dist/types/config/daemon.d.ts +16 -0
- package/dist/types/config/host-fanout.d.ts +53 -0
- package/dist/types/config/remote-connections.d.ts +3 -0
- package/dist/types/config/workspace-hosts.d.ts +7 -0
- package/dist/types/trajectory/types.d.ts +1 -0
- package/dist/types/trajectory/useTrajectoryWindow.d.ts +21 -36
- package/dist/types/trajectory/window-messages.d.ts +9 -0
- package/dist/types/trajectory/window-messages.transcript-stub.d.ts +7 -0
- package/dist/types/utils/workspace.d.ts +10 -0
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@ import { type ComposerSubmitMetadata, type EditorHandle } from '../hooks/useComp
|
|
|
10
10
|
import type { ContextUsageControls } from '../hooks/useContextUsageControls';
|
|
11
11
|
import type { VoiceStatusRevision, VoiceWorkspaceTarget } from '../voice/voice-workspace-target';
|
|
12
12
|
import { type SessionGitIntent } from './GitModePopover';
|
|
13
|
+
import { type WorkspaceSelectorOption } from './WorkspaceSelector';
|
|
13
14
|
export type ComposerToolbarAction = 'approvalMode' | 'plan' | 'contextUsage' | 'gitBranch' | 'model' | 'commands' | 'files' | 'widthMode' | 'voice' | 'workspace' | 'addMenu';
|
|
14
15
|
interface ChatEditorProps {
|
|
15
16
|
onSubmit: (text: string, images?: import('../adapters/promptTypes').PromptImage[], files?: import('../adapters/promptTypes').PromptFile[], commitAccepted?: import('../hooks/useComposerCore').ComposerSubmitCommit, metadata?: ComposerSubmitMetadata) => boolean | void;
|
|
@@ -101,16 +102,12 @@ interface ChatEditorProps {
|
|
|
101
102
|
onSelectModel?: (model: string) => void;
|
|
102
103
|
reasoning?: DaemonReasoningControls;
|
|
103
104
|
onSelectReasoningEffort?: (value: ReasoningSelection, source?: 'toggle') => Promise<void> | void;
|
|
104
|
-
workspaces?:
|
|
105
|
-
id: string;
|
|
106
|
-
cwd: string;
|
|
107
|
-
label: string;
|
|
108
|
-
primary: boolean;
|
|
109
|
-
trusted: boolean;
|
|
110
|
-
}>;
|
|
105
|
+
workspaces?: WorkspaceSelectorOption[];
|
|
111
106
|
selectedWorkspaceCwd?: string;
|
|
112
107
|
workspaceSelectionDisabled?: boolean;
|
|
113
108
|
onSelectWorkspace?: (workspaceCwd: string | undefined) => void;
|
|
109
|
+
/** Host-aware variant; see WorkspaceSelector. */
|
|
110
|
+
onSelectHostedWorkspace?: (hostOrigin: string, workspaceCwd: string | undefined) => void;
|
|
114
111
|
scratchWorkspaceSupported?: boolean;
|
|
115
112
|
existingFolderWorkspaceSupported?: boolean;
|
|
116
113
|
standaloneTargetSupported?: boolean;
|
|
@@ -4,6 +4,8 @@ export interface WorkspaceSelectorOption {
|
|
|
4
4
|
label: string;
|
|
5
5
|
primary: boolean;
|
|
6
6
|
trusted: boolean;
|
|
7
|
+
/** Daemon host this workspace lives on; defaults to the page origin. */
|
|
8
|
+
hostOrigin?: string;
|
|
7
9
|
}
|
|
8
10
|
interface WorkspaceSelectorProps {
|
|
9
11
|
workspaces: WorkspaceSelectorOption[];
|
|
@@ -17,6 +19,12 @@ interface WorkspaceSelectorProps {
|
|
|
17
19
|
selectedStandalone?: boolean;
|
|
18
20
|
className?: string;
|
|
19
21
|
onSelectWorkspace: (cwd: string | undefined) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Host-aware selection for multi-daemon pages. When provided it fires
|
|
24
|
+
* INSTEAD of `onSelectWorkspace`, with the option's host (page origin when
|
|
25
|
+
* unset); `undefined` cwd keeps marking the host's primary workspace.
|
|
26
|
+
*/
|
|
27
|
+
onSelectHostedWorkspace?: (hostOrigin: string, cwd: string | undefined) => void;
|
|
20
28
|
onSelectStandalone?: () => void;
|
|
21
29
|
onCreateScratch: () => void;
|
|
22
30
|
onOpenExistingFolder: () => void;
|
|
@@ -25,5 +33,5 @@ interface WorkspaceSelectorProps {
|
|
|
25
33
|
* Composer workspace menu. Capability-gated creation actions and disabled
|
|
26
34
|
* untrusted entries keep presentation aligned with daemon authorization.
|
|
27
35
|
*/
|
|
28
|
-
export declare function WorkspaceSelector({ workspaces, selectedWorkspaceCwd, disabled, busy, scratchSupported, existingFolderSupported, standaloneSupported, selectedStandalone, className, onSelectWorkspace, onSelectStandalone, onCreateScratch, onOpenExistingFolder, }: WorkspaceSelectorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
36
|
+
export declare function WorkspaceSelector({ workspaces, selectedWorkspaceCwd, disabled, busy, scratchSupported, existingFolderSupported, standaloneSupported, selectedStandalone, className, onSelectWorkspace, onSelectHostedWorkspace, onSelectStandalone, onCreateScratch, onOpenExistingFolder, }: WorkspaceSelectorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
29
37
|
export {};
|
|
@@ -30,6 +30,15 @@ export declare function readWorkspaceFileAsBlob(readFileBytes: (filePath: string
|
|
|
30
30
|
}): Promise<Blob>;
|
|
31
31
|
export declare function downloadWorkspaceFile(workspaceActions: Pick<DaemonWorkspaceActions, 'readFileBytes' | 'stat'>, workspacePath: string, mimeType?: string, isCancelled?: () => boolean): Promise<void>;
|
|
32
32
|
export declare function getArtifactLocation(artifact: DaemonSessionArtifact): string;
|
|
33
|
+
/**
|
|
34
|
+
* Workspace files are shown by filename. Links and managed artifacts have no
|
|
35
|
+
* file, so they keep the stored title.
|
|
36
|
+
*/
|
|
37
|
+
export declare function artifactDisplayName(artifact: Pick<DaemonSessionArtifact, 'title'> & {
|
|
38
|
+
workspacePath?: string;
|
|
39
|
+
}): string;
|
|
40
|
+
/** A backslash stays in the name, matching `path.posix.basename`. */
|
|
41
|
+
export declare function workspaceFileName(workspacePath: string | undefined): string | undefined;
|
|
33
42
|
export declare function normalizePath(value: string | undefined): string;
|
|
34
43
|
export declare function stripWorkspacePath(path: string, workspaceCwd?: string): string;
|
|
35
44
|
export declare function isSamePath(left: string | undefined, right: string | undefined, workspaceCwd?: string): boolean;
|
|
@@ -57,7 +57,7 @@ export interface paths {
|
|
|
57
57
|
};
|
|
58
58
|
get?: never;
|
|
59
59
|
put?: never;
|
|
60
|
-
/** @description POST SSE consumed through fetch response.body. An afterSequence below the replay floor ends the stream with one agent.session.resync_required frame instead of a 409; reload the transcript and resume after its lastSequence. */
|
|
60
|
+
/** @description POST SSE consumed through fetch response.body. An afterSequence below the replay floor ends the stream with one agent.session.resync_required frame instead of a 409 only while the Snapshot backs the floor (replay_floor_sequence <= snapshot_through_sequence); a stream reconciliation discards the Snapshot without lowering the floor, and during that rebuild such a cursor is served from the retained events. On the resync frame, reload the transcript and resume after its lastSequence. */
|
|
61
61
|
post: operations["webShellStreamEvents"];
|
|
62
62
|
delete?: never;
|
|
63
63
|
options?: never;
|
|
@@ -74,7 +74,7 @@ export interface paths {
|
|
|
74
74
|
};
|
|
75
75
|
get?: never;
|
|
76
76
|
put?: never;
|
|
77
|
-
/** @description Maps workspaceId/cwdRelative to public Workspace selection without using environmentId or absolute cwd. Shares G0's opt-in initial file-tool Turn admission and fixed server-owned profile with public Session creation.
|
|
77
|
+
/** @description Maps workspaceId/cwdRelative to public Workspace selection without using environmentId or absolute cwd. Shares G0's opt-in initial file-tool Turn admission and fixed server-owned profile with public Session creation. Any caller holding the OPERATOR role may submit later Turns and rename the Session under the same opt-in, while the Workspace registry row stays ACTIVE and still backs the binding, the actor recorded by the Workspace create command keeps OPERATOR or above, and the Session is an active, undeleted qwen-code Session on the frozen execution profile; Workspace close follows its separate close capability and lifecycle admission; the same caller may cancel a running Turn (its delivery re-checks no grants); archive and unarchive follow their separate retention capabilities after reliable Workspace close; delete supports either L3 idle ACTIVE files Sessions or L2 CLOSED/ARCHIVED Sessions; controlled same-Workspace cwd changes ship through the durable cwd_change operations (v1.32). The per-caller workspaceTurns capability on this surface advertises the same submit/rename admission rule; it does not gate cancellation. Freeze selection with the original idempotency key; admission does not prove physical directory readiness. */
|
|
78
78
|
post: operations["webShellCreateSession"];
|
|
79
79
|
delete?: never;
|
|
80
80
|
options?: never;
|
|
@@ -140,7 +140,7 @@ export interface paths {
|
|
|
140
140
|
};
|
|
141
141
|
get?: never;
|
|
142
142
|
put?: never;
|
|
143
|
-
/** @description W2, implemented: the camelCase twin of the public changeSessionCwd with the matched refusal order: 400 invalid_request for a missing or malformed field; 401 actor_required without a trusted actor; 400 invalid_idempotency_key for a malformed idempotencyKey — with two documented divergences: a key over 128 characters is refused during request validation with 400 invalid_request before the service's check, and a blank idempotencyKey is refused there too, while the public header answers 400 invalid_idempotency_key for both shapes; 400 invalid_cwd for a lexical violation and 400 invalid_request for an expectedContextRevision below 1; 404 session_not_found for an unknown Session id; 400 unsupported_feature for an unbound Session; 404 session_not_found for an unreadable Session
|
|
143
|
+
/** @description W2, implemented: the camelCase twin of the public changeSessionCwd with the matched refusal order: 400 invalid_request for a missing or malformed field; 401 actor_required without a trusted actor; 400 invalid_idempotency_key for a malformed idempotencyKey — with two documented divergences: a key over 128 characters is refused during request validation with 400 invalid_request before the service's check, and a blank idempotencyKey is refused there too, while the public header answers 400 invalid_idempotency_key for both shapes; 400 invalid_cwd for a lexical violation and 400 invalid_request for an expectedContextRevision below 1; 404 session_not_found for an unknown Session id; 400 unsupported_feature for an unbound Session; 404 session_not_found for an unreadable Session; 409 idempotency_conflict when one key carries different content, and a completed change under the same key always replays instead, before the role refusal; 403 session_operation_forbidden when a readable actor's Workspace role is below OPERATOR; 409 workspace_unavailable when execution is disabled; 404 session_not_found for a deleted Session; then 409 session_state_conflict, 409 workspace_unavailable from moved Registry facts (the recorded create-command actor's grant included, and the settlement re-checks the V56-persisted initiator the same way, so demoting either actor fails the operation, exactly like the public surface), 409 context_revision_conflict and 409 session_context_busy. Poll the operation or await session.context.changed; do not treat 202 as activation. */
|
|
144
144
|
post: operations["webShellChangeCwd"];
|
|
145
145
|
delete?: never;
|
|
146
146
|
options?: never;
|
|
@@ -173,7 +173,7 @@ export interface paths {
|
|
|
173
173
|
};
|
|
174
174
|
get?: never;
|
|
175
175
|
put?: never;
|
|
176
|
-
/** @description D6 serves Hosted permission Actions. Question Actions and vote_recorded remain planned. Reads follow Session authorization;
|
|
176
|
+
/** @description D6 serves Hosted permission Actions. Question Actions and vote_recorded remain planned. Reads follow Session authorization; the Session's recorded owner or any caller holding OPERATOR on the bound Workspace may respond (an unbound Session with no recorded creator and no recorded create command answers to any caller in its tenant, matching its read ACL; a bound Session without an owner record answers through the create-command actor recorded for it, or through the Workspace role arm). Responses are durable operations, reconciled against the original journal decision. */
|
|
177
177
|
post: operations["queryWebShellActions"];
|
|
178
178
|
delete?: never;
|
|
179
179
|
options?: never;
|
|
@@ -190,7 +190,7 @@ export interface paths {
|
|
|
190
190
|
};
|
|
191
191
|
get?: never;
|
|
192
192
|
put?: never;
|
|
193
|
-
/** @description D6 serves Hosted permission Actions. Question Actions and vote_recorded remain planned. Reads follow Session authorization;
|
|
193
|
+
/** @description D6 serves Hosted permission Actions. Question Actions and vote_recorded remain planned. Reads follow Session authorization; the Session's recorded owner or any caller holding OPERATOR on the bound Workspace may respond (an unbound Session with no recorded creator and no recorded create command answers to any caller in its tenant, matching its read ACL; a bound Session without an owner record answers through the create-command actor recorded for it, or through the Workspace role arm). Responses are durable operations, reconciled against the original journal decision. */
|
|
194
194
|
post: operations["getWebShellAction"];
|
|
195
195
|
delete?: never;
|
|
196
196
|
options?: never;
|
|
@@ -207,7 +207,7 @@ export interface paths {
|
|
|
207
207
|
};
|
|
208
208
|
get?: never;
|
|
209
209
|
put?: never;
|
|
210
|
-
/** @description D6 serves Hosted permission Actions. Question Actions and vote_recorded remain planned. Reads follow Session authorization;
|
|
210
|
+
/** @description D6 serves Hosted permission Actions. Question Actions and vote_recorded remain planned. Reads follow Session authorization; the Session's recorded owner or any caller holding OPERATOR on the bound Workspace may respond (an unbound Session with no recorded creator and no recorded create command answers to any caller in its tenant, matching its read ACL; a bound Session without an owner record answers through the create-command actor recorded for it, or through the Workspace role arm). Responses are durable operations, reconciled against the original journal decision. */
|
|
211
211
|
post: operations["respondWebShellAction"];
|
|
212
212
|
delete?: never;
|
|
213
213
|
options?: never;
|
|
@@ -224,7 +224,7 @@ export interface paths {
|
|
|
224
224
|
};
|
|
225
225
|
get?: never;
|
|
226
226
|
put?: never;
|
|
227
|
-
/** @description Uses the same close admission,
|
|
227
|
+
/** @description Uses the same close admission, owner authorization and durable cleanup semantics as the public close route. sessionClose describes deployment support; it does not grant actor authorization. New L3 Workspace close operations run SessionEnd only, retain data, and finish after durable effects verification and original Runtime stop. SessionDelete is reserved for ACTIVE delete. Missing protocol support rejects new admission; previously admitted operations retain their saved protocol. Unknown outcomes remain recovery_blocked. */
|
|
228
228
|
post: operations["closeWebShellSession"];
|
|
229
229
|
delete?: never;
|
|
230
230
|
options?: never;
|
|
@@ -241,7 +241,7 @@ export interface paths {
|
|
|
241
241
|
};
|
|
242
242
|
get?: never;
|
|
243
243
|
put?: never;
|
|
244
|
-
/** @description Workspace-bound archive requires a closed Session with completed reliable-close evidence and the
|
|
244
|
+
/** @description Workspace-bound archive requires a closed Session with completed reliable-close evidence and the Session's recorded owner with current read access. It completes atomically during admission, preserves data and the permanent close fence, and calls neither Harness nor Runtime. A readable non-owner returns 403; missing close evidence returns 409 workspace_unavailable. */
|
|
245
245
|
post: operations["archiveWebShellSession"];
|
|
246
246
|
delete?: never;
|
|
247
247
|
options?: never;
|
|
@@ -258,7 +258,7 @@ export interface paths {
|
|
|
258
258
|
};
|
|
259
259
|
get?: never;
|
|
260
260
|
put?: never;
|
|
261
|
-
/** @description Workspace-bound ACTIVE deletion supports idle hosted-workspace-files/1 Sessions when L3 lifecycle protocol and reliable Runtime stop are available. Only the creator with current read access may admit it; accepted, running, cancelling or approval-waiting Turns return 409 turn_active. Admission persists a lifecycle-only execution fence and a versioned actor-scoped operation. SessionEnd settles before SessionDelete; committed Hook results are verified in Session Store and saved before permanent draining, attachment cleanup and original worker stop. Unknown outcomes or missing original stop evidence remain recovery_blocked and are never replayed on a replacement worker. CLOSED/ARCHIVED deletion retains L2: completed reliable-close evidence is required and no Harness or Hook is invoked. Completion atomically commits retirement, tombstone, receipt and terminal event, retaining shared Workspace files and neighboring holders. Authorized same-actor/key replays return the original operation, including after deletion; readable non-
|
|
261
|
+
/** @description Workspace-bound ACTIVE deletion supports idle hosted-workspace-files/1 Sessions when L3 lifecycle protocol and reliable Runtime stop are available. Only the Session's recorded owner (owner_actor_key, with the pre-V40 creator fallback) with current read access may admit it; accepted, running, cancelling or approval-waiting Turns return 409 turn_active. Admission persists a lifecycle-only execution fence and a versioned actor-scoped operation. SessionEnd settles before SessionDelete; committed Hook results are verified in Session Store and saved before permanent draining, attachment cleanup and original worker stop. Unknown outcomes or missing original stop evidence remain recovery_blocked and are never replayed on a replacement worker. CLOSED/ARCHIVED deletion retains L2: completed reliable-close evidence is required and no Harness or Hook is invoked. Completion atomically commits retirement, tombstone, receipt and terminal event, retaining shared Workspace files and neighboring holders. Authorized same-actor/key replays return the original operation, including after deletion; a readable non-owner returns 403. Missing lifecycle capability or close evidence returns 409 workspace_unavailable. */
|
|
262
262
|
post: operations["deleteWebShellSession"];
|
|
263
263
|
delete?: never;
|
|
264
264
|
options?: never;
|
|
@@ -331,6 +331,22 @@ export interface paths {
|
|
|
331
331
|
patch?: never;
|
|
332
332
|
trace?: never;
|
|
333
333
|
};
|
|
334
|
+
"/api/agent/web-shell/v1/tasks/cancel": {
|
|
335
|
+
parameters: {
|
|
336
|
+
query?: never;
|
|
337
|
+
header?: never;
|
|
338
|
+
path?: never;
|
|
339
|
+
cookie?: never;
|
|
340
|
+
};
|
|
341
|
+
get?: never;
|
|
342
|
+
put?: never;
|
|
343
|
+
post: operations["cancelWebShellTask"];
|
|
344
|
+
delete?: never;
|
|
345
|
+
options?: never;
|
|
346
|
+
head?: never;
|
|
347
|
+
patch?: never;
|
|
348
|
+
trace?: never;
|
|
349
|
+
};
|
|
334
350
|
"/api/agent/web-shell/v1/tool-results/get": {
|
|
335
351
|
parameters: {
|
|
336
352
|
query?: never;
|
|
@@ -388,7 +404,7 @@ export interface paths {
|
|
|
388
404
|
};
|
|
389
405
|
get?: never;
|
|
390
406
|
put?: never;
|
|
391
|
-
/** @description Synchronously restores an archived Session to closed. Workspace-bound Sessions require completed reliable-close evidence and the
|
|
407
|
+
/** @description Synchronously restores an archived Session to closed. Workspace-bound Sessions require completed reliable-close evidence and the Session's recorded owner with current read access (404 unreadable, 403 readable non-owner). Bound keys are tenant/Session/actor scoped. Replay returns the current visible Session without repeating the mutation; a deleted Session returns 404. The permanent close fence is preserved and no Harness or Runtime call is made. */
|
|
392
408
|
post: operations["unarchiveWebShellSession"];
|
|
393
409
|
delete?: never;
|
|
394
410
|
options?: never;
|
|
@@ -528,14 +544,14 @@ export interface components {
|
|
|
528
544
|
/** @default false */
|
|
529
545
|
actions: boolean;
|
|
530
546
|
/**
|
|
531
|
-
* @description True when the caller may submit later Turns of this Workspace-bound Session: the deployment enables Workspace files, the caller
|
|
547
|
+
* @description True when the caller may submit later Turns of this Workspace-bound Session or rename it: the deployment enables Workspace files, the caller holds the OPERATOR role on a Workspace registry row whose state is ACTIVE and still backs the Session's binding, the actor recorded by the Workspace create command keeps OPERATOR or above, and the Session is an active qwen-code Session on the frozen execution profile. Cancelling only aborts work already running, so an OPERATOR caller may cancel a running Turn even when this is false; the capability does not gate cancellation. False for every other caller and for unbound Sessions, which do not use it.
|
|
532
548
|
* @default false
|
|
533
549
|
*/
|
|
534
550
|
workspaceTurns: boolean;
|
|
535
551
|
tasks: boolean;
|
|
536
552
|
artifacts: boolean;
|
|
537
553
|
/**
|
|
538
|
-
* @description Deployment support for close independently of archive/delete. Admission also requires
|
|
554
|
+
* @description Deployment support for close independently of archive/delete. Admission also requires Session ownership and current read access for a bound Session.
|
|
539
555
|
* @default false
|
|
540
556
|
*/
|
|
541
557
|
sessionClose?: boolean;
|
|
@@ -687,7 +703,7 @@ export interface components {
|
|
|
687
703
|
* @default false
|
|
688
704
|
*/
|
|
689
705
|
workspaceContext: boolean;
|
|
690
|
-
/** @description Supports authorized Workspace discovery, Session creation, and saved binding read-back. This capability does not advertise execution readiness. Deployments may separately opt in to an initial Workspace Read/Write/Edit Turn at creation; the
|
|
706
|
+
/** @description Supports authorized Workspace discovery, Session creation, and saved binding read-back. This capability does not advertise execution readiness. Deployments may separately opt in to an initial Workspace Read/Write/Edit Turn at creation; callers holding the OPERATOR role may submit later Turns or rename under the same opt-in while the registry row stays ACTIVE and still backs the Session's binding and the actor recorded by the Workspace create command keeps OPERATOR or above, and may cancel a running Turn (its delivery re-checks no grants), while close follows its separate capability and lifecycle admission; archive, delete and unarchive follow their separate retention capabilities after reliable Workspace close. */
|
|
691
707
|
workspaceBinding: boolean;
|
|
692
708
|
};
|
|
693
709
|
/** @description Same authorized explicit default as default_workspace, including when outside this page; null if absent or not creatable. A non-null default is active and has canCreateSession=true. */
|
|
@@ -759,6 +775,8 @@ export interface components {
|
|
|
759
775
|
sessionId: string;
|
|
760
776
|
/** @enum {unknown} */
|
|
761
777
|
type: "create_session" | "submit_input" | "cancel" | "action_response" | "close" | "archive" | "delete" | "task_cancel";
|
|
778
|
+
/** @description Task that a task_cancel operation targets. */
|
|
779
|
+
taskId?: string;
|
|
762
780
|
/** @enum {unknown} */
|
|
763
781
|
status: "pending" | "running" | "completed" | "failed" | "cancelled" | "recovery_blocked";
|
|
764
782
|
/** @enum {unknown} */
|
|
@@ -767,10 +785,10 @@ export interface components {
|
|
|
767
785
|
deliveryState: "pending" | "leased" | "confirmed" | "blocked";
|
|
768
786
|
receiptId?: string;
|
|
769
787
|
actionResolution?: components["schemas"]["WebShellActionResolution"];
|
|
770
|
-
/** @description Reason a durable response or task cancellation failed. Action response failures come from the original committed Action, or a definitive invalid response. Workspace close recovery_blocked reports original resource identity or unsettled execution; the Session remains closing. */
|
|
788
|
+
/** @description Reason a durable response or task cancellation failed. Action response failures come from the original committed Action, or a definitive invalid response. Task cancel failures are task_already_settled (the run ended before the stop request was recorded), task_action_unavailable and task_not_found; a recovery_blocked task cancel reports task_cancel_unconfirmed. Workspace close recovery_blocked reports original resource identity or unsettled execution; the Session remains closing. */
|
|
771
789
|
failureCode?: string;
|
|
772
790
|
replayed: boolean;
|
|
773
|
-
} & (unknown & unknown & unknown & unknown);
|
|
791
|
+
} & (unknown & unknown & unknown & unknown & unknown);
|
|
774
792
|
WebShellQuestionAction: {
|
|
775
793
|
actionId: string;
|
|
776
794
|
/** Format: uuid */
|
|
@@ -894,7 +912,7 @@ export interface components {
|
|
|
894
912
|
*/
|
|
895
913
|
TaskRuntimeState: "unbound" | "provisioning" | "ready" | "draining" | "lost";
|
|
896
914
|
/**
|
|
897
|
-
* @description Actions the task supports now, the same for every caller. cancel: the cancel route accepts a new command for this task; whether a caller may use it is an authorization check (403 on the cancel route). send_input: reserved for a later capability route. read_output: the task events route returns output events for this task to any caller that can read it. read_output does not change during the task's life, and a task without it produces no output events: its output goes only to Artifacts, so the events route never filters out events that exist.
|
|
915
|
+
* @description Actions the task supports now, the same for every caller. cancel: the cancel route accepts a new command for this task (since 1.40, child_agent tasks in pending, running, waiting or degraded, in an active Session); whether a caller may use it is an authorization check (403 on the cancel route). send_input: reserved for a later capability route. read_output: the task events route returns output events for this task to any caller that can read it. read_output does not change during the task's life, and a task without it produces no output events: its output goes only to Artifacts, so the events route never filters out events that exist.
|
|
898
916
|
* @enum {string}
|
|
899
917
|
*/
|
|
900
918
|
TaskActionCapability: "cancel" | "send_input" | "read_output";
|
|
@@ -983,6 +1001,14 @@ export interface components {
|
|
|
983
1001
|
/** @default 20 */
|
|
984
1002
|
limit?: number;
|
|
985
1003
|
};
|
|
1004
|
+
WebShellTaskCancelRequest: {
|
|
1005
|
+
/** @description Trace correlation only; excluded from the request digest, so a retry with another requestId still replays. A header-safe value (1 to 128 visible ASCII characters) is echoed as X-Request-Id; any other value is replaced by a server-chosen id. */
|
|
1006
|
+
requestId?: string | null;
|
|
1007
|
+
/** Format: uuid */
|
|
1008
|
+
sessionId: string;
|
|
1009
|
+
taskId: string;
|
|
1010
|
+
idempotencyKey: string;
|
|
1011
|
+
};
|
|
986
1012
|
/** @description state_changed, output or artifact. The set is open: a later minor version may add types and optional fields. Clients ignore unknown optional fields and unknown types, while still checkpointing event cursors; strict validation against an older minor response schema is not supported. Existing fields forbidden for a known type cannot be repurposed on that type. */
|
|
987
1013
|
TaskEventType: string;
|
|
988
1014
|
ToolResultPreview: {
|
|
@@ -1532,7 +1558,7 @@ export interface operations {
|
|
|
1532
1558
|
};
|
|
1533
1559
|
400: components["responses"]["BadRequest"];
|
|
1534
1560
|
401: components["responses"]["Unauthorized"];
|
|
1535
|
-
/** @description Responding requires the Session
|
|
1561
|
+
/** @description Responding requires the Session's recorded owner or a Workspace OPERATOR (action_forbidden). An unbound Session with no recorded creator and no recorded create command (anonymous open-mode creation, or an unbound Session created before the V40 migration that also has no Workspace creation record) answers to any caller in its tenant, matching its read ACL; a bound Session with no recorded owner answers through the create-command actor recorded for it, or through the Workspace role arm. The tenant filter's 403 actor_scope_mismatch also applies on this route. */
|
|
1536
1562
|
403: components["responses"]["Forbidden"];
|
|
1537
1563
|
/** @description Unknown or unreadable Session (session_not_found), or unknown Action (action_not_found). */
|
|
1538
1564
|
404: components["responses"]["NotFound"];
|
|
@@ -1748,6 +1774,37 @@ export interface operations {
|
|
|
1748
1774
|
413: components["responses"]["PayloadTooLarge"];
|
|
1749
1775
|
};
|
|
1750
1776
|
};
|
|
1777
|
+
cancelWebShellTask: {
|
|
1778
|
+
parameters: {
|
|
1779
|
+
query?: never;
|
|
1780
|
+
header?: never;
|
|
1781
|
+
path?: never;
|
|
1782
|
+
cookie?: never;
|
|
1783
|
+
};
|
|
1784
|
+
requestBody: {
|
|
1785
|
+
content: {
|
|
1786
|
+
"application/json": components["schemas"]["WebShellTaskCancelRequest"];
|
|
1787
|
+
};
|
|
1788
|
+
};
|
|
1789
|
+
responses: {
|
|
1790
|
+
/** @description Same authorized task cancellation semantics as the public API: key validation, current access, idempotent replay, then new-request capability, Session, task and storage-migration checks (409 workspace_unavailable under a migration fence). Replay returns the same operation and latest durable state. 202 is durable admission, completed is authority acceptance, and neither proves physical stop. Admission requires no other open operation on the Session (409 session_operation_active), as on the lifecycle routes. A requestId in the body becomes the response's X-Request-Id and stays out of the request digest. */
|
|
1791
|
+
202: {
|
|
1792
|
+
headers: {
|
|
1793
|
+
"X-Request-Id": components["headers"]["RequestId"];
|
|
1794
|
+
[name: string]: unknown;
|
|
1795
|
+
};
|
|
1796
|
+
content: {
|
|
1797
|
+
"application/json": components["schemas"]["WebShellCommandOperation"];
|
|
1798
|
+
};
|
|
1799
|
+
};
|
|
1800
|
+
400: components["responses"]["BadRequest"];
|
|
1801
|
+
401: components["responses"]["Unauthorized"];
|
|
1802
|
+
403: components["responses"]["Forbidden"];
|
|
1803
|
+
404: components["responses"]["NotFound"];
|
|
1804
|
+
409: components["responses"]["Conflict"];
|
|
1805
|
+
413: components["responses"]["PayloadTooLarge"];
|
|
1806
|
+
};
|
|
1807
|
+
};
|
|
1751
1808
|
getWebShellToolResult: {
|
|
1752
1809
|
parameters: {
|
|
1753
1810
|
query?: never;
|
|
@@ -12,11 +12,12 @@ export interface ManagedActionsState {
|
|
|
12
12
|
/** Sending an answer failed; the approval is shown again. */
|
|
13
13
|
answerError?: unknown;
|
|
14
14
|
/**
|
|
15
|
-
* The service refused an answer
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* The service refused an answer under the owner-or-Workspace-operator
|
|
16
|
+
* rule. That refusal is a fact about the viewer's Workspace role row,
|
|
17
|
+
* which an operator can raise while the page stays open, so the latch
|
|
18
|
+
* covers every later approval the same Session raises and survives
|
|
19
|
+
* leaving that Session and coming back — but `retry()` drops it and
|
|
20
|
+
* re-probes instead of treating one 403 as permanent for the mount.
|
|
20
21
|
*/
|
|
21
22
|
respondForbidden: boolean;
|
|
22
23
|
respond(actionId: string, optionId: string): Promise<void>;
|
|
@@ -89,6 +89,12 @@ interface WebShellSidebarProps {
|
|
|
89
89
|
onNewSession: (workspaceCwd?: string) => Promise<boolean> | boolean;
|
|
90
90
|
onNewStandaloneSession?: () => Promise<boolean> | boolean;
|
|
91
91
|
onLoadSession: (sessionId: string, workspaceCwd?: string) => Promise<void> | void;
|
|
92
|
+
/**
|
|
93
|
+
* Opens a session listed by a fan-out host group (#13727): the caller
|
|
94
|
+
* focuses that host in-app and loads the session there. When absent, the
|
|
95
|
+
* groups fall back to full navigation via `openHostedWorkspace`.
|
|
96
|
+
*/
|
|
97
|
+
onOpenHostSession?: (origin: string, sessionId: string, workspaceCwd?: string) => void;
|
|
92
98
|
onSelectCurrentSession?: () => void;
|
|
93
99
|
onSessionRenameConfirmed?: (workspaceCwd: string | undefined, sessionId: string, displayName: string) => void;
|
|
94
100
|
/**
|
|
@@ -156,4 +162,4 @@ interface WebShellSidebarProps {
|
|
|
156
162
|
onLoadStandaloneSession?: (sessionId: string) => Promise<void> | void;
|
|
157
163
|
onStandaloneNotice?: (message: string) => void;
|
|
158
164
|
}
|
|
159
|
-
export declare function WebShellSidebar({ collapsed, layout, activePage, containerWidth, onOpenHome, onCollapsedChange, onOpenSettings, onOpenAgents, onOpenPlugins, onOpenChannels, onOpenLive, onLiveVoiceSlotChange, onOpenManagedSessions, onOpenDaemonStatus, onOpenScheduledTasks, onOpenWorkflows, onOpenGoals, onOpenSessions, canOpenSessionsOverview, onOpenWorkspacesOverview, onOpenSplitView, canOpenSplitView, onNewSession, onNewStandaloneSession, onLoadSession, onSelectCurrentSession, onSessionRenameConfirmed, onSessionsDeleted, onError, theme, onThemeChange, mobileOpen, onMobileClose, selectedWorkspaceCwd, onSelectWorkspace, onOpenGitDiff, onOpenCommit, onOpenAddWorkspace, workspaces: providedWorkspaces, lockedWorkspaceCwd, lockedWorkspace: lockedWorkspaceOptions, branding, primaryNav: primaryNavOptions, showSessionSourceSwitch, showLive, hideProjectHeader, sessionActions: sessionActionsOptions, footer, workspaceOverview, onOpenWorkspaceManagement, onNewWorktreeSession, projectFeaturesEnabled, onLoadStandaloneSession, onStandaloneNotice, }: WebShellSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
165
|
+
export declare function WebShellSidebar({ collapsed, layout, activePage, containerWidth, onOpenHome, onCollapsedChange, onOpenSettings, onOpenAgents, onOpenPlugins, onOpenChannels, onOpenLive, onLiveVoiceSlotChange, onOpenManagedSessions, onOpenDaemonStatus, onOpenScheduledTasks, 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, showSessionSourceSwitch, showLive, hideProjectHeader, sessionActions: sessionActionsOptions, footer, workspaceOverview, onOpenWorkspaceManagement, onNewWorktreeSession, projectFeaturesEnabled, onLoadStandaloneSession, onStandaloneNotice, }: WebShellSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,6 +10,14 @@ export interface WorkspaceHeaderActionsContext {
|
|
|
10
10
|
}
|
|
11
11
|
interface WorkspaceSectionProps {
|
|
12
12
|
workspace: DaemonWorkspaceCapability;
|
|
13
|
+
/**
|
|
14
|
+
* localStorage seed for the expansion/collapsed-group preferences,
|
|
15
|
+
* defaulting to the workspace id. Multi-host renderers pass an
|
|
16
|
+
* origin-prefixed id so two daemons hosting the same workspace id
|
|
17
|
+
* never share a preference; single-host callers leave it unset and
|
|
18
|
+
* keep the keys they always had.
|
|
19
|
+
*/
|
|
20
|
+
storageKey?: string;
|
|
13
21
|
remote?: boolean;
|
|
14
22
|
renderHeader?: (expanded: boolean) => ReactNode;
|
|
15
23
|
hideHeader?: boolean;
|
|
@@ -117,5 +125,5 @@ interface WorkspaceSectionProps {
|
|
|
117
125
|
/** Commit entry for the same picker; the row still opens without it. */
|
|
118
126
|
onOpenCommit?: (workspaceCwd: string) => void;
|
|
119
127
|
}
|
|
120
|
-
export declare function WorkspaceSection({ workspace, remote, renderHeader, hideHeader, client, reloadToken, untrustedLabel, readOnlyLabel, trustToOpenLabel, noSessionsLabel, loadErrorLabel, organizationEnabled, sessionCatalogRequestsEnabled, sessionGroupCatalog, sessionLiveStateEnabled, sourceType, channelGroupingEnabled, ungroupedLabel, searchQuery, expanded: controlledExpanded, autoExpandKey, forceAutoExpand, onExpandedChange, renderSessions, renderSession, pendingSession, mapSession, showSessionDetails, headerActions, overviewEnabled, overviewMenuOpen, overviewItems, gitBranchWanted, sessionStats, onRenameGroup, onDeleteGroup, renameGroupLabel, deleteGroupLabel, groupActionsDisabled, excludePinned, limitSessions, isPinnedSectionMember, onOpenPathLocally, onOpenTerminalLocally, onOpenGitDiff, onOpenCommit, }: WorkspaceSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
128
|
+
export declare function WorkspaceSection({ workspace, storageKey, remote, renderHeader, hideHeader, client, reloadToken, untrustedLabel, readOnlyLabel, trustToOpenLabel, noSessionsLabel, loadErrorLabel, organizationEnabled, sessionCatalogRequestsEnabled, sessionGroupCatalog, sessionLiveStateEnabled, sourceType, channelGroupingEnabled, ungroupedLabel, searchQuery, expanded: controlledExpanded, autoExpandKey, forceAutoExpand, onExpandedChange, renderSessions, renderSession, pendingSession, mapSession, showSessionDetails, headerActions, overviewEnabled, overviewMenuOpen, overviewItems, gitBranchWanted, sessionStats, onRenameGroup, onDeleteGroup, renameGroupLabel, deleteGroupLabel, groupActionsDisabled, excludePinned, limitSessions, isPinnedSectionMember, onOpenPathLocally, onOpenTerminalLocally, onOpenGitDiff, onOpenCommit, }: WorkspaceSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
121
129
|
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon + short name for one daemon host: the page origin reads as "Local",
|
|
3
|
+
* anything else shows its URL host. Shared by the sidebar host groups and
|
|
4
|
+
* the composer workspace picker so every surface names hosts identically.
|
|
5
|
+
*/
|
|
6
|
+
export declare function HostLabel({ origin }: {
|
|
7
|
+
origin: string;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,9 +3,16 @@
|
|
|
3
3
|
* saved there is nothing to tell apart, so the plain list stays unlabeled.
|
|
4
4
|
*/
|
|
5
5
|
export declare function WorkspaceHostHeading(): import("react/jsx-runtime").JSX.Element | null;
|
|
6
|
+
export type OpenHostSessionHandler = (origin: string, sessionId: string, workspaceCwd?: string) => void;
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Live projects on the other hosts, grouped by host among the focused one's
|
|
9
|
+
* rank (#13727): when `rankOf` is provided, every group carries its own
|
|
10
|
+
* flex order inside the sidebar's host container, so a focused switch keeps
|
|
11
|
+
* all groups in place. Each group polls its own daemon; a host that drops
|
|
12
|
+
* offline or rejects the saved credential keeps its last known projects
|
|
13
|
+
* with a muted status hint.
|
|
10
14
|
*/
|
|
11
|
-
export declare function OtherHostProjects(
|
|
15
|
+
export declare function OtherHostProjects({ onOpenHostSession, rankOf, }: {
|
|
16
|
+
onOpenHostSession?: OpenHostSessionHandler;
|
|
17
|
+
rankOf?: (origin: string) => number;
|
|
18
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Compact label naming the host a chat runs on, with the working directory in
|
|
3
3
|
* its tooltip. Hidden until a project can live on more than one host.
|
|
4
|
+
* `hostOrigin` names the ACTIVE session's host on multi-daemon pages; without
|
|
5
|
+
* it the page daemon (the behavior before fan-out) decides.
|
|
4
6
|
*/
|
|
5
|
-
export declare function WorkspaceLocation({ cwd }: {
|
|
7
|
+
export declare function WorkspaceLocation({ cwd, hostOrigin, }: {
|
|
6
8
|
cwd?: string;
|
|
9
|
+
hostOrigin?: string;
|
|
7
10
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Qwen Team
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { ReactNode } from 'react';
|
|
7
|
+
export interface FocusHostTarget {
|
|
8
|
+
origin: string;
|
|
9
|
+
/** Preselect this workspace on the new host (by id), or clear otherwise. */
|
|
10
|
+
workspaceId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* One-shot intent carried across a focused-host switch: the remounted app
|
|
14
|
+
* performs it against the NEW host's provider (composer create on a picked
|
|
15
|
+
* workspace, or open an existing session). Kept here because this provider
|
|
16
|
+
* sits outside the interactive provider's remount boundary.
|
|
17
|
+
*/
|
|
18
|
+
export interface HostHandoff {
|
|
19
|
+
kind: 'create' | 'open';
|
|
20
|
+
/** The focused host this intent belongs to — stale intents are dropped. */
|
|
21
|
+
origin: string;
|
|
22
|
+
workspaceCwd?: string;
|
|
23
|
+
sessionId?: string;
|
|
24
|
+
/** Composer text to restore on the new host (attachments cannot carry). */
|
|
25
|
+
draftText?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface DaemonTargetController {
|
|
28
|
+
/** The focused daemon origin (page origin when no `?daemon=` is active). */
|
|
29
|
+
activeOrigin: string;
|
|
30
|
+
/** Origins the current document may open network connections to. */
|
|
31
|
+
coveredOrigins: ReadonlySet<string>;
|
|
32
|
+
coversOrigin(origin: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Focus another CSP-covered host: remounts the interactive provider at the
|
|
35
|
+
* new origin and rewrites `?daemon=` (+ optional `?workspace=`) in place.
|
|
36
|
+
* Never navigates; throws on an uncovered origin — callers must route those
|
|
37
|
+
* through the navigation-based connect flow instead.
|
|
38
|
+
*/
|
|
39
|
+
focusHost(target: FocusHostTarget): void;
|
|
40
|
+
/** Token for the focused host, refreshed when the focused origin (or any
|
|
41
|
+
* controller dependency) changes; a token edit alone does not re-key it. */
|
|
42
|
+
activeToken: string | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Focus another host and hand an intent to the remounted app. The app
|
|
45
|
+
* drains it via `takePendingHandoff` once the new provider is connected
|
|
46
|
+
* (create a session in that workspace / open that session there).
|
|
47
|
+
*/
|
|
48
|
+
focusHostWithHandoff(target: FocusHostTarget, handoff: HostHandoff): void;
|
|
49
|
+
/** Pending intent from the latest focus switch; consumed exactly once. */
|
|
50
|
+
pendingHandoff: HostHandoff | undefined;
|
|
51
|
+
takePendingHandoff(): HostHandoff | undefined;
|
|
52
|
+
}
|
|
53
|
+
export declare function DaemonTargetProvider({ children, }: {
|
|
54
|
+
children: ReactNode;
|
|
55
|
+
}): ReactNode;
|
|
56
|
+
export declare function useDaemonTarget(): DaemonTargetController;
|
|
57
|
+
/** Optional-context variant for components rendered both inside and outside
|
|
58
|
+
* the standalone tree (tests, embedded shells without the provider). */
|
|
59
|
+
export declare function useDaemonTargetOptional(): DaemonTargetController | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Intercept same-origin anchor clicks that point at another connected host
|
|
62
|
+
* (#13727): a transcript/session link with `?daemon=B` would otherwise
|
|
63
|
+
* hard-reload the document, losing all sidebar and composer state. When the
|
|
64
|
+
* target is inside the CSP-covered set the click becomes an in-app focus
|
|
65
|
+
* switch (open that session there); anything uncovered keeps the default
|
|
66
|
+
* navigation, which still re-serves the shell widened for the host.
|
|
67
|
+
*/
|
|
68
|
+
export declare function useInterceptHostLinks(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Keep the URL's `fanout` params equal to the saved-host set minus the
|
|
71
|
+
* focused daemon (which `?daemon=` already covers). Runs on mount, on host
|
|
72
|
+
* catalog changes, on focus switches, on cross-tab storage writes, and when
|
|
73
|
+
* the tab regains focus (settings flows that edited catalogs in place).
|
|
74
|
+
* `replaceState` only — the current document's CSP is unaffected.
|
|
75
|
+
*/
|
|
76
|
+
export declare function useFanoutUrlSync(): void;
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
export declare function getDaemonBaseUrl(): string;
|
|
2
|
+
/**
|
|
3
|
+
* Repeated `?fanout=` values validated into daemon origins. Fanout params
|
|
4
|
+
* name the hosts this page connects to simultaneously (multi-daemon view,
|
|
5
|
+
* #13727): the served CSP covers exactly the `daemon` + `fanout` set, so a
|
|
6
|
+
* focused-host switch inside that set never reloads the document. The page
|
|
7
|
+
* origin is dropped — `'self'` already covers it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getFanoutOrigins(): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Point the URL's `fanout` params at exactly `origins`, preserving every
|
|
12
|
+
* other param. `replaceState` only: this cannot widen the CURRENT document's
|
|
13
|
+
* CSP (the header is fixed at load) — it keeps the NEXT load in sync, so the
|
|
14
|
+
* host set stays covered without a reload. A newly-connected host therefore
|
|
15
|
+
* navigates once before it can be used; every switch after that is in-app.
|
|
16
|
+
*/
|
|
17
|
+
export declare function syncFanoutParams(origins: readonly string[]): void;
|
|
2
18
|
/**
|
|
3
19
|
* Whether host-local affordances are safe to offer here: true only when this
|
|
4
20
|
* page was served from a loopback host AND the shell is not pointed at a
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Qwen Team
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { DaemonClient } from '@qwen-code/sdk/daemon';
|
|
7
|
+
import type { DaemonCapabilities } from '@qwen-code/sdk/daemon';
|
|
8
|
+
export type HostConnectionStatus = 'connecting' | 'online' | 'offline' | 'unauthorized';
|
|
9
|
+
/**
|
|
10
|
+
* Stable read-only client for `origin`. Recreated only when the stored
|
|
11
|
+
* per-origin token changed; a client whose daemon vanished stays online as an
|
|
12
|
+
* instance (its next request fails) and its entry is dropped when the host
|
|
13
|
+
* loses its last subscriber.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getHostClient(origin: string): DaemonClient;
|
|
16
|
+
export declare const HOST_FANOUT_POLL_MS = 30000;
|
|
17
|
+
export interface HostCapabilitiesState {
|
|
18
|
+
workspaces: DaemonCapabilities['workspaces'];
|
|
19
|
+
status: HostConnectionStatus;
|
|
20
|
+
/** Bumps on every content-changed refresh so poll consumers resubscribe. */
|
|
21
|
+
generation: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Live `capabilities().workspaces` + connection status for one fan-out host.
|
|
25
|
+
* Shares the store's single poll round with every other consumer; the last
|
|
26
|
+
* successful payload survives later failures (status flips to
|
|
27
|
+
* offline/unauthorized but the rows keep rendering) and hosts are always
|
|
28
|
+
* polled with their own per-origin client.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useHostCapabilities(origin: string): HostCapabilitiesState & {
|
|
31
|
+
refresh: () => void;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The single ordered host set both the sidebar fan-out and App composers
|
|
35
|
+
* render from: every saved workspace host and connected remote origin, minus
|
|
36
|
+
* the focused daemon (its own UI comes from the interactive provider), plus
|
|
37
|
+
* the page origin when focused remote — the "way back" group. Memoized on
|
|
38
|
+
* content so consumers can pass it straight into `useHostFanout`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function useFanoutOrigins(): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Live connection state + a client for every `origins` entry, drawn from the
|
|
43
|
+
* shared per-origin store: subscribing here never adds a second poller — the
|
|
44
|
+
* composer picker and the sidebar groups observe the same rounds. Failed
|
|
45
|
+
* hosts keep their last-known snapshot; hosts that lose their last
|
|
46
|
+
* subscriber are dropped from the client pool.
|
|
47
|
+
*/
|
|
48
|
+
export declare function useHostFanout(origins: readonly string[]): {
|
|
49
|
+
clientsByOrigin: ReadonlyMap<string, DaemonClient>;
|
|
50
|
+
statusByOrigin: ReadonlyMap<string, HostConnectionStatus>;
|
|
51
|
+
workspacesByOrigin: ReadonlyMap<string, DaemonCapabilities['workspaces'] | undefined>;
|
|
52
|
+
refreshAll: () => void;
|
|
53
|
+
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
export declare const REMOTE_CONNECTIONS_CHANGE_EVENT = "qwen-remote-connections";
|
|
1
2
|
export declare function formatOriginHost(origin: string): string;
|
|
2
3
|
export declare function readRemoteConnections(): string[];
|
|
3
4
|
export declare function rememberRemoteConnection(origin: string): void;
|
|
4
5
|
export declare function forgetRemoteConnection(origin: string): string[];
|
|
6
|
+
/** Saved connection origins, kept in sync with catalog updates. */
|
|
7
|
+
export declare function useRemoteConnections(): string[];
|
|
5
8
|
export declare function isRemoteConnectionKnown(origin: string): boolean;
|
|
6
9
|
/**
|
|
7
10
|
* Remote computers offered as a workspace location: the persisted catalog plus
|