@platless/axom-cli 0.5.9 → 0.6.52

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 (258) hide show
  1. package/README.md +25 -6
  2. package/dist/axom-patch/cli/README.md +129 -12
  3. package/dist/axom-patch/cli/account-limits/generate.py +15 -12
  4. package/dist/axom-patch/cli/account-limits/kimi-proxy.mjs +20 -3
  5. package/dist/axom-patch/cli/claude-account-limits.json +9 -9
  6. package/dist/axom-patch/cli/claude-replay-lifecycle.json +16 -0
  7. package/dist/axom-patch/cli/codex-account-limits.json +11 -11
  8. package/dist/axom-patch/cli/codex-terminal-output.json +16 -0
  9. package/dist/axom-patch/cli/commandcode-account-limits.json +9 -9
  10. package/dist/axom-patch/cli/kimi-quota.mjs +12 -0
  11. package/dist/axom-patch/cli/kimi-subagents.mjs +173 -0
  12. package/dist/axom-patch/cli/nightly-task.md +55 -13
  13. package/dist/axom-patch/cli/probes/claude-replay-lifecycle.mjs +31 -0
  14. package/dist/axom-patch/cli/probes/codex-terminal-output.mjs +33 -0
  15. package/dist/axom-patch/cli/probes/kimi-subagent-subwork.mjs +82 -0
  16. package/dist/axom-patch/cli/probes/zcode-env-account.mjs +81 -0
  17. package/dist/axom-patch/cli/probes/zcode-subagent-subwork.mjs +7 -0
  18. package/dist/axom-patch/cli/qoder/dist/axom-acp-compat.mjs +1687 -0
  19. package/dist/axom-patch/cli/qoder/releases/1.1.75.json +277 -0
  20. package/dist/axom-patch/cli/qoder-background-terminal.md +13 -6
  21. package/dist/axom-patch/cli/qoder-foreground-output.md +14 -8
  22. package/dist/axom-patch/cli/qoder-native-acp.json +227 -0
  23. package/dist/axom-patch/cli/qoder-steering.md +20 -25
  24. package/dist/axom-patch/cli/qoder-subagent-subwork.md +17 -68
  25. package/dist/axom-patch/cli/runtime.json +19 -19
  26. package/dist/axom-patch/cli/zcode/env-account.mjs +13 -0
  27. package/dist/axom-patch/cli/zcode/generate-env-account.py +52 -0
  28. package/dist/axom-patch/cli/zcode-account-limits.json +10 -11
  29. package/dist/axom-patch/cli/zcode-env-account.json +58 -0
  30. package/dist/axom-patch/cli/zcode-models.json +9 -10
  31. package/dist/axom-patch/cli/zcode-subagent-subwork.json +10 -11
  32. package/dist/cli.js +11 -45
  33. package/dist/commands/auth.js +4 -1
  34. package/dist/commands/knowledge.js +47 -0
  35. package/dist/commands/update.js +126 -3
  36. package/dist/commands/workstation.js +101 -164
  37. package/dist/commands/workstationRegistrations.js +116 -0
  38. package/dist/credentialBroker.js +13 -2
  39. package/dist/credentials.js +16 -0
  40. package/dist/install/claude/commands.js +15 -15
  41. package/dist/keepers/terminal/keeper.mjs +1089 -673
  42. package/dist/keepers/terminal/manifest.json +4 -4
  43. package/dist/mcp.js +1 -1
  44. package/dist/native/darwin-x64/axom-quic +0 -0
  45. package/dist/workstation/acp/acpAgents.js +113 -102
  46. package/dist/workstation/acp/acpClient.js +26 -0
  47. package/dist/workstation/acp/builds/install/npm.js +99 -10
  48. package/dist/workstation/acp/initializeResponse.js +6 -1
  49. package/dist/workstation/acp/managedPatches.js +189 -25
  50. package/dist/workstation/acp/managedRuntime.js +314 -0
  51. package/dist/workstation/acp/outbox.js +12 -5
  52. package/dist/workstation/acp/patchAssets.js +40 -0
  53. package/dist/workstation/acp/permission.js +2 -2
  54. package/dist/workstation/acp/processor/checkpoint.js +26 -34
  55. package/dist/workstation/acp/processor/control.js +7 -80
  56. package/dist/workstation/acp/processor/jsonrpc.js +8 -0
  57. package/dist/workstation/acp/processor/runtime.js +5 -81
  58. package/dist/workstation/acp/processor/session.js +54 -82
  59. package/dist/workstation/acp/processor/state.js +7 -13
  60. package/dist/workstation/acp/processor/step.js +3 -20
  61. package/dist/workstation/acp/processor/test/fixtureLog.js +9 -16
  62. package/dist/workstation/acp/processor/transport/local.js +19 -3
  63. package/dist/workstation/acp/processor/updates.js +156 -105
  64. package/dist/workstation/acp/processorSession.js +20 -173
  65. package/dist/workstation/acp/registry/catalog.js +65 -39
  66. package/dist/workstation/acp/registry/launch.js +16 -1
  67. package/dist/workstation/acp/switching.js +0 -3
  68. package/dist/workstation/acp/test/fakeAgent.js +13 -0
  69. package/dist/workstation/acp/test/keeperWorld.js +32 -3
  70. package/dist/workstation/acp/test/raw/sources.js +16 -130
  71. package/dist/workstation/acp/test/realAdapter.js +1 -47
  72. package/dist/workstation/acp/test/scriptAgent.js +11 -3
  73. package/dist/workstation/agentFlow.js +1 -1
  74. package/dist/workstation/agentSessions.js +114 -166
  75. package/dist/workstation/channels/agent.js +9 -1
  76. package/dist/workstation/channels/computer.js +27 -4
  77. package/dist/workstation/channels/management.js +130 -15
  78. package/dist/workstation/channels/url.js +1 -1
  79. package/dist/workstation/config.js +33 -9
  80. package/dist/workstation/connection/encryptedChannel.js +4 -1
  81. package/dist/workstation/control/bindingStore.js +204 -0
  82. package/dist/workstation/control/commands.js +125 -0
  83. package/dist/workstation/control/daemonIdentity.js +143 -0
  84. package/dist/workstation/control/deviceCommands.js +191 -0
  85. package/dist/workstation/control/deviceProtocol.js +68 -0
  86. package/dist/workstation/control/enrollment.js +106 -0
  87. package/dist/workstation/control/inspect.js +71 -0
  88. package/dist/workstation/control/locks.js +110 -0
  89. package/dist/workstation/control/protocol.js +40 -0
  90. package/dist/workstation/control/restartGuard.js +46 -0
  91. package/dist/workstation/control/rootFormat.js +16 -0
  92. package/dist/workstation/control/runtimeClient.js +152 -0
  93. package/dist/workstation/control/runtimeHost.js +235 -0
  94. package/dist/workstation/control/serverIdentity.js +35 -0
  95. package/dist/workstation/control/updateTransition.js +91 -0
  96. package/dist/workstation/daemon.js +266 -264
  97. package/dist/workstation/daemonctl.js +226 -25
  98. package/dist/workstation/desktopControl/audio.js +99 -0
  99. package/dist/workstation/desktopControl/automationDevice.js +219 -0
  100. package/dist/workstation/desktopControl/automationJson.js +74 -0
  101. package/dist/workstation/desktopControl/automationLocalState.js +23 -0
  102. package/dist/workstation/desktopControl/automationProtocol.js +253 -0
  103. package/dist/workstation/desktopControl/automationSchema.generated.js +1 -0
  104. package/dist/workstation/desktopControl/automationSession.js +81 -0
  105. package/dist/workstation/desktopControl/automationTransport.js +138 -0
  106. package/dist/workstation/desktopControl/capabilities.js +93 -0
  107. package/dist/workstation/desktopControl/captureModes.js +9 -0
  108. package/dist/workstation/desktopControl/captureTargetLabel.js +9 -0
  109. package/dist/workstation/desktopControl/deviceAdmission.js +229 -0
  110. package/dist/workstation/desktopControl/deviceOwnership.js +130 -0
  111. package/dist/workstation/desktopControl/deviceSockets.js +246 -0
  112. package/dist/workstation/desktopControl/helperProcess.js +602 -0
  113. package/dist/workstation/desktopControl/hostGrant.js +65 -0
  114. package/dist/workstation/desktopControl/lobby.js +131 -0
  115. package/dist/workstation/desktopControl/macProvider.js +156 -0
  116. package/dist/workstation/desktopControl/media.js +331 -0
  117. package/dist/workstation/desktopControl/nativeDeviceAdmission.js +207 -0
  118. package/dist/workstation/desktopControl/nativeProvider.js +1044 -0
  119. package/dist/workstation/desktopControl/networkEvidence.js +43 -0
  120. package/dist/workstation/desktopControl/overview.js +58 -0
  121. package/dist/workstation/desktopControl/ownershipProtocol.js +31 -0
  122. package/dist/workstation/desktopControl/protocol.js +311 -0
  123. package/dist/workstation/desktopControl/provider.js +1 -0
  124. package/dist/workstation/desktopControl/quicMedia.js +240 -0
  125. package/dist/workstation/desktopControl/rateController.js +226 -0
  126. package/dist/workstation/desktopControl/supervisor.js +1774 -0
  127. package/dist/workstation/desktopControl/transport.js +27 -0
  128. package/dist/workstation/desktopControl/wallpaper.js +98 -0
  129. package/dist/workstation/exec/policy.js +5 -0
  130. package/dist/workstation/files/client.js +10 -1
  131. package/dist/workstation/files/credentials.js +142 -0
  132. package/dist/workstation/files/host.js +9 -2
  133. package/dist/workstation/files/text.js +42 -8
  134. package/dist/workstation/journal.js +5 -2
  135. package/dist/workstation/keepers/acp/client.js +38 -2
  136. package/dist/workstation/keepers/kit/buildVersion.js +35 -11
  137. package/dist/workstation/keepers/kit/bundle.js +21 -17
  138. package/dist/workstation/keepers/kit/client.js +2 -2
  139. package/dist/workstation/keepers/kit/launcher.js +123 -7
  140. package/dist/workstation/keepers/kit/paths.js +2 -1
  141. package/dist/workstation/keepers/legacy.js +16 -2
  142. package/dist/workstation/keepers/policy.js +5 -34
  143. package/dist/workstation/keepers/terminal/client.js +115 -23
  144. package/dist/workstation/keepers/terminal/exec.js +6 -3
  145. package/dist/workstation/keepers/terminal/frames.js +73 -0
  146. package/dist/workstation/keepers/terminal/generations.js +5 -8
  147. package/dist/workstation/keepers/terminal/gridProtocol.js +16 -0
  148. package/dist/workstation/keepers/terminal/input.js +146 -0
  149. package/dist/workstation/keepers/terminal/keeper.js +22 -8
  150. package/dist/workstation/keepers/terminal/main.js +1 -1
  151. package/dist/workstation/keepers/terminal/metadata.js +138 -0
  152. package/dist/workstation/keepers/terminal/protocol.js +4 -28
  153. package/dist/workstation/keepers/terminal/pty.js +1 -330
  154. package/dist/workstation/keepers/terminal/screen.js +246 -0
  155. package/dist/workstation/keepers/terminal/sessions.js +526 -0
  156. package/dist/workstation/managedInstall.js +57 -0
  157. package/dist/workstation/oauth/deviceAuthorization.js +31 -17
  158. package/dist/workstation/protocol/agent.js +2 -15
  159. package/dist/workstation/protocol/management.js +113 -5
  160. package/dist/workstation/protocol/runtimeDiagnostics.js +15 -0
  161. package/dist/workstation/rd/artifact.js +120 -0
  162. package/dist/workstation/rd/control.js +117 -0
  163. package/dist/workstation/rd/display.js +29 -0
  164. package/dist/workstation/rd/host.js +213 -0
  165. package/dist/workstation/rd/migrationReadiness.js +46 -0
  166. package/dist/workstation/rd/provider.js +256 -0
  167. package/dist/workstation/rd/sessions.js +391 -0
  168. package/dist/workstation/rd/state.js +57 -0
  169. package/dist/workstation/rd/update.js +168 -0
  170. package/dist/workstation/rd/upkeep.js +80 -0
  171. package/dist/workstation/register.js +27 -37
  172. package/dist/workstation/registrations/enrollment.js +250 -0
  173. package/dist/workstation/registrations/enrollmentPending.js +361 -0
  174. package/dist/workstation/registrations/migration.js +356 -0
  175. package/dist/workstation/registrations/model.js +34 -0
  176. package/dist/workstation/registrations/removal.js +222 -0
  177. package/dist/workstation/registrations/store.js +737 -0
  178. package/dist/workstation/runtime/desktopBinding.js +20 -0
  179. package/dist/workstation/runtime/deviceDesktop.js +193 -0
  180. package/dist/workstation/runtime/deviceRuntime.js +568 -0
  181. package/dist/workstation/runtime/deviceServices.js +117 -0
  182. package/dist/workstation/runtime/events.js +20 -0
  183. package/dist/workstation/runtime/ownership.js +100 -0
  184. package/dist/workstation/runtime/registrationRuntime.js +575 -0
  185. package/dist/workstation/runtime/remoteDesktopAdapter.js +186 -0
  186. package/dist/workstation/runtime/removalActivity.js +184 -0
  187. package/dist/workstation/service/installer.js +197 -14
  188. package/dist/workstation/service/launchd.js +2 -0
  189. package/dist/workstation/service/systemd.js +1 -0
  190. package/dist/workstation/storageMetrics.js +118 -0
  191. package/dist/workstation/systemMetrics.js +47 -92
  192. package/dist/workstation/toolchain.js +94 -0
  193. package/dist/workstation/tools/browser.js +28 -4
  194. package/dist/workstation/tools/client.js +8 -27
  195. package/dist/workstation/tools/info.js +6 -13
  196. package/dist/workstation/tools/terminalRouter.js +17 -172
  197. package/dist/workstation/tools/validation.js +55 -1
  198. package/dist/workstation/update/archiveEvidence.js +206 -0
  199. package/dist/workstation/update/artifact.js +2 -1
  200. package/dist/workstation/update/coordinator.js +34 -13
  201. package/dist/workstation/update/deviceCompatibility.js +119 -0
  202. package/dist/workstation/update/deviceCoordinator.js +369 -0
  203. package/dist/workstation/update/deviceHealth.js +104 -0
  204. package/dist/workstation/update/deviceHealthProtocol.js +26 -0
  205. package/dist/workstation/update/deviceRecoveryLifecycle.js +46 -0
  206. package/dist/workstation/update/deviceRollback.js +78 -0
  207. package/dist/workstation/update/globalInstall.js +186 -0
  208. package/dist/workstation/update/legacyBridge.js +414 -0
  209. package/dist/workstation/update/legacyOwner.js +39 -0
  210. package/dist/workstation/update/npmInstaller.js +51 -25
  211. package/dist/workstation/update/privateDurability.js +61 -0
  212. package/dist/workstation/update/rdRollback.js +145 -0
  213. package/dist/workstation/update/recoveryPlan.js +124 -0
  214. package/dist/workstation/update/runUpdate.js +10 -3
  215. package/dist/workstation/update/taskRegistry.js +161 -3
  216. package/dist/workstation/update/watchdog.js +29806 -333
  217. package/dist/workstation/update/watchdogProcess.js +72 -0
  218. package/package.json +11 -7
  219. package/skills/axom/SKILL.md +11 -11
  220. package/skills/axom-definition/SKILL.md +3 -3
  221. package/skills/axom-platform/SKILL.md +3 -3
  222. package/dist/axom-patch/cli/probes/qoder-steering.mjs +0 -89
  223. package/dist/axom-patch/cli/probes/qoder-subagent-origin.mjs +0 -61
  224. package/dist/axom-patch/cli/qoder-steering.json +0 -52
  225. package/dist/axom-patch/cli/qoder-subagent-origin.json +0 -73
  226. package/dist/commands/guide.js +0 -38
  227. package/dist/runtime-deps/qoder-sdk/package-lock.json +0 -1189
  228. package/dist/runtime-deps/qoder-sdk/package.json +0 -8
  229. package/dist/workstation/acp/delegationMcp.js +0 -24
  230. package/dist/workstation/acp/processor/sideChannel.js +0 -80
  231. package/dist/workstation/acp/qoderStartup.js +0 -45
  232. package/dist/workstation/acp/test/raw/qoderCaptures.js +0 -125
  233. package/dist/workstation/qoderAdapter/backgroundProcess.js +0 -118
  234. package/dist/workstation/qoderAdapter/backgroundTerminal.js +0 -193
  235. package/dist/workstation/qoderAdapter/backgroundTerminalFold.js +0 -372
  236. package/dist/workstation/qoderAdapter/callbackContext.js +0 -76
  237. package/dist/workstation/qoderAdapter/completedContinuation.js +0 -139
  238. package/dist/workstation/qoderAdapter/contract.js +0 -78
  239. package/dist/workstation/qoderAdapter/foregroundOutput.js +0 -36
  240. package/dist/workstation/qoderAdapter/history.js +0 -85
  241. package/dist/workstation/qoderAdapter/identityIndex.js +0 -191
  242. package/dist/workstation/qoderAdapter/inputQueue.js +0 -42
  243. package/dist/workstation/qoderAdapter/main.js +0 -95
  244. package/dist/workstation/qoderAdapter/mapper.js +0 -117
  245. package/dist/workstation/qoderAdapter/observerPlugin.js +0 -245
  246. package/dist/workstation/qoderAdapter/observerReceiver.js +0 -187
  247. package/dist/workstation/qoderAdapter/permissions.js +0 -61
  248. package/dist/workstation/qoderAdapter/profile.js +0 -93
  249. package/dist/workstation/qoderAdapter/sdkDriver.js +0 -48
  250. package/dist/workstation/qoderAdapter/sdkRuntime.js +0 -93
  251. package/dist/workstation/qoderAdapter/sdkRuntimeInstall.js +0 -145
  252. package/dist/workstation/qoderAdapter/session.js +0 -319
  253. package/dist/workstation/qoderAdapter/subagentMeta.js +0 -28
  254. package/dist/workstation/qoderAdapter/subwork.js +0 -85
  255. package/dist/workstation/qoderAdapter/taskControl.js +0 -38
  256. package/dist/workstation/qoderAdapter/taskLedger.js +0 -163
  257. package/dist/workstation/qoderAdapter/usage.js +0 -37
  258. /package/dist/workstation/{qoderAdapter/types.js → desktopControl/automationPreparation.js} +0 -0
@@ -1,42 +1,13 @@
1
- /**
2
- * The open session and its controls, as notes and their responses (Task 17b): `session/new|load|resume`,
3
- * `historyEnd`, `session/set_config_option`/`set_mode`, `_session/steering`, `_session/async_task/stop`,
4
- * delegation's non-secret fields and the runtime `launch` (spec 2026-10-11 §5.4).
5
- *
6
- * ## Opening, and binding from the response
7
- *
8
- * `agent_session_open{mode, cwd, sessionId?, mcpServers?, redact?, delegation?}` sends one request —
9
- * the params `AcpSession.open` (`buildSession`), `replayNativeSession` (`session/load`) and the Qoder
10
- * resume path build, `_meta` included (`newSessionMetaFor`, decided from the initialize reading). The
11
- * MCP server list arrives finished: the daemon validated the delegation lease (`buildSessionMcpServers`,
12
- * which reads the clock) before it wrote the note, and the bearer in it is a `secretRef` token the
13
- * executor substitutes into stdin only (`redact`, spec §13). The **response** binds the root
14
- * (`bindRootSession`) and sets the config snapshot — no pre-bind buffer, no window. A failed open is
15
- * reported (`processor.open_result`) and never retried as `session/new` here.
16
- *
17
- * ## Replies
18
- *
19
- * `agent_config_option_set` and `agent_steered` are RPC replies: unnumbered frames carrying the
20
- * server's frame `id` from the note, built as `agentSessions.ts` builds them. A steer's blocks travel
21
- * like a prompt's (`fill: {blocksRef}`); if the executor lost them, the same `agent_prompt_failed` note
22
- * fails the steer.
23
- *
24
- * ## `steeredIds` (spec §5.5.4)
25
- *
26
- * {@link steeredIds}: steers whose line reached the agent and that are unanswered, plus the last
27
- * {@link STEERED_HISTORY_LIMIT} the agent answered `injected`. A `promptRequired`, a refusal, or a
28
- * line that never reached the agent is not steered: the server delivers that message the ordinary way.
29
- */
1
+ /** Open-session binding, configuration, steering and launch notes. A response binds the native root; a failed load never silently creates another session here. The daemon supplies the finished MCP list with secrets replaced by references. */
30
2
  import { newSessionMetaFor } from '../activityReporting.js';
31
3
  import { flatChoicesOf, modesAlreadyRepresented, modelsAlreadyRepresented, normalizeConfigOptions, SYNTHESIZED_MODES_CONFIG_ID, SYNTHESIZED_MODEL_CONFIG_ID } from '../configOptions.js';
32
4
  import { ASYNC_TASK_STOP_METHOD, mapSteerOutcome, STEER_METHOD } from '../steering.js';
33
5
  import { emitEvent, isRecord } from './emit.js';
34
- import { settlementErrorCode } from './jsonrpc.js';
6
+ import { jsonRpcErrorText, settlementErrorCode } from './jsonrpc.js';
35
7
  import { sameCause } from './record.js';
36
- import { onLaunchNote, onRootBound } from './runtime.js';
8
+ import { onLaunchNote } from './runtime.js';
37
9
  import { bindRootSession, closeErrorText, connected } from './session.js';
38
10
  import { getOwn, putOwn, STEERED_HISTORY_LIMIT, } from './state.js';
39
- import { closeRepair } from './sideChannel.js';
40
11
  import { endHistory } from './updates.js';
41
12
  const OPEN_METHODS = { new: 'session/new', load: 'session/load', resume: 'session/resume' };
42
13
  export const NOT_INITIALIZED = 'The ACP connection has not finished initialize';
@@ -51,30 +22,12 @@ function request(state, out, method, params, kind, ctx, extras = {}) {
51
22
  function isStringArray(value) {
52
23
  return Array.isArray(value) && value.every((item) => typeof item === 'string');
53
24
  }
54
- function delegationOf(value) {
55
- if (value === undefined)
56
- return null;
57
- if (!isRecord(value))
58
- return undefined;
59
- const { expiresAtEpochMs, leaseId, bindingId, instanceId } = value;
60
- if (!Number.isSafeInteger(expiresAtEpochMs) || typeof leaseId !== 'string' || leaseId === ''
61
- || (bindingId !== undefined && typeof bindingId !== 'string') || (instanceId !== undefined && typeof instanceId !== 'string')
62
- || (bindingId !== undefined) !== (instanceId !== undefined))
63
- return undefined;
64
- return {
65
- expiresAtEpochMs: expiresAtEpochMs, leaseId,
66
- ...(bindingId !== undefined ? { bindingId, instanceId: instanceId, renewalRevision: 0 } : {}),
67
- };
68
- }
69
25
  // ---- open ---------------------------------------------------------------------------------------
70
- /** `agent_session_open{mode, cwd, sessionId?, mcpServers?, redact?, delegation?}`. */
71
26
  export function onOpenNote(state, note, out) {
72
27
  const { mode, cwd, sessionId, mcpServers, redact } = note;
73
- const delegation = delegationOf(note.delegation);
74
28
  if ((mode !== 'new' && mode !== 'load' && mode !== 'resume') || typeof cwd !== 'string' || cwd === ''
75
29
  || (mode === 'new' ? sessionId !== undefined : typeof sessionId !== 'string' || sessionId === '')
76
- || (mcpServers !== undefined && !Array.isArray(mcpServers)) || (redact !== undefined && !isStringArray(redact))
77
- || delegation === undefined) {
30
+ || (mcpServers !== undefined && !Array.isArray(mcpServers)) || (redact !== undefined && !isStringArray(redact))) {
78
31
  state.diagnostics.droppedNotes += 1;
79
32
  return;
80
33
  }
@@ -92,7 +45,7 @@ export function onOpenNote(state, note, out) {
92
45
  : mode === 'load'
93
46
  ? { sessionId, cwd, mcpServers: servers, ...(meta ? { _meta: meta } : {}) }
94
47
  : { sessionId, cwd, mcpServers: servers };
95
- const pending = request(state, out, OPEN_METHODS[mode], params, 'open', { mode, ...(sessionId !== undefined ? { sessionId } : {}), ...(delegation ? { delegation } : {}) }, redact !== undefined && redact.length > 0 ? { redact } : {});
48
+ const pending = request(state, out, OPEN_METHODS[mode], params, 'open', { mode, ...(sessionId !== undefined ? { sessionId } : {}) }, redact !== undefined && redact.length > 0 ? { redact } : {});
96
49
  state.open = { status: 'pending', requestId: pending.id, mode };
97
50
  if (mode === 'load')
98
51
  state.history = { rootSessionId: sessionId, scopes: {}, messages: [], droppedCount: 0 };
@@ -105,11 +58,10 @@ export function settleOpen(state, entry, settlement, out) {
105
58
  const { mode } = ctx;
106
59
  if (settlement.outcome !== 'result') {
107
60
  const code = settlementErrorCode(settlement);
108
- const error = settlement.outcome === 'error' ? settlement.error.message : closeErrorText(state);
61
+ const error = settlement.outcome === 'error' ? jsonRpcErrorText(settlement.error) : closeErrorText(state);
109
62
  state.open = { status: 'failed', mode, error, ...(code !== undefined ? { code } : {}) };
110
63
  endHistory(state, out, false);
111
64
  // A failed open closes the attached session, and its repair with it (`AcpSession.close`).
112
- closeRepair(state);
113
65
  out.unjournaled({ t: 'processor.open_result', ok: false, mode, error, ...(code !== undefined ? { code } : {}) });
114
66
  return;
115
67
  }
@@ -117,10 +69,8 @@ export function settleOpen(state, entry, settlement, out) {
117
69
  const nativeSessionId = mode === 'new' ? (typeof result.sessionId === 'string' ? result.sessionId : '') : ctx.sessionId;
118
70
  if (nativeSessionId.length > 0) {
119
71
  bindRootSession(state, nativeSessionId);
120
- onRootBound(state, out, nativeSessionId);
121
72
  }
122
73
  state.configOptions = normalizeConfigOptions(result.configOptions, result.modes, result.models);
123
- state.delegation = ctx.delegation ?? null;
124
74
  state.open = { status: 'open', mode };
125
75
  out.unjournaled({
126
76
  t: 'processor.open_result', ok: true, mode,
@@ -280,7 +230,7 @@ export function steeredIds(state) {
280
230
  const inFlight = Object.entries(state.steers).filter(([, steer]) => steer.sent).map(([id]) => id);
281
231
  return [...state.steered, ...inFlight];
282
232
  }
283
- // ---- background tasks, delegation, launch -------------------------------------------------------
233
+ // ---- background tasks, launch -------------------------------------------------------
284
234
  /** `agent_async_task_stop{asyncTaskId}` — `asyncTaskStopRequest`; its answer is diagnostics only. */
285
235
  export function onAsyncTaskStopNote(state, note, out) {
286
236
  const { asyncTaskId } = note;
@@ -290,29 +240,6 @@ export function onAsyncTaskStopNote(state, note, out) {
290
240
  }
291
241
  request(state, out, ASYNC_TASK_STOP_METHOD, { sessionId: state.rootSessionId, asyncTaskId }, 'rpc', undefined);
292
242
  }
293
- /**
294
- * `agent_delegation_renewed{expiresAtEpochMs, renewalRevision}` — a renewal the daemon accepted
295
- * (`agent_delegation_renew`'s checks read the clock, so the decision is the daemon's; the note is
296
- * its record).
297
- */
298
- export function onDelegationRenewedNote(state, note) {
299
- const { expiresAtEpochMs, renewalRevision } = note;
300
- const delegation = state.delegation;
301
- if (!delegation || delegation.bindingId === undefined || !Number.isSafeInteger(expiresAtEpochMs) || !Number.isSafeInteger(renewalRevision)) {
302
- state.diagnostics.droppedNotes += 1;
303
- return;
304
- }
305
- delegation.expiresAtEpochMs = expiresAtEpochMs;
306
- delegation.renewalRevision = renewalRevision;
307
- }
308
- /** `agent_delegation_refresh_pending{}` — a refreshed lease waits for the session to go idle. */
309
- export function onDelegationRefreshPendingNote(state) {
310
- if (!state.delegation) {
311
- state.diagnostics.droppedNotes += 1;
312
- return;
313
- }
314
- state.delegation.refreshPending = true;
315
- }
316
243
  /** `agent_launch{launch}` (see `runtime.ts`). */
317
244
  export function onLaunch(state, note) {
318
245
  if (!onLaunchNote(state, note.launch))
@@ -132,6 +132,14 @@ export function settlementOf(response) {
132
132
  const { code, message, data } = response.error;
133
133
  return { outcome: 'error', error: { code, message, data } };
134
134
  }
135
+ /**
136
+ * The text an agent's error is shown as. The ACP SDK's `RequestError.internalError(details)` puts the
137
+ * real cause only in `data.details` behind a generic "Internal error", so a string detail is kept.
138
+ */
139
+ export function jsonRpcErrorText(error) {
140
+ const details = isRecord(error.data) && typeof error.data.details === 'string' ? error.data.details.trim().slice(0, 2000) : '';
141
+ return details && !error.message.includes(details) ? `${error.message}: ${details}` : error.message;
142
+ }
135
143
  /** `jsonRpcErrorCode(err)` for a settlement: the code an agent answered with, if a frame may carry it. */
136
144
  export function settlementErrorCode(settlement) {
137
145
  return settlement.outcome === 'error' ? jsonRpcErrorCodeOf(settlement.error.code) : undefined;
@@ -1,25 +1,7 @@
1
- /**
2
- * The two level signals (spec §5.4: "电平类帧从状态现算"): the agent's self-reported activity
3
- * (`agent_session_state`) and the runtime diagnostics (`agent_runtime_profile`). Neither is numbered
4
- * or journaled (analysis B §5); both are folded into state from the log, so after a restart they are
5
- * recomputed by replay and re-sent with `agent_opened` ({@link activityRaw}, {@link runtimeDiagnostics}).
6
- *
7
- * - **Activity** — `connectAgent`'s `_claude/sdkMessage` handler (`claudeActivityRaw`) and the mapper's
8
- * `codexActivityRaw` on the root session's `session_info_update`, as `AcpSession.reportActivity`
9
- * joins them. Both sinks are bound only once the session is open, so earlier pushes are dropped,
10
- * as today.
11
- * - **Diagnostics** — `generation` is the keeper's `spawnId` (analysis B B2: no `randomUUID`), and
12
- * `revision` is a fold: +1 on process exit and on every applied Qoder profile (the `connectAgent`
13
- * closure, `acpClient.ts`). `launch` arrives in an `agent_launch` note the daemon writes after the
14
- * spawn (analysis B D5: computed once, at spawn). Task 17c: the permission callback snapshot
15
- * (`callbacks`, {@link callbackSnapshot}) — published, and the revision bumped, on every change to the
16
- * session's pending/settled permission cards, as `AcpSession.publishCallbacks` does for every agent.
17
- */
1
+ const connectionGeneration = (spawnId) => `session:${spawnId}`;
18
2
  import { claudeActivityRaw } from '../activityReporting.js';
19
- import { parseQoderProfile, sameProfileIdentity } from '../../qoderAdapter/profile.js';
20
- import { connectionGenerationOf } from '../../qoderAdapter/callbackContext.js';
21
3
  import { isRecord } from './emit.js';
22
- import { getOwn, initialRuntime, PENDING_PROFILE_LIMIT, putOwn } from './state.js';
4
+ import { initialRuntime } from './state.js';
23
5
  function opened(state) {
24
6
  return state.open.status === 'open';
25
7
  }
@@ -60,7 +42,7 @@ export function callbackSnapshot(state) {
60
42
  if (rootSessionId === null || spawnId === undefined)
61
43
  return undefined;
62
44
  return {
63
- rootSessionId, connectionGeneration: connectionGenerationOf(spawnId), complete,
45
+ rootSessionId, connectionGeneration: connectionGeneration(spawnId), complete,
64
46
  pending: complete ? Object.values(state.permissions).map((card) => ({
65
47
  requestId: card.requestId, originNativeSessionId: card.origin, rpcRequestId: card.rpcRequestId,
66
48
  })) : [],
@@ -70,11 +52,11 @@ export function callbackSnapshot(state) {
70
52
  /** The diagnostics as `agent_runtime_profile`/`agent_opened.runtimeDiagnostics` carry them, or `undefined` before a spawn and its `agent_launch` note. */
71
53
  export function runtimeDiagnostics(state) {
72
54
  const spawnId = currentSpawnId(state);
73
- const { revision, available, launch, profile } = state.runtime;
55
+ const { revision, available, launch } = state.runtime;
74
56
  if (spawnId === undefined || launch === undefined)
75
57
  return undefined;
76
58
  const callbacks = callbackSnapshot(state);
77
- return { generation: spawnId, revision, available, launch, ...(profile !== undefined ? { profile } : {}),
59
+ return { generation: spawnId, revision, available, launch,
78
60
  ...(callbacks !== undefined ? { callbacks } : {}) };
79
61
  }
80
62
  /**
@@ -113,69 +95,11 @@ export function onLaunchNote(state, launch) {
113
95
  state.runtime.launch = { source: source, executable: executable.slice(0, 4096), platform, architecture, transport };
114
96
  return true;
115
97
  }
116
- /** The `initialize` result's `_meta.qoderProfile` (`connectAgent`, right after the handshake). */
117
- export function onInitialized(state, result) {
118
- const meta = isRecord(result) && isRecord(result._meta) ? result._meta : undefined;
119
- const profile = parseQoderProfile(meta?.qoderProfile);
120
- if (profile)
121
- state.runtime.profile = profile;
122
- else
123
- delete state.runtime.profile;
124
- }
125
98
  /** The child exited: unavailable, profile no longer observed (`child.once('exit')` in `connectAgent`). */
126
99
  export function onProcessExit(state, out) {
127
100
  const runtime = state.runtime;
128
101
  runtime.revision += 1;
129
102
  runtime.available = false;
130
- if (runtime.profile)
131
- runtime.profile = { ...runtime.profile, observerHealthy: false, rootConfirmed: false };
132
- changed(state, out);
133
- }
134
- function applyProfile(state, out, sessionId, revision, profile) {
135
- const runtime = state.runtime;
136
- const previous = runtime.profile;
137
- if (!previous || !runtime.available || sessionId !== state.rootSessionId || revision <= runtime.adapterRevision
138
- || !sameProfileIdentity(previous, profile) || profile.rootSessionId !== state.rootSessionId
139
- || (previous.runtimeGeneration !== undefined && profile.runtimeGeneration !== previous.runtimeGeneration)
140
- || (profile.rootConfirmed === true && !profile.runtimeGeneration))
141
- return;
142
- runtime.adapterRevision = revision;
143
- runtime.revision += 1;
144
- runtime.profile = profile;
145
103
  changed(state, out);
146
104
  }
147
- /** `_axom/qoder/profile{sessionId, revision, profile}` — the `connectAgent` handler, over state. */
148
- export function onProfileNotification(state, out, params) {
149
- if (!isRecord(params))
150
- return;
151
- const profile = parseQoderProfile(params.profile);
152
- const { sessionId, revision } = params;
153
- if (!state.runtime.profile || !profile || typeof sessionId !== 'string' || profile.rootSessionId !== sessionId
154
- || !Number.isSafeInteger(revision) || revision <= 0 || !sameProfileIdentity(state.runtime.profile, profile))
155
- return;
156
- if (state.rootSessionId !== null) {
157
- applyProfile(state, out, sessionId, revision, profile);
158
- return;
159
- }
160
- // ACP may notify before its new/load reply: bounded candidates, evidence only once the reply binds.
161
- const pending = state.runtime.pendingProfiles;
162
- const previous = getOwn(pending, sessionId);
163
- if (previous && (revision <= previous.revision || profile.runtimeGeneration !== previous.profile.runtimeGeneration))
164
- return;
165
- if (!previous && Object.keys(pending).length >= PENDING_PROFILE_LIMIT)
166
- return;
167
- putOwn(pending, sessionId, { revision: revision, profile });
168
- }
169
105
  /** The root just bound (`bindDraftUpdates`' diagnostics half): drop a profile for another root, apply a pending one. */
170
- export function onRootBound(state, out, sessionId) {
171
- const runtime = state.runtime;
172
- const current = runtime.profile;
173
- if (current?.rootSessionId && current.rootSessionId !== sessionId) {
174
- const { rootSessionId: _root, runtimeGeneration: _generation, ...rest } = current;
175
- runtime.profile = { ...rest, rootConfirmed: false, initialized: false, observerHealthy: false };
176
- }
177
- const pending = getOwn(runtime.pendingProfiles, sessionId);
178
- runtime.pendingProfiles = {};
179
- if (pending)
180
- applyProfile(state, out, sessionId, pending.revision, pending.profile);
181
- }
@@ -1,67 +1,16 @@
1
- /**
2
- * The session layer of the ACP processor (Task 17a): turns, interrupt, permission and elicitation
3
- * cards, and the permission-origin graph — `AcpSession` + `permission.ts` + the turn half of
4
- * `agentSessions.ts`, re-expressed as a synchronous fold over the raw log (spec 2026-10-11 §5.4).
5
- *
6
- * ## Turns
7
- *
8
- * - An `agent_prompt` note asks for a turn. Admission (`TaskRegistry.tryAdmitTurn`, a daemon-wide
9
- * decision) arrives **in** the note (`admitted: false`), so a refusal lands on the note's offset and
10
- * replays identically; so do the processor's own refusals (no connection, an overlapping exact
11
- * turn). Those are the three daemon-initiated `turn_done`s of `agentSessions.ts`'s `agent_prompt`
12
- * branch, with the same two frame shapes (see {@link refuseTurn} / {@link finishTurn}).
13
- * - An admitted prompt becomes one `session/prompt` command. The note carries no blocks — only a
14
- * `blocksRef` the executor resolves (`DownCommand.fill`), so the blocks appear once in the log, in
15
- * that `down` record (§5.4). `platformTurnId` rides in the command's annotation and is **read back
16
- * from the `down` record** when the processor folds it: that record is what started the turn on the
17
- * agent.
18
- * - A turn ends exactly on the record that settles its request — the agent's response line, a
19
- * `proc exit`, or an `agent_prompt_failed` note (the executor could not write the line). There is no
20
- * `settleUpdates` heuristic: log order is the truth (analysis B A4). One consequence, recorded
21
- * rather than hidden: an update the agent writes **after** its `session/prompt` response belongs to
22
- * whatever follows, not to the finished turn (analysis B §1.5).
23
- * - Turns are matched to their response by request id, not FIFO: two overlapping prompts the agent
24
- * answers out of order keep their own results (`AcpSession.inFlightTurns` documents the swap the
25
- * FIFO rule had).
26
- *
27
- * ## Cards
28
- *
29
- * `session/request_permission` and `'form'` `elicitation/create` follow `permission.ts` step for step
30
- * (the same builders and `validateWireEvent`), with ids derived from the log: a permission card is
31
- * `perm:<spawnId>:<JSON agent id>` ({@link permissionRequestId}, shared with the live path), an
32
- * elicitation card keeps the agent's id. A card the user has not answered stays in state with the
33
- * JSON-RPC id it came on, so after a restore it is still pending under the same id
34
- * ({@link pendingRequestIds}, spec §5.5.3/4) and the answer is written back on the original id.
35
- *
36
- * ## Task 17b
37
- *
38
- * `session/update` mapping and `agent_message` synthesis live in `updates.ts` (a turn's end flushes
39
- * the streaming message before its own frame, and a turn's start closes a message that began
40
- * outside any turn); the open session, config, steering and delegation in `control.ts`.
41
- *
42
- * ## Task 17c: callbacks and the adapter boundaries
43
- *
44
- * Every change to the pending/settled permission cards publishes the callback snapshot
45
- * (`runtime.ts` `publishCallbacks`), at the points `AcpSession` does: a registration (accepted, or
46
- * refused for its fields/capacity/a reused id — which also makes the snapshot incomplete), a
47
- * settlement (`answered` by a note, `canceled` by the agent or for want of a callback context), a
48
- * drain (interrupt, an interrupted turn, the connection closing — incomplete from then on). A Qoder
49
- * SDK adapter's root card carries its `callbackContext` (`qoderAdapter/callbackContext.ts`, the
50
- * function `AcpSession.emitEvent` uses), computed from that snapshot and the runtime profile — log
51
- * data only; without one the card is settled `canceled` and answered `cancelled`, as today. Cards are
52
- * emitted through the same boundaries as any other event (`updates.ts` `emitSessionEvent`).
53
- */
1
+ /** Session turns, permission and elicitation cards, and callback snapshots over checkpointed state. Root and child permission origins are verified before a card is emitted; callback generations derive from the process spawn ID. */
54
2
  import { buildElicitationRequestedEvent, buildPermissionRequestedEvent, elicitationFieldKeys, isBlank, permissionRequestId, } from '../permission.js';
55
3
  import { validateWireEvent } from '../validate.js';
56
- import { isSdkCallbackCard, permissionCallbackContext } from '../../qoderAdapter/callbackContext.js';
57
4
  import { isRecord, nextSeq } from './emit.js';
58
- import { inboundKey, settlementErrorCode } from './jsonrpc.js';
5
+ import { inboundKey, jsonRpcErrorText, settlementErrorCode } from './jsonrpc.js';
59
6
  import { sameCause } from './record.js';
60
- import { callbackSnapshot, publishCallbacks, resetRuntime } from './runtime.js';
61
- import { getOwn, initialBoundaries, initialCallbacks, initialMessage, PENDING_PERMISSION_LIMIT, SETTLED_PERMISSION_LIMIT, } from './state.js';
62
- import { emitSessionEvent, endForegroundTurn, endHistory, flushMessage, flushOutOfTurnMessage } from './updates.js';
7
+ import { publishCallbacks, resetRuntime } from './runtime.js';
8
+ import { getOwn, initialCallbacks, initialMessage, PENDING_PERMISSION_LIMIT, SETTLED_PERMISSION_LIMIT, } from './state.js';
9
+ import { emitSessionEvent, endHistory, flushMessage, flushOutOfTurnMessage } from './updates.js';
63
10
  /** `agentSessions.ts`'s admission refusal text, verbatim. */
64
11
  export const ADMISSION_REFUSED = 'Workstation is not accepting new work';
12
+ /** The agent answered `session/prompt` with `stopReason: 'refusal'` and no words of its own. */
13
+ export const PROMPT_REFUSED = 'The agent refused this prompt.';
65
14
  /** `AcpSession.prompt`'s overlap refusal text, verbatim. */
66
15
  export const OVERLAPPING_TURN = 'An exact platform turn is still running; overlapping prompts are unavailable';
67
16
  /** What the SDK rejects pending requests with when the adapter's stdout ends (`jsonrpc.js` `close()`). */
@@ -95,13 +44,14 @@ export function resetForSpawn(state) {
95
44
  state.rootSessionId = null;
96
45
  state.open = { status: 'idle' };
97
46
  state.configOptions = null;
98
- state.delegation = null;
99
47
  state.history = null;
100
48
  state.mapperScopes = {};
101
49
  state.message = initialMessage();
102
50
  state.steers = {};
103
51
  state.steered = [];
104
52
  state.asyncTasks = {};
53
+ state.draftSubagents = { children: {}, overflow: false };
54
+ state.closedReplayScopes = {};
105
55
  resetRuntime(state);
106
56
  state.turns = [];
107
57
  state.exactExecutionUnconfirmed = false;
@@ -111,7 +61,6 @@ export function resetForSpawn(state) {
111
61
  state.elicitations = {};
112
62
  state.settledPermissions = [];
113
63
  state.callbacks = initialCallbacks();
114
- state.boundaries = initialBoundaries();
115
64
  state.permissionOrigins = {};
116
65
  state.permissionParents = {};
117
66
  state.unresolvedPermissionOrigins = {};
@@ -147,7 +96,8 @@ const STOP_REASONS = {
147
96
  end_turn: 'end_turn',
148
97
  max_tokens: 'max_tokens',
149
98
  max_turn_requests: 'max_turns',
150
- refusal: 'refusal',
99
+ // No `refusal`: a refusal result settles 'failed' (see `settlePrompt`), and a completed turn
100
+ // never carries it.
151
101
  };
152
102
  /**
153
103
  * End turn `index` — `AcpSession.finishTurn` + `agentSessions.ts`'s `onAgentTurnDone` frame, in one.
@@ -158,8 +108,6 @@ function finishTurn(state, out, index, status, finish) {
158
108
  const [turn] = state.turns.splice(index, 1);
159
109
  if (!turn)
160
110
  return;
161
- if (state.turns.length === 0)
162
- endForegroundTurn(state);
163
111
  // Before the turn's own frame, on every path that ends a turn (`flushMessageCompleted`).
164
112
  flushMessage(state, out);
165
113
  const resolved = turn.interrupted ? 'interrupted' : status;
@@ -243,6 +191,28 @@ export function onDown(state, record) {
243
191
  else
244
192
  delete turn.platformTurnId;
245
193
  }
194
+ /**
195
+ * The measured `_meta` key a refusal *result* carries its would-be error response under: a JSON
196
+ * string of the JSON-RPC error the agent chose not to send (`codebuddy-code` 2.171.0; shape-read,
197
+ * same rule as `acpClient`'s `_codebuddy.ai/authUrl`).
198
+ */
199
+ const REFUSAL_ERROR_META_KEY = 'codebuddy.ai/errorMessage';
200
+ function refusalErrorDetail(result) {
201
+ if (!isRecord(result) || !isRecord(result._meta))
202
+ return undefined;
203
+ const raw = result._meta[REFUSAL_ERROR_META_KEY];
204
+ if (typeof raw !== 'string')
205
+ return undefined;
206
+ try {
207
+ const parsed = JSON.parse(raw);
208
+ if (!isRecord(parsed) || typeof parsed.message !== 'string')
209
+ return undefined;
210
+ return { ...(typeof parsed.code === 'number' ? { code: parsed.code } : {}), message: parsed.message };
211
+ }
212
+ catch {
213
+ return undefined;
214
+ }
215
+ }
246
216
  /** A `session/prompt` request settled: its turn ends on this record. */
247
217
  export function settlePrompt(state, entry, settlement, out) {
248
218
  const index = state.turns.findIndex((turn) => turn.requestId === entry.id);
@@ -252,14 +222,32 @@ export function settlePrompt(state, entry, settlement, out) {
252
222
  case 'result': {
253
223
  const stopReason = isRecord(settlement.result) ? settlement.result.stopReason : undefined;
254
224
  // ACP's own `cancelled` forces `interrupted` even when no interrupt was sent (a backstop).
255
- finishTurn(state, out, index, stopReason === 'cancelled' ? 'interrupted' : 'completed', { stopReason, executionEnded: true });
225
+ if (stopReason === 'cancelled') {
226
+ finishTurn(state, out, index, 'interrupted', { stopReason, executionEnded: true });
227
+ return;
228
+ }
229
+ // Measured (codebuddy-code 2.171.0): an agent that needs credentials answers `session/prompt`
230
+ // with a *result* `stopReason: 'refusal'` — zero content, no JSON-RPC error — which used to
231
+ // settle 'completed' and render as nothing at all. A refusal result settles exactly like the
232
+ // agent's own refusal below ('failed' + `agentRefused`), with the agent's detail read out of
233
+ // the measured `_meta` key; a code-less detail stays an ordinary failure card server-side,
234
+ // while `-32000` beside the observed auth methods is what turns it into the sign-in card.
235
+ if (stopReason === 'refusal') {
236
+ const detail = refusalErrorDetail(settlement.result);
237
+ finishTurn(state, out, index, 'failed', {
238
+ agentRefused: true, executionEnded: true,
239
+ error: detail?.message ?? PROMPT_REFUSED, ...(detail?.code !== undefined ? { errorCode: detail.code } : {}),
240
+ });
241
+ return;
242
+ }
243
+ finishTurn(state, out, index, 'completed', { stopReason, executionEnded: true });
256
244
  return;
257
245
  }
258
246
  case 'error': {
259
247
  // The one exit where the agent itself answered (`TurnResult.agentRefused`).
260
248
  const errorCode = settlementErrorCode(settlement);
261
249
  finishTurn(state, out, index, 'failed', {
262
- error: settlement.error.message, agentRefused: true, errorCode, executionEnded: errorCode !== undefined,
250
+ error: jsonRpcErrorText(settlement.error), agentRefused: true, errorCode, executionEnded: errorCode !== undefined,
263
251
  });
264
252
  return;
265
253
  }
@@ -405,23 +393,7 @@ export function onPermissionRequest(state, id, params, out) {
405
393
  const rpcKey = inboundKey(id);
406
394
  state.permissions[requestId] = { requestId, rpcKey, origin, rpcRequestId, optionIds: options.map((option) => option.optionId) };
407
395
  publishCallbacks(state, out);
408
- let payload = event.payload;
409
- const toolCall = payload.toolCall;
410
- if (isSdkCallbackCard(toolCall)) {
411
- // `AcpSession.emitEvent`: an SDK callback card is shown only with the evidence the server needs
412
- // to route its answer back (`callbackContext`); without it, it is cancelled.
413
- const spawnId = state.process.spawn.spawnId;
414
- const callbackContext = root === null ? undefined : permissionCallbackContext({
415
- rootSessionId: root, origin, requestId, toolCall, pendingRpcRequestId: rpcRequestId,
416
- diagnostics: { generation: spawnId, available: state.runtime.available, profile: state.runtime.profile, callbacks: callbackSnapshot(state) },
417
- });
418
- if (!callbackContext) {
419
- settlePermission(state, out, requestId, PERMISSION_CANCELLED, 'canceled');
420
- state.diagnostics.refusedRequests += 1;
421
- return undefined;
422
- }
423
- payload = { ...payload, callbackContext };
424
- }
396
+ const payload = event.payload;
425
397
  emitSessionEvent(state, out, { eventName: event.eventName, payload, acpSessionId: origin });
426
398
  return requestId;
427
399
  }
@@ -1,22 +1,16 @@
1
- /**
2
- * 2: Task 17b's open-session layer. 3: Task 17c (`boundaries`, `callbacks`, settled permissions with
3
- * their reason, `rpcRequestId` on a pending permission). 4: the repair's `polledProcesses`. An older
4
- * checkpoint is refused, never half-read.
5
- */
6
- export const PROCESSOR_STATE_SCHEMA = 4;
1
+ /** State history: 2 — open-session layer; 3 — callback snapshots and adapter fold data;
2
+ * 4 — polled process state; 5 — adapter fold data and retired optional state removed.
3
+ * Schemas before 4 remain unreadable; schema 4 is upgraded by checkpoint.ts. */
4
+ export const PROCESSOR_STATE_SCHEMA = 5;
7
5
  export const SETTLED_HISTORY_LIMIT = 16;
8
6
  export const SETTLED_PERMISSION_LIMIT = 64;
9
7
  export const PENDING_PERMISSION_LIMIT = 64;
10
8
  export const UNRESOLVED_ORIGIN_LIMIT = 1024;
11
- export const PENDING_PROFILE_LIMIT = 8;
12
9
  export const STEERED_HISTORY_LIMIT = 64;
13
10
  /** Unfinished async tasks tracked per connection, all sessions together. */
14
11
  export const ASYNC_TASK_LIMIT = 1024;
15
12
  export function initialRuntime() {
16
- return { revision: 0, available: true, adapterRevision: 0, pendingProfiles: {} };
17
- }
18
- export function initialBoundaries() {
19
- return { foreground: { pending: {} }, subwork: { calls: {}, count: 0 }, repair: null, sideChunk: null };
13
+ return { revision: 0, available: true };
20
14
  }
21
15
  export function initialCallbacks() {
22
16
  return { complete: true, rootSessionId: null };
@@ -48,16 +42,16 @@ export function initialState() {
48
42
  unresolvedPermissionOrigins: {},
49
43
  open: { status: 'idle' },
50
44
  configOptions: null,
51
- delegation: null,
52
45
  history: null,
46
+ closedReplayScopes: {},
53
47
  mapperScopes: {},
54
48
  message: initialMessage(),
55
49
  steers: {},
56
50
  steered: [],
51
+ draftSubagents: { children: {}, overflow: false },
57
52
  asyncTasks: {},
58
53
  activity: null,
59
54
  runtime: initialRuntime(),
60
- boundaries: initialBoundaries(),
61
55
  diagnostics: {
62
56
  orphanResponses: 0, protocolErrors: 0, ignoredLines: 0, unknownNotes: 0, droppedNotes: 0, refusedRequests: 0,
63
57
  rejectedRelations: 0, droppedUpdates: 0, invalidEvents: 0, untrackedAsyncTasks: 0, settled: [],
@@ -1,15 +1,14 @@
1
+ /** The ACP processor folds records synchronously in log order. No clock, randomness, environment, file I/O or timers: identical records and state produce byte-identical outputs. Commands execute before frames are recorded; IDs derive from log offsets. A failed fold poisons the state; unknown notes are counted for forward compatibility. */
1
2
  import { accountLimitsSchema, ACCOUNT_LIMITS_READ, ACCOUNT_LIMITS_UPDATED } from '../../protocol/accountLimits.js';
2
3
  import { initializeRequestParams, parseInitializeResult } from '../initializeResponse.js';
3
4
  import { STEER_METHOD } from '../steering.js';
4
5
  import { checkpointOf } from './checkpoint.js';
5
- import { failUnsentSteer, onAsyncTaskStopNote, onDelegationRefreshPendingNote, onDelegationRenewedNote, onHistoryEndNote, onInstallOutcomeNote, onOutputGapNote, onLaunch, onOpenNote, onSetConfigOptionNote, onSteerDown, onSteerNote, settleConfig, settleOpen, settleSteer, } from './control.js';
6
+ import { failUnsentSteer, onAsyncTaskStopNote, onHistoryEndNote, onInstallOutcomeNote, onOutputGapNote, onLaunch, onOpenNote, onSetConfigOptionNote, onSteerDown, onSteerNote, settleConfig, settleOpen, settleSteer, } from './control.js';
6
7
  import { CANCEL_REQUEST_METHOD, classifyLine, inboundKey, invalidParams, invalidRequest, isJsonRpcId, methodNotFound, outboundKey, parseError, settlementErrorCode, settlementOf, } from './jsonrpc.js';
7
8
  import { RecordOutput } from './output.js';
8
9
  import { INBOUND_REQUEST_SCHEMAS } from './sdkSchemas.js';
9
10
  import { BATCH_CLOSE_REASON, connected, dropCards, finishAllTurns, forgetCard, onAnswerNote, onDown, onElicitationAnswerNote, onElicitationRequest, onInboundCancelled, onInterruptNote, onPermissionRequest, onPromptFailedNote, onPromptNote, onUndeliverableNote, resetForSpawn, settlePrompt, } from './session.js';
10
- import { onClaudeSdkMessage, onInitialized, onProcessExit, onProfileNotification } from './runtime.js';
11
- import { closeRepair, onRepairNote, onSideNote } from './sideChannel.js';
12
- import { REPAIR_NOTE, SIDE_NOTE } from '../../qoderAdapter/backgroundTerminalFold.js';
11
+ import { onClaudeSdkMessage, onProcessExit } from './runtime.js';
13
12
  import { endHistory, onSessionUpdate } from './updates.js';
14
13
  import { initialState, SETTLED_HISTORY_LIMIT, } from './state.js';
15
14
  /** Serialized size above which a note is dropped (`droppedNotes`). */
@@ -73,7 +72,6 @@ function closeConnection(state, reason, out) {
73
72
  state.outbound = {};
74
73
  state.inbound = {};
75
74
  dropCards(state, out);
76
- closeRepair(state);
77
75
  state.closed = reason;
78
76
  for (const entry of pending)
79
77
  settle(state, entry, { outcome: 'closed', reason }, out);
@@ -151,8 +149,6 @@ function onUp(state, line, o, t, out) {
151
149
  onSessionUpdate(state, message.params, out, t);
152
150
  else if (message.method === '_claude/sdkMessage')
153
151
  onClaudeSdkMessage(state, out, message.params, t);
154
- else if (message.method === '_axom/qoder/profile')
155
- onProfileNotification(state, out, message.params);
156
152
  return;
157
153
  case 'request':
158
154
  onInboundRequest(state, message.id, message.method, message.params, o, out);
@@ -265,7 +261,6 @@ function settleInitialize(state, entry, settlement, out) {
265
261
  }
266
262
  const { protocolSupported: _supported, ...facts } = reading;
267
263
  state.initialize = { status: 'ready', facts: JSON.parse(JSON.stringify(facts)) };
268
- onInitialized(state, settlement.result);
269
264
  const capability = settlement.result.agentCapabilities?._meta?.['axom/accountRateLimits'];
270
265
  if (capability && typeof capability === 'object' && capability.read === true) {
271
266
  const quotaCapability = capability;
@@ -339,12 +334,6 @@ function onNote(state, note, out) {
339
334
  case 'agent_async_task_stop':
340
335
  onAsyncTaskStopNote(state, note, out);
341
336
  return;
342
- case 'agent_delegation_renewed':
343
- onDelegationRenewedNote(state, note);
344
- return;
345
- case 'agent_delegation_refresh_pending':
346
- onDelegationRefreshPendingNote(state);
347
- return;
348
337
  case 'agent_launch':
349
338
  onLaunch(state, note);
350
339
  return;
@@ -354,12 +343,6 @@ function onNote(state, note, out) {
354
343
  case 'agent_output_gap':
355
344
  onOutputGapNote(state, note, out);
356
345
  return;
357
- case REPAIR_NOTE:
358
- onRepairNote(state, note);
359
- return;
360
- case SIDE_NOTE:
361
- onSideNote(state, note, out);
362
- return;
363
346
  case 'agent_account_read': {
364
347
  if (!connected(state)) {
365
348
  out.unjournaled({ t: 'agent_account_read_result', id: note.id, ok: false, error: 'Agent is offline' });