@gajae-code/coding-agent 0.11.10 → 0.12.0

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 (249) hide show
  1. package/CHANGELOG.md +86 -2
  2. package/dist/types/cli/read-cli.d.ts +1 -0
  3. package/dist/types/cli.d.ts +8 -1
  4. package/dist/types/commands/deep-interview.d.ts +9 -0
  5. package/dist/types/commands/harness.d.ts +22 -0
  6. package/dist/types/commands/read.d.ts +6 -0
  7. package/dist/types/config/model-profile-activation.d.ts +1 -0
  8. package/dist/types/config/model-profile-contract.d.ts +2 -0
  9. package/dist/types/config/model-registry.d.ts +4 -0
  10. package/dist/types/config/provider-auth-health.d.ts +14 -0
  11. package/dist/types/config/provider-ranking.d.ts +59 -0
  12. package/dist/types/config/settings-schema.d.ts +86 -3
  13. package/dist/types/config/settings.d.ts +3 -0
  14. package/dist/types/extensibility/extensions/types.d.ts +43 -2
  15. package/dist/types/extensibility/shared-events.d.ts +6 -0
  16. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
  17. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
  18. package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
  19. package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
  20. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  21. package/dist/types/gjc-runtime/linux-proc.d.ts +22 -14
  22. package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
  23. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +112 -1
  24. package/dist/types/gjc-runtime/state-runtime.d.ts +3 -1
  25. package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
  26. package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
  27. package/dist/types/gjc-runtime/team-runtime.d.ts +2 -1
  28. package/dist/types/gjc-runtime/team-store.d.ts +12 -0
  29. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
  30. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +7 -0
  31. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
  32. package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
  33. package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
  34. package/dist/types/main.d.ts +1 -1
  35. package/dist/types/memories/index.d.ts +2 -0
  36. package/dist/types/modes/acp/acp-agent.d.ts +22 -9
  37. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  38. package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
  39. package/dist/types/modes/components/queue-pane.d.ts +8 -0
  40. package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
  41. package/dist/types/modes/components/read-tool-group.d.ts +4 -4
  42. package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
  43. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  44. package/dist/types/modes/components/tool-execution.d.ts +8 -0
  45. package/dist/types/modes/components/welcome.d.ts +1 -0
  46. package/dist/types/modes/controllers/event-controller.d.ts +3 -0
  47. package/dist/types/modes/interactive-mode.d.ts +7 -1
  48. package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
  49. package/dist/types/modes/types.d.ts +2 -0
  50. package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
  51. package/dist/types/runtime/memory-domain.d.ts +9 -0
  52. package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
  53. package/dist/types/runtime/memory-guard.d.ts +39 -0
  54. package/dist/types/runtime/memory-limit.d.ts +11 -0
  55. package/dist/types/runtime-mcp/manager.d.ts +8 -0
  56. package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
  57. package/dist/types/sdk/acp/final-text.d.ts +19 -0
  58. package/dist/types/sdk/acp/mcp.d.ts +23 -0
  59. package/dist/types/sdk/broker/lifecycle.d.ts +7 -0
  60. package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -1
  61. package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
  62. package/dist/types/sdk/bus/index.d.ts +18 -2
  63. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
  64. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
  65. package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
  66. package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
  67. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -4
  68. package/dist/types/sdk/bus/telegram-daemon.d.ts +23 -3
  69. package/dist/types/sdk/host/control/operations.d.ts +2 -1
  70. package/dist/types/sdk/host/host.d.ts +2 -0
  71. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  72. package/dist/types/sdk/lifecycle-session.d.ts +10 -1
  73. package/dist/types/sdk/startup-capability.d.ts +6 -0
  74. package/dist/types/session/agent-session.d.ts +51 -19
  75. package/dist/types/session/fallback-chain-controller.d.ts +18 -2
  76. package/dist/types/session/internal/managed-session-scope.d.ts +27 -0
  77. package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
  78. package/dist/types/session/session-manager.d.ts +59 -13
  79. package/dist/types/session/streaming-output.d.ts +60 -5
  80. package/dist/types/skill-state/active-state.d.ts +0 -4
  81. package/dist/types/skill-state/workflow-hud.d.ts +3 -0
  82. package/dist/types/task/executor.d.ts +6 -0
  83. package/dist/types/task/types.d.ts +36 -0
  84. package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
  85. package/dist/types/tools/browser/launch.d.ts +7 -0
  86. package/dist/types/tools/fetch.d.ts +17 -1
  87. package/dist/types/tools/output-meta.d.ts +21 -1
  88. package/dist/types/tools/read-internals.d.ts +12 -0
  89. package/dist/types/tools/read.d.ts +45 -1
  90. package/dist/types/tools/resource-gc.d.ts +23 -0
  91. package/dist/types/tools/tool-result.d.ts +7 -1
  92. package/package.json +9 -13
  93. package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
  94. package/scripts/capture-sticky-viewport-showcase.ts +292 -0
  95. package/scripts/generate-sdk-operation-inventory.ts +4 -0
  96. package/scripts/run-test-manifest.ts +6 -4
  97. package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
  98. package/scripts/verify-sticky-viewport-showcase.ts +611 -0
  99. package/src/capability/index.ts +8 -0
  100. package/src/cli/args.ts +14 -8
  101. package/src/cli/fast-help.ts +1 -1
  102. package/src/cli/read-cli.ts +2 -1
  103. package/src/cli.ts +49 -2
  104. package/src/commands/deep-interview.ts +29 -9
  105. package/src/commands/harness.ts +35 -12
  106. package/src/commands/read.ts +11 -2
  107. package/src/commands/sdk.ts +91 -7
  108. package/src/commands/team.ts +1 -1
  109. package/src/config/model-profile-activation.ts +1 -0
  110. package/src/config/model-profile-contract.ts +13 -0
  111. package/src/config/model-profiles.ts +24 -0
  112. package/src/config/model-registry.ts +21 -2
  113. package/src/config/provider-auth-health.ts +42 -0
  114. package/src/config/provider-ranking.ts +119 -0
  115. package/src/config/settings-schema.ts +84 -3
  116. package/src/config/settings.ts +254 -108
  117. package/src/defaults/gjc/skills/deep-interview/SKILL.md +229 -82
  118. package/src/defaults/gjc/skills/ralplan/SKILL.md +78 -26
  119. package/src/defaults/gjc/skills/team/SKILL.md +1 -1
  120. package/src/defaults/gjc/skills/ultragoal/SKILL.md +26 -16
  121. package/src/eval/py/executor.ts +7 -2
  122. package/src/extensibility/extensions/runner.ts +4 -0
  123. package/src/extensibility/extensions/types.ts +42 -4
  124. package/src/extensibility/shared-events.ts +5 -0
  125. package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -68
  126. package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
  127. package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
  128. package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
  129. package/src/gjc-runtime/deep-interview-state.ts +12 -921
  130. package/src/gjc-runtime/gc-render.ts +1 -0
  131. package/src/gjc-runtime/gc-runtime.ts +11 -1
  132. package/src/gjc-runtime/linux-proc.ts +70 -36
  133. package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
  134. package/src/gjc-runtime/ralplan-runtime.ts +979 -71
  135. package/src/gjc-runtime/state-runtime.ts +50 -12
  136. package/src/gjc-runtime/state-writer.ts +70 -222
  137. package/src/gjc-runtime/team-launch.ts +34 -5
  138. package/src/gjc-runtime/team-runtime.ts +970 -33
  139. package/src/gjc-runtime/team-store.ts +32 -0
  140. package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
  141. package/src/gjc-runtime/team-workers.ts +1 -0
  142. package/src/gjc-runtime/tmux-owner-isolation.ts +18 -0
  143. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
  144. package/src/gjc-runtime/ultragoal-runtime.ts +13 -7
  145. package/src/gjc-runtime/workflow-manifest.generated.json +97 -350
  146. package/src/gjc-runtime/workflow-manifest.ts +34 -179
  147. package/src/hooks/native-skill-hook.ts +17 -4
  148. package/src/hooks/skill-state.ts +1 -23
  149. package/src/internal-urls/docs-index.generated.ts +10 -11
  150. package/src/internal-urls/local-protocol.ts +23 -4
  151. package/src/internal-urls/local-root-gc.ts +127 -0
  152. package/src/main.ts +9 -5
  153. package/src/memories/index.ts +10 -0
  154. package/src/modes/DESIGN.md +47 -0
  155. package/src/modes/acp/acp-agent.ts +597 -67
  156. package/src/modes/acp/acp-event-mapper.ts +106 -12
  157. package/src/modes/acp/acp-mode.ts +39 -3
  158. package/src/modes/components/assistant-message.ts +123 -22
  159. package/src/modes/components/irc-sidebar.ts +176 -62
  160. package/src/modes/components/model-selector.ts +76 -5
  161. package/src/modes/components/notifications-settings-editor.ts +1 -1
  162. package/src/modes/components/oauth-selector.ts +42 -12
  163. package/src/modes/components/queue-pane.ts +55 -9
  164. package/src/modes/components/queued-message-selector.ts +53 -10
  165. package/src/modes/components/read-tool-group.ts +82 -14
  166. package/src/modes/components/session-observer-overlay.ts +187 -32
  167. package/src/modes/components/settings-selector.ts +60 -18
  168. package/src/modes/components/tool-execution.ts +138 -27
  169. package/src/modes/components/tool-status-header.ts +1 -4
  170. package/src/modes/components/welcome.ts +18 -3
  171. package/src/modes/controllers/command-controller.ts +4 -0
  172. package/src/modes/controllers/event-controller.ts +109 -27
  173. package/src/modes/controllers/extension-ui-controller.ts +23 -12
  174. package/src/modes/controllers/input-controller.ts +62 -6
  175. package/src/modes/controllers/selector-controller.ts +83 -37
  176. package/src/modes/interactive-mode.ts +127 -29
  177. package/src/modes/irc-observation-ledger.ts +71 -15
  178. package/src/modes/runtime-init.ts +20 -2
  179. package/src/modes/types.ts +2 -0
  180. package/src/modes/utils/ui-helpers.ts +94 -1
  181. package/src/prompts/agents/architect.md +9 -1
  182. package/src/prompts/agents/critic.md +9 -0
  183. package/src/prompts/agents/executor.md +1 -1
  184. package/src/prompts/system/system-prompt.md +0 -1
  185. package/src/prompts/tools/read.md +4 -2
  186. package/src/runtime/memory-domain.ts +66 -0
  187. package/src/runtime/memory-guard-contract.ts +73 -0
  188. package/src/runtime/memory-guard.ts +292 -0
  189. package/src/runtime/memory-limit.ts +50 -0
  190. package/src/runtime-mcp/manager.ts +26 -6
  191. package/src/runtime-mcp/smithery-auth.ts +17 -2
  192. package/src/runtime-mcp/smithery-connect.ts +11 -1
  193. package/src/sdk/acp/adapter.ts +8 -1
  194. package/src/sdk/acp/final-text.ts +40 -0
  195. package/src/sdk/acp/mcp.ts +26 -0
  196. package/src/sdk/broker/lifecycle.ts +107 -7
  197. package/src/sdk/bus/chat-daemon-cli.ts +2 -2
  198. package/src/sdk/bus/chat-daemon-control.ts +4 -3
  199. package/src/sdk/bus/config.ts +1 -1
  200. package/src/sdk/bus/control-drain-lease.ts +104 -0
  201. package/src/sdk/bus/index.ts +503 -60
  202. package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
  203. package/src/sdk/bus/prompt-reconciliation.ts +2 -1
  204. package/src/sdk/bus/rate-limit-pool.ts +8 -0
  205. package/src/sdk/bus/reconciliation-store.ts +224 -0
  206. package/src/sdk/bus/telegram-daemon-contract.ts +6 -4
  207. package/src/sdk/bus/telegram-daemon.ts +531 -53
  208. package/src/sdk/host/control/dispatch.ts +7 -1
  209. package/src/sdk/host/control/operations.ts +2 -1
  210. package/src/sdk/host/host.ts +25 -3
  211. package/src/sdk/host/query/handlers.ts +55 -0
  212. package/src/sdk/lifecycle-session.ts +19 -3
  213. package/src/sdk/mcp/server.ts +46 -18
  214. package/src/sdk/protocol/operation-inventory.generated.json +76 -0
  215. package/src/sdk/protocol/operation-registry.ts +8 -2
  216. package/src/sdk/session.ts +25 -2
  217. package/src/sdk/startup-capability.ts +6 -0
  218. package/src/session/agent-session.ts +720 -190
  219. package/src/session/fallback-chain-controller.ts +47 -8
  220. package/src/session/internal/managed-session-scope.ts +40 -10
  221. package/src/session/internal/native-publish-outcome.ts +8 -3
  222. package/src/session/memory-guard-checkpoint-participant.ts +131 -0
  223. package/src/session/session-manager.ts +1372 -42
  224. package/src/session/streaming-output.ts +262 -43
  225. package/src/setup/provider-onboarding.ts +19 -4
  226. package/src/skill-state/active-state.ts +0 -10
  227. package/src/skill-state/workflow-hud.ts +25 -2
  228. package/src/skill-state/workflow-mutation-guard.ts +65 -7
  229. package/src/task/executor.ts +11 -3
  230. package/src/task/index.ts +2 -0
  231. package/src/task/types.ts +22 -11
  232. package/src/task/ultragoal-redteam-activation.ts +75 -0
  233. package/src/tools/ask.ts +89 -69
  234. package/src/tools/browser/launch.ts +41 -6
  235. package/src/tools/fetch.ts +114 -23
  236. package/src/tools/output-meta.ts +176 -9
  237. package/src/tools/path-utils.ts +5 -1
  238. package/src/tools/read-internals.ts +44 -0
  239. package/src/tools/read.ts +1542 -310
  240. package/src/tools/resource-gc.ts +665 -125
  241. package/src/tools/tool-result.ts +14 -1
  242. package/src/web/search/providers/codex.ts +1 -1
  243. package/src/workflow/workflow-intent-diff.ts +4 -1
  244. package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
  245. package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
  246. package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
  247. package/src/gjc-runtime/deep-interview-draft.ts +0 -843
  248. package/src/gjc-runtime/deep-interview-payload.ts +0 -262
  249. package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
@@ -158,7 +158,11 @@ function invoke(
158
158
  case "workflow.plan_approve":
159
159
  return surface.approvePlan(text(input, "id"), input.choice, input.expectedSessionId as string | undefined);
160
160
  case "skill.invoke":
161
- return surface.invokeSkill(text(input, "name"), input.args);
161
+ return surface.invokeSkill(
162
+ text(input, "name"),
163
+ input.args,
164
+ typeof input.clientRef === "string" ? input.clientRef : undefined,
165
+ );
162
166
  case "mode.plan.set":
163
167
  return surface.setPlanMode(input.on as boolean);
164
168
  case "mode.goal.operate":
@@ -167,6 +171,8 @@ function invoke(
167
171
  return surface.replaceTodo(input.items);
168
172
  case "model.set":
169
173
  return surface.setModel(text(input, "id"), input.thinkingLevel);
174
+ case "model.profile.set":
175
+ return surface.setModelProfile(text(input, "id"));
170
176
  case "model.cycle":
171
177
  return surface.cycleModel();
172
178
  case "thinking.set":
@@ -19,11 +19,12 @@ export interface ControlSurface {
19
19
  idempotencyKey?: string,
20
20
  ): Promise<ControlValue> | ControlValue;
21
21
  approvePlan(id: string, choice: ControlValue, expectedSessionId?: string): Promise<ControlValue> | ControlValue;
22
- invokeSkill(name: string, args: ControlValue): Promise<ControlValue> | ControlValue;
22
+ invokeSkill(name: string, args: ControlValue, clientRef?: string): Promise<ControlValue> | ControlValue;
23
23
  setPlanMode(on: boolean): Promise<ControlValue> | ControlValue;
24
24
  operateGoal(op: string, objective?: string): Promise<ControlValue> | ControlValue;
25
25
  replaceTodo(items: ControlValue): Promise<ControlValue> | ControlValue;
26
26
  setModel(id: string, thinkingLevel?: ControlValue): Promise<ControlValue> | ControlValue;
27
+ setModelProfile(id: string): Promise<ControlValue> | ControlValue;
27
28
  cycleModel(): Promise<ControlValue> | ControlValue;
28
29
  setThinking(level: ControlValue): Promise<ControlValue> | ControlValue;
29
30
  cycleThinking(): Promise<ControlValue> | ControlValue;
@@ -9,6 +9,13 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
9
9
  query?: (connectionId: string, frame: SdkFrame) => unknown | Promise<unknown>;
10
10
  /** Best-effort diagnostic observation of accepted control/query frames. */
11
11
  onRequest?: SdkRequestObserver;
12
+ /** Runs before a control response is sent; identity transitions use sendTerminal. */
13
+ beforeControlResponse?: (
14
+ connectionId: string,
15
+ request: SdkFrame,
16
+ response: SdkFrame,
17
+ sendTerminal: () => Promise<void>,
18
+ ) => void | Promise<void>;
12
19
  /** Runs only after a successful control response has been sent to the client. */
13
20
  afterControlResponse?: (connectionId: string, request: SdkFrame, response: SdkFrame) => void | Promise<void>;
14
21
  installProviderDefinitions?: (capability: string, definitions: unknown) => void;
@@ -18,7 +25,7 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
18
25
  connectionCapabilities?: (connectionId: string) => ReadonlySet<string> | undefined;
19
26
  }
20
27
 
21
- const TOOL_ACTIVITY_V1 = "tool_activity_v1";
28
+ const TOOL_ACTIVITY_CAPABILITY = "tool_activity_v2";
22
29
  const CAP_GATED_FRAME_KINDS = new Set(["tool_activity", "reasoning_summary"]);
23
30
  const EMPTY_CAPABILITIES: ReadonlySet<string> = new Set();
24
31
 
@@ -36,6 +43,14 @@ function errorFrame(connectionId: string, frame: SdkFrame, error: unknown): SdkF
36
43
  ? candidate.code
37
44
  : "internal";
38
45
  const message = typeof candidate?.message === "string" ? candidate.message : "SDK host operation failed.";
46
+ if (frame.type === "control_request") {
47
+ return {
48
+ type: "control_response",
49
+ id: typeof frame.id === "string" ? frame.id : "",
50
+ ok: false,
51
+ error: { code, message },
52
+ };
53
+ }
39
54
  return {
40
55
  type: "reverse_response",
41
56
  id: typeof frame.id === "string" ? frame.id : "",
@@ -214,7 +229,14 @@ export class SessionSdkHost {
214
229
  const result = await this.#options.control?.(connectionId, frame);
215
230
  if (result !== undefined) {
216
231
  const response = { type: "control_response", ...(result as SdkFrame) };
217
- await this.#send(connectionId, response);
232
+ let terminalSent = false;
233
+ const sendTerminal = async (): Promise<void> => {
234
+ if (terminalSent) return;
235
+ terminalSent = true;
236
+ await this.#send(connectionId, response);
237
+ };
238
+ await this.#options.beforeControlResponse?.(connectionId, frame, response, sendTerminal);
239
+ await sendTerminal();
218
240
  await this.#options.afterControlResponse?.(connectionId, frame, response);
219
241
  }
220
242
  break;
@@ -233,7 +255,7 @@ export class SessionSdkHost {
233
255
  const replay = this.events.replay(sinceSeq, sinceGeneration);
234
256
  const capabilities = this.#options.connectionCapabilities?.(connectionId) ?? EMPTY_CAPABILITIES;
235
257
  const events = replay.events.filter(
236
- event => !CAP_GATED_FRAME_KINDS.has(String(event.kind)) || capabilities.has(TOOL_ACTIVITY_V1),
258
+ event => !CAP_GATED_FRAME_KINDS.has(String(event.kind)) || capabilities.has(TOOL_ACTIVITY_CAPABILITY),
237
259
  );
238
260
  await this.#send(connectionId, {
239
261
  type: "event_replay_result",
@@ -46,6 +46,11 @@ export interface SessionSurface {
46
46
  getJobs(): unknown | Promise<unknown>;
47
47
  /** Q26 keyed lookup of a submitted prompt's authoritative reconciliation status. */
48
48
  getPromptStatus?(selector: { commandId?: string; turnId?: string; clientRef?: string }): unknown | Promise<unknown>;
49
+ getSkillInvokeStatus?(selector: {
50
+ commandId?: string;
51
+ turnId?: string;
52
+ clientRef?: string;
53
+ }): unknown | Promise<unknown>;
49
54
  /** Q27 effective model-profile catalog from the live session registry. */
50
55
  getModelProfiles?(): unknown[] | Promise<unknown[]>;
51
56
  /** Query rows backed by the session's installed binding map. */
@@ -127,6 +132,7 @@ const names = [
127
132
  "runtime.jobs.list",
128
133
  "turn.prompt_status",
129
134
  "models.profiles.list",
135
+ "skill.invoke_status",
130
136
  ];
131
137
 
132
138
  export class QueryHandlers {
@@ -156,6 +162,7 @@ export class QueryHandlers {
156
162
  if (query === "Q02") return await this.#transcriptBody(request);
157
163
  if (query === "Q23") return await this.#resourceBody(request);
158
164
  if (query === "Q26") return await this.#promptStatus(request);
165
+ if (query === "Q28") return await this.#skillInvokeStatus(request);
159
166
  if (query === "Q24") return await this.#artifact(request);
160
167
  if (query === "Q27" && request.input && Object.keys(request.input).length > 0)
161
168
  return this.#error(request, "invalid_request", false, "models.profiles.list does not accept input fields.");
@@ -517,6 +524,54 @@ export class QueryHandlers {
517
524
  return { id: request.id, ok: true, page };
518
525
  }
519
526
 
527
+ async #skillInvokeStatus(request: QueryRequest): Promise<QueryResponse> {
528
+ if (request.cursor)
529
+ return this.#error(request, "invalid_request", false, "skill.invoke_status does not support cursors.");
530
+ const input = request.input ?? {};
531
+ for (const key of Object.keys(input))
532
+ if (key !== "commandId" && key !== "turnId" && key !== "clientRef")
533
+ return this.#error(
534
+ request,
535
+ "invalid_request",
536
+ false,
537
+ `skill.invoke_status does not accept selector field "${key}".`,
538
+ );
539
+ const commandId = typeof input.commandId === "string" && input.commandId ? input.commandId : undefined;
540
+ const turnId = typeof input.turnId === "string" && input.turnId ? input.turnId : undefined;
541
+ const rawClientRef = typeof input.clientRef === "string" ? input.clientRef : undefined;
542
+ const trimmedClientRef = rawClientRef?.trim();
543
+ if (rawClientRef !== undefined && (!trimmedClientRef || trimmedClientRef.length > PROMPT_CLIENT_REF_MAX_LENGTH))
544
+ return this.#error(
545
+ request,
546
+ "invalid_request",
547
+ false,
548
+ "clientRef must be a non-empty string of at most 128 characters.",
549
+ );
550
+ const clientRef = trimmedClientRef || undefined;
551
+ if ((commandId === undefined) !== (turnId === undefined))
552
+ return this.#error(request, "invalid_request", false, "commandId and turnId must be provided together.");
553
+ if (commandId !== undefined && clientRef !== undefined)
554
+ return this.#error(
555
+ request,
556
+ "invalid_request",
557
+ false,
558
+ "Provide exactly one selector: a commandId/turnId pair or a clientRef.",
559
+ );
560
+ if (commandId === undefined && clientRef === undefined)
561
+ return this.#error(
562
+ request,
563
+ "invalid_request",
564
+ false,
565
+ "skill.invoke_status requires a commandId/turnId pair or a clientRef.",
566
+ );
567
+ if (typeof this.surface.getSkillInvokeStatus !== "function")
568
+ return this.#error(request, "unavailable", false, "skill.invoke_status is unavailable for this session.");
569
+ const result = await this.surface.getSkillInvokeStatus(
570
+ clientRef !== undefined ? { clientRef } : { commandId: commandId!, turnId: turnId! },
571
+ );
572
+ return { id: request.id, ok: true, result };
573
+ }
574
+
520
575
  async #promptStatus(request: QueryRequest): Promise<QueryResponse> {
521
576
  if (request.cursor)
522
577
  return this.#error(request, "invalid_request", false, "turn.prompt_status does not support cursors.");
@@ -1,6 +1,7 @@
1
1
  import type { AgentSession } from "../session/agent-session";
2
2
  import { type CreateAgentSessionOptions, createAgentSession } from "./session";
3
3
  import {
4
+ lifecycleMcpStartupTimeoutOption,
4
5
  lifecycleStartupCapabilityOption,
5
6
  SdkStartupCapability,
6
7
  type SdkStartupFailure,
@@ -15,17 +16,32 @@ export type CreateLifecycleAgentSessionResult =
15
16
  }
16
17
  | { capability: SdkStartupCapability; rollback: SdkStartupRollbackTracker; failure: SdkStartupFailure };
17
18
 
19
+ /** Options accepted by lifecycle-only session construction. */
20
+ export type CreateLifecycleAgentSessionOptions = CreateAgentSessionOptions & {
21
+ /**
22
+ * Startup budget for ACP lifecycle MCP launches, in milliseconds. Set only
23
+ * when the lifecycle request supplies `mcpServers`; ordinary consumers keep
24
+ * the manager's short default ceiling.
25
+ */
26
+ mcpStartupTimeoutMs?: number;
27
+ };
28
+
18
29
  /** Internal lifecycle-only session construction with an owner-bound SDK startup result. */
19
30
  export async function createLifecycleAgentSession(
20
- options: CreateAgentSessionOptions = {},
31
+ options: CreateLifecycleAgentSessionOptions = {},
21
32
  ): Promise<CreateLifecycleAgentSessionResult> {
22
33
  const rollback = new SdkStartupRollbackTracker();
23
34
  const capability = new SdkStartupCapability(rollback);
24
35
  try {
36
+ const { mcpStartupTimeoutMs, ...sessionOptions } = options;
25
37
  const internalOptions = {
26
- ...options,
38
+ ...sessionOptions,
27
39
  [lifecycleStartupCapabilityOption]: capability,
28
- } as CreateAgentSessionOptions & { [lifecycleStartupCapabilityOption]: SdkStartupCapability };
40
+ ...(mcpStartupTimeoutMs !== undefined ? { [lifecycleMcpStartupTimeoutOption]: mcpStartupTimeoutMs } : {}),
41
+ } as CreateAgentSessionOptions & {
42
+ [lifecycleStartupCapabilityOption]: SdkStartupCapability;
43
+ [lifecycleMcpStartupTimeoutOption]?: number;
44
+ };
29
45
  const result = await createAgentSession(internalOptions);
30
46
  if (!result.session.extensionRunner)
31
47
  capability.settleFailure(capability.normalizeFailure("registration", "runner_absent"));
@@ -301,9 +301,16 @@ export function createSdkMcpServer(options: SdkMcpServerOptions = {}) {
301
301
  export async function runSdkMcpStdio(options: SdkMcpServerOptions = {}): Promise<void> {
302
302
  const server = createSdkMcpServer(options);
303
303
  let buffer = "";
304
+ const inflight = new Set<Promise<void>>();
304
305
  process.stdin.setEncoding("utf8");
305
- await new Promise<void>(resolve => {
306
- process.stdin.on("data", (chunk: string) => {
306
+
307
+ const track = (work: Promise<void>): void => {
308
+ inflight.add(work);
309
+ void work.finally(() => inflight.delete(work));
310
+ };
311
+
312
+ await new Promise<void>((resolve, reject) => {
313
+ const onData = (chunk: string) => {
307
314
  buffer += chunk;
308
315
  let index = buffer.indexOf("\n");
309
316
  while (index >= 0) {
@@ -311,22 +318,43 @@ export async function runSdkMcpStdio(options: SdkMcpServerOptions = {}): Promise
311
318
  buffer = buffer.slice(index + 1);
312
319
  index = buffer.indexOf("\n");
313
320
  if (!line) continue;
314
- void (async () => {
315
- let request: JsonRpcRequest;
316
- try {
317
- request = JSON.parse(line) as JsonRpcRequest;
318
- } catch {
319
- process.stdout.write(
320
- `${JSON.stringify({ jsonrpc: "2.0", id: null, error: { code: -32700, message: "parse_error" } })}\n`,
321
- );
322
- return;
323
- }
324
- const response = await server.handleJsonRpc(request);
325
- // JSON-RPC notifications (no id) receive no response.
326
- if (request.id !== undefined) process.stdout.write(`${JSON.stringify(response)}\n`);
327
- })();
321
+ track(
322
+ (async () => {
323
+ let request: JsonRpcRequest;
324
+ try {
325
+ request = JSON.parse(line) as JsonRpcRequest;
326
+ } catch {
327
+ process.stdout.write(
328
+ `${JSON.stringify({ jsonrpc: "2.0", id: null, error: { code: -32700, message: "parse_error" } })}\n`,
329
+ );
330
+ return;
331
+ }
332
+ const response = await server.handleJsonRpc(request);
333
+ // JSON-RPC notifications (no id) receive no response.
334
+ if (request.id !== undefined) process.stdout.write(`${JSON.stringify(response)}\n`);
335
+ })(),
336
+ );
328
337
  }
329
- });
330
- process.stdin.on("end", () => resolve());
338
+ };
339
+ const onEnd = () => {
340
+ process.stdin.off("data", onData);
341
+ process.stdin.off("end", onEnd);
342
+ process.stdin.off("error", onError);
343
+ resolve();
344
+ };
345
+ const onError = (error: Error) => {
346
+ process.stdin.off("data", onData);
347
+ process.stdin.off("end", onEnd);
348
+ process.stdin.off("error", onError);
349
+ reject(error);
350
+ };
351
+ process.stdin.on("data", onData);
352
+ process.stdin.on("end", onEnd);
353
+ process.stdin.on("error", onError);
331
354
  });
355
+
356
+ // Stdin EOF must not drop in-flight tools/call handlers (WS connect/query).
357
+ // Awaiting them also prevents the process from exiting before responses flush,
358
+ // and lets clients close so the event loop can drain deterministically.
359
+ await Promise.allSettled([...inflight]);
332
360
  }
@@ -935,6 +935,24 @@
935
935
  "packages/coding-agent/test/sdk-operation-inventory.test.ts"
936
936
  ]
937
937
  },
938
+ {
939
+ "sourceId": "registry:C53",
940
+ "sourceFile": "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
941
+ "sourceKind": "registry",
942
+ "decision": "include",
943
+ "sdkId": "model.profile.set",
944
+ "adapterMappings": {
945
+ "telegram": "generic_safe",
946
+ "discord": "generic_safe",
947
+ "slack": "generic_safe",
948
+ "mcp": "generic_safe",
949
+ "acp": "generic_safe",
950
+ "daemonCli": "generic_safe"
951
+ },
952
+ "testIds": [
953
+ "packages/coding-agent/test/sdk-operation-inventory.test.ts"
954
+ ]
955
+ },
938
956
  {
939
957
  "sourceId": "registry:G01",
940
958
  "sourceFile": "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
@@ -1547,6 +1565,24 @@
1547
1565
  "packages/coding-agent/test/sdk-operation-inventory.test.ts"
1548
1566
  ]
1549
1567
  },
1568
+ {
1569
+ "sourceId": "registry:Q28",
1570
+ "sourceFile": "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
1571
+ "sourceKind": "registry",
1572
+ "decision": "include",
1573
+ "sdkId": "skill.invoke_status",
1574
+ "adapterMappings": {
1575
+ "telegram": "prohibited",
1576
+ "discord": "prohibited",
1577
+ "slack": "prohibited",
1578
+ "mcp": "generic_safe",
1579
+ "acp": "generic_safe",
1580
+ "daemonCli": "generic_safe"
1581
+ },
1582
+ "testIds": [
1583
+ "packages/coding-agent/test/sdk-operation-inventory.test.ts"
1584
+ ]
1585
+ },
1550
1586
  {
1551
1587
  "sourceId": "registry:R01",
1552
1588
  "sourceFile": "packages/coding-agent/src/sdk/protocol/operation-registry.ts",
@@ -2885,6 +2921,17 @@
2885
2921
  "testIds": "not_applicable"
2886
2922
  }
2887
2923
  },
2924
+ {
2925
+ "sourceId": "agent_session:restoreFromMemoryGuardCheckpoint",
2926
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
2927
+ "sourceKind": "agent_session",
2928
+ "decision": "exclude",
2929
+ "rationale": "internal owner-recovery staged restore builder after durable claims/fencing, never a user-facing SDK operation",
2930
+ "exclusionMetadata": {
2931
+ "adapterMappings": "not_applicable",
2932
+ "testIds": "not_applicable"
2933
+ }
2934
+ },
2888
2935
  {
2889
2936
  "sourceId": "agent_session:promoteRecoveryHydrationAfterOwnershipReadyFence",
2890
2937
  "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
@@ -2918,6 +2965,17 @@
2918
2965
  "testIds": "not_applicable"
2919
2966
  }
2920
2967
  },
2968
+ {
2969
+ "sourceId": "agent_session:buildPreparedDisplaySessionContext",
2970
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
2971
+ "sourceKind": "agent_session",
2972
+ "decision": "exclude",
2973
+ "rationale": "internal accessor/plumbing, not a user-facing control seam",
2974
+ "exclusionMetadata": {
2975
+ "adapterMappings": "not_applicable",
2976
+ "testIds": "not_applicable"
2977
+ }
2978
+ },
2921
2979
  {
2922
2980
  "sourceId": "agent_session:convertMessagesToLlm",
2923
2981
  "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
@@ -3721,6 +3779,24 @@
3721
3779
  "testIds": "not_applicable"
3722
3780
  }
3723
3781
  },
3782
+ {
3783
+ "sourceId": "agent_session:activateModelProfileForControl",
3784
+ "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
3785
+ "sourceKind": "agent_session",
3786
+ "decision": "include",
3787
+ "sdkId": "model.profile.set",
3788
+ "adapterMappings": {
3789
+ "telegram": "generic_safe",
3790
+ "discord": "generic_safe",
3791
+ "slack": "generic_safe",
3792
+ "mcp": "generic_safe",
3793
+ "acp": "generic_safe",
3794
+ "daemonCli": "generic_safe"
3795
+ },
3796
+ "testIds": [
3797
+ "packages/coding-agent/test/sdk-operation-inventory.test.ts"
3798
+ ]
3799
+ },
3724
3800
  {
3725
3801
  "sourceId": "agent_session:getConfiguredModelChain",
3726
3802
  "sourceFile": "packages/coding-agent/src/session/agent-session.ts",
@@ -116,6 +116,7 @@ const controls = [
116
116
  ["retry.last", "Retry the last interrupted or failed turn."],
117
117
  ["retry.now", "Immediately retry pending backoff."],
118
118
  ["bash.background", "Move active managed bash to the background."],
119
+ ["model.profile.set", "Activate a model profile for the current session."],
119
120
  ] as const;
120
121
 
121
122
  const globals = [
@@ -159,6 +160,10 @@ const queries = [
159
160
  "Read the authoritative reconciliation status of a submitted prompt by command/turn IDs or clientRef.",
160
161
  ],
161
162
  ["models.profiles.list", "List the effective built-in and configured model profiles for this session."],
163
+ [
164
+ "skill.invoke_status",
165
+ "Read the authoritative reconciliation status of a skill.invoke by command/turn IDs or clientRef.",
166
+ ],
162
167
  ] as const;
163
168
 
164
169
  const reverse = [
@@ -196,7 +201,8 @@ function controlDisposition(id: string): Record<Adapter, AdapterDisposition> {
196
201
 
197
202
  function controlErrors(id: string): string[] {
198
203
  const errors: Record<string, string[]> = {
199
- C01: ["client_ref_conflict", "reconciliation_capacity"],
204
+ C01: ["client_ref_conflict", "reconciliation_capacity", "reconciliation_persist_failed"],
205
+ C09: ["client_ref_conflict", "reconciliation_capacity", "reconciliation_persist_failed"],
200
206
  C06: ["action_claimed"],
201
207
  C07: ["action_claimed", "terminal_uncertain"],
202
208
  C08: ["action_claimed", "terminal_uncertain"],
@@ -237,7 +243,7 @@ function queryContinuityClass(id: string): QueryContinuityClass {
237
243
  }
238
244
 
239
245
  function queryDisposition(id: string): Record<Adapter, AdapterDisposition> {
240
- if (["Q23", "Q24", "Q25", "Q26", "Q27"].includes(id))
246
+ if (["Q23", "Q24", "Q25", "Q26", "Q27", "Q28"].includes(id))
241
247
  return dispositions({ telegram: "prohibited", discord: "prohibited", slack: "prohibited" });
242
248
  return dispositions();
243
249
  }
@@ -21,6 +21,7 @@ import {
21
21
  type ToolResultMessage,
22
22
  } from "@gajae-code/ai";
23
23
  import {
24
+ codexToolWireName,
24
25
  getOpenAICodexTransportDetails,
25
26
  prewarmOpenAICodexResponses,
26
27
  } from "@gajae-code/ai/providers/openai-codex-responses";
@@ -168,6 +169,7 @@ import { buildNamedToolChoice, buildNamedToolChoiceResult } from "../utils/tool-
168
169
  import { buildWorkspaceTree, type WorkspaceTree } from "../workspace-tree";
169
170
  import {
170
171
  attachLifecycleStartupCapability,
172
+ lifecycleMcpStartupTimeoutOption,
171
173
  lifecycleStartupCapabilityOption,
172
174
  type SdkStartupCapability,
173
175
  } from "./startup-capability";
@@ -1028,6 +1030,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1028
1030
  const lifecycleStartupCapability = (
1029
1031
  options as CreateAgentSessionOptions & { [lifecycleStartupCapabilityOption]?: SdkStartupCapability }
1030
1032
  )[lifecycleStartupCapabilityOption];
1033
+ // ACP lifecycle launches carry their own MCP startup budget; every other
1034
+ // consumer keeps the manager's short default ceiling.
1035
+ const lifecycleMcpStartupTimeoutMs = (
1036
+ options as CreateAgentSessionOptions & { [lifecycleMcpStartupTimeoutOption]?: number }
1037
+ )[lifecycleMcpStartupTimeoutOption];
1031
1038
  const isCanonicalSubSession =
1032
1039
  (options.taskDepth ?? 0) > 0 || Boolean(options.parentTaskPrefix) || Boolean(options.currentAgentType);
1033
1040
  if (isCanonicalSubSession && options.mcpConfigPath !== undefined) {
@@ -1720,7 +1727,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1720
1727
 
1721
1728
  const preExactCustomToolNames = customTools.map(tool => tool.name);
1722
1729
  if (explicitMcpConfigPath !== undefined) {
1723
- const owned = new MCPManager(cwd, null, { toolsOnly: true });
1730
+ const owned = new MCPManager(cwd, null, {
1731
+ toolsOnly: true,
1732
+ ...(lifecycleMcpStartupTimeoutMs !== undefined
1733
+ ? { maxStartupTimeoutMs: lifecycleMcpStartupTimeoutMs }
1734
+ : {}),
1735
+ });
1724
1736
  owned.setAuthStorage(authStorage);
1725
1737
  mcpManager = owned;
1726
1738
  ownsMcpManager = true;
@@ -2177,7 +2189,18 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
2177
2189
  const previousPromptMetadataModel = promptMetadataModel;
2178
2190
  promptMetadataModel = candidateModel;
2179
2191
  try {
2180
- return buildSystemPromptToolMetadata(tools);
2192
+ const activeModel = candidateModel ?? agent?.state.model ?? model;
2193
+ // Codex renames reserved tool names on the wire; the prompt must
2194
+ // refer to the tools by the names the model actually receives.
2195
+ const overrides =
2196
+ activeModel?.api === "openai-codex-responses"
2197
+ ? Object.fromEntries(
2198
+ Array.from(tools.keys())
2199
+ .filter(name => codexToolWireName(name) !== name)
2200
+ .map(name => [name, { wireName: codexToolWireName(name) }]),
2201
+ )
2202
+ : {};
2203
+ return buildSystemPromptToolMetadata(tools, overrides);
2181
2204
  } finally {
2182
2205
  promptMetadataModel = previousPromptMetadataModel;
2183
2206
  }
@@ -22,6 +22,12 @@ const MAX_MESSAGE_BYTES = 512;
22
22
 
23
23
  /** Internal symbols for lifecycle-only SDK startup construction and bus wiring. */
24
24
  export const lifecycleStartupCapabilityOption: unique symbol = Symbol("lifecycleStartupCapability");
25
+ /**
26
+ * Internal option carrying the startup budget for ACP lifecycle MCP launches.
27
+ * Only set when the lifecycle request actually supplies `mcpServers`, so the
28
+ * longer ceiling never leaks to ordinary CLI/SDK `mcpConfigPath` consumers.
29
+ */
30
+ export const lifecycleMcpStartupTimeoutOption: unique symbol = Symbol("lifecycleMcpStartupTimeout");
25
31
  const lifecycleStartupCapabilityOnApi: unique symbol = Symbol("lifecycleStartupCapabilityOnApi");
26
32
 
27
33
  export function attachLifecycleStartupCapability(api: object, capability: SdkStartupCapability): void {