@agentclientprotocol/claude-agent-acp 0.94.0 → 0.94.1-preview.10

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 (50) hide show
  1. package/README.md +21 -9
  2. package/dist/acp-agent.d.ts +39 -3
  3. package/dist/acp-agent.d.ts.map +1 -1
  4. package/dist/acp-agent.js +196 -67
  5. package/dist/acp-subagents.d.ts +2 -1
  6. package/dist/acp-subagents.d.ts.map +1 -1
  7. package/dist/air-extension.d.ts +5 -0
  8. package/dist/air-extension.d.ts.map +1 -1
  9. package/dist/air-extension.js +5 -0
  10. package/dist/async-tasks.d.ts +19 -0
  11. package/dist/async-tasks.d.ts.map +1 -1
  12. package/dist/async-tasks.js +52 -0
  13. package/dist/clear-context-coordinator.d.ts +1 -0
  14. package/dist/clear-context-coordinator.d.ts.map +1 -1
  15. package/dist/clear-context-coordinator.js +1 -0
  16. package/dist/index.js +2 -3
  17. package/dist/native-subagents.d.ts +64 -0
  18. package/dist/native-subagents.d.ts.map +1 -1
  19. package/dist/native-subagents.js +224 -9
  20. package/dist/permissions/options/shared.d.ts +3 -0
  21. package/dist/permissions/options/shared.d.ts.map +1 -1
  22. package/dist/permissions/options/tools.js +1 -1
  23. package/dist/serve.d.ts +19 -11
  24. package/dist/serve.d.ts.map +1 -1
  25. package/dist/serve.js +26 -18
  26. package/dist/session-index/activity.d.ts +4 -0
  27. package/dist/session-index/activity.d.ts.map +1 -1
  28. package/dist/session-index/activity.js +16 -0
  29. package/dist/session-index/background-tasks.d.ts +69 -0
  30. package/dist/session-index/background-tasks.d.ts.map +1 -0
  31. package/dist/session-index/background-tasks.js +173 -0
  32. package/dist/session-index/service.d.ts +2 -0
  33. package/dist/session-index/service.d.ts.map +1 -1
  34. package/dist/session-index/service.js +6 -1
  35. package/dist/session-index/session-index.d.ts +14 -0
  36. package/dist/session-index/session-index.d.ts.map +1 -1
  37. package/dist/session-index/session-index.js +25 -2
  38. package/dist/session-index/transcript-scan.d.ts +8 -1
  39. package/dist/session-index/transcript-scan.d.ts.map +1 -1
  40. package/dist/session-index/transcript-scan.js +22 -1
  41. package/dist/session-titles.d.ts +44 -16
  42. package/dist/session-titles.d.ts.map +1 -1
  43. package/dist/session-titles.js +89 -27
  44. package/dist/subagent-replay.d.ts +21 -1
  45. package/dist/subagent-replay.d.ts.map +1 -1
  46. package/dist/subagent-replay.js +51 -3
  47. package/dist/task-notifications.d.ts +30 -0
  48. package/dist/task-notifications.d.ts.map +1 -0
  49. package/dist/task-notifications.js +62 -0
  50. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { randomUUID } from "node:crypto";
1
2
  import { AIR_ASYNC_TASKS_CAPABILITY, clientSupportsAirCapability } from "./air-extension.js";
2
3
  import { noticeOrTranscriptUpdate } from "./session-notices.js";
3
4
  const MAX_TOOL_RESULT_PATHS = 500;
@@ -23,6 +24,10 @@ export class AsyncTaskRuntime {
23
24
  * The oldest entries are dropped.
24
25
  */
25
26
  outputPathsByToolCall = new Map();
27
+ /** The task of the autonomous turn that runs now. */
28
+ autonomousTurn;
29
+ /** The summary of the last task notification, which usually starts the next autonomous turn. */
30
+ lastNotificationSummary;
26
31
  constructor(enabled, sessionId, publish,
27
32
  /** `notices`: the client can present `notice` updates, so the stop
28
33
  * acknowledgement need not be a transcript line. `routeOf`: the route of
@@ -174,6 +179,7 @@ export class AsyncTaskRuntime {
174
179
  const state = taskState(message.status);
175
180
  if (!taskId || !state || state === "running" || state === "paused")
176
181
  return;
182
+ this.lastNotificationSummary = nonBlankString(message.summary) ?? this.lastNotificationSummary;
177
183
  const task = this.task(taskId);
178
184
  const wasTerminal = isTerminal(task.state);
179
185
  const correctsLevelState = wasTerminal && task.terminalSource === "level";
@@ -234,6 +240,7 @@ export class AsyncTaskRuntime {
234
240
  for (const task of this.tasks.values()) {
235
241
  if ((task.announced || task.held) &&
236
242
  !task.ignored &&
243
+ !task.autonomousTurn &&
237
244
  !isTerminal(task.state) &&
238
245
  !live.has(task.id)) {
239
246
  // This replace-semantics level is itself the authoritative liveness
@@ -247,6 +254,7 @@ export class AsyncTaskRuntime {
247
254
  }
248
255
  }
249
256
  async finishAll(state) {
257
+ this.autonomousTurn = undefined;
250
258
  const errors = [];
251
259
  for (const task of this.tasks.values()) {
252
260
  if ((task.announced || task.held) && !task.ignored && !isTerminal(task.state)) {
@@ -283,6 +291,8 @@ export class AsyncTaskRuntime {
283
291
  if (!task || !task.announced || task.ignored || task.stopAnnounced)
284
292
  return;
285
293
  task.stopAnnounced = true;
294
+ if (this.autonomousTurn === task)
295
+ this.autonomousTurn = undefined;
286
296
  // No terminal summary: a stopped task leaves the Async Tasks panel at once,
287
297
  // so anything said there is said to nobody.
288
298
  await this.finish(task, "stopped", undefined, "event");
@@ -302,6 +312,45 @@ export class AsyncTaskRuntime {
302
312
  // its tool call), not whether the agent may answer a direct user action.
303
313
  await this.send(task, noticeOrTranscriptUpdate({ severity: "info", title: "Task stopped by user", description: `${task.name}.` }, this.options.notices ?? false));
304
314
  }
315
+ /**
316
+ * Publishes a model turn that Claude Code started with no prompt open, for
317
+ * example to answer a task notification. ACP v1 has no session state, and
318
+ * the client already got the stop reason of its last prompt, so this task is
319
+ * the only sign that the agent works. The tool calls of the turn are in the
320
+ * transcript already, so the task is not shown there. Does nothing while
321
+ * such a task is open.
322
+ */
323
+ async autonomousTurnStarted() {
324
+ if (!this.enabled || this.autonomousTurn)
325
+ return;
326
+ const task = this.task(`autonomous-turn-${randomUUID()}`);
327
+ task.autonomousTurn = true;
328
+ task.startedObserved = true;
329
+ task.name = "Claude is working";
330
+ task.taskType = "turn";
331
+ task.description =
332
+ this.lastNotificationSummary ?? "Claude Code started a turn without a prompt.";
333
+ task.showInTranscript = false;
334
+ this.lastNotificationSummary = undefined;
335
+ this.autonomousTurn = task;
336
+ await this.announce(task, { withoutToolCall: true });
337
+ }
338
+ /** Whether the task of an autonomous turn is open. */
339
+ get autonomousTurnOpen() {
340
+ return this.autonomousTurn !== undefined;
341
+ }
342
+ /** Ends the task of the autonomous turn that runs now, if there is one. */
343
+ async autonomousTurnEnded(state) {
344
+ const task = this.autonomousTurn;
345
+ if (!task)
346
+ return;
347
+ this.autonomousTurn = undefined;
348
+ await this.finish(task, state, undefined, "event");
349
+ }
350
+ /** Whether the task stands for an autonomous turn, which a stop interrupts. */
351
+ isAutonomousTurn(taskId) {
352
+ return this.tasks.get(taskId)?.autonomousTurn === true;
353
+ }
305
354
  /** Whether a task of the tool call went to the background, so the client gets it. */
306
355
  isBackgroundedToolCall(toolCallId) {
307
356
  for (const task of this.tasks.values()) {
@@ -356,6 +405,8 @@ export class AsyncTaskRuntime {
356
405
  clear() {
357
406
  this.tasks.clear();
358
407
  this.outputPathsByToolCall.clear();
408
+ this.autonomousTurn = undefined;
409
+ this.lastNotificationSummary = undefined;
359
410
  }
360
411
  /**
361
412
  * Marks a task that the client never sees. Only a task that is not announced
@@ -388,6 +439,7 @@ export class AsyncTaskRuntime {
388
439
  stopAnnounced: false,
389
440
  state: "running",
390
441
  published: new Map(),
442
+ autonomousTurn: false,
391
443
  };
392
444
  this.tasks.set(taskId, task);
393
445
  return task;
@@ -36,6 +36,7 @@ export type ClearContextSession<Turn extends ClearContextTurn = ClearContextTurn
36
36
  turnQueue?: Turn[];
37
37
  pendingExitPlanContextReset?: ClearContextReset;
38
38
  contextUsedTokens?: number;
39
+ sentUserUuids?: Set<string>;
39
40
  input: {
40
41
  push(message: SDKUserMessage): unknown;
41
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"clear-context-coordinator.d.ts","sourceRoot":"","sources":["../src/clear-context-coordinator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clear-context-coordinator.d.ts","sourceRoot":"","sources":["../src/clear-context-coordinator.ts"],"names":[],"mappings":"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"}
@@ -73,6 +73,7 @@ export async function continuePlanInFreshContext(sessionId, oldSession, reset, h
73
73
  host.logError("Failed to publish clear-context session state:", error);
74
74
  }
75
75
  assertRestartActive(freshSession);
76
+ (freshSession.sentUserUuids ??= new Set()).add(turn.promptUuid);
76
77
  freshSession.input.push(host.continuationMessage(sessionId, reset.plan, turn.promptUuid));
77
78
  assertRestartActive(freshSession);
78
79
  host.ensureConsumer(freshSession, sessionId);
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { claudeCliPath } from "./acp-agent.js";
3
3
  import { applyManagedPolicyEnv } from "./managed-policy.js";
4
- import { serveAcp } from "./serve.js";
4
+ import { acpProtocolsFromEnv, serveAcp } from "./serve.js";
5
5
  import packageJson from "../package.json" with { type: "json" };
6
6
  import { appendFileSync, mkdirSync } from "node:fs";
7
7
  import { join } from "node:path";
@@ -78,9 +78,8 @@ else {
78
78
  })()
79
79
  : undefined;
80
80
  logger?.log("Claude ACP started");
81
- // The draft ACP v2 is opt-in while it is a draft.
82
81
  const acp = serveAcp(logger, {
83
- experimentalV2: process.env.CLAUDE_AGENT_ACP_EXPERIMENTAL_V2 === "1",
82
+ protocols: acpProtocolsFromEnv(process.env.CLAUDE_AGENT_ACP_PROTOCOL),
84
83
  });
85
84
  async function shutdown() {
86
85
  await acp.dispose().catch((err) => {
@@ -41,6 +41,8 @@ export type NativeSubagent = {
41
41
  promptIds?: Set<string>;
42
42
  /** The RFD form: the calls that delegated to the child, whose runs ended. */
43
43
  endedRuns?: Set<string>;
44
+ /** The RFD form: the calls that delegated to the child, whose runs handed back a report. */
45
+ handedBack?: Set<string>;
44
46
  announced?: boolean;
45
47
  terminalState?: SubagentState;
46
48
  /** Connection-local single-flight state; never serialized on the wire. */
@@ -127,6 +129,18 @@ export declare class NativeSubagentRuntime {
127
129
  private readonly taskFinishPromises;
128
130
  /** The session that made each SendMessage call. */
129
131
  private readonly senderByToolUse;
132
+ /**
133
+ * The RFD form: the Agent/Task calls that the client is not shown, until
134
+ * their final update. Kept by id because the adapter's own report that
135
+ * closes an unfinished call has no `toolName` to recognize it by.
136
+ */
137
+ private readonly hiddenLaunches;
138
+ /**
139
+ * The RFD form: the SubagentHandback calls of announced children that the
140
+ * client is not shown yet, with their first report, the report from their
141
+ * input, and the call that delegated the run.
142
+ */
143
+ private readonly handbacks;
130
144
  private readonly generationByTaskId;
131
145
  private readonly pending;
132
146
  private pendingCount;
@@ -331,6 +345,25 @@ export declare class NativeSubagentRuntime {
331
345
  * sender of the prompt when the call resumes a child.
332
346
  */
333
347
  private rememberSendMessage;
348
+ /**
349
+ * The RFD form: an update of the Agent/Task call that launches `child`,
350
+ * which the parent's session messages replace. Only a launch whose child
351
+ * was never exposed stays a tool call of the parent, with its final status,
352
+ * since the RFD lets the Agent represent unexposed work through the parent.
353
+ * A background launch completes before its child starts, so its completion
354
+ * is not such a case.
355
+ */
356
+ private routeRfdLaunch;
357
+ /**
358
+ * The RFD form: an update of a SubagentHandback call of the announced
359
+ * `child`, which its report replaces: the child's message to its parent,
360
+ * see {@link linkedSessionMessages}. A failed call delivered nothing, so the
361
+ * child is shown the call after all. `undefined` for any other update.
362
+ */
363
+ private routeRfdHandback;
364
+ /** Whether `update` is of an Agent/Task call, by its tool name or, in the
365
+ * RFD form, by the id of a call the client is not shown. */
366
+ private isControlUpdate;
334
367
  private rememberToolCallOwner;
335
368
  /**
336
369
  * The RFD form: how many cancels the client sent for `child`, its
@@ -384,6 +417,37 @@ export declare class NativeSubagentRuntime {
384
417
  */
385
418
  export declare function announceNativeSubagent(child: NativeSubagent, publish: Publish, form: SubagentForm): Promise<void>;
386
419
  export declare function finishNativeSubagent(session: NativeSubagentSession, taskId: string, state: SubagentState, publish: Publish): Promise<void>;
420
+ /**
421
+ * The RFD form: a message that a tool call sent, which the client is not
422
+ * shown, as two session messages: the sender's outgoing view, then the
423
+ * recipient's incoming one. That call is a launch's Agent/Task call, whose
424
+ * prompt goes from the parent to the child, or a child's SubagentHandback
425
+ * call, whose report goes from the child to the parent. Both views use the
426
+ * call's tool use id, and each names the other with the draft RFD's
427
+ * `recipientMessageId` and `senderMessageId`.
428
+ */
429
+ export declare function linkedSessionMessages(toolUseId: string, senderSessionId: string, recipientSessionId: string, text: string): AcpSessionNotification[];
430
+ /**
431
+ * The tool with which a child hands its report to its parent, when Claude
432
+ * Code runs in hand-back mode. The Agent/Task result then only says that the
433
+ * report was delivered as a message, with `handback: "send"` in its
434
+ * structured result.
435
+ */
436
+ export declare const HANDBACK_TOOL = "SubagentHandback";
437
+ /** The report of a SubagentHandback call, from its input. */
438
+ export declare function handbackMessage(input: unknown): string | undefined;
439
+ /**
440
+ * The RFD form: the answer of a foreground child, from the completed result
441
+ * of the Agent/Task call `launchId` that launched it, as the child's message
442
+ * in the parent's transcript (its incoming view). It replaces that call's
443
+ * result, which the parent is not shown. The child's transcript has its
444
+ * answer as its own agent message, not as a session message, so this view
445
+ * links to no other. `undefined` for a result without text. Not used for a
446
+ * run whose child handed back its report: the result has no report then.
447
+ */
448
+ export declare function launchReply(launchId: string, childSessionId: string, parentSessionId: string, result: Extract<AcpSessionNotification["update"], {
449
+ sessionUpdate: "tool_call_update" | "tool_call";
450
+ }>): AcpSessionNotification | undefined;
387
451
  /**
388
452
  * The RFD form: the work state at the end of a child's work.
389
453
  *
@@ -1 +1 @@
1
- {"version":3,"file":"native-subagents.d.ts","sourceRoot":"","sources":["../src/native-subagents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"native-subagents.d.ts","sourceRoot":"","sources":["../src/native-subagents.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { RequestError } from "@agentclientprotocol/sdk/unstable";
2
2
  import { AIR_SUBAGENT_KEY, airExtensionMeta } from "./air-extension.js";
3
+ import { isFinalToolCallStatus } from "./tool-calls/renderer.js";
3
4
  const MAX_PENDING_PARENTS = 64;
4
5
  const MAX_PENDING_UPDATES = 256;
5
6
  const MAX_PENDING_UPDATES_PER_PARENT = 32;
@@ -34,6 +35,18 @@ export class NativeSubagentRuntime {
34
35
  taskFinishPromises = new Map();
35
36
  /** The session that made each SendMessage call. */
36
37
  senderByToolUse = new Map();
38
+ /**
39
+ * The RFD form: the Agent/Task calls that the client is not shown, until
40
+ * their final update. Kept by id because the adapter's own report that
41
+ * closes an unfinished call has no `toolName` to recognize it by.
42
+ */
43
+ hiddenLaunches = new Map();
44
+ /**
45
+ * The RFD form: the SubagentHandback calls of announced children that the
46
+ * client is not shown yet, with their first report, the report from their
47
+ * input, and the call that delegated the run.
48
+ */
49
+ handbacks = new Map();
37
50
  generationByTaskId = new Map();
38
51
  pending = new Map();
39
52
  pendingCount = 0;
@@ -83,7 +96,7 @@ export class NativeSubagentRuntime {
83
96
  async routeUpdate(notification, deliver, forcedSessionId) {
84
97
  const { update } = notification;
85
98
  const claudeMeta = update._meta?.claudeCode;
86
- const isControl = isNativeSubagentControlUpdate(update);
99
+ const isControl = this.isControlUpdate(update);
87
100
  if (!this.enabled)
88
101
  return notification;
89
102
  if (this.enabled && isControl) {
@@ -126,12 +139,18 @@ export class NativeSubagentRuntime {
126
139
  if (forcedSessionId) {
127
140
  return { ...notification, sessionId: forcedSessionId };
128
141
  }
129
- return failedControlFallback(initial, notification, parentSessionId ?? this.rootSessionId);
142
+ return unexposedControlFallback(initial, notification, parentSessionId ?? this.rootSessionId);
130
143
  }
131
144
  return forcedSessionId ? { ...notification, sessionId: forcedSessionId } : null;
132
145
  }
133
- // The RFD form: the Agent/Task tool call is the parent's record of the
134
- // delegation, so it stays a tool call of the session that made it.
146
+ // The RFD form: the parent's session messages replace the Agent/Task
147
+ // tool call, its prompt as the parent's outgoing message (see
148
+ // `linkedSessionMessages`) and its result as the child's reply (see
149
+ // `launchReply`). A call made inside a child that is not announced yet
150
+ // is buffered below, as any update of that child.
151
+ if (!parentPending) {
152
+ return this.routeRfdLaunch(notification, child, parentSessionId ?? this.rootSessionId, forcedSessionId);
153
+ }
135
154
  }
136
155
  const toolCallId = update.sessionUpdate === "tool_call" || update.sessionUpdate === "tool_call_update"
137
156
  ? update.toolCallId
@@ -147,6 +166,15 @@ export class NativeSubagentRuntime {
147
166
  return { ...notification, sessionId: forcedSessionId };
148
167
  }
149
168
  const owner = toolCallId ? this.childByToolCall.get(toolCallId) : undefined;
169
+ const announcedChild = owner ??
170
+ (claudeMeta?.parentToolUseId
171
+ ? this.childByParentToolUse.get(claudeMeta.parentToolUseId)
172
+ : undefined);
173
+ if (this.form === "rfd" && announcedChild?.announced) {
174
+ const handback = await this.routeRfdHandback(notification, announcedChild);
175
+ if (handback !== undefined)
176
+ return handback;
177
+ }
150
178
  if (owner)
151
179
  return this.toChild(owner, notification, toolCallId);
152
180
  if (this.enabled && claudeMeta?.parentToolUseId) {
@@ -762,6 +790,94 @@ export class NativeSubagentRuntime {
762
790
  this.senderByToolUse.delete(oldest);
763
791
  }
764
792
  }
793
+ /**
794
+ * The RFD form: an update of the Agent/Task call that launches `child`,
795
+ * which the parent's session messages replace. Only a launch whose child
796
+ * was never exposed stays a tool call of the parent, with its final status,
797
+ * since the RFD lets the Agent represent unexposed work through the parent.
798
+ * A background launch completes before its child starts, so its completion
799
+ * is not such a case.
800
+ */
801
+ async routeRfdLaunch(notification, child, parentSessionId, forcedSessionId) {
802
+ const { update } = notification;
803
+ if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
804
+ return null;
805
+ }
806
+ const toolCallId = update.toolCallId;
807
+ // A permission request already showed the call to the client, so it
808
+ // keeps getting its updates.
809
+ if (forcedSessionId)
810
+ return { ...notification, sessionId: forcedSessionId };
811
+ const launch = this.hiddenLaunches.get(toolCallId) ?? { background: false };
812
+ if (isBackgroundLaunch(update.rawInput))
813
+ launch.background = true;
814
+ if (!isFinalToolCallStatus(update.status)) {
815
+ this.hiddenLaunches.set(toolCallId, launch);
816
+ return null;
817
+ }
818
+ this.hiddenLaunches.delete(toolCallId);
819
+ if (child?.announcePromise)
820
+ await child.announcePromise;
821
+ const background = launch.background;
822
+ if (child?.announced) {
823
+ const reply = update.status === "completed" && !background && !child.handedBack?.has(toolCallId)
824
+ ? launchReply(toolCallId, child.sessionId, child.parentSessionId, update)
825
+ : undefined;
826
+ if (reply)
827
+ await this.publish(reply);
828
+ return null;
829
+ }
830
+ if (background && update.status === "completed")
831
+ return null;
832
+ this.takePending(toolCallId);
833
+ const initial = this.controlByToolUse.get(toolCallId);
834
+ this.cleanupControl(toolCallId);
835
+ return unexposedControlFallback(initial, notification, parentSessionId);
836
+ }
837
+ /**
838
+ * The RFD form: an update of a SubagentHandback call of the announced
839
+ * `child`, which its report replaces: the child's message to its parent,
840
+ * see {@link linkedSessionMessages}. A failed call delivered nothing, so the
841
+ * child is shown the call after all. `undefined` for any other update.
842
+ */
843
+ async routeRfdHandback(notification, child) {
844
+ const { update } = notification;
845
+ if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
846
+ return undefined;
847
+ }
848
+ const claudeMeta = update._meta?.claudeCode;
849
+ let handback = this.handbacks.get(update.toolCallId);
850
+ if (!handback) {
851
+ if (claudeMeta?.toolName !== HANDBACK_TOOL)
852
+ return undefined;
853
+ handback = {
854
+ initial: notification,
855
+ delegationId: claudeMeta.parentToolUseId ?? child.parentToolUseId,
856
+ };
857
+ this.handbacks.set(update.toolCallId, handback);
858
+ }
859
+ handback.message = handbackMessage(update.rawInput) ?? handback.message;
860
+ if (!isFinalToolCallStatus(update.status))
861
+ return null;
862
+ this.handbacks.delete(update.toolCallId);
863
+ if (update.status === "completed" && handback.message) {
864
+ for (const view of linkedSessionMessages(update.toolCallId, child.sessionId, child.parentSessionId, handback.message)) {
865
+ await this.publish(view);
866
+ }
867
+ if (handback.delegationId)
868
+ (child.handedBack ??= new Set()).add(handback.delegationId);
869
+ return null;
870
+ }
871
+ return unexposedControlFallback(handback.initial, notification, child.sessionId);
872
+ }
873
+ /** Whether `update` is of an Agent/Task call, by its tool name or, in the
874
+ * RFD form, by the id of a call the client is not shown. */
875
+ isControlUpdate(update) {
876
+ if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
877
+ return false;
878
+ }
879
+ return this.hiddenLaunches.has(update.toolCallId) || isNativeSubagentControlUpdate(update);
880
+ }
765
881
  rememberToolCallOwner(toolCallId, child) {
766
882
  this.childByToolCall.delete(toolCallId);
767
883
  this.childByToolCall.set(toolCallId, child);
@@ -808,6 +924,8 @@ export class NativeSubagentRuntime {
808
924
  this.childByParentToolUse.clear();
809
925
  this.taskFinishPromises.clear();
810
926
  this.senderByToolUse.clear();
927
+ this.hiddenLaunches.clear();
928
+ this.handbacks.clear();
811
929
  this.generationByTaskId.clear();
812
930
  this.pending.clear();
813
931
  this.pendingCount = 0;
@@ -949,7 +1067,7 @@ export async function announceNativeSubagent(child, publish, form) {
949
1067
  child.announced = true;
950
1068
  // The immediate parent made the Agent/Task call that launched the child.
951
1069
  if (child.prompt) {
952
- await publishPrompt(child, child.prompt, child.parentToolUseId, child.parentSessionId, publish);
1070
+ await publishPrompt(child, child.prompt, child.parentToolUseId, child.parentSessionId, publish, { replacesLaunch: true });
953
1071
  }
954
1072
  return;
955
1073
  }
@@ -1008,13 +1126,23 @@ export async function finishNativeSubagent(session, taskId, state, publish) {
1008
1126
  * Agent/Task call or a SendMessage, so a prompt whose id is already in the
1009
1127
  * transcript is the same delegation and is not sent again. `sender` is the
1010
1128
  * session that made that call, when known.
1129
+ *
1130
+ * A launch's prompt (`replacesLaunch`) also goes to the parent, see
1131
+ * {@link linkedSessionMessages}. A SendMessage call stays a tool call of the
1132
+ * sender, so its message has only the incoming view.
1011
1133
  */
1012
- async function publishPrompt(child, prompt, toolUseId, sender, publish) {
1134
+ async function publishPrompt(child, prompt, toolUseId, sender, publish, { replacesLaunch = false } = {}) {
1013
1135
  child.promptIds ??= new Set();
1014
1136
  const messageId = toolUseId ?? `${child.sessionId}:prompt:${child.promptIds.size + 1}`;
1015
1137
  if (child.promptIds.has(messageId))
1016
1138
  return;
1017
1139
  child.promptIds.add(messageId);
1140
+ if (replacesLaunch && sender !== undefined && toolUseId !== undefined) {
1141
+ for (const view of linkedSessionMessages(toolUseId, sender, child.sessionId, prompt)) {
1142
+ await publish(view);
1143
+ }
1144
+ return;
1145
+ }
1018
1146
  await publish({
1019
1147
  sessionId: child.sessionId,
1020
1148
  update: {
@@ -1026,6 +1154,87 @@ async function publishPrompt(child, prompt, toolUseId, sender, publish) {
1026
1154
  },
1027
1155
  });
1028
1156
  }
1157
+ /**
1158
+ * The RFD form: a message that a tool call sent, which the client is not
1159
+ * shown, as two session messages: the sender's outgoing view, then the
1160
+ * recipient's incoming one. That call is a launch's Agent/Task call, whose
1161
+ * prompt goes from the parent to the child, or a child's SubagentHandback
1162
+ * call, whose report goes from the child to the parent. Both views use the
1163
+ * call's tool use id, and each names the other with the draft RFD's
1164
+ * `recipientMessageId` and `senderMessageId`.
1165
+ */
1166
+ export function linkedSessionMessages(toolUseId, senderSessionId, recipientSessionId, text) {
1167
+ const message = {
1168
+ sessionUpdate: "session_message",
1169
+ messageId: toolUseId,
1170
+ senderSessionId,
1171
+ recipientSessionId,
1172
+ content: [{ type: "text", text }],
1173
+ };
1174
+ return [
1175
+ {
1176
+ sessionId: senderSessionId,
1177
+ update: { ...message, recipientMessageId: toolUseId },
1178
+ },
1179
+ {
1180
+ sessionId: recipientSessionId,
1181
+ update: { ...message, senderMessageId: toolUseId },
1182
+ },
1183
+ ];
1184
+ }
1185
+ /**
1186
+ * The tool with which a child hands its report to its parent, when Claude
1187
+ * Code runs in hand-back mode. The Agent/Task result then only says that the
1188
+ * report was delivered as a message, with `handback: "send"` in its
1189
+ * structured result.
1190
+ */
1191
+ export const HANDBACK_TOOL = "SubagentHandback";
1192
+ /** The report of a SubagentHandback call, from its input. */
1193
+ export function handbackMessage(input) {
1194
+ const message = input?.message;
1195
+ return typeof message === "string" && message.trim() ? message : undefined;
1196
+ }
1197
+ /**
1198
+ * The RFD form: the answer of a foreground child, from the completed result
1199
+ * of the Agent/Task call `launchId` that launched it, as the child's message
1200
+ * in the parent's transcript (its incoming view). It replaces that call's
1201
+ * result, which the parent is not shown. The child's transcript has its
1202
+ * answer as its own agent message, not as a session message, so this view
1203
+ * links to no other. `undefined` for a result without text. Not used for a
1204
+ * run whose child handed back its report: the result has no report then.
1205
+ */
1206
+ export function launchReply(launchId, childSessionId, parentSessionId, result) {
1207
+ const content = replyContent(result);
1208
+ if (content.length === 0)
1209
+ return undefined;
1210
+ return {
1211
+ sessionId: parentSessionId,
1212
+ update: {
1213
+ sessionUpdate: "session_message",
1214
+ messageId: `${launchId}:reply`,
1215
+ senderSessionId: childSessionId,
1216
+ recipientSessionId: parentSessionId,
1217
+ content,
1218
+ },
1219
+ };
1220
+ }
1221
+ /**
1222
+ * The text of a completed launch's result, from the tool call's `content`:
1223
+ * `AgentReporter` removed the parts meant for the model there (the
1224
+ * `agentId: … (use SendMessage …)` line, the `<usage>` block and the hand-back
1225
+ * frame), which `rawOutput` still has.
1226
+ */
1227
+ function replyContent(result) {
1228
+ return (result.content ?? []).flatMap((item) => item.type === "content" && item.content.type === "text" && item.content.text.trim()
1229
+ ? [{ type: "text", text: item.content.text }]
1230
+ : []);
1231
+ }
1232
+ /** Whether an Agent/Task call's input runs its child in the background. */
1233
+ function isBackgroundLaunch(rawInput) {
1234
+ return (typeof rawInput === "object" &&
1235
+ rawInput !== null &&
1236
+ rawInput.run_in_background === true);
1237
+ }
1029
1238
  /** The RFD form: whether the child's foreground work is in progress. */
1030
1239
  function isWorking(child) {
1031
1240
  return child.workState === "running" || child.workState === "requires_action";
@@ -1165,7 +1374,13 @@ function isFailedToolCallUpdate(update) {
1165
1374
  return ((update.sessionUpdate === "tool_call" || update.sessionUpdate === "tool_call_update") &&
1166
1375
  update.status === "failed");
1167
1376
  }
1168
- function failedControlFallback(initial, terminal, sessionId) {
1377
+ /**
1378
+ * A tool call that the client was not shown, as one `tool_call` with its
1379
+ * final status, shown after all: an Agent/Task call whose child was never
1380
+ * exposed (AIR's draft shows only a failed one, the RFD form also a completed
1381
+ * one), or a failed SubagentHandback call.
1382
+ */
1383
+ function unexposedControlFallback(initial, terminal, sessionId) {
1169
1384
  if (terminal.update.sessionUpdate !== "tool_call" &&
1170
1385
  terminal.update.sessionUpdate !== "tool_call_update") {
1171
1386
  return { ...terminal, sessionId };
@@ -1178,7 +1393,7 @@ function failedControlFallback(initial, terminal, sessionId) {
1178
1393
  update: {
1179
1394
  ...terminal.update,
1180
1395
  sessionUpdate: "tool_call",
1181
- status: "failed",
1396
+ status: terminal.update.status ?? "failed",
1182
1397
  // The synthesized tool_call is this call's first report, so give it
1183
1398
  // the standard `name` the initial one would have carried.
1184
1399
  ...(typeof claudeMeta?.toolName === "string" ? { name: claudeMeta.toolName } : {}),
@@ -1198,7 +1413,7 @@ function failedControlFallback(initial, terminal, sessionId) {
1198
1413
  ...initial.update,
1199
1414
  ...terminal.update,
1200
1415
  sessionUpdate: "tool_call",
1201
- status: "failed",
1416
+ status: terminal.update.status ?? "failed",
1202
1417
  title: typeof terminal.update.title === "string" && terminal.update.title.trim().length > 0
1203
1418
  ? terminal.update.title
1204
1419
  : initial.update.title,
@@ -28,6 +28,9 @@ export interface PermissionOptionContext {
28
28
  /** The mode the session left when it entered plan mode. */
29
29
  prePlanMode?: string;
30
30
  contextUsedPercent?: number;
31
+ /** False when no ACP turn can continue an accepted plan in a fresh
32
+ * context. Then an ExitPlanMode request offers no clear-context option. */
33
+ allowContextReset?: boolean;
31
34
  }
32
35
  export declare function allowOnce(name?: string): PermissionOption;
33
36
  export declare function allowWithUpdates(name: string): PermissionOption;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/permissions/options/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEtE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;CAavB,CAAC;AAEX,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;wEACoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,IAAI,SAAQ,GAAG,gBAAgB,CAExD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAE/D;AAED,wBAAgB,MAAM,CAAC,IAAI,SAAO,GAAG,gBAAgB,CAEpD;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,SAAQ,EACjB,UAAU,SAAO,GAChB,gBAAgB,EAAE,CAKpB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAkBT;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,QAAQ,EAAE,MAAM,GACf,OAAO,CAYT;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAAO,GAAG,gBAAgB,EAAE,CAEvF"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/permissions/options/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEtE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;CAavB,CAAC;AAEX,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;wEACoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;gFAC4E;IAC5E,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,IAAI,SAAQ,GAAG,gBAAgB,CAExD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAE/D;AAED,wBAAgB,MAAM,CAAC,IAAI,SAAO,GAAG,gBAAgB,CAEpD;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,SAAQ,EACjB,UAAU,SAAO,GAChB,gBAAgB,EAAE,CAKpB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAkBT;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,0BAA0B,GAAG,SAAS,EACjD,QAAQ,EAAE,MAAM,GACf,OAAO,CAYT;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAAO,GAAG,gBAAgB,EAAE,CAEvF"}
@@ -50,7 +50,7 @@ export function buildExitPlanModePermissionOptions(context) {
50
50
  ? ["bypassPermissions", "auto"]
51
51
  : ["auto", "bypassPermissions"]).filter((mode) => modes.has(mode));
52
52
  const preferredMode = elevatedModes[0] ?? "acceptEdits";
53
- if (plainString(context.input.plan)) {
53
+ if (context.allowContextReset !== false && plainString(context.input.plan)) {
54
54
  const usage = context.contextUsedPercent === undefined ? "" : ` (${context.contextUsedPercent}% used)`;
55
55
  options.push(preferredMode === "auto"
56
56
  ? {