@gajae-code/coding-agent 0.13.2 → 0.14.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 (610) hide show
  1. package/CHANGELOG.md +215 -8
  2. package/README.md +2 -0
  3. package/bin/gajaessi.js +4 -0
  4. package/dist/types/async/job-manager.d.ts +55 -2
  5. package/dist/types/async/support.d.ts +14 -0
  6. package/dist/types/capability/mcp.d.ts +6 -0
  7. package/dist/types/capability/types.d.ts +6 -0
  8. package/dist/types/cli/accounts-cli.d.ts +19 -0
  9. package/dist/types/cli/args.d.ts +3 -0
  10. package/dist/types/cli/config-cli.d.ts +6 -0
  11. package/dist/types/cli/crash-cli.d.ts +10 -0
  12. package/dist/types/cli/customize-doctor.d.ts +145 -0
  13. package/dist/types/cli/daemon-cli.d.ts +3 -1
  14. package/dist/types/cli/mcp-cli.d.ts +11 -0
  15. package/dist/types/cli/notify-cli.d.ts +1 -1
  16. package/dist/types/cli/root-flags.d.ts +12 -0
  17. package/dist/types/cli/setup-cli.d.ts +3 -1
  18. package/dist/types/cli/skills-cli.d.ts +2 -1
  19. package/dist/types/cli/update-cli.d.ts +19 -1
  20. package/dist/types/cli.d.ts +6 -0
  21. package/dist/types/commands/accounts.d.ts +40 -0
  22. package/dist/types/commands/crash.d.ts +24 -0
  23. package/dist/types/commands/customize.d.ts +22 -0
  24. package/dist/types/commands/daemon.d.ts +1 -1
  25. package/dist/types/commands/launch.d.ts +6 -0
  26. package/dist/types/commands/setup.d.ts +6 -0
  27. package/dist/types/commands/skills.d.ts +6 -1
  28. package/dist/types/commands/update.d.ts +7 -0
  29. package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
  30. package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
  31. package/dist/types/config/config-schema-version.d.ts +10 -0
  32. package/dist/types/config/file-lock.d.ts +18 -0
  33. package/dist/types/config/model-profile-activation.d.ts +3 -1
  34. package/dist/types/config/model-registry.d.ts +10 -1
  35. package/dist/types/config/models-config-schema.d.ts +2 -0
  36. package/dist/types/config/settings-schema.d.ts +73 -9
  37. package/dist/types/config/settings.d.ts +63 -0
  38. package/dist/types/config/skill-settings-defaults.d.ts +26 -0
  39. package/dist/types/config/task-delegation.d.ts +39 -0
  40. package/dist/types/config/update-channel.d.ts +10 -0
  41. package/dist/types/coordinator-mcp/server.d.ts +5 -1
  42. package/dist/types/crash/index-store.d.ts +87 -0
  43. package/dist/types/crash/nudge.d.ts +50 -0
  44. package/dist/types/crash/record-loader.d.ts +17 -0
  45. package/dist/types/crash/report.d.ts +134 -0
  46. package/dist/types/crash/sanitize.d.ts +25 -0
  47. package/dist/types/cursor.d.ts +13 -2
  48. package/dist/types/customization/import.d.ts +37 -0
  49. package/dist/types/customization/index.d.ts +4 -0
  50. package/dist/types/customization/inventory.d.ts +25 -0
  51. package/dist/types/customization/mutations.d.ts +32 -0
  52. package/dist/types/customization/types.d.ts +115 -0
  53. package/dist/types/daemon/control-types.d.ts +8 -1
  54. package/dist/types/daemon/operator-contract.d.ts +4 -4
  55. package/dist/types/discovery/claude.d.ts +39 -1
  56. package/dist/types/discovery/codex.d.ts +39 -1
  57. package/dist/types/discovery/index.d.ts +2 -0
  58. package/dist/types/discovery/mcp-compat.d.ts +30 -0
  59. package/dist/types/edit/renderer.d.ts +23 -0
  60. package/dist/types/extensibility/extensions/runner.d.ts +3 -0
  61. package/dist/types/extensibility/extensions/types.d.ts +21 -4
  62. package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
  63. package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
  64. package/dist/types/extensibility/hooks/loader.d.ts +19 -5
  65. package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
  66. package/dist/types/extensibility/skill-management.d.ts +107 -0
  67. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
  68. package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
  69. package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
  70. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
  71. package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
  72. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
  73. package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
  74. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
  75. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
  76. package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
  77. package/dist/types/hooks/events.d.ts +60 -0
  78. package/dist/types/hooks/normalize.d.ts +83 -0
  79. package/dist/types/hooks/skill-state.d.ts +9 -2
  80. package/dist/types/main.d.ts +2 -1
  81. package/dist/types/modes/acp/abort-scope.d.ts +13 -0
  82. package/dist/types/modes/acp/acp-agent.d.ts +7 -4
  83. package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
  84. package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
  85. package/dist/types/modes/components/customization/index.d.ts +1 -0
  86. package/dist/types/modes/components/dynamic-theme-text.d.ts +9 -0
  87. package/dist/types/modes/components/gajae-pet-widget.d.ts +6 -28
  88. package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
  89. package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
  90. package/dist/types/modes/components/oauth-selector.d.ts +10 -4
  91. package/dist/types/modes/components/pet-capability.d.ts +7 -21
  92. package/dist/types/modes/components/settings-selector.d.ts +5 -0
  93. package/dist/types/modes/components/status-line/gh.d.ts +6 -2
  94. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
  95. package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
  96. package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
  97. package/dist/types/modes/interactive-mode.d.ts +1 -0
  98. package/dist/types/modes/theme/defaults/index.d.ts +118 -0
  99. package/dist/types/modes/types.d.ts +1 -0
  100. package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
  101. package/dist/types/runtime-mcp/config.d.ts +9 -0
  102. package/dist/types/runtime-mcp/manager.d.ts +26 -1
  103. package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
  104. package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
  105. package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
  106. package/dist/types/runtime-mcp/protocol.d.ts +278 -0
  107. package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
  108. package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
  109. package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
  110. package/dist/types/runtime-mcp/types.d.ts +102 -10
  111. package/dist/types/sdk/acp/adapter.d.ts +26 -5
  112. package/dist/types/sdk/broker/broker.d.ts +3 -55
  113. package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
  114. package/dist/types/sdk/broker/session-index.d.ts +14 -5
  115. package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
  116. package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
  117. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
  118. package/dist/types/sdk/bus/config.d.ts +11 -0
  119. package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
  120. package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
  121. package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
  122. package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
  123. package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
  124. package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
  125. package/dist/types/sdk/bus/index.d.ts +85 -99
  126. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
  127. package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
  128. package/dist/types/sdk/bus/notification-service.d.ts +52 -0
  129. package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
  130. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
  131. package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
  132. package/dist/types/sdk/bus/session-control.d.ts +25 -1
  133. package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
  134. package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
  135. package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
  136. package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
  137. package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
  138. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
  139. package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
  140. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
  141. package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
  142. package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
  143. package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
  144. package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
  145. package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
  146. package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
  147. package/dist/types/sdk/cli/rows.d.ts +2 -11
  148. package/dist/types/sdk/cli/session-cli.d.ts +15 -25
  149. package/dist/types/sdk/client/client.d.ts +97 -1
  150. package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
  151. package/dist/types/sdk/host/control/index.d.ts +1 -1
  152. package/dist/types/sdk/host/control/operations.d.ts +18 -5
  153. package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
  154. package/dist/types/sdk/host/host.d.ts +15 -1
  155. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  156. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  157. package/dist/types/sdk/host/session-runtime.d.ts +127 -7
  158. package/dist/types/sdk/host/types.d.ts +1 -1
  159. package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
  160. package/dist/types/sdk/index.d.ts +2 -1
  161. package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
  162. package/dist/types/sdk/lifecycle/client.d.ts +59 -0
  163. package/dist/types/sdk/lifecycle/index.d.ts +3 -0
  164. package/dist/types/sdk/lifecycle/service.d.ts +232 -0
  165. package/dist/types/sdk/mcp/server.d.ts +9 -6
  166. package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
  167. package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
  168. package/dist/types/sdk/prompt-status.d.ts +10 -3
  169. package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
  170. package/dist/types/sdk/receipt-state.d.ts +17 -0
  171. package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
  172. package/dist/types/sdk/router/index.d.ts +1 -0
  173. package/dist/types/sdk/router/session-router.d.ts +152 -0
  174. package/dist/types/sdk/session-list.d.ts +22 -0
  175. package/dist/types/sdk/session-reconnect.d.ts +43 -1
  176. package/dist/types/sdk/session.d.ts +34 -1
  177. package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
  178. package/dist/types/session/account-inventory.d.ts +86 -0
  179. package/dist/types/session/agent-session.d.ts +145 -6
  180. package/dist/types/session/agent-storage.d.ts +10 -0
  181. package/dist/types/session/coordinator-tool-label.d.ts +28 -0
  182. package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
  183. package/dist/types/session/messages.d.ts +1 -1
  184. package/dist/types/session/secure-token-file.d.ts +3 -0
  185. package/dist/types/session/session-manager.d.ts +47 -1
  186. package/dist/types/session/startup-auth-config.d.ts +44 -0
  187. package/dist/types/session/terminal-abort.d.ts +378 -0
  188. package/dist/types/session/yield-queue.d.ts +7 -0
  189. package/dist/types/session-import/claude.d.ts +26 -0
  190. package/dist/types/session-import/codex.d.ts +88 -0
  191. package/dist/types/session-import/command.d.ts +35 -0
  192. package/dist/types/session-import/detect.d.ts +22 -0
  193. package/dist/types/session-import/index.d.ts +7 -0
  194. package/dist/types/session-import/provider-codex.d.ts +22 -0
  195. package/dist/types/session-import/provider-service.d.ts +38 -0
  196. package/dist/types/session-import/redact.d.ts +23 -0
  197. package/dist/types/session-import/service.d.ts +47 -0
  198. package/dist/types/session-import/types.d.ts +120 -0
  199. package/dist/types/setup/paseo/check.d.ts +16 -0
  200. package/dist/types/setup/paseo/install-saga.d.ts +115 -0
  201. package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
  202. package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
  203. package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
  204. package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
  205. package/dist/types/setup/paseo/provider-config.d.ts +35 -0
  206. package/dist/types/setup/paseo/remove.d.ts +14 -0
  207. package/dist/types/setup/paseo/result-types.d.ts +59 -0
  208. package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
  209. package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
  210. package/dist/types/skill-state/active-state.d.ts +5 -1
  211. package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
  212. package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
  213. package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
  214. package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
  215. package/dist/types/slash-commands/types.d.ts +7 -1
  216. package/dist/types/task/executor.d.ts +10 -0
  217. package/dist/types/task/index.d.ts +3 -1
  218. package/dist/types/tools/ask-answer-registry.d.ts +6 -3
  219. package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
  220. package/dist/types/tools/bash.d.ts +2 -6
  221. package/dist/types/tools/browser/attach.d.ts +11 -0
  222. package/dist/types/tools/browser/launch.d.ts +20 -0
  223. package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
  224. package/dist/types/tools/browser/render.d.ts +1 -0
  225. package/dist/types/tools/browser.d.ts +3 -1
  226. package/dist/types/tools/image-gen.d.ts +10 -2
  227. package/dist/types/tools/index.d.ts +8 -0
  228. package/dist/types/tools/monitor.d.ts +1 -1
  229. package/dist/types/tools/skill-discovery.d.ts +8 -1
  230. package/dist/types/tools/subagent.d.ts +2 -0
  231. package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
  232. package/dist/types/utils/herdr-pane.d.ts +76 -0
  233. package/package.json +19 -9
  234. package/scripts/build-binary.ts +2 -1
  235. package/scripts/build-sdk-package-smoke.ts +2 -13
  236. package/scripts/capture-sticky-viewport-showcase.ts +0 -1
  237. package/scripts/compile-args.ts +2 -0
  238. package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
  239. package/scripts/generate-sdk-operation-inventory.ts +28 -0
  240. package/scripts/generate-telegram-baseline-manifest.ts +1 -0
  241. package/scripts/generate-tool-catalog.ts +6 -4
  242. package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
  243. package/src/async/job-manager.ts +352 -17
  244. package/src/async/support.ts +25 -0
  245. package/src/autoresearch/dashboard.ts +28 -13
  246. package/src/capability/index.ts +3 -1
  247. package/src/capability/mcp.ts +6 -0
  248. package/src/capability/types.ts +6 -0
  249. package/src/cli/accounts-cli.ts +395 -0
  250. package/src/cli/args.ts +23 -0
  251. package/src/cli/auth-broker-cli.ts +136 -66
  252. package/src/cli/auth-gateway-cli.ts +94 -70
  253. package/src/cli/config-cli.ts +27 -2
  254. package/src/cli/crash-cli.ts +78 -0
  255. package/src/cli/customize-doctor.ts +1605 -0
  256. package/src/cli/daemon-cli.ts +12 -3
  257. package/src/cli/fast-help.ts +1 -0
  258. package/src/cli/mcp-cli.ts +128 -60
  259. package/src/cli/notify-cli.ts +8 -14
  260. package/src/cli/root-flags.ts +8 -0
  261. package/src/cli/setup-cli.ts +145 -0
  262. package/src/cli/skills-cli.ts +38 -2
  263. package/src/cli/update-cli.ts +167 -12
  264. package/src/cli.ts +4 -0
  265. package/src/commands/accounts.ts +71 -0
  266. package/src/commands/crash.ts +35 -0
  267. package/src/commands/customize.ts +84 -0
  268. package/src/commands/daemon.ts +2 -2
  269. package/src/commands/deep-interview.ts +2 -0
  270. package/src/commands/launch.ts +1 -0
  271. package/src/commands/mcp.ts +12 -7
  272. package/src/commands/ralplan.ts +2 -0
  273. package/src/commands/sdk.ts +65 -32
  274. package/src/commands/setup.ts +5 -0
  275. package/src/commands/skills.ts +14 -4
  276. package/src/commands/ultragoal.ts +10 -1
  277. package/src/commands/update.ts +26 -15
  278. package/src/config/atomic-yaml-patch-worker.ts +57 -0
  279. package/src/config/atomic-yaml-patch.ts +769 -29
  280. package/src/config/config-schema-version.ts +10 -0
  281. package/src/config/file-lock.ts +70 -1
  282. package/src/config/mcp-schema.json +52 -14
  283. package/src/config/model-profile-activation.ts +23 -2
  284. package/src/config/model-profiles.ts +88 -21
  285. package/src/config/model-registry.ts +147 -21
  286. package/src/config/models-config-schema.ts +1 -1
  287. package/src/config/settings-schema.ts +77 -7
  288. package/src/config/settings.ts +4038 -199
  289. package/src/config/skill-settings-defaults.ts +41 -3
  290. package/src/config/task-delegation.ts +87 -0
  291. package/src/config/update-channel.ts +23 -0
  292. package/src/coordinator-mcp/server.ts +377 -308
  293. package/src/crash/index-store.ts +723 -0
  294. package/src/crash/nudge.ts +89 -0
  295. package/src/crash/record-loader.ts +149 -0
  296. package/src/crash/report.ts +551 -0
  297. package/src/crash/sanitize.ts +129 -0
  298. package/src/cursor.ts +36 -10
  299. package/src/customization/import.ts +946 -0
  300. package/src/customization/index.ts +4 -0
  301. package/src/customization/inventory.ts +335 -0
  302. package/src/customization/mutations.ts +141 -0
  303. package/src/customization/types.ts +223 -0
  304. package/src/daemon/control-types.ts +8 -1
  305. package/src/daemon/operator-contract.ts +6 -6
  306. package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +31 -6
  307. package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
  308. package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
  309. package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
  310. package/src/discovery/claude-hooks.ts +38 -0
  311. package/src/discovery/claude.ts +142 -209
  312. package/src/discovery/codex-hooks.ts +38 -0
  313. package/src/discovery/codex.ts +132 -198
  314. package/src/discovery/helpers.ts +8 -1
  315. package/src/discovery/index.ts +2 -0
  316. package/src/discovery/mcp-compat.ts +234 -0
  317. package/src/discovery/mcp-json.ts +6 -0
  318. package/src/edit/renderer.ts +40 -0
  319. package/src/edit/streaming.ts +4 -2
  320. package/src/exec/bash-executor.ts +24 -20
  321. package/src/export/html/index.ts +51 -2
  322. package/src/extensibility/extensions/loader.ts +9 -1
  323. package/src/extensibility/extensions/runner.ts +17 -4
  324. package/src/extensibility/extensions/types.ts +31 -6
  325. package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
  326. package/src/extensibility/gjc-plugins/installer.ts +9 -5
  327. package/src/extensibility/gjc-plugins/observability.ts +8 -2
  328. package/src/extensibility/gjc-plugins/registry.ts +13 -2
  329. package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
  330. package/src/extensibility/gjc-plugins/schema.ts +222 -39
  331. package/src/extensibility/hooks/loader.ts +154 -10
  332. package/src/extensibility/runtime-skill-discovery.ts +257 -60
  333. package/src/extensibility/skill-management.ts +368 -0
  334. package/src/extensibility/skills.ts +52 -16
  335. package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
  336. package/src/gjc-runtime/launch-worktree.ts +56 -2
  337. package/src/gjc-runtime/linux-proc.ts +7 -1
  338. package/src/gjc-runtime/ralplan-runtime.ts +100 -164
  339. package/src/gjc-runtime/session-state-lock.ts +992 -0
  340. package/src/gjc-runtime/session-state-sidecar.ts +644 -142
  341. package/src/gjc-runtime/state-writer.ts +39 -14
  342. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
  343. package/src/gjc-runtime/ultragoal-guard.ts +11 -4
  344. package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
  345. package/src/gjc-runtime/workflow-settings.ts +596 -0
  346. package/src/goals/tools/goal-tool.ts +6 -1
  347. package/src/hooks/events.ts +291 -0
  348. package/src/hooks/native-skill-hook.ts +4 -0
  349. package/src/hooks/normalize.ts +369 -0
  350. package/src/hooks/skill-state.ts +165 -46
  351. package/src/internal-urls/docs-index.generated.ts +41 -32
  352. package/src/main.ts +36 -5
  353. package/src/migrate/mcp-mapper.ts +25 -2
  354. package/src/modes/acp/abort-scope.ts +29 -0
  355. package/src/modes/acp/acp-agent.ts +423 -98
  356. package/src/modes/components/assistant-message.ts +6 -1
  357. package/src/modes/components/chrome.ts +4 -3
  358. package/src/modes/components/customization/customization-dashboard.ts +443 -0
  359. package/src/modes/components/customization/import-wizard.ts +372 -0
  360. package/src/modes/components/customization/index.ts +1 -0
  361. package/src/modes/components/dynamic-theme-text.ts +22 -0
  362. package/src/modes/components/gajae-pet-widget.ts +607 -193
  363. package/src/modes/components/irc-sidebar.ts +11 -0
  364. package/src/modes/components/iterm-pet-transport.ts +585 -0
  365. package/src/modes/components/model-selector.ts +1 -6
  366. package/src/modes/components/oauth-selector.ts +277 -86
  367. package/src/modes/components/pet-capability.ts +35 -31
  368. package/src/modes/components/settings-selector.ts +29 -5
  369. package/src/modes/components/status-line/gh.ts +45 -1
  370. package/src/modes/components/status-line/segments.ts +19 -4
  371. package/src/modes/components/tool-status-header.ts +13 -3
  372. package/src/modes/controllers/command-controller.ts +20 -8
  373. package/src/modes/controllers/extension-ui-controller.ts +56 -257
  374. package/src/modes/controllers/input-controller.ts +10 -0
  375. package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
  376. package/src/modes/controllers/selector-controller.ts +238 -77
  377. package/src/modes/controllers/stt-controller.ts +3 -3
  378. package/src/modes/interactive-mode.ts +88 -16
  379. package/src/modes/print-mode.ts +35 -6
  380. package/src/modes/runtime-init.ts +21 -68
  381. package/src/modes/theme/defaults/index.ts +2 -0
  382. package/src/modes/theme/defaults/ouroboros.json +118 -0
  383. package/src/modes/types.ts +1 -0
  384. package/src/modes/utils/injected-user-submission.ts +25 -0
  385. package/src/modes/utils/terminal-bell.ts +15 -1
  386. package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
  387. package/src/prompts/agent-fragments/restricted-bash.md +1 -1
  388. package/src/prompts/agents/critic.md +1 -1
  389. package/src/prompts/system/rlm-research.md +1 -1
  390. package/src/prompts/system/system-prompt.md +0 -2
  391. package/src/prompts/tools/bash.md +7 -1
  392. package/src/prompts/tools/browser.md +1 -1
  393. package/src/prompts/tools/cron.md +6 -6
  394. package/src/prompts/tools/read.md +0 -2
  395. package/src/prompts/tools/skill-discovery.md +4 -2
  396. package/src/runtime-mcp/client.ts +427 -23
  397. package/src/runtime-mcp/config.ts +37 -5
  398. package/src/runtime-mcp/manager-pool.test.ts +56 -0
  399. package/src/runtime-mcp/manager.ts +52 -2
  400. package/src/runtime-mcp/oauth-discovery.ts +13 -0
  401. package/src/runtime-mcp/oauth-flow.ts +46 -1
  402. package/src/runtime-mcp/pool-key.ts +5 -1
  403. package/src/runtime-mcp/pool.test.ts +9 -0
  404. package/src/runtime-mcp/protocol.test.ts +353 -0
  405. package/src/runtime-mcp/protocol.ts +624 -0
  406. package/src/runtime-mcp/scope-config.ts +78 -0
  407. package/src/runtime-mcp/tool-bridge.ts +44 -10
  408. package/src/runtime-mcp/transports/http.ts +84 -13
  409. package/src/runtime-mcp/types.ts +123 -12
  410. package/src/sdk/acp/adapter.ts +328 -97
  411. package/src/sdk/broker/broker.ts +160 -741
  412. package/src/sdk/broker/ensure.ts +9 -1
  413. package/src/sdk/broker/lifecycle.ts +510 -116
  414. package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
  415. package/src/sdk/broker/process-incarnation.ts +19 -0
  416. package/src/sdk/broker/session-index.ts +516 -117
  417. package/src/sdk/broker/startup-failure.ts +28 -5
  418. package/src/sdk/broker/transport.ts +1 -13
  419. package/src/sdk/bus/chat-daemon-cli.ts +4 -2
  420. package/src/sdk/bus/chat-daemon-control.ts +67 -6
  421. package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
  422. package/src/sdk/bus/config.ts +13 -0
  423. package/src/sdk/bus/conversation-store.ts +59 -171
  424. package/src/sdk/bus/daemon-paths.ts +20 -0
  425. package/src/sdk/bus/discord-conversation.ts +2 -0
  426. package/src/sdk/bus/discord-daemon.ts +524 -126
  427. package/src/sdk/bus/discord-live-provider.ts +206 -79
  428. package/src/sdk/bus/existing-thread-readiness.ts +4 -97
  429. package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
  430. package/src/sdk/bus/index.ts +2480 -456
  431. package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
  432. package/src/sdk/bus/lifecycle-commands.ts +2 -2
  433. package/src/sdk/bus/managed-daemon.ts +2 -145
  434. package/src/sdk/bus/notification-service.ts +196 -0
  435. package/src/sdk/bus/operator-runtime.ts +1 -1
  436. package/src/sdk/bus/prompt-reconciliation.ts +24 -15
  437. package/src/sdk/bus/reconciliation-store.ts +553 -24
  438. package/src/sdk/bus/session-control.ts +49 -3
  439. package/src/sdk/bus/slack-conversation.ts +4 -0
  440. package/src/sdk/bus/slack-daemon.ts +733 -134
  441. package/src/sdk/bus/slack-live-provider.ts +65 -15
  442. package/src/sdk/bus/slack-provider.ts +4 -0
  443. package/src/sdk/bus/slack-thread-binding.ts +9 -104
  444. package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
  445. package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
  446. package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
  447. package/src/sdk/bus/telegram-daemon-control.ts +3 -13
  448. package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
  449. package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
  450. package/src/sdk/bus/telegram-daemon.ts +2552 -2280
  451. package/src/sdk/bus/telegram-reference.ts +1 -226
  452. package/src/sdk/bus/telegram-setup.ts +2 -2
  453. package/src/sdk/bus/threaded-render.ts +1 -0
  454. package/src/sdk/bus/topic-registry.ts +279 -146
  455. package/src/sdk/cli/rows.ts +2 -35
  456. package/src/sdk/cli/session-cli.ts +776 -700
  457. package/src/sdk/client/client.ts +892 -1
  458. package/src/sdk/host/control/dispatch.ts +93 -58
  459. package/src/sdk/host/control/index.ts +1 -1
  460. package/src/sdk/host/control/operations.ts +18 -10
  461. package/src/sdk/host/control/runtime-gate.ts +40 -0
  462. package/src/sdk/host/host.ts +63 -12
  463. package/src/sdk/host/query/handlers.ts +66 -7
  464. package/src/sdk/host/reverse-leases.ts +2 -2
  465. package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
  466. package/src/sdk/host/session-runtime.test.ts +2787 -34
  467. package/src/sdk/host/session-runtime.ts +1489 -101
  468. package/src/sdk/host/surface-policy.ts +12 -8
  469. package/src/sdk/host/types.ts +1 -1
  470. package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
  471. package/src/sdk/host/websocket-transport.ts +85 -50
  472. package/src/sdk/index.ts +2 -1
  473. package/src/sdk/lifecycle/broker-client.ts +53 -0
  474. package/src/sdk/lifecycle/client.ts +234 -0
  475. package/src/sdk/lifecycle/index.ts +3 -0
  476. package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
  477. package/src/sdk/lifecycle/service.ts +720 -0
  478. package/src/sdk/mcp/server.ts +226 -188
  479. package/src/sdk/prompt-deadline-lease.ts +55 -0
  480. package/src/sdk/prompt-deadline-manager.ts +148 -0
  481. package/src/sdk/prompt-status.ts +11 -3
  482. package/src/sdk/protocol/operation-inventory.generated.json +272 -129
  483. package/src/sdk/protocol/operation-registry.ts +71 -8
  484. package/src/sdk/receipt-state.ts +43 -0
  485. package/src/sdk/reconciliation-extensions.ts +14 -0
  486. package/src/sdk/router/index.ts +1 -0
  487. package/src/sdk/router/session-router.ts +1658 -0
  488. package/src/sdk/session-list.ts +93 -0
  489. package/src/sdk/session-reconnect.ts +45 -1
  490. package/src/sdk/session.ts +716 -120
  491. package/src/sdk/transport/serve-cli.ts +18 -34
  492. package/src/session/account-inventory.ts +603 -0
  493. package/src/session/agent-session.ts +2873 -559
  494. package/src/session/agent-storage.ts +35 -0
  495. package/src/session/blob-store.ts +32 -1
  496. package/src/session/coordinator-tool-label.ts +40 -0
  497. package/src/session/internal/managed-session-scope.ts +4 -0
  498. package/src/session/internal/managed-session-storage.ts +199 -31
  499. package/src/session/messages.ts +1 -1
  500. package/src/session/secure-token-file.ts +80 -0
  501. package/src/session/session-manager.ts +757 -57
  502. package/src/session/session-storage.ts +25 -16
  503. package/src/session/startup-auth-config.ts +297 -0
  504. package/src/session/terminal-abort.ts +1253 -0
  505. package/src/session/yield-queue.ts +57 -15
  506. package/src/session-import/claude.ts +334 -0
  507. package/src/session-import/codex.ts +1033 -0
  508. package/src/session-import/command.ts +77 -0
  509. package/src/session-import/detect.ts +133 -0
  510. package/src/session-import/index.ts +7 -0
  511. package/src/session-import/provider-codex.ts +327 -0
  512. package/src/session-import/provider-service.ts +457 -0
  513. package/src/session-import/redact.ts +128 -0
  514. package/src/session-import/service.ts +1264 -0
  515. package/src/session-import/types.ts +148 -0
  516. package/src/setup/paseo/check.ts +213 -0
  517. package/src/setup/paseo/install-saga.ts +293 -0
  518. package/src/setup/paseo/json-publisher.ts +263 -0
  519. package/src/setup/paseo/orchestration-preferences.ts +86 -0
  520. package/src/setup/paseo/paseo-ownership.ts +224 -0
  521. package/src/setup/paseo/paseo-setup.ts +253 -0
  522. package/src/setup/paseo/provider-config.ts +139 -0
  523. package/src/setup/paseo/remove.ts +183 -0
  524. package/src/setup/paseo/result-types.ts +79 -0
  525. package/src/setup/paseo/setup-deps.ts +175 -0
  526. package/src/setup/paseo/skills-bridge.ts +260 -0
  527. package/src/skill-state/active-state.ts +21 -11
  528. package/src/slash-commands/acp-builtins.ts +9 -1
  529. package/src/slash-commands/builtin-registry.ts +117 -19
  530. package/src/slash-commands/helpers/credential-switch.ts +143 -0
  531. package/src/slash-commands/helpers/mcp.ts +9 -3
  532. package/src/slash-commands/helpers/usage-report.ts +61 -56
  533. package/src/slash-commands/types.ts +7 -2
  534. package/src/task/executor.ts +30 -11
  535. package/src/task/index.ts +66 -7
  536. package/src/task/render.ts +23 -9
  537. package/src/tools/ask-answer-registry.ts +23 -7
  538. package/src/tools/ask.ts +8 -4
  539. package/src/tools/bash-sleep-advisory.ts +115 -0
  540. package/src/tools/bash.ts +98 -18
  541. package/src/tools/browser/attach.ts +71 -3
  542. package/src/tools/browser/launch.ts +86 -13
  543. package/src/tools/browser/profile-discovery.ts +57 -7
  544. package/src/tools/browser/render.ts +8 -1
  545. package/src/tools/browser.ts +130 -21
  546. package/src/tools/computer.enforcement.test.ts +1 -1
  547. package/src/tools/computer.ts +3 -2
  548. package/src/tools/cron.ts +12 -1
  549. package/src/tools/image-gen.ts +349 -142
  550. package/src/tools/index.ts +8 -0
  551. package/src/tools/job.ts +33 -6
  552. package/src/tools/monitor.ts +41 -2
  553. package/src/tools/skill-discovery.ts +21 -29
  554. package/src/tools/subagent.ts +142 -24
  555. package/src/tools/todo-contract.ts +55 -3
  556. package/src/tools/todo-write.ts +4 -3
  557. package/src/tools/tool-catalog.generated.ts +6 -6
  558. package/src/tools/ultragoal-ask-guard.ts +10 -3
  559. package/src/utils/herdr-pane.ts +345 -0
  560. package/src/utils/title-generator.ts +2 -0
  561. package/src/web/scrapers/index.ts +6 -4
  562. package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
  563. package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
  564. package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
  565. package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
  566. package/dist/types/runtime/lazy-service.test.d.ts +0 -1
  567. package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
  568. package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
  569. package/dist/types/runtime-mcp/config.test.d.ts +0 -1
  570. package/dist/types/runtime-mcp/http.test.d.ts +0 -1
  571. package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
  572. package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
  573. package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
  574. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
  575. package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
  576. package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
  577. package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
  578. package/dist/types/sdk/elevation/audit.d.ts +0 -93
  579. package/dist/types/sdk/elevation/capability.d.ts +0 -3
  580. package/dist/types/sdk/elevation/digest.d.ts +0 -72
  581. package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
  582. package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
  583. package/dist/types/sdk/elevation/owner.d.ts +0 -48
  584. package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
  585. package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
  586. package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
  587. package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
  588. package/dist/types/session/auth-broker-config.d.ts +0 -13
  589. package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
  590. package/dist/types/skills/skills.test.d.ts +0 -1
  591. package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
  592. package/dist/types/task/token-log.test.d.ts +0 -1
  593. package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
  594. package/dist/types/tools/descriptors.test.d.ts +0 -1
  595. package/scripts/g005-daemon-smoke.ts +0 -180
  596. package/scripts/g011-daemon-path-smoke.ts +0 -153
  597. package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
  598. package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
  599. package/src/sdk/bus/telegram-cli.ts +0 -212
  600. package/src/sdk/elevation/allowlist.ts +0 -54
  601. package/src/sdk/elevation/audit.ts +0 -208
  602. package/src/sdk/elevation/capability.ts +0 -41
  603. package/src/sdk/elevation/digest.ts +0 -129
  604. package/src/sdk/elevation/dispatch-receipt.ts +0 -184
  605. package/src/sdk/elevation/grant-ledger.ts +0 -1142
  606. package/src/sdk/elevation/owner.ts +0 -109
  607. package/src/session/auth-broker-config.ts +0 -109
  608. /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
  609. /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
  610. /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
@@ -1,19 +1,25 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+
1
3
  /**
2
4
  * Kind-aware invocation reconciliation (prompt | skill) with optional durable store.
3
- * Preserves Q26 admit/first-terminal/capacity/TTL semantics; indexes and caps are per-kind.
5
+ * Preserves Q26 admit/first-terminal/capacity semantics; indexes and caps are per-kind.
4
6
  */
5
7
 
6
8
  import { sanitizePromptFailure } from "../prompt-failure";
7
9
  import type { PromptReconciliationStatus, SdkPromptTerminalOutcome, TurnPromptReconciliation } from "../prompt-status";
10
+ import type { ReceiptState } from "../receipt-state";
8
11
  import { sanitizeTurnResultContent, type TurnResultContent, type TurnResultPage } from "../turn-result";
9
-
10
12
  import {
11
13
  PROMPT_RECONCILIATION_ACTIVE_CAPACITY,
12
14
  PROMPT_RECONCILIATION_TERMINAL_CAPACITY,
13
- PROMPT_RECONCILIATION_TERMINAL_TTL_MS,
14
15
  type PromptCorrelation,
15
16
  } from "./prompt-reconciliation";
16
- import type { DurableReconciliationRecord, ReconciliationKind, ReconciliationStore } from "./reconciliation-store";
17
+ import type {
18
+ DurableReconciliationRecord,
19
+ DurableSteerReconciliationRecord,
20
+ ReconciliationKind,
21
+ ReconciliationStore,
22
+ } from "./reconciliation-store";
17
23
 
18
24
  export type { ReconciliationKind };
19
25
 
@@ -22,6 +28,16 @@ export interface KindCorrelation extends PromptCorrelation {
22
28
  content?: TurnResultContent;
23
29
  }
24
30
 
31
+ export interface SteerReconciliationResult {
32
+ commandId: string;
33
+ turnId: string;
34
+ clientRef: string;
35
+ status: "accepted" | "rejected" | "uncertain";
36
+ acceptedAt: number;
37
+ terminalAt?: number;
38
+ error?: { code: string; message: string };
39
+ }
40
+
25
41
  export interface KindAwareReconciliation {
26
42
  admit(kind: ReconciliationKind, clientRef?: string): void;
27
43
  releaseAdmission(kind: ReconciliationKind, clientRef?: string): void;
@@ -39,16 +55,19 @@ export interface KindAwareReconciliation {
39
55
  | { type: "agent_failed"; error: unknown; content?: TurnResultContent },
40
56
  ): Promise<void>;
41
57
  claimPendingOutcome(
58
+ kind: ReconciliationKind,
42
59
  correlation: PromptCorrelation,
43
60
  outcome: SdkPromptTerminalOutcome,
61
+ receiptState?: Extract<ReceiptState, "present" | "missing">,
44
62
  ): Promise<SdkPromptTerminalOutcome>;
45
- finalizePromptOutcome(
63
+ finalizeOutcome(
64
+ kind: ReconciliationKind,
46
65
  correlation: PromptCorrelation,
47
66
  outcome?: SdkPromptTerminalOutcome,
48
67
  recordError?: { code: string; message: string },
49
68
  content?: unknown,
50
69
  ): Promise<void>;
51
- peekPendingOutcome(correlation: PromptCorrelation): SdkPromptTerminalOutcome | undefined;
70
+ peekPendingOutcome(kind: ReconciliationKind, correlation: PromptCorrelation): SdkPromptTerminalOutcome | undefined;
52
71
  lookup(
53
72
  kind: ReconciliationKind,
54
73
  selector: { commandId?: string; turnId?: string; clientRef?: string },
@@ -57,6 +76,15 @@ export interface KindAwareReconciliation {
57
76
  kind: ReconciliationKind,
58
77
  selector: { commandId?: string; turnId?: string; clientRef?: string },
59
78
  ): TurnResultPage;
79
+ reserveSteer(clientRef: string, text: string): Promise<{ replay: boolean; result: SteerReconciliationResult }>;
80
+ settleSteer(
81
+ clientRef: string,
82
+ status: "accepted" | "rejected" | "uncertain",
83
+ error?: unknown,
84
+ ): Promise<SteerReconciliationResult>;
85
+ lookupSteer(
86
+ selector: string | { commandId?: string; turnId?: string; clientRef?: string },
87
+ ): SteerReconciliationResult | { clientRef?: string; status: "unknown" };
60
88
  cleanup(): void;
61
89
  activeCount(kind: ReconciliationKind): number;
62
90
  /** Hydrate from durable store (call once at session host start). */
@@ -77,28 +105,51 @@ export function createKindAwareReconciliation(
77
105
  const keyOf = (kind: ReconciliationKind, correlation: PromptCorrelation) =>
78
106
  `${kind}:${correlation.commandId}:${correlation.turnId}`;
79
107
  const refKey = (kind: ReconciliationKind, clientRef: string) => `${kind}\0${clientRef}`;
108
+ const steerKey = (clientRef: string) => `steer:${clientRef}`;
109
+ const steerResult = (record: DurableSteerReconciliationRecord): SteerReconciliationResult => ({
110
+ commandId: record.commandId,
111
+ turnId: record.turnId,
112
+ clientRef: record.clientRef,
113
+ status: record.status === "dispatching" ? "uncertain" : record.status,
114
+ acceptedAt: record.acceptedAt,
115
+ ...(record.status !== "dispatching" && record.status !== "accepted" ? { terminalAt: record.settledAt } : {}),
116
+ ...(record.error
117
+ ? { error: record.error }
118
+ : record.status === "dispatching"
119
+ ? { error: { code: "delivery_uncertain", message: "Steer delivery is still dispatching or uncertain." } }
120
+ : {}),
121
+ });
80
122
 
81
123
  const indexRecords = (source: Map<string, DurableReconciliationRecord>) => {
82
124
  const index = new Map<string, string>();
83
125
  for (const [key, record] of source)
84
- if (record.clientRef !== undefined) index.set(refKey(record.kind, record.clientRef), key);
126
+ if (record.kind !== "steer" && record.clientRef !== undefined)
127
+ index.set(refKey(record.kind, record.clientRef), key);
85
128
  return index;
86
129
  };
87
130
 
88
131
  const cleanupRecords = (source: Map<string, DurableReconciliationRecord>) => {
89
- const at = now();
90
- for (const [key, record] of source)
91
- if (record.terminalAt !== undefined && record.terminalAt + PROMPT_RECONCILIATION_TERMINAL_TTL_MS <= at)
92
- source.delete(key);
93
132
  for (const kind of ["prompt", "skill"] as const) {
94
133
  const terminalEntries = [...source.entries()].filter(
95
134
  ([, record]) => record.kind === kind && record.terminalAt !== undefined,
96
135
  );
97
136
  if (terminalEntries.length <= PROMPT_RECONCILIATION_TERMINAL_CAPACITY) continue;
98
- terminalEntries.sort((a, b) => (a[1].terminalAt as number) - (b[1].terminalAt as number));
137
+ terminalEntries.sort(
138
+ (a, b) =>
139
+ ((a[1].kind === "steer" ? a[1].settledAt : a[1].terminalAt) as number) -
140
+ ((b[1].kind === "steer" ? b[1].settledAt : b[1].terminalAt) as number),
141
+ );
99
142
  for (const [key] of terminalEntries.slice(0, terminalEntries.length - PROMPT_RECONCILIATION_TERMINAL_CAPACITY))
100
143
  source.delete(key);
101
144
  }
145
+ const settledSteers: Array<[string, DurableSteerReconciliationRecord]> = [];
146
+ for (const [key, record] of source)
147
+ if (record.kind === "steer" && record.settledAt !== undefined) settledSteers.push([key, record]);
148
+ if (settledSteers.length > PROMPT_RECONCILIATION_TERMINAL_CAPACITY) {
149
+ settledSteers.sort((a, b) => (a[1].settledAt as number) - (b[1].settledAt as number));
150
+ for (const [key] of settledSteers.slice(0, settledSteers.length - PROMPT_RECONCILIATION_TERMINAL_CAPACITY))
151
+ source.delete(key);
152
+ }
102
153
  };
103
154
 
104
155
  const queueMutation = async <T>(
@@ -122,6 +173,67 @@ export function createKindAwareReconciliation(
122
173
  return await pending;
123
174
  };
124
175
 
176
+ const reserveSteer = async (clientRef: string, text: string) => {
177
+ const textDigest = createHash("sha256").update(text).digest("hex");
178
+ return await queueMutation(candidate => {
179
+ cleanupRecords(candidate);
180
+ const existing = candidate.get(steerKey(clientRef));
181
+ if (existing?.kind === "steer") {
182
+ if (existing.textDigest !== textDigest)
183
+ throw Object.assign(new Error("clientRef is already bound to different steer text."), {
184
+ code: "client_ref_conflict",
185
+ });
186
+ return { value: { replay: true, result: steerResult(existing) }, changed: false };
187
+ }
188
+ const correlation = { commandId: randomUUID(), turnId: randomUUID() };
189
+ const record: DurableSteerReconciliationRecord = {
190
+ kind: "steer",
191
+ ...correlation,
192
+ clientRef,
193
+ textDigest,
194
+ createdAt: now(),
195
+ acceptedAt: now(),
196
+ status: "dispatching",
197
+ };
198
+ candidate.set(steerKey(clientRef), record);
199
+ return { value: { replay: false, result: steerResult(record) }, changed: true };
200
+ });
201
+ };
202
+
203
+ const settleSteer = async (clientRef: string, status: "accepted" | "rejected" | "uncertain", error?: unknown) =>
204
+ await queueMutation(candidate => {
205
+ const record = candidate.get(steerKey(clientRef));
206
+ if (record?.kind !== "steer")
207
+ throw Object.assign(new Error("Unknown steer clientRef."), { code: "unknown_client_ref" });
208
+ if (record.status !== "dispatching") return { value: steerResult(record), changed: false };
209
+ record.status = status;
210
+ record.settledAt = now();
211
+ if (status !== "accepted") record.error = sanitizePromptFailure(error);
212
+ cleanupRecords(candidate);
213
+ return { value: steerResult(record), changed: true };
214
+ });
215
+
216
+ const lookupSteer = (selector: string | { commandId?: string; turnId?: string; clientRef?: string }) => {
217
+ const record =
218
+ typeof selector === "string"
219
+ ? records.get(steerKey(selector))
220
+ : selector.clientRef !== undefined
221
+ ? records.get(steerKey(selector.clientRef))
222
+ : selector.commandId !== undefined && selector.turnId !== undefined
223
+ ? [...records.values()].find(
224
+ candidate =>
225
+ candidate.kind === "steer" &&
226
+ candidate.commandId === selector.commandId &&
227
+ candidate.turnId === selector.turnId,
228
+ )
229
+ : undefined;
230
+ return record?.kind === "steer"
231
+ ? steerResult(record)
232
+ : typeof selector === "string"
233
+ ? { clientRef: selector, status: "unknown" as const }
234
+ : { status: "unknown" as const };
235
+ };
236
+
125
237
  const reservedFor = (kind: ReconciliationKind) => {
126
238
  let set = reservedClientRefs.get(kind);
127
239
  if (!set) {
@@ -138,7 +250,8 @@ export function createKindAwareReconciliation(
138
250
 
139
251
  const activeCount = (kind: ReconciliationKind) => {
140
252
  let count = 0;
141
- for (const record of records.values()) if (record.kind === kind && record.terminalAt === undefined) count++;
253
+ for (const record of records.values())
254
+ if (record.kind !== "steer" && record.kind === kind && record.terminalAt === undefined) count++;
142
255
  return count;
143
256
  };
144
257
 
@@ -207,7 +320,7 @@ export function createKindAwareReconciliation(
207
320
  if (!correlation) return;
208
321
  await queueMutation(candidate => {
209
322
  const record = candidate.get(keyOf(kind, correlation));
210
- if (!record) return { value: undefined, changed: false };
323
+ if (!record || record.kind === "steer") return { value: undefined, changed: false };
211
324
  if (record.terminalAt !== undefined) {
212
325
  // The terminal is claimed by one delivery path while the reason arrives on
213
326
  // another, so ordering is not the caller's to control. A late agent_failed
@@ -227,43 +340,61 @@ export function createKindAwareReconciliation(
227
340
  record.status = "in_flight";
228
341
  record.startedAt = now();
229
342
  if (frame.content) record.content = sanitizeTurnResultContent(frame.content.text);
230
-
231
343
  return { value: undefined, changed: true };
232
344
  }
345
+ const pendingOutcome = record.pendingOutcome;
233
346
  record.terminalAt = now();
234
347
  if (frame.content) record.content = sanitizeTurnResultContent(frame.content.text);
235
-
236
- if (frame.type === "agent_failed") {
348
+ if (pendingOutcome !== undefined) {
349
+ record.outcome = pendingOutcome;
350
+ record.pendingOutcome = undefined;
351
+ if (pendingOutcome.kind === "failed") {
352
+ record.status = "failed";
353
+ record.error = { code: pendingOutcome.code, message: pendingOutcome.message };
354
+ } else {
355
+ record.status = "terminal_ok";
356
+ }
357
+ record.receiptState = record.pendingReceiptState ?? "missing";
358
+ record.pendingReceiptState = undefined;
359
+ } else if (frame.type === "agent_failed") {
237
360
  record.status = "failed";
238
361
  record.error = sanitizePromptFailure(frame.error);
239
- } else record.status = "terminal_ok";
362
+ record.receiptState = frame.content?.text?.trim() ? "present" : "missing";
363
+ } else {
364
+ record.status = "terminal_ok";
365
+ record.receiptState = frame.content?.text?.trim() ? "present" : "missing";
366
+ }
240
367
  cleanupRecords(candidate);
241
368
  return { value: undefined, changed: true };
242
369
  });
243
370
  };
244
371
 
245
372
  const claimPendingOutcome = async (
373
+ kind: ReconciliationKind,
246
374
  correlation: PromptCorrelation,
247
375
  outcome: SdkPromptTerminalOutcome,
376
+ receiptState?: Extract<ReceiptState, "present" | "missing">,
248
377
  ): Promise<SdkPromptTerminalOutcome> =>
249
378
  await queueMutation(candidate => {
250
- const record = candidate.get(keyOf("prompt", correlation));
251
- if (!record || record.terminalAt !== undefined || record.kind !== "prompt")
379
+ const record = candidate.get(keyOf(kind, correlation));
380
+ if (!record || record.terminalAt !== undefined || record.kind !== kind)
252
381
  return { value: outcome, changed: false };
253
382
  if (record.pendingOutcome !== undefined) return { value: record.pendingOutcome, changed: false };
254
383
  record.pendingOutcome = outcome;
384
+ record.pendingReceiptState = receiptState;
255
385
  return { value: outcome, changed: true };
256
386
  });
257
387
 
258
- const finalizePromptOutcome = async (
388
+ const finalizeOutcome = async (
389
+ kind: ReconciliationKind,
259
390
  correlation: PromptCorrelation,
260
391
  outcome?: SdkPromptTerminalOutcome,
261
392
  recordError?: { code: string; message: string },
262
393
  content?: unknown,
263
394
  ) => {
264
395
  await queueMutation(candidate => {
265
- const record = candidate.get(keyOf("prompt", correlation));
266
- if (!record || record.terminalAt !== undefined || record.kind !== "prompt")
396
+ const record = candidate.get(keyOf(kind, correlation));
397
+ if (!record || record.terminalAt !== undefined || record.kind !== kind)
267
398
  return { value: undefined, changed: false };
268
399
  const finalOutcome = outcome ?? record.pendingOutcome;
269
400
  record.terminalAt = now();
@@ -273,14 +404,16 @@ export function createKindAwareReconciliation(
273
404
  } else record.status = "terminal_ok";
274
405
  record.content = sanitizeTurnResultContent(content);
275
406
  record.outcome = finalOutcome;
407
+ record.receiptState = record.pendingReceiptState ?? "unknown";
276
408
  record.pendingOutcome = undefined;
409
+ record.pendingReceiptState = undefined;
277
410
  cleanupRecords(candidate);
278
411
  return { value: undefined, changed: true };
279
412
  });
280
413
  };
281
414
 
282
- const peekPendingOutcome = (correlation: PromptCorrelation) =>
283
- records.get(keyOf("prompt", correlation))?.pendingOutcome;
415
+ const peekPendingOutcome = (kind: ReconciliationKind, correlation: PromptCorrelation) =>
416
+ records.get(keyOf(kind, correlation))?.pendingOutcome;
284
417
 
285
418
  const lookup = (
286
419
  kind: ReconciliationKind,
@@ -294,20 +427,22 @@ export function createKindAwareReconciliation(
294
427
  ? keyOf(kind, { commandId: selector.commandId, turnId: selector.turnId })
295
428
  : undefined;
296
429
  const record = key === undefined ? undefined : records.get(key);
297
- if (!record) return { status: "unknown" };
430
+ if (!record) return { status: "unknown", receiptState: "unknown" };
431
+ if (record.kind === "steer") return { status: "unknown", receiptState: "unknown" };
298
432
  const identity = {
299
433
  commandId: record.commandId,
300
434
  turnId: record.turnId,
301
435
  ...(record.clientRef !== undefined ? { clientRef: record.clientRef } : {}),
302
436
  acceptedAt: record.acceptedAt,
303
437
  };
304
- if (record.status === "accepted") return { status: "accepted", ...identity };
438
+ if (record.status === "accepted") return { status: "accepted", receiptState: "absent", ...identity };
305
439
  if (record.status === "in_flight")
306
- return { status: "in_flight", ...identity, startedAt: record.startedAt as number };
440
+ return { status: "in_flight", receiptState: "absent", ...identity, startedAt: record.startedAt as number };
307
441
  const terminal = {
308
442
  ...identity,
309
443
  ...(record.startedAt !== undefined ? { startedAt: record.startedAt } : {}),
310
444
  terminalAt: record.terminalAt as number,
445
+ receiptState: record.receiptState ?? "unknown",
311
446
  ...(record.outcome !== undefined ? { outcome: record.outcome } : {}),
312
447
  };
313
448
  if (record.status === "terminal_ok")
@@ -331,9 +466,11 @@ export function createKindAwareReconciliation(
331
466
  ? keyOf(kind, { commandId: selector.commandId, turnId: selector.turnId })
332
467
  : undefined;
333
468
  const record = key === undefined ? undefined : records.get(key);
334
- if (!record) return { status: "unknown" };
469
+ if (!record || record.kind === "steer") return { status: "unknown" };
335
470
  const identity = {
336
- kind: record.kind,
471
+ // Durable terminal markers (kind "terminal") are not prompt/skill
472
+ // invocation pages: never surface them under a prompt/skill kind.
473
+ kind: record.kind === "terminal" ? undefined : record.kind,
337
474
  commandId: record.commandId,
338
475
  turnId: record.turnId,
339
476
  ...(record.clientRef !== undefined ? { clientRef: record.clientRef } : {}),
@@ -347,16 +484,46 @@ export function createKindAwareReconciliation(
347
484
  terminalAt: record.terminalAt as number,
348
485
  ...(record.content !== undefined ? { content: record.content } : {}),
349
486
  };
350
- if (record.status === "terminal_ok") return { status: "terminal_ok", ...terminal };
487
+ if (record.status === "terminal_ok")
488
+ return {
489
+ status: "terminal_ok",
490
+ ...terminal,
491
+ ...(record.error !== undefined ? { error: record.error } : {}),
492
+ };
351
493
  return { status: "failed", ...terminal, error: record.error ?? sanitizePromptFailure(undefined) };
352
494
  };
353
495
  const hydrateFromStore = async () => {
354
496
  if (!store) return;
355
497
  const run = async () => {
356
498
  const loaded = await store.load();
357
- const candidate = new Map(loaded.map(record => [keyOf(record.kind, record), { ...record }] as const));
499
+ const candidate = new Map(
500
+ loaded.map(record => {
501
+ const hydrated =
502
+ record.kind === "steer" && record.status === "accepted"
503
+ ? {
504
+ ...record,
505
+ status: "uncertain" as const,
506
+ settledAt: now(),
507
+ error: {
508
+ code: "process_restart_uncertain",
509
+ message: "Steer delivery cannot be proven after process restart.",
510
+ },
511
+ }
512
+ : { ...record };
513
+ return [
514
+ record.kind === "steer" ? steerKey(record.clientRef) : keyOf(record.kind, record),
515
+ hydrated,
516
+ ] as const;
517
+ }),
518
+ );
358
519
  const candidateIndex = indexRecords(candidate);
359
- await store.transact(() => [...candidate.values()].map(record => ({ ...record })));
520
+ // Persist only when hydration settled accepted steers to uncertain: an
521
+ // unconditional transact emits a rename on every startup even for empty
522
+ // stores, which a test pause hook or slow fs can intercept before any
523
+ // prompt/skill admission — stalling reconciliationReady so a concurrent
524
+ // abort misses the not-yet-registered pending preflight entry (#4522).
525
+ const settledSteers = loaded.some(record => record.kind === "steer" && record.status === "accepted");
526
+ if (settledSteers) await store.transact(() => [...candidate.values()].map(record => ({ ...record })));
360
527
  records = candidate;
361
528
  clientRefIndex = candidateIndex;
362
529
  };
@@ -374,13 +541,16 @@ export function createKindAwareReconciliation(
374
541
  noteAccepted,
375
542
  noteTransition,
376
543
  claimPendingOutcome,
377
- finalizePromptOutcome,
544
+ finalizeOutcome,
378
545
  peekPendingOutcome,
379
546
  lookup,
380
547
  lookupResult,
381
548
  cleanup,
382
549
  activeCount,
383
550
  hydrateFromStore,
551
+ reserveSteer,
552
+ settleSteer,
553
+ lookupSteer,
384
554
  };
385
555
  }
386
556
 
@@ -293,13 +293,13 @@ function isSafeBranch(value: string): boolean {
293
293
  export function formatLifecycleOutcome(r: SessionLifecycleResponse, verb?: LifecycleCommandVerb): string {
294
294
  switch (r.type) {
295
295
  case "session_create_response":
296
- return `\u{1f680} Launching session ${r.sessionId} in tmux. It will appear once ready \u2014 check /session_recent.`;
296
+ return `\u{1f680} Launching session ${r.sessionId} through SDK core. It will appear once ready — check /session_recent.`;
297
297
  case "session_close_response":
298
298
  return `\u2705 Closed session ${r.sessionId} (history preserved \u2014 you can resume it later).`;
299
299
  case "session_resume_response":
300
300
  return r.mode === "reattached"
301
301
  ? `\u2705 Reattached to live session ${r.sessionId}.`
302
- : `\u{1f680} Cold-restarting session ${r.sessionId} from saved history in tmux \u2014 check /session_recent.`;
302
+ : `\u{1f680} Resuming session ${r.sessionId} from saved history through SDK core — check /session_recent.`;
303
303
  case "session_lifecycle_error":
304
304
  break;
305
305
  default:
@@ -1,163 +1,20 @@
1
- import * as path from "node:path";
2
- import type { Settings } from "../../config/settings";
3
1
  import { RateLimitPool } from "./rate-limit-pool";
4
- import {
5
- CLIENT_PING_PONG_CAPABILITY,
6
- HEARTBEAT_INTERVAL_MS,
7
- HEARTBEAT_TTL_MS,
8
- NOTIFICATION_PROTOCOL_VERSION,
9
- } from "./telegram-daemon";
10
- import { readEndpoint } from "./telegram-reference";
11
2
  import { renderThreadedFrame, type ThreadedSend } from "./threaded-render";
12
3
 
13
- export interface ManagedNotificationDaemonFs {
14
- readdir(path: string): Promise<string[]>;
15
- }
16
-
17
- export interface ManagedSessionSocket {
18
- sessionId: string;
19
- token: string;
20
- ws: WebSocket;
21
- pending: Map<string, { sessionId: string; actionId: string }>;
22
- capable: boolean;
23
- lastPongAt: number;
24
- awaitingNonce: string | undefined;
25
- pingTimer: ReturnType<typeof setInterval> | undefined;
26
- }
27
-
4
+ /** Shared presentation engine for managed notification providers. */
28
5
  export interface ManagedNotificationDaemonOptions {
29
- settings: Settings;
30
- fs: ManagedNotificationDaemonFs;
31
- WebSocketImpl?: typeof WebSocket;
32
6
  now?: () => number;
33
- setIntervalImpl?: typeof setInterval;
34
- clearIntervalImpl?: typeof clearInterval;
35
7
  rateLimitPool?: RateLimitPool<{ send: ThreadedSend; topicId?: string }>;
36
8
  }
37
9
 
38
10
  export abstract class ManagedNotificationDaemon {
39
- readonly sessions = new Map<string, ManagedSessionSocket>();
40
11
  readonly pool: RateLimitPool<{ send: ThreadedSend; topicId?: string }>;
41
12
 
42
- protected constructor(protected readonly opts: ManagedNotificationDaemonOptions) {
13
+ protected constructor(opts: ManagedNotificationDaemonOptions = {}) {
43
14
  this.pool = opts.rateLimitPool ?? new RateLimitPool<{ send: ThreadedSend; topicId?: string }>({ now: opts.now });
44
15
  }
45
16
 
46
- async scanRoots(): Promise<void> {
47
- const rootState = await this.readRoots();
48
- for (const root of rootState) {
49
- const dir = path.join(root, "sdk");
50
- let files: string[];
51
- try {
52
- files = await this.opts.fs.readdir(dir);
53
- } catch {
54
- continue;
55
- }
56
- for (const file of files.filter(item => item.endsWith(".json"))) {
57
- const sessionId = path.basename(file, ".json");
58
- if (this.sessions.has(sessionId)) continue;
59
- try {
60
- const endpoint = readEndpoint(path.join(dir, file));
61
- this.connectSession(sessionId, endpoint.url, endpoint.token);
62
- } catch {}
63
- }
64
- }
65
- }
66
-
67
- connectSession(sessionId: string, url: string, token: string): ManagedSessionSocket {
68
- const WS = this.opts.WebSocketImpl ?? WebSocket;
69
- const ws = new WS(`${url}/?token=${encodeURIComponent(token)}`);
70
- const session: ManagedSessionSocket = {
71
- sessionId,
72
- token,
73
- ws,
74
- pending: new Map(),
75
- capable: false,
76
- lastPongAt: 0,
77
- awaitingNonce: undefined,
78
- pingTimer: undefined,
79
- };
80
- this.sessions.set(sessionId, session);
81
- ws.addEventListener("open", () => this.sendHello(session));
82
- ws.addEventListener("message", ev => {
83
- if (this.sessions.get(sessionId) !== session) return;
84
- void this.handleSessionMessage(session, JSON.parse(String(ev.data))).catch(() => undefined);
85
- });
86
- ws.addEventListener("close", () => this.dropSession(session));
87
- return session;
88
- }
89
-
90
- protected async handleSessionMessage(session: ManagedSessionSocket, msg: Record<string, unknown>): Promise<boolean> {
91
- if (msg.type === "hello") {
92
- const caps = Array.isArray(msg.capabilities) ? msg.capabilities : [];
93
- if (caps.includes(CLIENT_PING_PONG_CAPABILITY)) {
94
- session.capable = true;
95
- this.startLiveness(session);
96
- }
97
- return true;
98
- }
99
- if (msg.type === "pong") {
100
- if (typeof msg.nonce === "string" && msg.nonce === session.awaitingNonce) {
101
- session.awaitingNonce = undefined;
102
- session.lastPongAt = (this.opts.now ?? Date.now)();
103
- }
104
- return true;
105
- }
106
- return false;
107
- }
108
-
109
17
  protected renderFrame(frame: Record<string, unknown>): ThreadedSend | undefined {
110
18
  return renderThreadedFrame(frame);
111
19
  }
112
-
113
- protected dropSession(session: ManagedSessionSocket): void {
114
- const clearIntervalImpl = this.opts.clearIntervalImpl ?? clearInterval;
115
- if (session.pingTimer) {
116
- clearIntervalImpl(session.pingTimer);
117
- session.pingTimer = undefined;
118
- }
119
- if (this.sessions.get(session.sessionId) === session) this.sessions.delete(session.sessionId);
120
- if (session.ws.readyState !== WebSocket.CLOSED) {
121
- try {
122
- session.ws.close();
123
- } catch {}
124
- }
125
- }
126
-
127
- protected abstract readRoots(): Promise<string[]>;
128
-
129
- private sendHello(session: ManagedSessionSocket): void {
130
- if (session.ws.readyState !== WebSocket.OPEN) return;
131
- try {
132
- session.ws.send(
133
- JSON.stringify({
134
- type: "hello",
135
- protocolVersion: NOTIFICATION_PROTOCOL_VERSION,
136
- capabilities: [CLIENT_PING_PONG_CAPABILITY],
137
- }),
138
- );
139
- } catch {}
140
- }
141
-
142
- private startLiveness(session: ManagedSessionSocket): void {
143
- if (session.pingTimer) return;
144
- const setIntervalImpl = this.opts.setIntervalImpl ?? setInterval;
145
- const now = () => (this.opts.now ?? Date.now)();
146
- session.lastPongAt = now();
147
- session.pingTimer = setIntervalImpl(() => {
148
- if (this.sessions.get(session.sessionId) !== session) return;
149
- const t = now();
150
- if (t - session.lastPongAt >= HEARTBEAT_TTL_MS) {
151
- this.dropSession(session);
152
- return;
153
- }
154
- if (session.ws.readyState === WebSocket.OPEN) {
155
- const nonce = `${session.sessionId}:${t}:${Math.random().toString(36).slice(2)}`;
156
- session.awaitingNonce = nonce;
157
- try {
158
- session.ws.send(JSON.stringify({ type: "ping", nonce }));
159
- } catch {}
160
- }
161
- }, HEARTBEAT_INTERVAL_MS);
162
- }
163
20
  }