@qwen-code/web-shell 0.25.0 → 0.25.1-preview.1

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 (52) hide show
  1. package/dist/agents-route-DAa1HKQE.js +1546 -0
  2. package/dist/daemon-react-sdk.js +1 -1
  3. package/dist/{index-tVJkU24-.js → index-zUj3SlrB.js} +45814 -44258
  4. package/dist/index.js +22 -22
  5. package/dist/sw.js +1 -1
  6. package/dist/{toolNames-CAeFJ9L9.js → toolNames-B_KiYcXs.js} +3679 -3764
  7. package/dist/transcript.js +9608 -9312
  8. package/dist/types/adapters/messageTypes.d.ts +8 -1
  9. package/dist/types/adapters/transcriptAdapter.d.ts +1 -0
  10. package/dist/types/components/ChatContextHeader.d.ts +3 -1
  11. package/dist/types/components/agents/AgentCreatePage.d.ts +7 -1
  12. package/dist/types/components/agents/AgentsManagerPage.d.ts +4 -5
  13. package/dist/types/components/artifacts/ArtifactPanel.d.ts +1 -8
  14. package/dist/types/components/artifacts/TrajectoryFilters.d.ts +15 -0
  15. package/dist/types/components/artifacts/TrajectoryInspector.d.ts +3 -1
  16. package/dist/types/components/managed/generated/managed-agent-api.d.ts +191 -9
  17. package/dist/types/components/managed/java-managed-agent-client.d.ts +3 -1
  18. package/dist/types/components/managed/managed-agent-provider.d.ts +9 -0
  19. package/dist/types/components/messages/AssistantMessage.d.ts +3 -1
  20. package/dist/types/components/messages/UserMessage.d.ts +3 -1
  21. package/dist/types/components/messages/agent-message-details.d.ts +36 -0
  22. package/dist/types/components/messages/squad-tag.d.ts +16 -0
  23. package/dist/types/components/sidebar/WebShellSidebar.d.ts +2 -4
  24. package/dist/types/components/sidebar/WorkspaceSection.d.ts +1 -2
  25. package/dist/types/components/workspace-agents/ThreadsPage.d.ts +31 -55
  26. package/dist/types/components/workspace-agents/add-runtime-dialog.d.ts +34 -5
  27. package/dist/types/components/workspace-agents/agent-events.d.ts +4 -34
  28. package/dist/types/components/workspace-agents/agents-route.d.ts +19 -0
  29. package/dist/types/components/workspace-agents/agents-view-logic.d.ts +14 -163
  30. package/dist/types/components/workspace-agents/lazy-agents-route.d.ts +7 -0
  31. package/dist/types/components/workspace-agents/messages.d.ts +2 -2
  32. package/dist/types/components/workspace-agents/session-agent-live-runs.d.ts +96 -0
  33. package/dist/types/components/workspace-agents/session-agents-api.d.ts +39 -0
  34. package/dist/types/components/workspace-agents/squads-section.d.ts +28 -0
  35. package/dist/types/components/workspace-agents/threads-api.d.ts +25 -36
  36. package/dist/types/components/workspace-agents/use-session-agent-runs.d.ts +66 -0
  37. package/dist/types/components/workspace-agents/useAgentChatEntry.d.ts +74 -10
  38. package/dist/types/components/workspaces/WorkspaceHostProjects.d.ts +11 -0
  39. package/dist/types/components/workspaces/WorkspaceLocation.d.ts +7 -0
  40. package/dist/types/config/workspace-hosts.d.ts +11 -0
  41. package/dist/types/daemon/session/types.d.ts +19 -3
  42. package/dist/types/trajectory/filter-messages.d.ts +9 -0
  43. package/dist/types/trajectory/filter-messages.transcript-stub.d.ts +7 -0
  44. package/dist/types/trajectory/filterTrajectory.d.ts +22 -0
  45. package/dist/types/utils/cancelledTurn.d.ts +17 -0
  46. package/package.json +2 -1
  47. package/dist/ThreadsRoute-CtecWS_K.js +0 -2358
  48. package/dist/types/components/workspace-agents/LazyThreadsRoute.d.ts +0 -7
  49. package/dist/types/components/workspace-agents/ThreadChat.d.ts +0 -35
  50. package/dist/types/components/workspace-agents/ThreadView.d.ts +0 -72
  51. package/dist/types/components/workspace-agents/ThreadsRoute.d.ts +0 -23
  52. package/dist/types/components/workspace-agents/useProjectConversations.d.ts +0 -10
@@ -0,0 +1,96 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { SessionAgentPermissionPrompt, SessionAgentRunFrame } from '@qwen-code/sdk/daemon';
7
+ import type { PermissionRequest } from '../../adapters/types';
8
+ import { useI18n } from '../../i18n';
9
+ type Translate = ReturnType<typeof useI18n>['t'];
10
+ /** No agent activity for this long: say it may be stuck. */
11
+ export declare const STALL_NOTICE_MS: number;
12
+ /**
13
+ * One line saying where a live run is. Returns `attention` for the states the
14
+ * user should notice (stuck, failed, offline).
15
+ */
16
+ export declare function describeRun(run: SessionAgentRunFrame, now: number, t: Translate): {
17
+ text?: string;
18
+ attention: boolean;
19
+ };
20
+ /** Client-side cap on a tool input preview (the daemon bounds it too). */
21
+ export declare const INPUT_PREVIEW_MAX_CHARS = 4000;
22
+ /**
23
+ * The run's permission prompt as the main chat's approval card reads it. A
24
+ * shell tool shows its command as the main chat's shell approval does; any
25
+ * other tool shows its input preview in the card's monospace content block.
26
+ */
27
+ export declare function toApprovalRequest(permission: SessionAgentPermissionPrompt, agent: string, t: Translate): PermissionRequest;
28
+ /**
29
+ * A finished run the daemon offers to run again (`retryable`): failed by a
30
+ * restart, offline, or one whose record a restart lost. Never a stopped one.
31
+ */
32
+ export declare function canRetryRun(run: SessionAgentRunFrame): boolean;
33
+ /** A delegated member in a squad engagement. */
34
+ export interface SquadMemberView {
35
+ name: string;
36
+ /** The agent's color, tinting its avatar as on its replies. */
37
+ color?: string;
38
+ /** `replied`: its run completed and its reply is on the way to the leader. */
39
+ state: 'working' | 'replied';
40
+ }
41
+ /** One squad engagement as the live runs show it. */
42
+ export interface SquadEngagementView {
43
+ squadId: string;
44
+ squadName: string;
45
+ /** The leader, while its squad-mode run is queued or running. */
46
+ leader?: string;
47
+ leaderColor?: string;
48
+ /** Delegated members, in arrival order. */
49
+ members: SquadMemberView[];
50
+ }
51
+ /**
52
+ * Squad engagements under way in this session, derived from live run frames
53
+ * carrying `squadId`: a leader run names its squad on its author; a member
54
+ * run the leader waits on carries the squad id (and name) on the frame. A
55
+ * member's completed frame keeps them while its record is pending, which is
56
+ * the only time a finished run is still in the list: that member `replied`.
57
+ */
58
+ export declare function squadEngagements(runs: readonly SessionAgentRunFrame[]): SquadEngagementView[];
59
+ /**
60
+ * A small bar per active squad engagement: the squad's tag, then one entry per
61
+ * participant (avatar, name, state): the leader "deciding", a member working
62
+ * (spinner) or replied (check).
63
+ */
64
+ export declare function SquadEngagementBar({ runs, }: {
65
+ runs: readonly SessionAgentRunFrame[];
66
+ }): import("react/jsx-runtime").JSX.Element | null;
67
+ /**
68
+ * The session's live agent runs, rendered at the bottom of the message list as
69
+ * the agents' messages-in-progress. Each is replaced by the agent's recorded
70
+ * reply once that lands in the transcript.
71
+ *
72
+ * Mounted only by App (through MessageList's `tailContent`), never by the
73
+ * exported transcript, so it may use the collaboration dictionary.
74
+ */
75
+ export declare function SessionAgentLiveRuns({ runs, onCancel, onRespond, onRetry, }: {
76
+ runs: readonly SessionAgentRunFrame[];
77
+ onCancel: (runId: string) => Promise<void>;
78
+ onRespond: (runId: string, requestId: string, optionId: string) => Promise<void>;
79
+ /** Offered on a failed run the daemon marked retryable. */
80
+ onRetry?: (runId: string) => Promise<void>;
81
+ }): import("react/jsx-runtime").JSX.Element | null;
82
+ /**
83
+ * The user's @-mentions the daemon holds until the running main-model turn
84
+ * settles, shown as their messages until the recorded ones replace them.
85
+ */
86
+ export declare function PendingAgentMentions({ mentions, }: {
87
+ mentions: ReadonlyArray<{
88
+ id: string;
89
+ text: string;
90
+ }>;
91
+ }): import("react/jsx-runtime").JSX.Element | null;
92
+ /** Shown near the composer while any agent in this session is working. */
93
+ export declare function StopAllAgentsButton({ onStopAll, }: {
94
+ onStopAll: () => Promise<void>;
95
+ }): import("react/jsx-runtime").JSX.Element;
96
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { SessionAgentEventFrame, SessionAgentRunFrame, SessionAgentRunStatus } from '@qwen-code/sdk/daemon';
7
+ import { type AgentStreamState } from './agent-events';
8
+ /** 202 body of `POST sessions/:sessionId/mentions`. */
9
+ export interface SessionMentionResult {
10
+ recordId: string;
11
+ deferred?: boolean;
12
+ runs: Array<{
13
+ runId: string;
14
+ agentId: string;
15
+ status: SessionAgentRunStatus;
16
+ }>;
17
+ /** Why some mentioned squads were not started (the others were). */
18
+ squadError?: string;
19
+ }
20
+ /**
21
+ * The session-scoped collaboration routes: agents answering @-mentions inside
22
+ * an ordinary chat session.
23
+ */
24
+ export interface SessionAgentsApi {
25
+ listRuns(sessionId: string): Promise<{
26
+ frames: SessionAgentRunFrame[];
27
+ }>;
28
+ mention(sessionId: string, input: {
29
+ text: string;
30
+ clientMessageId: string;
31
+ }): Promise<SessionMentionResult>;
32
+ cancelRun(sessionId: string, runId: string): Promise<unknown>;
33
+ /** Runs a failed run marked `retryable` again. */
34
+ retryRun(sessionId: string, runId: string): Promise<unknown>;
35
+ stopAll(sessionId: string): Promise<unknown>;
36
+ respondToPermission(sessionId: string, runId: string, requestId: string, optionId: string): Promise<unknown>;
37
+ subscribe(sessionId: string, onEvent: (event: SessionAgentEventFrame) => void, onState: (state: AgentStreamState) => void): () => void;
38
+ }
39
+ export declare function createSessionAgentsHttpApi(baseUrl: string, token: string | undefined, workspaceCwd: string): SessionAgentsApi;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { SessionSquadView } from '@qwen-code/sdk/daemon';
7
+ import type { WorkspaceAgentSummaryView } from './ThreadsPage';
8
+ import type { SquadInput } from './threads-api';
9
+ export interface SquadsSectionProps {
10
+ squads: readonly SessionSquadView[];
11
+ agents: readonly WorkspaceAgentSummaryView[];
12
+ pending?: boolean;
13
+ /** The New squad form is open (its button is in the page header). */
14
+ creating: boolean;
15
+ onCreatingChange: (creating: boolean) => void;
16
+ onCreate: (input: SquadInput) => Promise<boolean>;
17
+ onUpdate: (squadId: string, input: SquadInput) => Promise<boolean>;
18
+ onRetire: (squadId: string) => void;
19
+ /** Puts `@name ` into the chat composer; absent hides the button. */
20
+ onMention?: (name: string) => void;
21
+ }
22
+ /** No squads (or a daemon without squad routes). */
23
+ export declare function SquadsEmpty(): import("react/jsx-runtime").JSX.Element;
24
+ /**
25
+ * The Agents page's Squads view: list, create, edit, retire. A squad is
26
+ * addressed by `@name` in a chat, which wakes its leader (session-multi-agent design §11.5).
27
+ */
28
+ export declare function SquadsSection({ squads, agents, pending, creating, onCreatingChange, onCreate, onUpdate, onRetire, onMention, }: SquadsSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -3,61 +3,50 @@
3
3
  * Copyright 2026 Qwen Team
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import type { AgentCapabilitiesView, AgentConfigPatch, NewThread, NewWorkspaceAgent, WorkspaceAgentRuntimeView, WorkspaceAgentSummaryView } from './ThreadsPage';
7
- import type { ThreadDetailView } from './ThreadView';
8
- import type { RoutingPreviewTarget, ThreadSummaryView } from './agents-view-logic';
9
- import { type AgentLiveEvent, type AgentStreamState } from './agent-events';
10
- import type { JoinToken } from './add-runtime-dialog';
6
+ import type { AgentConfigPatch, NewWorkspaceAgent, WorkspaceAgentRuntimeView, WorkspaceAgentSummaryView } from './ThreadsPage';
7
+ import type { ConnectExistingInput, JoinCoordinatorInput, JoinToken } from './add-runtime-dialog';
11
8
  import type { AgentShare, AgentShareSummary } from './share-agent-dialog';
12
- interface CreateThreadResult {
13
- id: string;
9
+ import type { SessionSquadView } from '@qwen-code/sdk/daemon';
10
+ /** Body of a squad create; on update, `null` clears a text field. */
11
+ export interface SquadInput {
12
+ name: string;
13
+ description: string | null;
14
+ instructions: string | null;
15
+ leaderAgentId: string;
16
+ members: Array<{
17
+ agentId: string;
18
+ role?: string;
19
+ }>;
14
20
  }
21
+ /** Agent roster, runtimes, enrollment and sharing for one workspace. */
15
22
  export interface ThreadsApi {
16
- connectRemoteHost?(input: {
17
- remoteUrl: string;
18
- remoteToken: string;
19
- remoteCwd: string;
20
- serverUrl: string;
21
- provider: 'qwen';
22
- allowHttp: boolean;
23
- }): Promise<unknown>;
23
+ connectRemoteHost?(input: ConnectExistingInput): Promise<unknown>;
24
+ /** Makes this daemon a runtime of another coordinator. */
25
+ joinCoordinator?(input: JoinCoordinatorInput): Promise<unknown>;
24
26
  listAgents(): Promise<{
25
27
  agents: WorkspaceAgentSummaryView[];
26
28
  runtime?: WorkspaceAgentRuntimeView;
27
29
  runtimes?: WorkspaceAgentRuntimeView[];
28
- capabilities?: AgentCapabilitiesView;
29
30
  }>;
30
31
  /** A single-use token for `qwen serve --join` on another machine. */
31
- createJoinToken?(): Promise<JoinToken>;
32
+ createJoinToken?(supersedesHostId?: string): Promise<JoinToken>;
32
33
  removeHost?(hostId: string): Promise<unknown>;
33
34
  createShare?(agentId: string): Promise<AgentShare>;
34
35
  listShares?(agentId: string): Promise<{
35
36
  shares: AgentShareSummary[];
36
37
  }>;
37
38
  revokeShare?(agentId: string, callerId: string): Promise<unknown>;
38
- listThreads(): Promise<{
39
- threads: ThreadSummaryView[];
40
- }>;
41
- getThread(id: string): Promise<ThreadDetailView>;
42
39
  createAgent(input: NewWorkspaceAgent): Promise<unknown>;
43
40
  deleteAgent(id: string): Promise<unknown>;
44
41
  setAgentEnabled(id: string, enabled: boolean): Promise<unknown>;
45
42
  updateAgent(id: string, patch: AgentConfigPatch): Promise<unknown>;
46
- createThread(input: NewThread): Promise<CreateThreadResult>;
47
- previewThread(assignee?: string): Promise<{
48
- targets: RoutingPreviewTarget[];
49
- }>;
50
- assignThread(id: string, assignee?: string): Promise<unknown>;
51
- previewReply(id: string, text: string): Promise<{
52
- targets: RoutingPreviewTarget[];
43
+ /** Squads; absent on a daemon without them. */
44
+ listSquads?(): Promise<{
45
+ squads: SessionSquadView[];
53
46
  }>;
54
- postReply(id: string, text: string): Promise<unknown>;
55
- markDone(id: string): Promise<unknown>;
56
- cancelRun(threadId: string, runId: string): Promise<unknown>;
57
- /** Live events; absent in tests and older daemons, which then poll. */
58
- subscribe?(onEvent: (event: AgentLiveEvent) => void, onState: (state: AgentStreamState) => void): () => void;
59
- /** Answers a tool approval an agent is waiting on. */
60
- respondToPermission?(sessionId: string, requestId: string, optionId: string): Promise<unknown>;
47
+ createSquad?(input: SquadInput): Promise<unknown>;
48
+ updateSquad?(id: string, input: Partial<SquadInput>): Promise<unknown>;
49
+ /** Retires the squad (it keeps its name and history). */
50
+ retireSquad?(id: string): Promise<unknown>;
61
51
  }
62
52
  export declare function createThreadsHttpApi(baseUrl: string, token: string | undefined, workspaceCwd: string): ThreadsApi;
63
- export {};
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { type DaemonTranscriptBlock, type SessionAgentRunFrame, type SessionAgentRunStatus } from '@qwen-code/sdk/daemon';
7
+ import type { SessionAgentsApi } from './session-agents-api';
8
+ export declare function isTerminalRunStatus(status: SessionAgentRunStatus): boolean;
9
+ /**
10
+ * The runs whose `agent_message` is already in the transcript, as one string
11
+ * (run ids joined by newlines) so a caller can memoize a Set on it: the blocks
12
+ * change on every streamed delta, the answer almost never.
13
+ */
14
+ export declare function settledAgentRunKey(blocks: readonly DaemonTranscriptBlock[]): string;
15
+ interface TrackedFrame {
16
+ frame: SessionAgentRunFrame;
17
+ /** Arrival order, so the list does not reshuffle as frames update. */
18
+ order: number;
19
+ /**
20
+ * The run is off the screen for good: its record is in the transcript, or
21
+ * none will be written. Kept, slimmed, so that a stale snapshot cannot put
22
+ * the card back.
23
+ */
24
+ settled?: true;
25
+ }
26
+ export type RunFrameMap = ReadonlyMap<string, TrackedFrame>;
27
+ /**
28
+ * Whether a frame ends the run's card (contract `recorded`): a terminal frame
29
+ * keeps it only while `recorded` is `false` (record pending, or the run is
30
+ * retryable). `true` means the record now renders; absent means none will be
31
+ * written (cancelled while queued, dismissed, retried).
32
+ */
33
+ export declare function isSettledRunFrame(frame: SessionAgentRunFrame): boolean;
34
+ /**
35
+ * Folds one frame into the map. A frame seen twice (the stream opens with a
36
+ * snapshot that a GET may already have delivered) is harmless; an older frame
37
+ * never overwrites a newer one, a terminal run never comes back to life, and
38
+ * a settled run stays settled (a snapshot polled before the record landed can
39
+ * arrive after the frame that settled it).
40
+ */
41
+ export declare function applyRunFrame(current: RunFrameMap, frame: SessionAgentRunFrame, order: number): RunFrameMap;
42
+ /**
43
+ * Settles runs whose `agent_message` the transcript already shows (it can
44
+ * land before the frame that says so). Returns `current` when nothing
45
+ * changed.
46
+ */
47
+ export declare function pruneRunFrames(current: RunFrameMap, settledRunIds: ReadonlySet<string>): RunFrameMap;
48
+ /**
49
+ * Live agent runs of one chat session: the `runs` snapshot, then the
50
+ * `session-events` stream. A run keeps its card, finished or not, until a
51
+ * frame settles it (see {@link isSettledRunFrame}) or its `agent_message`
52
+ * shows up in the transcript (`settledRunIds`), which is what replaces it on
53
+ * screen. A finished run whose record waits behind a main-model turn, or a
54
+ * run a daemon restart cut short, stays until then.
55
+ */
56
+ export declare function useSessionAgentRuns({ api, sessionId, settledRunIds, }: {
57
+ api: SessionAgentsApi | undefined;
58
+ sessionId: string | undefined;
59
+ settledRunIds: ReadonlySet<string>;
60
+ }): {
61
+ runs: SessionAgentRunFrame[];
62
+ anyLive: boolean;
63
+ /** Runs a `retryable` run again; rejects when the daemon refuses. */
64
+ retry: (runId: string) => Promise<void>;
65
+ };
66
+ export {};
@@ -2,27 +2,90 @@ import { type ComponentProps } from 'react';
2
2
  import type { ChatEditor } from '../ChatEditor';
3
3
  import type { WebShellAtProvider } from '../../customization';
4
4
  import type { useI18n } from '../../i18n';
5
+ import { type SessionAgentsApi } from './session-agents-api';
6
+ import type { WorkspaceAgentSummaryView } from './ThreadsPage';
7
+ import { type DaemonTranscriptBlock, type SessionSquadView } from '@qwen-code/sdk/daemon';
5
8
  type Submit = ComponentProps<typeof ChatEditor>['onSubmit'];
6
9
  /**
7
- * The tail of the conversation an agent was mentioned from, so a thread
8
- * started mid-conversation does not begin blind.
10
+ * The @tokens of a message, lowercased. Same rules as core's parseMentions: no
11
+ * ASCII word character before `@`, so "请@迁移助手" counts and "a@b.dev" does
12
+ * not; a token followed by `/` is a path, not a mention.
9
13
  */
10
- export declare function conversationContext(messages: readonly {
11
- role: string;
12
- content?: unknown;
13
- }[]): string;
14
- export declare function useAgentChatEntry({ enabled, cwd, baseUrl, token, onSubmit, onOpen, onError, getContext, onCreateAgent, t, }: {
14
+ export declare function mentionTokens(text: string): string[];
15
+ /**
16
+ * The agents a message addresses, in mention order. A name may run into the
17
+ * next word in scripts without spaces ("@迁移助手看一下"); the longest name the
18
+ * token starts with wins. Same addressability predicate as the picker: an
19
+ * agent the server would skip must not divert the message.
20
+ */
21
+ export declare function resolveMentionedAgents(tokens: readonly string[], agents: readonly WorkspaceAgentSummaryView[]): WorkspaceAgentSummaryView[];
22
+ /** A 32px "people" mask: squads get an icon in the picker, agents none. */
23
+ export declare const SQUAD_PICKER_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAVklEQVR42u2TMQ4AIAgD+f+ncXXRgKFWTC/pai8CZkKIJvgi1PKdRKlgRgDyU20ETkb1lwD0WqIPU88VdoaCOlsPhlo+S5QJOijU8rAEXeDGrggh3mEAQPbbJbEAqj0AAAAASUVORK5CYII=";
24
+ /**
25
+ * The squads a message addresses, by the same token rules as
26
+ * {@link resolveMentionedAgents}. A token that names an agent exactly is the
27
+ * agent's, as on the daemon.
28
+ */
29
+ export declare function resolveMentionedSquads(tokens: readonly string[], squads: readonly SessionSquadView[]): SessionSquadView[];
30
+ /** The chat session an @-mention goes to, and the workspace it lives in. */
31
+ export interface AgentMentionSession {
32
+ sessionId: string;
33
+ /** Unset: the hook's own `cwd`. */
34
+ workspaceCwd?: string;
35
+ }
36
+ /**
37
+ * An @-mention the daemon accepted but deferred behind a running main-model
38
+ * turn (`deferred: true`): its record, and so the user's message, only lands
39
+ * once that turn settles. Shown as the user's message until then.
40
+ */
41
+ export interface PendingAgentMention {
42
+ /** The post's `clientMessageId`. */
43
+ id: string;
44
+ sessionId: string;
45
+ text: string;
46
+ /**
47
+ * Recorded mentions with this text the session already had, plus earlier
48
+ * pending ones, when it was posted: the record that settles this one is
49
+ * the next.
50
+ */
51
+ recordedBefore: number;
52
+ }
53
+ /**
54
+ * The text of each recorded @-mention (`agent_mention` user message) in the
55
+ * transcript, in order. Compare with {@link isPendingMentionRecorded}.
56
+ */
57
+ export declare function recordedAgentMentionTexts(blocks: readonly DaemonTranscriptBlock[]): string[];
58
+ /** True once the record of `mention` is among the recorded mention texts. */
59
+ export declare function isPendingMentionRecorded(mention: PendingAgentMention, recordedTexts: readonly string[]): boolean;
60
+ export declare function useAgentChatEntry({ enabled, cwd, baseUrl, token, sessionApi, sessionApiFor, ensureSession, onSubmit, onError, onCreateAgent, sessionId, recordedMentionTexts, t, }: {
15
61
  enabled: boolean;
16
62
  cwd?: string;
17
63
  baseUrl: string;
18
64
  token?: string;
65
+ /** The session routes of the same workspace (`cwd`). */
66
+ sessionApi?: SessionAgentsApi;
67
+ /**
68
+ * The session routes of another workspace, for a session that lives
69
+ * elsewhere. Defaults to the HTTP routes of that workspace.
70
+ */
71
+ sessionApiFor?: (workspaceCwd: string) => SessionAgentsApi;
72
+ /**
73
+ * The current chat session, creating it first when this is a new chat (the
74
+ * same lazy creation an ordinary first prompt goes through), with the
75
+ * workspace it was created in.
76
+ */
77
+ ensureSession: () => Promise<AgentMentionSession | string | undefined>;
19
78
  onSubmit: Submit;
20
- onOpen: (id: string, cwd: string) => void;
21
79
  onError: (message: string) => void;
22
- /** The conversation so far, when mentioning from a chat that has one. */
23
- getContext?: () => string;
24
80
  /** Offered as the picker's last item: open the New agent page. */
25
81
  onCreateAgent?: () => void;
82
+ /** The session the chat shows; only its pending @-mentions are returned. */
83
+ sessionId?: string;
84
+ /**
85
+ * {@link recordedAgentMentionTexts} of that session's transcript, memoized:
86
+ * a pending @-mention is dropped once its record shows up here.
87
+ */
88
+ recordedMentionTexts?: readonly string[];
26
89
  /**
27
90
  * The caller's translator. App calls this hook above its I18nProvider, where
28
91
  * useI18n() would hand back the default that echoes keys.
@@ -32,5 +95,6 @@ export declare function useAgentChatEntry({ enabled, cwd, baseUrl, token, onSubm
32
95
  providers: WebShellAtProvider[];
33
96
  submit: (text: string, images?: import("../../adapters/promptTypes").PromptImage[], files?: import("../../adapters/promptTypes").PromptFile[], commitAccepted?: import("../../hooks/useComposerCore").ComposerSubmitCommit, metadata?: import("../../hooks/useComposerCore").ComposerSubmitMetadata) => boolean | void;
34
97
  pending: boolean;
98
+ pendingMentions: PendingAgentMention[];
35
99
  };
36
100
  export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Names the connected host above its live project list. Until another host is
3
+ * saved there is nothing to tell apart, so the plain list stays unlabeled.
4
+ */
5
+ export declare function WorkspaceHostHeading(): import("react/jsx-runtime").JSX.Element | null;
6
+ /**
7
+ * Saved projects on the other hosts, grouped by host below the live list.
8
+ * Only the connected host is live; choosing one of these reloads the page
9
+ * against its host.
10
+ */
11
+ export declare function OtherHostProjects(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Compact label naming the host a chat runs on, with the working directory in
3
+ * its tooltip. Hidden until a project can live on more than one host.
4
+ */
5
+ export declare function WorkspaceLocation({ cwd }: {
6
+ cwd?: string;
7
+ }): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,11 @@
1
+ import type { DaemonWorkspaceCapability } from '@qwen-code/sdk/daemon';
2
+ export declare const WorkspaceHostsEnabled: import("react").Context<boolean>;
3
+ export interface WorkspaceHost {
4
+ origin: string;
5
+ workspaces: Pick<DaemonWorkspaceCapability, 'id' | 'cwd' | 'displayName'>[];
6
+ }
7
+ export declare function readWorkspaceHosts(): WorkspaceHost[];
8
+ export declare function rememberWorkspaceHost(origin: string, workspaces: WorkspaceHost['workspaces']): void;
9
+ /** Saved hosts, kept in sync with catalog updates from this and other tabs. */
10
+ export declare function useWorkspaceHosts(): WorkspaceHost[];
11
+ export declare function openHostedWorkspace(origin: string, workspaceId?: string): void;
@@ -202,6 +202,12 @@ export interface DaemonPromptSettledEvent {
202
202
  sessionId: string;
203
203
  promptId: string;
204
204
  outcome: DaemonPromptSettlementOutcome;
205
+ /**
206
+ * The client that submitted the prompt, from the terminal frame's
207
+ * envelope. Lets a submitter recognise its own turn when the admission
208
+ * response never reached it.
209
+ */
210
+ originatorClientId?: string;
205
211
  /** Daemon terminal reason. Present for completed and cancelled turns. */
206
212
  stopReason?: string;
207
213
  error?: {
@@ -277,9 +283,12 @@ export interface SendPromptOptions {
277
283
  * runs to completion. Lets a caller act on "the prompt reached the session"
278
284
  * without waiting for the whole turn — e.g. the scheduled-tasks "run now",
279
285
  * which records the run at admission so a long/stalled turn or a closed tab
280
- * can't lose the record.
286
+ * can't lose the record. Carries the daemon's id for the prompt, the key
287
+ * its terminal `turn_complete` / `turn_error` settles under.
281
288
  */
282
- onAdmitted?: () => void;
289
+ onAdmitted?: (admission: {
290
+ promptId: string;
291
+ }) => void;
283
292
  }
284
293
  export interface SubmitPromptOptions extends SendPromptOptions {
285
294
  sessionId?: string;
@@ -440,11 +449,18 @@ export interface DaemonSessionActions {
440
449
  generateSessionContent(prompt: string, opts?: {
441
450
  signal?: AbortSignal;
442
451
  }): AsyncGenerator<DaemonSessionGenerationEvent>;
443
- getRewindSnapshots(): Promise<{
452
+ getRewindSnapshots(opts?: {
453
+ /** Rethrow failures raw instead of recording a notice; for best-effort
454
+ * callers that fall back on their own. */
455
+ silent?: boolean;
456
+ }): Promise<{
444
457
  snapshots: DaemonRewindSnapshotInfo[];
445
458
  }>;
446
459
  rewindSession(promptId: string, opts?: {
447
460
  rewindFiles?: boolean;
461
+ /** Rethrow failures raw instead of recording a notice; for best-effort
462
+ * callers that fall back on their own. */
463
+ silent?: boolean;
448
464
  }): Promise<DaemonRewindResult>;
449
465
  btwSession(question: string, opts?: {
450
466
  signal?: AbortSignal;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ type FilterMessage = string | ((vars?: Record<string, string | number>) => string);
7
+ export declare const TRAJECTORY_FILTER_MESSAGES_EN: Record<string, FilterMessage>;
8
+ export declare const TRAJECTORY_FILTER_MESSAGES_ZH: Record<string, FilterMessage>;
9
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export declare const TRAJECTORY_FILTER_MESSAGES_EN: {};
7
+ export declare const TRAJECTORY_FILTER_MESSAGES_ZH: {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { Trajectory, TrajectoryRow } from './types';
7
+ export interface TrajectoryFilter {
8
+ query: string;
9
+ type: 'all' | TrajectoryRow['kind'];
10
+ status: 'all' | 'success' | 'error' | 'cancelled' | 'running' | 'unknown';
11
+ }
12
+ export interface TrajectorySearchIndex {
13
+ rows: Array<{
14
+ key: string;
15
+ kind: TrajectoryRow['kind'];
16
+ status?: Exclude<TrajectoryFilter['status'], 'all'>;
17
+ fields: string[];
18
+ }>;
19
+ truncatedCount: number;
20
+ }
21
+ export declare function buildTrajectorySearchIndex(trajectory: Trajectory): TrajectorySearchIndex;
22
+ export declare function filterTrajectory(index: TrajectorySearchIndex, filter: TrajectoryFilter): string[];
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Qwen Team
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { DaemonTranscriptBlock } from '@qwen-code/sdk/daemon';
7
+ /**
8
+ * Whether everything a cancelled turn left behind its prompt can go with it.
9
+ * Thoughts count as nothing: cancelling mid-reasoning is exactly when taking
10
+ * the prompt back matters, and the TUI's restore-on-cancel treats them the
11
+ * same way. An answer, a tool call, shell output, a permission request or a
12
+ * later user message all keep the turn.
13
+ *
14
+ * Only meaningful once the daemon has settled the turn: until its terminal
15
+ * event arrives, "nothing received yet" is not "nothing produced".
16
+ */
17
+ export declare function cancelledTurnProducedNothing(blocksAfterPrompt: readonly DaemonTranscriptBlock[]): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qwen-code/web-shell",
3
- "version": "0.25.0",
3
+ "version": "0.25.1-preview.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/QwenLM/qwen-code.git",
@@ -72,6 +72,7 @@
72
72
  },
73
73
  "devDependencies": {
74
74
  "@playwright/test": "1.61.1",
75
+ "@qwen-code/acp-bridge": "file:../acp-bridge",
75
76
  "@qwen-code/sdk": "file:../sdk-typescript",
76
77
  "@tailwindcss/vite": "^4.3.2",
77
78
  "@types/hast": "^3.0.5",