@gajae-code/coding-agent 0.10.2 → 0.11.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 (465) hide show
  1. package/CHANGELOG.md +50 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/cli/args.d.ts +4 -5
  4. package/dist/types/cli/daemon-cli.d.ts +12 -1
  5. package/dist/types/cli/notify-cli.d.ts +21 -1
  6. package/dist/types/cli.d.ts +3 -0
  7. package/dist/types/commands/daemon.d.ts +39 -0
  8. package/dist/types/commands/launch.d.ts +3 -0
  9. package/dist/types/commands/notify.d.ts +28 -1
  10. package/dist/types/commands/sdk.d.ts +33 -0
  11. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  12. package/dist/types/config/model-profile-activation.d.ts +35 -15
  13. package/dist/types/config/model-profiles.d.ts +11 -5
  14. package/dist/types/config/model-registry.d.ts +3 -3
  15. package/dist/types/config/model-resolver.d.ts +39 -6
  16. package/dist/types/config/model-selector-value.d.ts +17 -0
  17. package/dist/types/config/models-config-schema.d.ts +10 -6
  18. package/dist/types/config/settings-schema.d.ts +133 -6
  19. package/dist/types/config/settings.d.ts +63 -35
  20. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  21. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  22. package/dist/types/daemon/builtin.d.ts +6 -5
  23. package/dist/types/daemon/control-types.d.ts +1 -1
  24. package/dist/types/discovery/mcp-json.d.ts +12 -1
  25. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  26. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  27. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  28. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  29. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  30. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  31. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  32. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  33. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  34. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  35. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  36. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  37. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  38. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  39. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  40. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  41. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  42. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  43. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  44. package/dist/types/harness-control-plane/types.d.ts +3 -4
  45. package/dist/types/lsp/index.d.ts +1 -1
  46. package/dist/types/main.d.ts +32 -38
  47. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  48. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  49. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  50. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  51. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  52. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  53. package/dist/types/modes/components/model-selector.d.ts +1 -0
  54. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  55. package/dist/types/modes/components/settings-selector.d.ts +6 -4
  56. package/dist/types/modes/components/welcome.d.ts +1 -1
  57. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  58. package/dist/types/modes/index.d.ts +0 -4
  59. package/dist/types/modes/interactive-mode.d.ts +3 -0
  60. package/dist/types/modes/runtime-init.d.ts +2 -2
  61. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  62. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  63. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  64. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  65. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  66. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  67. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  68. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  69. package/dist/types/modes/types.d.ts +5 -0
  70. package/dist/types/runtime-mcp/client.d.ts +2 -0
  71. package/dist/types/runtime-mcp/config.d.ts +5 -1
  72. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  73. package/dist/types/runtime-mcp/types.d.ts +4 -0
  74. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  75. package/dist/types/sdk/acp/index.d.ts +2 -0
  76. package/dist/types/sdk/broker/broker.d.ts +53 -0
  77. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  78. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  79. package/dist/types/sdk/broker/identity.d.ts +3 -0
  80. package/dist/types/sdk/broker/index.d.ts +8 -0
  81. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  82. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  83. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  84. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  85. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  86. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  87. package/dist/types/sdk/broker/transport.d.ts +9 -0
  88. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  89. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  90. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  91. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  92. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  93. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  94. package/dist/types/sdk/bus/config.d.ts +274 -0
  95. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  96. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  97. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  98. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  99. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  100. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  101. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  102. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  103. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  104. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  105. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  106. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  107. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  108. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  109. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  110. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  111. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  112. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  113. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  114. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  115. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  118. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  119. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  120. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  121. package/dist/types/sdk/cli/index.d.ts +1 -0
  122. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  123. package/dist/types/sdk/client/client.d.ts +1 -0
  124. package/dist/types/sdk/client/discovery.d.ts +27 -0
  125. package/dist/types/sdk/client/index.d.ts +2 -0
  126. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  127. package/dist/types/sdk/host/control/index.d.ts +2 -0
  128. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  129. package/dist/types/sdk/host/events.d.ts +35 -0
  130. package/dist/types/sdk/host/host.d.ts +35 -0
  131. package/dist/types/sdk/host/index.d.ts +4 -0
  132. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  133. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  134. package/dist/types/sdk/host/query/index.d.ts +3 -0
  135. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  136. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  137. package/dist/types/sdk/host/types.d.ts +32 -0
  138. package/dist/types/sdk/index.d.ts +6 -0
  139. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  140. package/dist/types/sdk/mcp/index.d.ts +1 -0
  141. package/dist/types/sdk/mcp/server.d.ts +37 -0
  142. package/dist/types/sdk/models.d.ts +44 -0
  143. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  144. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  145. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  146. package/dist/types/sdk/startup-capability.d.ts +50 -0
  147. package/dist/types/session/agent-session.d.ts +114 -21
  148. package/dist/types/session/default-model-selection.d.ts +25 -0
  149. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  150. package/dist/types/session/session-manager.d.ts +58 -1
  151. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  152. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  153. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  154. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  155. package/dist/types/tools/browser/launch.d.ts +22 -0
  156. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  157. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  158. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  159. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  160. package/dist/types/tools/browser/registry.d.ts +19 -0
  161. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  162. package/dist/types/tools/index.d.ts +8 -8
  163. package/package.json +34 -13
  164. package/scripts/build-sdk-package-smoke.ts +94 -0
  165. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  166. package/scripts/compile-args.ts +4 -2
  167. package/scripts/g005-daemon-smoke.ts +4 -5
  168. package/scripts/g011-daemon-path-smoke.ts +5 -5
  169. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  170. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  171. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  172. package/scripts/manifest-schema.ts +124 -0
  173. package/scripts/run-test-manifest.ts +153 -0
  174. package/scripts/run-threat-model-check.ts +157 -0
  175. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  176. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  177. package/src/append-only-mode.ts +1 -1
  178. package/src/cli/args.ts +43 -12
  179. package/src/cli/auth-gateway-cli.ts +2 -2
  180. package/src/cli/config-cli.ts +2 -1
  181. package/src/cli/daemon-cli.ts +63 -14
  182. package/src/cli/list-models.ts +1 -1
  183. package/src/cli/notify-cli.ts +288 -286
  184. package/src/cli.ts +21 -2
  185. package/src/commands/daemon.ts +50 -6
  186. package/src/commands/harness.ts +93 -36
  187. package/src/commands/launch.ts +5 -2
  188. package/src/commands/mcp-serve.ts +19 -12
  189. package/src/commands/notify.ts +36 -3
  190. package/src/commands/sdk.ts +426 -0
  191. package/src/commit/agentic/agent.ts +1 -0
  192. package/src/config/atomic-yaml-patch.ts +423 -0
  193. package/src/config/model-profile-activation.ts +240 -89
  194. package/src/config/model-profiles.ts +18 -15
  195. package/src/config/model-registry.ts +51 -26
  196. package/src/config/model-resolver.ts +138 -51
  197. package/src/config/model-selector-value.ts +50 -0
  198. package/src/config/models-config-schema.ts +14 -21
  199. package/src/config/settings-schema.ts +128 -10
  200. package/src/config/settings.ts +1120 -158
  201. package/src/coordinator-mcp/model-preset.ts +74 -20
  202. package/src/coordinator-mcp/server.ts +1597 -3052
  203. package/src/daemon/builtin.ts +8 -5
  204. package/src/daemon/control-types.ts +1 -1
  205. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  206. package/src/discovery/mcp-json.ts +327 -20
  207. package/src/extensibility/custom-tools/types.ts +1 -1
  208. package/src/extensibility/extensions/compact-handler.ts +3 -3
  209. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  210. package/src/extensibility/extensions/loader.ts +69 -5
  211. package/src/extensibility/extensions/runner.ts +112 -4
  212. package/src/extensibility/extensions/types.ts +176 -17
  213. package/src/extensibility/hooks/types.ts +1 -1
  214. package/src/gjc-runtime/launch-tmux.ts +170 -86
  215. package/src/gjc-runtime/psmux-detect.ts +82 -4
  216. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  217. package/src/gjc-runtime/team-runtime.ts +54 -35
  218. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  219. package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
  220. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  221. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  222. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  223. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  224. package/src/harness-control-plane/operate.ts +9 -9
  225. package/src/harness-control-plane/owner.ts +283 -39
  226. package/src/harness-control-plane/receipts.ts +0 -1
  227. package/src/harness-control-plane/sdk-transport.ts +395 -0
  228. package/src/harness-control-plane/session-transport.ts +94 -0
  229. package/src/harness-control-plane/types.ts +1 -1
  230. package/src/internal-urls/docs-index.generated.ts +34 -35
  231. package/src/lsp/client.ts +42 -6
  232. package/src/lsp/index.ts +2 -2
  233. package/src/main.ts +299 -204
  234. package/src/modes/DESIGN.md +258 -0
  235. package/src/modes/acp/acp-agent.ts +1228 -2612
  236. package/src/modes/acp/acp-client-bridge.ts +2 -20
  237. package/src/modes/acp/acp-event-mapper.ts +18 -2
  238. package/src/modes/acp/acp-mode.ts +8 -36
  239. package/src/modes/acp/permission-mode.ts +25 -0
  240. package/src/modes/acp/startup-options.ts +6 -0
  241. package/src/modes/components/agent-dashboard.ts +37 -17
  242. package/src/modes/components/model-selector.ts +93 -35
  243. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  244. package/src/modes/components/settings-selector.ts +60 -11
  245. package/src/modes/components/welcome.ts +4 -4
  246. package/src/modes/controllers/command-controller.ts +1 -2
  247. package/src/modes/controllers/event-controller.ts +11 -16
  248. package/src/modes/controllers/extension-ui-controller.ts +348 -4
  249. package/src/modes/controllers/selector-controller.ts +674 -36
  250. package/src/modes/index.ts +0 -22
  251. package/src/modes/interactive-mode.ts +59 -20
  252. package/src/modes/runtime-init.ts +298 -6
  253. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  254. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  255. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  256. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  257. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  258. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  259. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  260. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  261. package/src/modes/types.ts +5 -0
  262. package/src/runtime-mcp/client.ts +94 -19
  263. package/src/runtime-mcp/config.ts +27 -15
  264. package/src/runtime-mcp/manager.ts +343 -105
  265. package/src/runtime-mcp/oauth-flow.ts +42 -12
  266. package/src/runtime-mcp/transports/http.ts +49 -19
  267. package/src/runtime-mcp/transports/stdio.ts +47 -28
  268. package/src/runtime-mcp/types.ts +10 -0
  269. package/src/sdk/acp/adapter.ts +418 -0
  270. package/src/sdk/acp/index.ts +2 -0
  271. package/src/sdk/broker/broker.ts +642 -0
  272. package/src/sdk/broker/discovery.ts +94 -0
  273. package/src/sdk/broker/ensure.ts +249 -0
  274. package/src/sdk/broker/identity.ts +42 -0
  275. package/src/sdk/broker/index.ts +8 -0
  276. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  277. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  278. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  279. package/src/sdk/broker/lifecycle.ts +2157 -0
  280. package/src/sdk/broker/process-incarnation.ts +159 -0
  281. package/src/sdk/broker/runtime.ts +164 -0
  282. package/src/sdk/broker/session-index.ts +318 -0
  283. package/src/sdk/broker/state-version.ts +23 -0
  284. package/src/sdk/broker/transport.ts +125 -0
  285. package/src/sdk/bus/chat-command-policy.ts +107 -0
  286. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  287. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  288. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  289. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  290. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  291. package/src/sdk/bus/config.ts +433 -0
  292. package/src/sdk/bus/conversation-store.ts +391 -0
  293. package/src/sdk/bus/discord-conversation.ts +85 -0
  294. package/src/sdk/bus/discord-daemon.ts +2275 -0
  295. package/src/sdk/bus/discord-live-provider.ts +521 -0
  296. package/src/sdk/bus/discord-provider.ts +56 -0
  297. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  298. package/src/sdk/bus/index.ts +3943 -0
  299. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  300. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  301. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  302. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  303. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  304. package/src/sdk/bus/natives-augment.d.ts +38 -0
  305. package/src/sdk/bus/notification-orchestration.ts +535 -0
  306. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  307. package/src/sdk/bus/session-control.ts +333 -0
  308. package/src/sdk/bus/slack-conversation.ts +74 -0
  309. package/src/sdk/bus/slack-daemon.ts +2144 -0
  310. package/src/sdk/bus/slack-live-provider.ts +380 -0
  311. package/src/sdk/bus/slack-provider.ts +76 -0
  312. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  313. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  314. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  315. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  316. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  317. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  318. package/src/sdk/bus/telegram-setup.ts +663 -0
  319. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  320. package/src/sdk/cli/index.ts +1 -0
  321. package/src/sdk/cli/session-cli.ts +275 -0
  322. package/src/sdk/client/client.ts +1 -0
  323. package/src/sdk/client/discovery.ts +108 -0
  324. package/src/sdk/client/index.ts +2 -0
  325. package/src/sdk/host/control/dispatch.ts +367 -0
  326. package/src/sdk/host/control/index.ts +10 -0
  327. package/src/sdk/host/control/operations.ts +63 -0
  328. package/src/sdk/host/events.ts +91 -0
  329. package/src/sdk/host/host.ts +296 -0
  330. package/src/sdk/host/index.ts +4 -0
  331. package/src/sdk/host/query/cursor.ts +189 -0
  332. package/src/sdk/host/query/handlers.ts +533 -0
  333. package/src/sdk/host/query/index.ts +3 -0
  334. package/src/sdk/host/query/revision-store.ts +1126 -0
  335. package/src/sdk/host/reverse-leases.ts +325 -0
  336. package/src/sdk/host/types.ts +29 -0
  337. package/src/sdk/index.ts +13 -0
  338. package/src/sdk/lifecycle-session.ts +39 -0
  339. package/src/sdk/mcp/index.ts +1 -0
  340. package/src/sdk/mcp/server.ts +332 -0
  341. package/src/sdk/models.ts +168 -0
  342. package/src/sdk/protocol/adapter-validation.ts +48 -0
  343. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  344. package/src/sdk/protocol/operation-registry.ts +312 -0
  345. package/src/{sdk.ts → sdk/session.ts} +339 -212
  346. package/src/sdk/startup-capability.ts +189 -0
  347. package/src/session/agent-session.ts +2453 -894
  348. package/src/session/default-model-selection.ts +93 -0
  349. package/src/session/fallback-chain-controller.ts +136 -0
  350. package/src/session/session-manager.ts +438 -11
  351. package/src/session/session-storage.ts +8 -1
  352. package/src/setup/credential-auto-import.ts +290 -35
  353. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  354. package/src/slash-commands/builtin-registry.ts +2 -1
  355. package/src/task/executor.ts +62 -13
  356. package/src/tools/ask-answer-registry.ts +1 -1
  357. package/src/tools/ask.ts +13 -8
  358. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  359. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  360. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  361. package/src/tools/browser/launch.ts +124 -19
  362. package/src/tools/browser/profile-discovery.ts +63 -0
  363. package/src/tools/browser/profile-posture.ts +59 -0
  364. package/src/tools/browser/profile-reuse.ts +102 -0
  365. package/src/tools/browser/profile-warmup.ts +109 -0
  366. package/src/tools/browser/registry.ts +87 -11
  367. package/src/tools/browser/tab-protocol.ts +1 -0
  368. package/src/tools/browser/tab-supervisor.ts +1 -0
  369. package/src/tools/browser/tab-worker.ts +1 -1
  370. package/src/tools/browser.ts +6 -0
  371. package/src/tools/index.ts +8 -8
  372. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  373. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  374. package/src/tools/telegram-send.ts +2 -2
  375. package/vendor/insane-search/MANIFEST.json +2 -1
  376. package/vendor/insane-search/engine/bias_check.py +4 -1
  377. package/vendor/insane-search/engine/phase0.py +26 -1
  378. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  379. package/dist/types/modes/bridge/auth.d.ts +0 -12
  380. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  381. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  382. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  383. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  384. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  385. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  386. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  387. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  388. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  389. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  390. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  391. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  392. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  393. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  394. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  395. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  396. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  397. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  398. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  399. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  400. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  401. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  402. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  403. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  404. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  405. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  406. package/dist/types/notifications/config.d.ts +0 -132
  407. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  408. package/src/modes/bridge/auth.ts +0 -41
  409. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  410. package/src/modes/bridge/bridge-mode.ts +0 -675
  411. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  412. package/src/modes/bridge/event-stream.ts +0 -70
  413. package/src/modes/rpc/host-tools.ts +0 -1
  414. package/src/modes/rpc/host-uris.ts +0 -1
  415. package/src/modes/rpc/rpc-client.ts +0 -1166
  416. package/src/modes/rpc/rpc-mode.ts +0 -1029
  417. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  418. package/src/modes/rpc/rpc-types.ts +0 -637
  419. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  420. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  421. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  422. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  423. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  424. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  425. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  426. package/src/modes/shared/agent-wire/responses.ts +0 -17
  427. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  428. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  429. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  430. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  431. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  432. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  433. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  434. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  435. package/src/notifications/config.ts +0 -219
  436. package/src/notifications/index.ts +0 -1835
  437. package/src/notifications/telegram-daemon-cli.ts +0 -243
  438. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  439. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  440. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  441. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  442. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  443. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  444. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  445. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  446. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  447. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  448. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  453. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  454. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  455. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  456. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  457. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  458. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  459. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  460. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  461. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -8,7 +8,7 @@
8
8
  * effect-injected so the decision logic is unit-testable and the same code path
9
9
  * is exercised end-to-end by a real-tmux integration smoke.
10
10
  *
11
- * The Rust control ingress (crates/gjc-notifications control server) has already
11
+ * The Rust control ingress (crates/gjc-sdk control server) has already
12
12
  * authenticated frames before they reach here; this module never sees or logs
13
13
  * the raw control token.
14
14
  */
@@ -37,6 +37,7 @@ export interface LedgerEntry {
37
37
  /** Close effect outcome: whether the tmux process is confirmed gone. */
38
38
  processGone?: boolean;
39
39
  reason?: LifecycleErrorReason;
40
+ resumeMode?: ResumeEffectResult["mode"];
40
41
  }
41
42
 
42
43
  /** The full on-disk ledger document. */
@@ -52,8 +53,9 @@ export interface LedgerStore {
52
53
  write(doc: LedgerDoc): Promise<void>;
53
54
  }
54
55
 
55
- /** One audit line. Tokens and raw prompts are NEVER included. */
56
+ /** Redacted audit-v2 event. */
56
57
  export interface AuditEvent {
58
+ schemaVersion: 2;
57
59
  ts: string;
58
60
  event:
59
61
  | "accepted"
@@ -65,19 +67,13 @@ export interface AuditEvent {
65
67
  | "success"
66
68
  | "failure"
67
69
  | "terminal_uncertain";
68
- chatId: string;
70
+ chatRef: string;
69
71
  updateId: number;
70
- requestId: string;
71
- requestHash: string;
72
+ requestRef: string;
72
73
  verb: SessionLifecycleRequest["type"];
73
- targetSummary: Record<string, unknown>;
74
- sessionId?: string;
75
- tmuxSession?: string;
74
+ targetKind: CanonicalTargetKind;
75
+ targetRef: string;
76
76
  reason?: LifecycleErrorReason;
77
- /** Prompt byte length only (never the prompt text). */
78
- promptBytes?: number;
79
- /** Prompt content hash only (never the prompt text). */
80
- promptHash?: string;
81
77
  }
82
78
 
83
79
  export interface CreateEffectResult {
@@ -96,13 +92,21 @@ export interface ResumeEffectResult extends CreateEffectResult {
96
92
  export interface OrchestratorDeps {
97
93
  /** The single paired chat id. Anything else is rejected before parsing. */
98
94
  pairedChatId: string;
95
+ /** In-memory, derived 32-byte audit-v2 HMAC key. */
96
+ auditRedactionKey: Uint8Array;
99
97
  now: () => number;
100
98
  store: LedgerStore;
101
99
  audit: (event: AuditEvent) => Promise<void> | void;
100
+ /** Resolves the returned tmux provider once per request for psmux preflight. */
101
+ isPsmuxProvider: () => boolean;
102
102
  /** Per-chat create rate limiter: returns true when allowed. */
103
103
  allowCreate: (chatId: string, nowMs: number) => boolean;
104
- /** Persist the once-consumed 0600 startup-prompt file; returns its ref. */
105
- writeStartupPrompt: (requestId: string, prompt: string | undefined) => Promise<string | undefined>;
104
+ /** Persist the once-consumed 0600 startup-prompt file after durably recording its ref. */
105
+ writeStartupPrompt: (
106
+ requestId: string,
107
+ prompt: string | undefined,
108
+ persistRef: (ref: string) => Promise<void>,
109
+ ) => Promise<string | undefined>;
106
110
  /** Spawn a session for a create/cold-restart. */
107
111
  spawnCreate: (
108
112
  frame: SessionCreateFrame,
@@ -117,11 +121,73 @@ export interface OrchestratorDeps {
117
121
  sessionIdOrPrefix: string;
118
122
  path?: string;
119
123
  }) => Promise<ResumeEffectResult | { ambiguous: ResumeCandidate[] } | { notFound: true }>;
120
- newLifecycleRequestId: () => string;
121
- newSessionId: () => string;
122
124
  }
123
125
 
124
- /** A redaction-safe summary of a request target (never includes the token). */
126
+ export type CanonicalTargetKind = "existing_path" | "worktree" | "plain_dir" | "session_close" | "session_resume";
127
+
128
+ function isUnicodeScalarString(value: string): boolean {
129
+ for (let index = 0; index < value.length; index++) {
130
+ const code = value.charCodeAt(index);
131
+ if (code >= 0xd800 && code <= 0xdbff) {
132
+ if (index + 1 >= value.length) return false;
133
+ const next = value.charCodeAt(++index);
134
+ if (next < 0xdc00 || next > 0xdfff) return false;
135
+ } else if (code >= 0xdc00 && code <= 0xdfff) {
136
+ return false;
137
+ }
138
+ }
139
+ return true;
140
+ }
141
+
142
+ function jsonString(value: string): string {
143
+ if (!isUnicodeScalarString(value)) throw new Error("invalid_target");
144
+ return JSON.stringify(value);
145
+ }
146
+
147
+ export function canonicalTarget(frame: SessionLifecycleRequest): string {
148
+ switch (frame.type) {
149
+ case "session_create":
150
+ switch (frame.target.kind) {
151
+ case "existing_path":
152
+ return `{"kind":"existing_path","path":${jsonString(frame.target.path)}}`;
153
+ case "worktree":
154
+ return `{"kind":"worktree","repo":${jsonString(frame.target.repo)},"branch":${jsonString(frame.target.branch)}}`;
155
+ case "plain_dir":
156
+ return `{"kind":"plain_dir","path":${jsonString(frame.target.path)}}`;
157
+ }
158
+ throw new Error("invalid_target");
159
+ case "session_close":
160
+ return `{"kind":"session_close","sessionId":${jsonString(frame.target.sessionId)},"tmuxSession":${frame.target.tmuxSession === undefined ? "null" : jsonString(frame.target.tmuxSession)},"sessionStateFile":${frame.target.sessionStateFile === undefined ? "null" : jsonString(frame.target.sessionStateFile)}}`;
161
+ case "session_resume":
162
+ return `{"kind":"session_resume","sessionIdOrPrefix":${jsonString(frame.target.sessionIdOrPrefix)},"path":${frame.target.path === undefined ? "null" : jsonString(frame.target.path)}}`;
163
+ }
164
+ }
165
+
166
+ export function canonicalRequest(frame: SessionLifecycleRequest): string {
167
+ const target = canonicalTarget(frame);
168
+ const startupPromptRef =
169
+ frame.type === "session_create" && frame.startupPromptRef !== undefined
170
+ ? jsonString(frame.startupPromptRef)
171
+ : "null";
172
+ const modelPreset =
173
+ frame.type === "session_create" && frame.modelPreset !== undefined ? jsonString(frame.modelPreset) : "null";
174
+ const force = frame.type === "session_close" ? (frame.force === true ? "true" : "false") : "null";
175
+ return `{"type":${jsonString(frame.type)},"target":${target},"startupPromptRef":${startupPromptRef},"modelPreset":${modelPreset},"force":${force}}`;
176
+ }
177
+
178
+ function requestHashFromCanonical(canonical: string): string {
179
+ return crypto.createHash("sha256").update(canonical, "utf8").digest("hex");
180
+ }
181
+
182
+ export function requestHash(frame: SessionLifecycleRequest): string {
183
+ return requestHashFromCanonical(canonicalRequest(frame));
184
+ }
185
+
186
+ export function auditRedactionRef(key: Uint8Array, domain: string, value: string): string {
187
+ if (key.byteLength !== 32) throw new Error("invalid_audit_redaction_key");
188
+ return crypto.createHmac("sha256", key).update(domain, "utf8").update(value, "utf8").digest("hex");
189
+ }
190
+
125
191
  export function summarizeTarget(frame: SessionLifecycleRequest): Record<string, unknown> {
126
192
  switch (frame.type) {
127
193
  case "session_create":
@@ -135,20 +201,6 @@ export function summarizeTarget(frame: SessionLifecycleRequest): Record<string,
135
201
  }
136
202
  }
137
203
 
138
- /**
139
- * Stable request hash over the meaningful (non-token) request content. Used to
140
- * detect a duplicate update id reused with a DIFFERENT body (conflict).
141
- */
142
- export function requestHash(frame: SessionLifecycleRequest): string {
143
- const canonical = JSON.stringify({
144
- type: frame.type,
145
- target: summarizeTarget(frame),
146
- startupPromptRef: "startupPromptRef" in frame ? frame.startupPromptRef : undefined,
147
- force: frame.type === "session_close" ? frame.force === true : undefined,
148
- });
149
- return crypto.createHash("sha256").update(canonical).digest("hex");
150
- }
151
-
152
204
  export function ledgerKey(chatId: string, updateId: number): string {
153
205
  return `${chatId}:${updateId}`;
154
206
  }
@@ -193,18 +245,34 @@ export async function handleLifecycleRequest(
193
245
  deps: OrchestratorDeps,
194
246
  ): Promise<LifecycleOutcome> {
195
247
  const nowMs = deps.now();
196
- const hash = requestHash(frame);
248
+ let hash: string;
249
+ let canonicalRequestBytes: string;
250
+ let canonicalTargetBytes: string;
251
+ try {
252
+ canonicalRequestBytes = canonicalRequest(frame);
253
+ canonicalTargetBytes = canonicalTarget(frame);
254
+ hash = requestHashFromCanonical(canonicalRequestBytes);
255
+ } catch {
256
+ return { status: "error", reason: "invalid_target", message: "invalid lifecycle target" };
257
+ }
258
+ if (deps.auditRedactionKey.byteLength !== 32) throw new Error("invalid_audit_redaction_key");
197
259
  const key = ledgerKey(frame.chatId, frame.updateId);
198
260
  const targetSummary = summarizeTarget(frame);
199
-
261
+ const targetKind: CanonicalTargetKind =
262
+ frame.type === "session_create"
263
+ ? frame.target.kind
264
+ : frame.type === "session_close"
265
+ ? "session_close"
266
+ : "session_resume";
200
267
  const baseAudit = {
268
+ schemaVersion: 2 as const,
201
269
  ts: new Date(nowMs).toISOString(),
202
- chatId: frame.chatId,
270
+ chatRef: auditRedactionRef(deps.auditRedactionKey, "gjc.lifecycle.audit.v2.chat\0", frame.chatId),
203
271
  updateId: frame.updateId,
204
- requestId: frame.requestId,
205
- requestHash: hash,
272
+ requestRef: auditRedactionRef(deps.auditRedactionKey, "gjc.lifecycle.audit.v2.request\0", canonicalRequestBytes),
206
273
  verb: frame.type,
207
- targetSummary,
274
+ targetKind,
275
+ targetRef: auditRedactionRef(deps.auditRedactionKey, "gjc.lifecycle.audit.v2.target\0", canonicalTargetBytes),
208
276
  } as const;
209
277
 
210
278
  // 1. Strict paired-chat gating — BEFORE touching paths/processes or the ledger.
@@ -212,8 +280,34 @@ export async function handleLifecycleRequest(
212
280
  await deps.audit({ ...baseAudit, event: "rejected", reason: "unauthorized" });
213
281
  return { status: "error", reason: "unauthorized", message: "chat not paired" };
214
282
  }
283
+ if (frame.type === "session_close" && frame.force !== true) {
284
+ await deps.audit({ ...baseAudit, event: "rejected", reason: "invalid_target" });
285
+ return {
286
+ status: "error",
287
+ reason: "invalid_target",
288
+ message: "session_close requires force=true; graceful close is not supported",
289
+ };
290
+ }
291
+ const suppliedStartupPromptRef =
292
+ frame.type === "session_create" || frame.type === "session_resume" ? frame.startupPromptRef : undefined;
293
+ if (suppliedStartupPromptRef !== undefined) {
294
+ return {
295
+ status: "error",
296
+ reason: "invalid_target",
297
+ message: "startup prompt capability transport is unavailable; retry without a startup prompt",
298
+ };
299
+ }
300
+ if (deps.isPsmuxProvider()) {
301
+ await deps.audit({ ...baseAudit, event: "rejected", reason: "unsupported_platform" });
302
+ return {
303
+ status: "error",
304
+ reason: "unsupported_platform",
305
+ message:
306
+ "Remote session lifecycle is unavailable on this psmux host because GJC cannot prove immutable session identity. No lifecycle action was performed. Use a local GJC terminal with a supported tmux provider.",
307
+ };
308
+ }
215
309
 
216
- // 2. Durable idempotency.
310
+ // 4. Durable idempotency.
217
311
  const doc = await deps.store.read();
218
312
  const dup = classifyDuplicate(doc.entries[key], hash);
219
313
  switch (dup.kind) {
@@ -221,19 +315,20 @@ export async function handleLifecycleRequest(
221
315
  await deps.audit({ ...baseAudit, event: "rejected", reason: "duplicate_conflict" });
222
316
  return { status: "error", reason: "duplicate_conflict", message: "update id reused with different body" };
223
317
  case "reack_success":
224
- await deps.audit({ ...baseAudit, event: "duplicate_reack", sessionId: dup.entry.sessionId });
225
- return { status: "ok", entry: dup.entry };
318
+ await deps.audit({ ...baseAudit, event: "duplicate_reack" });
319
+ return { status: "ok", entry: dup.entry, ...(dup.entry.resumeMode ? { mode: dup.entry.resumeMode } : {}) };
226
320
  case "reack_failure":
321
+ if (dup.entry.reason === undefined) throw new Error("invalid lifecycle failure ledger entry");
227
322
  await deps.audit({ ...baseAudit, event: "duplicate_reack", reason: dup.entry.reason });
228
323
  return {
229
324
  status: "error",
230
- reason: dup.entry.reason ?? "terminal_uncertain",
325
+ reason: dup.entry.reason,
231
326
  message: "previously failed; send a new update to retry",
232
327
  };
233
328
  case "in_progress":
234
329
  // A retry arrived while the first attempt is still running: never
235
330
  // respawn — report pending so the caller waits for the original.
236
- await deps.audit({ ...baseAudit, event: "recovered_in_progress", sessionId: dup.entry.intendedSessionId });
331
+ await deps.audit({ ...baseAudit, event: "recovered_in_progress" });
237
332
  return { status: "pending", entry: dup.entry };
238
333
  case "terminal_uncertain":
239
334
  await deps.audit({ ...baseAudit, event: "recovered_in_progress", reason: "terminal_uncertain" });
@@ -246,50 +341,44 @@ export async function handleLifecycleRequest(
246
341
  break;
247
342
  }
248
343
 
249
- // 3. Per-chat create rate limit (create only).
344
+ // 5. Per-chat create rate limit (create only).
250
345
  if (frame.type === "session_create" && !deps.allowCreate(frame.chatId, nowMs)) {
251
346
  await deps.audit({ ...baseAudit, event: "rate_limited", reason: "rate_limited" });
252
347
  return { status: "error", reason: "rate_limited", message: "create rate limit exceeded" };
253
348
  }
254
349
 
255
- // 4. Close is intentionally force-only until a graceful close contract exists.
256
- if (frame.type === "session_close" && frame.force !== true) {
257
- await deps.audit({ ...baseAudit, event: "rejected", reason: "invalid_target" });
258
- return {
259
- status: "error",
260
- reason: "invalid_target",
261
- message: "session_close requires force=true; graceful close is not supported",
262
- };
263
- }
264
-
265
- // 5. Preallocate ids + write in_progress (fsynced) BEFORE any spawn.
266
- const lifecycleRequestId = frame.type === "session_create" ? frame.lifecycleRequestId : deps.newLifecycleRequestId();
267
- const intendedSessionId =
268
- frame.type === "session_create" ? frame.intendedSessionId || deps.newSessionId() : deps.newSessionId();
350
+ // 6. Persist immutable create ids + write in_progress (fsynced) BEFORE any spawn.
351
+ if (frame.type === "session_create" && (!frame.lifecycleRequestId || !frame.intendedSessionId))
352
+ return { status: "error", reason: "invalid_target", message: "create lifecycle ids must be non-empty" };
269
353
  let startupPromptRef: string | undefined;
270
- let promptBytes: number | undefined;
271
- let promptHash: string | undefined;
272
354
 
273
355
  const entry: LedgerEntry = {
274
356
  requestHash: hash,
275
357
  state: "in_progress",
276
358
  requestId: frame.requestId,
277
359
  verb: frame.type,
278
- intendedSessionId,
360
+ intendedSessionId: frame.type === "session_create" ? frame.intendedSessionId : undefined,
279
361
  createdAt: nowMs,
280
362
  updatedAt: nowMs,
281
363
  targetSummary,
282
364
  };
283
365
  doc.entries[key] = entry;
284
366
  await deps.store.write(doc);
285
- await deps.audit({ ...baseAudit, event: "accepted", sessionId: intendedSessionId });
367
+ await deps.audit({ ...baseAudit, event: "accepted" });
286
368
 
287
369
  try {
288
370
  if (frame.type === "session_create") {
289
- startupPromptRef = await deps.writeStartupPrompt(frame.requestId, undefined);
371
+ startupPromptRef = await deps.writeStartupPrompt(frame.requestId, frame.startupPromptRef, async ref => {
372
+ entry.startupPromptRef = ref;
373
+ await deps.store.write(doc);
374
+ });
290
375
  entry.startupPromptRef = startupPromptRef;
291
- await deps.audit({ ...baseAudit, event: "spawn_started", sessionId: intendedSessionId });
292
- const result = await deps.spawnCreate(frame, { lifecycleRequestId, intendedSessionId, startupPromptRef });
376
+ await deps.audit({ ...baseAudit, event: "spawn_started" });
377
+ const result = await deps.spawnCreate(frame, {
378
+ lifecycleRequestId: frame.lifecycleRequestId,
379
+ intendedSessionId: frame.intendedSessionId,
380
+ startupPromptRef,
381
+ });
293
382
  Object.assign(entry, {
294
383
  state: "success",
295
384
  updatedAt: deps.now(),
@@ -299,14 +388,7 @@ export async function handleLifecycleRequest(
299
388
  endpointUrl: result.endpointUrl,
300
389
  });
301
390
  await deps.store.write(doc);
302
- await deps.audit({
303
- ...baseAudit,
304
- event: "success",
305
- sessionId: result.sessionId,
306
- tmuxSession: result.tmuxSession,
307
- promptBytes,
308
- promptHash,
309
- });
391
+ await deps.audit({ ...baseAudit, event: "success" });
310
392
  return { status: "ok", entry };
311
393
  }
312
394
 
@@ -320,7 +402,7 @@ export async function handleLifecycleRequest(
320
402
  processGone: closed.processGone,
321
403
  });
322
404
  await deps.store.write(doc);
323
- await deps.audit({ ...baseAudit, event: "success", sessionId: frame.target.sessionId });
405
+ await deps.audit({ ...baseAudit, event: "success" });
324
406
  return { status: "ok", entry };
325
407
  }
326
408
 
@@ -349,11 +431,16 @@ export async function handleLifecycleRequest(
349
431
  sessionId: resumed.sessionId,
350
432
  tmuxSession: resumed.tmuxSession,
351
433
  endpointUrl: resumed.endpointUrl,
434
+ resumeMode: resumed.mode,
352
435
  });
353
436
  await deps.store.write(doc);
354
- await deps.audit({ ...baseAudit, event: "success", sessionId: resumed.sessionId });
437
+ await deps.audit({ ...baseAudit, event: "success" });
355
438
  return { status: "ok", entry, mode: resumed.mode };
356
439
  } catch (err) {
440
+ if (typeof err === "object" && err !== null && "startupPromptRef" in err) {
441
+ const failedPromptRef = Reflect.get(err, "startupPromptRef");
442
+ if (typeof failedPromptRef === "string") entry.startupPromptRef = failedPromptRef;
443
+ }
357
444
  // A side effect may have occurred; do not repeat it automatically. Mark
358
445
  // terminal-uncertain so a retry reconciles instead of duplicating work.
359
446
  let reason: LifecycleErrorReason = "terminal_uncertain";
@@ -1,5 +1,5 @@
1
1
  import * as path from "node:path";
2
- import type { Settings } from "../config/settings";
2
+ import type { Settings } from "../../config/settings";
3
3
  import { RateLimitPool } from "./rate-limit-pool";
4
4
  import {
5
5
  CLIENT_PING_PONG_CAPABILITY,
@@ -46,7 +46,7 @@ export abstract class ManagedNotificationDaemon {
46
46
  async scanRoots(): Promise<void> {
47
47
  const rootState = await this.readRoots();
48
48
  for (const root of rootState) {
49
- const dir = path.join(root, "notifications");
49
+ const dir = path.join(root, "sdk");
50
50
  let files: string[];
51
51
  try {
52
52
  files = await this.opts.fs.readdir(dir);
@@ -0,0 +1,42 @@
1
+ const REQUIRED_WORKFLOW_ARBITRATION_METHODS = ["registerArbitratedAsk", "retireIfUnclaimed"] as const;
2
+
3
+ export class NativeRuntimeCompatibilityError extends Error {
4
+ readonly code = "native_runtime_incompatible";
5
+ readonly retryable = false;
6
+
7
+ constructor(
8
+ readonly runtimeVersion: string,
9
+ readonly nativeVersion: string,
10
+ readonly workflowArbitrationAvailable: boolean,
11
+ ) {
12
+ super(
13
+ `Incompatible @gajae-code/natives for @gajae-code/coding-agent@${runtimeVersion}: ` +
14
+ `loaded native version is ${nativeVersion}, and required workflow arbitration methods are ` +
15
+ `${workflowArbitrationAvailable ? "available" : "missing"}. ` +
16
+ `Reinstall matching @gajae-code/coding-agent and @gajae-code/natives packages.`,
17
+ );
18
+ this.name = "NativeRuntimeCompatibilityError";
19
+ }
20
+ }
21
+
22
+ function hasWorkflowArbitrationMethods(notificationServer: unknown): boolean {
23
+ if (!notificationServer || (typeof notificationServer !== "object" && typeof notificationServer !== "function"))
24
+ return false;
25
+ return REQUIRED_WORKFLOW_ARBITRATION_METHODS.every(
26
+ method => typeof (notificationServer as Record<string, unknown>)[method] === "function",
27
+ );
28
+ }
29
+
30
+ export function assertNativeRuntimeCompatibility(input: {
31
+ runtimeVersion: string;
32
+ nativeVersion: string;
33
+ notificationServer: unknown;
34
+ }): void {
35
+ const workflowArbitrationAvailable = hasWorkflowArbitrationMethods(input.notificationServer);
36
+ if (input.runtimeVersion !== input.nativeVersion || !workflowArbitrationAvailable)
37
+ throw new NativeRuntimeCompatibilityError(
38
+ input.runtimeVersion,
39
+ input.nativeVersion,
40
+ workflowArbitrationAvailable,
41
+ );
42
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Worktree-local module augmentation for the v3 SDK connection lane added to
3
+ * the pi-natives NotificationServer in this branch (onSdkFrame / sendTo /
4
+ * onConnectionClose). Linked sibling checkouts sharing the root node_modules
5
+ * can dedupe `@gajae-code/natives` declarations by package ID to an older
6
+ * generated file; this augmentation guarantees the new members are visible and
7
+ * is a harmless re-declaration when the resolved declarations already have
8
+ * them.
9
+ */
10
+ import "@gajae-code/natives";
11
+
12
+ declare module "@gajae-code/natives" {
13
+ interface SdkFrameEvent {
14
+ connectionId: string;
15
+ json: string;
16
+ }
17
+ interface PresentationLease {
18
+ actionId: string;
19
+ registrationEpoch: number;
20
+ }
21
+ interface RetireIfUnclaimedResult {
22
+ status: "retired" | "already_terminal" | "claimed" | "stale";
23
+ }
24
+ interface NotificationServer {
25
+ /** Register the raw v3 SDK frame callback. Must be called before start. */
26
+ onSdkFrame(callback: (err: null | Error, frame: SdkFrameEvent) => void): void;
27
+ /** Register the connection-close callback. Must be called before start. */
28
+ onConnectionClose(callback: (err: null | Error, connectionId: string) => void): void;
29
+ /** Directed send of a JSON text frame to one connection. */
30
+ sendTo(connectionId: string, json: string): void;
31
+ /** Register a correlated workflow-gate action_needed frame. */
32
+ registerWorkflowGateAsk(workflowJson: string, repliable: boolean): void;
33
+ /** Atomically register the single active arbitrated action and return its private lease. */
34
+ registerArbitratedAsk(actionJson: string, repliable: boolean): PresentationLease;
35
+ /** Retire an exact private lease unless a generic reply has already claimed it. */
36
+ retireIfUnclaimed(lease: PresentationLease): RetireIfUnclaimedResult;
37
+ }
38
+ }