@gajae-code/coding-agent 0.10.2 → 0.11.1

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 (476) hide show
  1. package/CHANGELOG.md +58 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/async/job-manager.d.ts +46 -7
  4. package/dist/types/cli/args.d.ts +4 -5
  5. package/dist/types/cli/daemon-cli.d.ts +12 -1
  6. package/dist/types/cli/notify-cli.d.ts +21 -1
  7. package/dist/types/cli.d.ts +3 -0
  8. package/dist/types/commands/daemon.d.ts +39 -0
  9. package/dist/types/commands/launch.d.ts +3 -0
  10. package/dist/types/commands/notify.d.ts +28 -1
  11. package/dist/types/commands/sdk.d.ts +33 -0
  12. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  13. package/dist/types/config/model-profile-activation.d.ts +35 -15
  14. package/dist/types/config/model-profiles.d.ts +11 -5
  15. package/dist/types/config/model-registry.d.ts +3 -3
  16. package/dist/types/config/model-resolver.d.ts +39 -6
  17. package/dist/types/config/model-selector-value.d.ts +17 -0
  18. package/dist/types/config/models-config-schema.d.ts +10 -6
  19. package/dist/types/config/settings-schema.d.ts +133 -6
  20. package/dist/types/config/settings.d.ts +63 -35
  21. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  22. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  23. package/dist/types/daemon/builtin.d.ts +6 -5
  24. package/dist/types/daemon/control-types.d.ts +1 -1
  25. package/dist/types/discovery/mcp-json.d.ts +12 -1
  26. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  27. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  28. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  29. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  30. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  31. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  32. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  33. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  34. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  35. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  36. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  37. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  38. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  39. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +11 -0
  40. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  41. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  42. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  43. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  44. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  45. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  46. package/dist/types/harness-control-plane/types.d.ts +3 -4
  47. package/dist/types/lsp/index.d.ts +1 -1
  48. package/dist/types/main.d.ts +32 -38
  49. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  50. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  51. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  52. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  53. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  54. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  55. package/dist/types/modes/components/model-selector.d.ts +1 -0
  56. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  57. package/dist/types/modes/components/settings-selector.d.ts +6 -4
  58. package/dist/types/modes/components/welcome.d.ts +1 -1
  59. package/dist/types/modes/controllers/command-controller.d.ts +2 -2
  60. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -0
  61. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  62. package/dist/types/modes/index.d.ts +0 -4
  63. package/dist/types/modes/interactive-mode.d.ts +5 -2
  64. package/dist/types/modes/runtime-init.d.ts +2 -2
  65. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  66. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  67. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  68. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  69. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  70. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +170 -30
  71. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  72. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  73. package/dist/types/modes/types.d.ts +7 -2
  74. package/dist/types/runtime-mcp/client.d.ts +2 -0
  75. package/dist/types/runtime-mcp/config.d.ts +5 -1
  76. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  77. package/dist/types/runtime-mcp/types.d.ts +4 -0
  78. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  79. package/dist/types/sdk/acp/index.d.ts +2 -0
  80. package/dist/types/sdk/broker/broker.d.ts +53 -0
  81. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  82. package/dist/types/sdk/broker/ensure.d.ts +42 -0
  83. package/dist/types/sdk/broker/identity.d.ts +3 -0
  84. package/dist/types/sdk/broker/index.d.ts +8 -0
  85. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  86. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  87. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  88. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  89. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  90. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  91. package/dist/types/sdk/broker/transport.d.ts +9 -0
  92. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  93. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  94. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  95. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  96. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  97. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  98. package/dist/types/sdk/bus/config.d.ts +274 -0
  99. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  100. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  101. package/dist/types/sdk/bus/discord-daemon.d.ts +50 -0
  102. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  103. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  104. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  105. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  106. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  107. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  108. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  109. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  110. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  111. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  112. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  113. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  114. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  115. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  116. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  117. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  118. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  119. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  120. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  121. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +78 -17
  122. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  123. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  124. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  125. package/dist/types/sdk/cli/index.d.ts +1 -0
  126. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  127. package/dist/types/sdk/client/client.d.ts +1 -0
  128. package/dist/types/sdk/client/discovery.d.ts +27 -0
  129. package/dist/types/sdk/client/index.d.ts +2 -0
  130. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  131. package/dist/types/sdk/host/control/index.d.ts +2 -0
  132. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  133. package/dist/types/sdk/host/events.d.ts +35 -0
  134. package/dist/types/sdk/host/host.d.ts +35 -0
  135. package/dist/types/sdk/host/index.d.ts +4 -0
  136. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  137. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  138. package/dist/types/sdk/host/query/index.d.ts +3 -0
  139. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  140. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  141. package/dist/types/sdk/host/types.d.ts +32 -0
  142. package/dist/types/sdk/index.d.ts +6 -0
  143. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  144. package/dist/types/sdk/mcp/index.d.ts +1 -0
  145. package/dist/types/sdk/mcp/server.d.ts +37 -0
  146. package/dist/types/sdk/models.d.ts +44 -0
  147. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  148. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  149. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  150. package/dist/types/sdk/startup-capability.d.ts +50 -0
  151. package/dist/types/session/agent-session.d.ts +114 -21
  152. package/dist/types/session/default-model-selection.d.ts +25 -0
  153. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  154. package/dist/types/session/session-manager.d.ts +58 -1
  155. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  156. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  157. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  158. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  159. package/dist/types/tools/browser/launch.d.ts +22 -0
  160. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  161. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  162. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  163. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  164. package/dist/types/tools/browser/registry.d.ts +19 -0
  165. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  166. package/dist/types/tools/index.d.ts +8 -8
  167. package/dist/types/tools/subagent-render.d.ts +1 -0
  168. package/dist/types/tools/subagent.d.ts +6 -1
  169. package/package.json +34 -13
  170. package/scripts/build-sdk-package-smoke.ts +99 -0
  171. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  172. package/scripts/compile-args.ts +4 -2
  173. package/scripts/g005-daemon-smoke.ts +4 -5
  174. package/scripts/g011-daemon-path-smoke.ts +5 -5
  175. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  176. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  177. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  178. package/scripts/manifest-schema.ts +124 -0
  179. package/scripts/run-test-manifest.ts +153 -0
  180. package/scripts/run-threat-model-check.ts +157 -0
  181. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  182. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  183. package/src/append-only-mode.ts +1 -1
  184. package/src/async/job-manager.ts +406 -63
  185. package/src/cli/args.ts +43 -12
  186. package/src/cli/auth-gateway-cli.ts +2 -2
  187. package/src/cli/config-cli.ts +2 -1
  188. package/src/cli/daemon-cli.ts +63 -14
  189. package/src/cli/list-models.ts +1 -1
  190. package/src/cli/notify-cli.ts +288 -286
  191. package/src/cli.ts +21 -2
  192. package/src/commands/daemon.ts +50 -6
  193. package/src/commands/harness.ts +93 -36
  194. package/src/commands/launch.ts +5 -2
  195. package/src/commands/mcp-serve.ts +19 -12
  196. package/src/commands/notify.ts +36 -3
  197. package/src/commands/sdk.ts +426 -0
  198. package/src/commit/agentic/agent.ts +1 -0
  199. package/src/config/atomic-yaml-patch.ts +423 -0
  200. package/src/config/model-profile-activation.ts +240 -89
  201. package/src/config/model-profiles.ts +18 -15
  202. package/src/config/model-registry.ts +51 -26
  203. package/src/config/model-resolver.ts +138 -51
  204. package/src/config/model-selector-value.ts +50 -0
  205. package/src/config/models-config-schema.ts +14 -21
  206. package/src/config/settings-schema.ts +128 -10
  207. package/src/config/settings.ts +1120 -158
  208. package/src/coordinator-mcp/model-preset.ts +74 -20
  209. package/src/coordinator-mcp/server.ts +1597 -3052
  210. package/src/daemon/builtin.ts +8 -5
  211. package/src/daemon/control-types.ts +1 -1
  212. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  213. package/src/discovery/mcp-json.ts +327 -20
  214. package/src/extensibility/custom-tools/types.ts +1 -1
  215. package/src/extensibility/extensions/compact-handler.ts +3 -3
  216. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  217. package/src/extensibility/extensions/loader.ts +69 -5
  218. package/src/extensibility/extensions/runner.ts +112 -4
  219. package/src/extensibility/extensions/types.ts +176 -17
  220. package/src/extensibility/hooks/types.ts +1 -1
  221. package/src/gjc-runtime/launch-tmux.ts +170 -86
  222. package/src/gjc-runtime/psmux-detect.ts +82 -4
  223. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  224. package/src/gjc-runtime/team-runtime.ts +54 -35
  225. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  226. package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
  227. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  228. package/src/gjc-runtime/ultragoal-guard.ts +108 -14
  229. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +102 -1
  230. package/src/gjc-runtime/ultragoal-runtime.ts +227 -11
  231. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  232. package/src/harness-control-plane/operate.ts +9 -9
  233. package/src/harness-control-plane/owner.ts +283 -39
  234. package/src/harness-control-plane/receipts.ts +0 -1
  235. package/src/harness-control-plane/sdk-transport.ts +395 -0
  236. package/src/harness-control-plane/session-transport.ts +94 -0
  237. package/src/harness-control-plane/types.ts +1 -1
  238. package/src/internal-urls/docs-index.generated.ts +34 -35
  239. package/src/lsp/client.ts +42 -6
  240. package/src/lsp/index.ts +2 -2
  241. package/src/main.ts +299 -204
  242. package/src/modes/DESIGN.md +258 -0
  243. package/src/modes/acp/acp-agent.ts +1228 -2612
  244. package/src/modes/acp/acp-client-bridge.ts +2 -20
  245. package/src/modes/acp/acp-event-mapper.ts +18 -2
  246. package/src/modes/acp/acp-mode.ts +8 -36
  247. package/src/modes/acp/permission-mode.ts +25 -0
  248. package/src/modes/acp/startup-options.ts +6 -0
  249. package/src/modes/components/agent-dashboard.ts +37 -17
  250. package/src/modes/components/model-selector.ts +93 -35
  251. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  252. package/src/modes/components/settings-selector.ts +60 -11
  253. package/src/modes/components/welcome.ts +4 -4
  254. package/src/modes/controllers/command-controller.ts +10 -17
  255. package/src/modes/controllers/event-controller.ts +11 -16
  256. package/src/modes/controllers/extension-ui-controller.ts +396 -28
  257. package/src/modes/controllers/selector-controller.ts +674 -36
  258. package/src/modes/index.ts +0 -22
  259. package/src/modes/interactive-mode.ts +87 -36
  260. package/src/modes/runtime-init.ts +298 -6
  261. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  262. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  263. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  264. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  265. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  266. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1258 -87
  267. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  268. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  269. package/src/modes/types.ts +7 -2
  270. package/src/runtime-mcp/client.ts +94 -19
  271. package/src/runtime-mcp/config.ts +27 -15
  272. package/src/runtime-mcp/manager.ts +343 -105
  273. package/src/runtime-mcp/oauth-flow.ts +42 -12
  274. package/src/runtime-mcp/transports/http.ts +49 -19
  275. package/src/runtime-mcp/transports/stdio.ts +47 -28
  276. package/src/runtime-mcp/types.ts +10 -0
  277. package/src/sdk/acp/adapter.ts +418 -0
  278. package/src/sdk/acp/index.ts +2 -0
  279. package/src/sdk/broker/broker.ts +642 -0
  280. package/src/sdk/broker/discovery.ts +113 -0
  281. package/src/sdk/broker/ensure.ts +307 -0
  282. package/src/sdk/broker/identity.ts +42 -0
  283. package/src/sdk/broker/index.ts +8 -0
  284. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  285. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  286. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  287. package/src/sdk/broker/lifecycle.ts +2157 -0
  288. package/src/sdk/broker/process-incarnation.ts +159 -0
  289. package/src/sdk/broker/runtime.ts +164 -0
  290. package/src/sdk/broker/session-index.ts +318 -0
  291. package/src/sdk/broker/state-version.ts +23 -0
  292. package/src/sdk/broker/transport.ts +125 -0
  293. package/src/sdk/bus/chat-command-policy.ts +107 -0
  294. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  295. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  296. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  297. package/src/sdk/bus/chat-effect-journal.ts +355 -0
  298. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  299. package/src/sdk/bus/config.ts +433 -0
  300. package/src/sdk/bus/conversation-store.ts +391 -0
  301. package/src/sdk/bus/discord-conversation.ts +85 -0
  302. package/src/sdk/bus/discord-daemon.ts +2292 -0
  303. package/src/sdk/bus/discord-live-provider.ts +521 -0
  304. package/src/sdk/bus/discord-provider.ts +56 -0
  305. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  306. package/src/sdk/bus/index.ts +3979 -0
  307. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  308. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  309. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  310. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  311. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  312. package/src/sdk/bus/natives-augment.d.ts +38 -0
  313. package/src/sdk/bus/notification-orchestration.ts +535 -0
  314. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  315. package/src/sdk/bus/session-control.ts +333 -0
  316. package/src/sdk/bus/slack-conversation.ts +74 -0
  317. package/src/sdk/bus/slack-daemon.ts +2144 -0
  318. package/src/sdk/bus/slack-live-provider.ts +380 -0
  319. package/src/sdk/bus/slack-provider.ts +76 -0
  320. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  321. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  322. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  323. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  324. package/src/{notifications → sdk/bus}/telegram-daemon.ts +603 -63
  325. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  326. package/src/sdk/bus/telegram-setup.ts +663 -0
  327. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  328. package/src/sdk/cli/index.ts +1 -0
  329. package/src/sdk/cli/session-cli.ts +275 -0
  330. package/src/sdk/client/client.ts +1 -0
  331. package/src/sdk/client/discovery.ts +108 -0
  332. package/src/sdk/client/index.ts +2 -0
  333. package/src/sdk/host/control/dispatch.ts +367 -0
  334. package/src/sdk/host/control/index.ts +10 -0
  335. package/src/sdk/host/control/operations.ts +63 -0
  336. package/src/sdk/host/events.ts +91 -0
  337. package/src/sdk/host/host.ts +296 -0
  338. package/src/sdk/host/index.ts +4 -0
  339. package/src/sdk/host/query/cursor.ts +189 -0
  340. package/src/sdk/host/query/handlers.ts +533 -0
  341. package/src/sdk/host/query/index.ts +3 -0
  342. package/src/sdk/host/query/revision-store.ts +1126 -0
  343. package/src/sdk/host/reverse-leases.ts +325 -0
  344. package/src/sdk/host/types.ts +29 -0
  345. package/src/sdk/index.ts +13 -0
  346. package/src/sdk/lifecycle-session.ts +39 -0
  347. package/src/sdk/mcp/index.ts +1 -0
  348. package/src/sdk/mcp/server.ts +332 -0
  349. package/src/sdk/models.ts +168 -0
  350. package/src/sdk/protocol/adapter-validation.ts +48 -0
  351. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  352. package/src/sdk/protocol/operation-registry.ts +312 -0
  353. package/src/{sdk.ts → sdk/session.ts} +339 -212
  354. package/src/sdk/startup-capability.ts +189 -0
  355. package/src/session/agent-session.ts +2650 -944
  356. package/src/session/default-model-selection.ts +93 -0
  357. package/src/session/fallback-chain-controller.ts +136 -0
  358. package/src/session/session-manager.ts +438 -11
  359. package/src/session/session-storage.ts +8 -1
  360. package/src/setup/credential-auto-import.ts +290 -35
  361. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  362. package/src/slash-commands/builtin-registry.ts +2 -1
  363. package/src/task/executor.ts +62 -13
  364. package/src/task/index.ts +26 -16
  365. package/src/tools/ask-answer-registry.ts +1 -1
  366. package/src/tools/ask.ts +13 -8
  367. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  368. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  369. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  370. package/src/tools/browser/launch.ts +124 -19
  371. package/src/tools/browser/profile-discovery.ts +63 -0
  372. package/src/tools/browser/profile-posture.ts +59 -0
  373. package/src/tools/browser/profile-reuse.ts +102 -0
  374. package/src/tools/browser/profile-warmup.ts +109 -0
  375. package/src/tools/browser/registry.ts +87 -11
  376. package/src/tools/browser/tab-protocol.ts +1 -0
  377. package/src/tools/browser/tab-supervisor.ts +1 -0
  378. package/src/tools/browser/tab-worker.ts +1 -1
  379. package/src/tools/browser.ts +6 -0
  380. package/src/tools/index.ts +8 -8
  381. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  382. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  383. package/src/tools/subagent-render.ts +19 -8
  384. package/src/tools/subagent.ts +84 -32
  385. package/src/tools/telegram-send.ts +2 -2
  386. package/vendor/insane-search/MANIFEST.json +2 -1
  387. package/vendor/insane-search/engine/bias_check.py +4 -1
  388. package/vendor/insane-search/engine/phase0.py +26 -1
  389. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  390. package/dist/types/modes/bridge/auth.d.ts +0 -12
  391. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  392. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  393. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  394. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  395. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  396. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  397. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  398. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  399. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  400. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  401. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  402. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  403. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  404. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  405. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  406. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  407. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  408. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  409. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  410. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  411. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  412. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  413. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  414. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  415. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  416. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  417. package/dist/types/notifications/config.d.ts +0 -132
  418. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  419. package/src/modes/bridge/auth.ts +0 -41
  420. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  421. package/src/modes/bridge/bridge-mode.ts +0 -675
  422. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  423. package/src/modes/bridge/event-stream.ts +0 -70
  424. package/src/modes/rpc/host-tools.ts +0 -1
  425. package/src/modes/rpc/host-uris.ts +0 -1
  426. package/src/modes/rpc/rpc-client.ts +0 -1166
  427. package/src/modes/rpc/rpc-mode.ts +0 -1029
  428. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  429. package/src/modes/rpc/rpc-types.ts +0 -637
  430. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  431. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  432. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  433. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  434. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  435. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  436. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  437. package/src/modes/shared/agent-wire/responses.ts +0 -17
  438. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  439. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  440. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  441. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  442. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  443. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  444. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  445. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  446. package/src/notifications/config.ts +0 -219
  447. package/src/notifications/index.ts +0 -1835
  448. package/src/notifications/telegram-daemon-cli.ts +0 -243
  449. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  450. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  453. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  454. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  455. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  456. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  457. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  458. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  459. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  460. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  461. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  462. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  463. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  466. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  467. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  468. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  469. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  470. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  471. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  472. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  473. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  474. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  475. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  476. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -279,6 +279,8 @@ export function formatLifecycleOutcome(r: SessionLifecycleResponse): string {
279
279
  return "\u26a0\ufe0f Close refused: that session is not GJC-managed or did not match.";
280
280
  case "not_found":
281
281
  return "\u2753 No matching session was found.";
282
+ case "unsupported_platform":
283
+ return "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.";
282
284
  case "terminal_uncertain":
283
285
  return /in progress/i.test(r.message)
284
286
  ? "\u23f3 That request is already in progress \u2014 hold on."
@@ -10,20 +10,21 @@ import * as crypto from "node:crypto";
10
10
  import * as fs from "node:fs";
11
11
  import * as fsPromises from "node:fs/promises";
12
12
  import * as path from "node:path";
13
- import { tmuxRuntimeSessionPath } from "../gjc-runtime/session-layout";
13
+ import type { NotificationControlServer as NativeNotificationControlServer } from "@gajae-code/natives";
14
+ import { tmuxRuntimeSessionPath } from "../../gjc-runtime/session-layout";
14
15
  import {
15
16
  GJC_COORDINATOR_SESSION_ID_ENV,
16
17
  GJC_COORDINATOR_SESSION_STATE_FILE_ENV,
17
18
  GJC_TMUX_OWNER_GENERATION_ENV,
18
19
  GJC_TMUX_OWNER_SERVER_KEY_ENV,
19
20
  GJC_TMUX_OWNER_STATE_DIR_ENV,
20
- } from "../gjc-runtime/session-state-sidecar";
21
+ } from "../../gjc-runtime/session-state-sidecar";
21
22
  import {
22
23
  buildGjcTmuxProfileCommands,
23
24
  buildGjcTmuxSessionSlug,
24
25
  resolveGjcTmuxBinary,
25
26
  resolveGjcTmuxCommand,
26
- } from "../gjc-runtime/tmux-common";
27
+ } from "../../gjc-runtime/tmux-common";
27
28
  import {
28
29
  captureOwnerGenerationBaseline,
29
30
  classifyCgroup,
@@ -33,15 +34,20 @@ import {
33
34
  planTmuxOwnerIsolation,
34
35
  replaceOwnerGeneration,
35
36
  type TmuxServerProof,
36
- } from "../gjc-runtime/tmux-owner-isolation";
37
+ } from "../../gjc-runtime/tmux-owner-isolation";
37
38
  import {
38
39
  findGjcTmuxSessionByName,
39
40
  forceCloseGjcTmuxSession,
40
41
  type GjcTmuxSessionStatus,
41
42
  listGjcTmuxSessions,
42
- } from "../gjc-runtime/tmux-sessions";
43
-
44
- import type { ResumeCandidate, SessionCreateFrame, SessionLifecycleRequest, SessionLifecycleResponse } from "./index";
43
+ } from "../../gjc-runtime/tmux-sessions";
44
+ import type {
45
+ LifecycleErrorReason,
46
+ ResumeCandidate,
47
+ SessionCreateFrame,
48
+ SessionLifecycleRequest,
49
+ SessionLifecycleResponse,
50
+ } from "./index";
45
51
  import { normalizeLifecyclePath } from "./lifecycle-commands";
46
52
  import {
47
53
  type AuditEvent,
@@ -56,6 +62,16 @@ import {
56
62
  } from "./lifecycle-orchestrator";
57
63
  import { listRecentSessions } from "./recent-activity";
58
64
 
65
+ type NativeControlServerConstructor = new (
66
+ token: string,
67
+ ownerId: string,
68
+ agentDir?: string,
69
+ ) => NativeNotificationControlServer;
70
+
71
+ interface NativeControlServerModule {
72
+ NotificationControlServer: NativeControlServerConstructor;
73
+ }
74
+
59
75
  /** Minimal view of the native control server this runtime depends on. */
60
76
  export interface ControlServerLike {
61
77
  onLifecycleRequest(
@@ -80,6 +96,24 @@ export type LifecycleControlServerFactory = (input: {
80
96
  ownerId: string;
81
97
  agentDir: string;
82
98
  }) => LifecycleControlServer;
99
+ const lifecycleErrorReasons = new Set<LifecycleErrorReason>([
100
+ "unauthorized",
101
+ "rate_limited",
102
+ "duplicate_conflict",
103
+ "invalid_target",
104
+ "ambiguous_target",
105
+ "spawn_failed",
106
+ "discovery_timeout",
107
+ "readiness_timeout",
108
+ "close_refused",
109
+ "not_found",
110
+ "terminal_uncertain",
111
+ "unsupported_platform",
112
+ ]);
113
+
114
+ function isLifecycleErrorReason(value: unknown): value is LifecycleErrorReason {
115
+ return typeof value === "string" && lifecycleErrorReasons.has(value as LifecycleErrorReason);
116
+ }
83
117
 
84
118
  /** Atomic + fsynced file-backed idempotency ledger store. */
85
119
  function ledgerReadError(error: unknown): Error {
@@ -95,7 +129,7 @@ function isLedgerDoc(value: unknown): value is LedgerDoc {
95
129
  return Object.values(doc.entries).every(entry => {
96
130
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
97
131
  const candidate = entry as Partial<LedgerEntry>;
98
- return (
132
+ const isBaseEntry =
99
133
  typeof candidate.requestHash === "string" &&
100
134
  (candidate.state === "in_progress" ||
101
135
  candidate.state === "success" ||
@@ -109,11 +143,44 @@ function isLedgerDoc(value: unknown): value is LedgerDoc {
109
143
  typeof candidate.updatedAt === "number" &&
110
144
  !!candidate.targetSummary &&
111
145
  typeof candidate.targetSummary === "object" &&
112
- !Array.isArray(candidate.targetSummary)
113
- );
146
+ !Array.isArray(candidate.targetSummary);
147
+ if (!isBaseEntry) return false;
148
+ if (candidate.state === "failure" || candidate.state === "terminal_uncertain")
149
+ return isLifecycleErrorReason(candidate.reason);
150
+ if (candidate.state !== "success") return true;
151
+ switch (candidate.verb) {
152
+ case "session_create":
153
+ return (
154
+ typeof candidate.intendedSessionId === "string" &&
155
+ typeof candidate.sessionId === "string" &&
156
+ typeof candidate.tmuxSession === "string" &&
157
+ typeof candidate.endpointUrl === "string"
158
+ );
159
+ case "session_close":
160
+ return typeof candidate.sessionId === "string" && typeof candidate.processGone === "boolean";
161
+ case "session_resume":
162
+ return (
163
+ typeof candidate.sessionId === "string" &&
164
+ typeof candidate.tmuxSession === "string" &&
165
+ typeof candidate.endpointUrl === "string" &&
166
+ (candidate.resumeMode === undefined ||
167
+ candidate.resumeMode === "reattached" ||
168
+ candidate.resumeMode === "cold_restarted")
169
+ );
170
+ }
171
+ return false;
114
172
  });
115
173
  }
116
174
 
175
+ function migrateLegacyLedger(doc: LedgerDoc): LedgerDoc {
176
+ for (const entry of Object.values(doc.entries)) {
177
+ if (entry.state === "success" && entry.verb === "session_resume" && entry.resumeMode === undefined) {
178
+ entry.resumeMode = "reattached";
179
+ }
180
+ }
181
+ return doc;
182
+ }
183
+
117
184
  function isUnsupportedDirectorySyncError(error: unknown): boolean {
118
185
  const code = (error as NodeJS.ErrnoException | undefined)?.code;
119
186
  return code === "EINVAL" || code === "ENOTSUP" || code === "EOPNOTSUPP";
@@ -163,7 +230,7 @@ export function fileLedgerStore(idempotencyFile: string): LedgerStore {
163
230
  try {
164
231
  const doc = JSON.parse(contents) as unknown;
165
232
  if (!isLedgerDoc(doc)) throw new Error("invalid");
166
- return doc;
233
+ return migrateLegacyLedger(doc);
167
234
  } catch (error) {
168
235
  throw ledgerReadError(error);
169
236
  }
@@ -640,6 +707,91 @@ async function assertLifecycleTmuxServerSafe(input: {
640
707
  throw new Error(`gjc_lifecycle_owner_${proof.state === "unsafe" ? "server_unsafe" : "server_unverifiable"}`);
641
708
  }
642
709
 
710
+ async function completeLifecycleSpawnTransaction(input: {
711
+ tmux: string;
712
+ env: NodeJS.ProcessEnv;
713
+ sessionId: string;
714
+ generation: string;
715
+ stateDir: string;
716
+ cwd: string;
717
+ sessionName: string;
718
+ sessionStateFile: string;
719
+ argv: string[];
720
+ ownerIsolationProbe?: OwnerIsolationProbe;
721
+ prepareSpawn?: () => void;
722
+ }): Promise<void> {
723
+ const previousBaseline = await captureOwnerGenerationBaseline(input.stateDir, input.sessionId);
724
+ let ownerExecution: LifecycleAttemptExecution | undefined;
725
+ try {
726
+ ownerExecution = await executeLifecycleTmuxOwnerPlan({
727
+ ...input,
728
+ previousBaseline,
729
+ onAttemptCreated: attempt => {
730
+ ownerExecution = attempt;
731
+ },
732
+ });
733
+ if (
734
+ !ownerExecution.nativeSessionId ||
735
+ ownerExecution.serverPid === undefined ||
736
+ ownerExecution.serverStartTime === undefined
737
+ )
738
+ throw new Error("gjc_lifecycle_owner_server_unverifiable");
739
+ await applyRequiredLifecycleTmuxMetadata(
740
+ input.tmux,
741
+ `${ownerExecution.nativeSessionId}:`,
742
+ input.env,
743
+ {
744
+ sessionId: input.sessionId,
745
+ sessionStateFile: input.sessionStateFile,
746
+ project: input.cwd,
747
+ ownerGeneration: input.generation,
748
+ ownerServerKey: ownerExecution.serverKey,
749
+ },
750
+ {
751
+ nativeSessionId: ownerExecution.nativeSessionId,
752
+ attemptSession: ownerExecution.attemptSession,
753
+ serverPid: ownerExecution.serverPid,
754
+ },
755
+ );
756
+ if (
757
+ !(await reproveLifecycleAttempt({
758
+ tmux: input.tmux,
759
+ env: input.env,
760
+ serverKey: ownerExecution.serverKey,
761
+ nativeSessionId: ownerExecution.nativeSessionId,
762
+ attemptSession: ownerExecution.attemptSession,
763
+ expectedServerPid: ownerExecution.serverPid,
764
+ expectedServerStartTime: ownerExecution.serverStartTime,
765
+ ownerIsolationProbe: input.ownerIsolationProbe,
766
+ }))
767
+ )
768
+ throw new Error("gjc_lifecycle_owner_server_unverifiable");
769
+ if (!(await isLifecycleGenerationUnchanged(input.stateDir, input.sessionId, previousBaseline)))
770
+ throw new Error("gjc_lifecycle_owner_generation_changed");
771
+ await replaceOwnerGeneration(input.stateDir, input.sessionId, input.generation, previousBaseline);
772
+ } catch (error) {
773
+ let cleanupFailure: unknown;
774
+ if (ownerExecution?.attemptCreated) {
775
+ try {
776
+ await cleanupLifecycleAttempt({
777
+ tmux: input.tmux,
778
+ env: input.env,
779
+ serverKey: ownerExecution.serverKey,
780
+ nativeSessionId: ownerExecution.nativeSessionId,
781
+ attemptSession: ownerExecution.attemptSession,
782
+ expectedServerPid: ownerExecution.serverPid,
783
+ expectedServerStartTime: ownerExecution.serverStartTime,
784
+ ownerIsolationProbe: input.ownerIsolationProbe,
785
+ });
786
+ } catch (cleanupError) {
787
+ cleanupFailure = cleanupError;
788
+ }
789
+ }
790
+ if (cleanupFailure !== undefined)
791
+ throw new AggregateError([error, cleanupFailure], "gjc_lifecycle_cleanup_uncertain");
792
+ throw error;
793
+ }
794
+ }
643
795
  /** Real daemon-safe tmux launcher: canonical owner-isolation plan + GJC tags. */
644
796
  export function daemonSpawnCreate(
645
797
  env: NodeJS.ProcessEnv = process.env,
@@ -657,7 +809,6 @@ export function daemonSpawnCreate(
657
809
  const sessionStateFile = lifecycleRuntimeStateFile(cwd, ids.intendedSessionId, name);
658
810
  const stateDir = path.dirname(sessionStateFile);
659
811
  const generation = crypto.randomUUID();
660
- const previousBaseline = await captureOwnerGenerationBaseline(stateDir, ids.intendedSessionId);
661
812
  // Detached: no interactive TTY needed (daemon-safe). These values contain
662
813
  // only opaque ids and paths needed by the resident sidecar to publish its
663
814
  // exact-owner terminal verdict.
@@ -674,91 +825,24 @@ export function daemonSpawnCreate(
674
825
  };
675
826
  if (ids.startupPromptRef) childEnv.GJC_STARTUP_PROMPT_REF = ids.startupPromptRef;
676
827
  const envPairs = Object.entries(childEnv)
677
- .map(([k, v]) => `${k}=${shellQuote(v)}`)
828
+ .map(([key, value]) => `${key}=${shellQuote(value)}`)
678
829
  .join(" ");
679
830
  const command = `cd ${shellQuote(cwd)} && exec env ${envPairs} gjc ${args.map(shellQuote).join(" ")}`;
680
- let ownerExecution: LifecycleAttemptExecution | undefined;
681
- try {
682
- ownerExecution = await executeLifecycleTmuxOwnerPlan({
683
- tmux,
684
- env,
685
- sessionId: ids.intendedSessionId,
686
- generation,
687
- stateDir,
688
- cwd,
689
- sessionName: name,
690
- argv: [tmux, "new-session", "-d", "-P", "-F", "#{session_id}", "-s", name, "sh", "-c", command],
691
- ownerIsolationProbe: opts.ownerIsolationProbe,
692
- onAttemptCreated: attempt => {
693
- ownerExecution = attempt;
694
- },
695
- previousBaseline,
696
-
697
- prepareSpawn: () => {
698
- if (frame.target.kind === "plain_dir") fs.mkdirSync(cwd, { recursive: true });
699
- },
700
- });
701
- if (!ownerExecution.nativeSessionId || ownerExecution.serverPid === undefined)
702
- throw new Error("gjc_lifecycle_owner_server_unverifiable");
703
- const target = `${ownerExecution.nativeSessionId}:`;
704
- await applyRequiredLifecycleTmuxMetadata(
705
- tmux,
706
- target,
707
- env,
708
- {
709
- sessionId: ids.intendedSessionId,
710
- sessionStateFile,
711
- project: cwd,
712
- ownerGeneration: generation,
713
- ownerServerKey: ownerExecution.serverKey,
714
- },
715
- {
716
- nativeSessionId: ownerExecution.nativeSessionId,
717
- attemptSession: ownerExecution.attemptSession,
718
- serverPid: ownerExecution.serverPid,
719
- },
720
- );
721
- if (
722
- !ownerExecution.nativeSessionId ||
723
- ownerExecution.serverPid === undefined ||
724
- ownerExecution.serverStartTime === undefined ||
725
- !(await reproveLifecycleAttempt({
726
- tmux,
727
- env,
728
- serverKey: ownerExecution.serverKey,
729
- nativeSessionId: ownerExecution.nativeSessionId,
730
- attemptSession: ownerExecution.attemptSession,
731
- expectedServerPid: ownerExecution.serverPid,
732
- expectedServerStartTime: ownerExecution.serverStartTime,
733
- ownerIsolationProbe: opts.ownerIsolationProbe,
734
- }))
735
- )
736
- throw new Error("gjc_lifecycle_owner_server_unverifiable");
737
- if (!(await isLifecycleGenerationUnchanged(stateDir, ids.intendedSessionId, previousBaseline)))
738
- throw new Error("gjc_lifecycle_owner_generation_changed");
739
- await replaceOwnerGeneration(stateDir, ids.intendedSessionId, generation, previousBaseline);
740
- } catch (error) {
741
- let cleanupFailure: unknown;
742
- if (ownerExecution?.attemptCreated) {
743
- try {
744
- await cleanupLifecycleAttempt({
745
- tmux,
746
- env,
747
- serverKey: ownerExecution.serverKey,
748
- nativeSessionId: ownerExecution.nativeSessionId,
749
- attemptSession: ownerExecution.attemptSession,
750
- expectedServerPid: ownerExecution.serverPid,
751
- expectedServerStartTime: ownerExecution.serverStartTime,
752
- ownerIsolationProbe: opts.ownerIsolationProbe,
753
- });
754
- } catch (cleanupError) {
755
- cleanupFailure = cleanupError;
756
- }
757
- }
758
- if (cleanupFailure !== undefined)
759
- throw new AggregateError([error, cleanupFailure], "gjc_lifecycle_cleanup_uncertain");
760
- throw error;
761
- }
831
+ await completeLifecycleSpawnTransaction({
832
+ tmux,
833
+ env,
834
+ sessionId: ids.intendedSessionId,
835
+ generation,
836
+ stateDir,
837
+ cwd,
838
+ sessionName: name,
839
+ sessionStateFile,
840
+ argv: [tmux, "new-session", "-d", "-P", "-F", "#{session_id}", "-s", name, "sh", "-c", command],
841
+ ownerIsolationProbe: opts.ownerIsolationProbe,
842
+ prepareSpawn: () => {
843
+ if (frame.target.kind === "plain_dir") fs.mkdirSync(cwd, { recursive: true });
844
+ },
845
+ });
762
846
 
763
847
  return {
764
848
  sessionId: ids.intendedSessionId,
@@ -912,7 +996,6 @@ export function daemonResumeSession(
912
996
  const sessionStateFile = lifecycleRuntimeStateFile(resolvedResumeCwd, resumeId, name);
913
997
  const stateDir = path.dirname(sessionStateFile);
914
998
  const generation = crypto.randomUUID();
915
- const previousBaseline = await captureOwnerGenerationBaseline(stateDir, resumeId);
916
999
  const childEnv: Record<string, string> = {
917
1000
  GJC_TMUX_LAUNCHED: "1",
918
1001
  GJC_NOTIFICATIONS: "1",
@@ -926,84 +1009,18 @@ export function daemonResumeSession(
926
1009
  .map(([key, value]) => `${key}=${shellQuote(value)}`)
927
1010
  .join(" ");
928
1011
  const command = `cd ${shellQuote(resolvedResumeCwd)} && exec env ${envPairs} gjc --resume ${shellQuote(resumeId)}`;
929
- let ownerExecution: LifecycleAttemptExecution | undefined;
930
- try {
931
- ownerExecution = await executeLifecycleTmuxOwnerPlan({
932
- tmux,
933
- env,
934
- sessionId: resumeId,
935
- generation,
936
- stateDir,
937
- cwd: resolvedResumeCwd,
938
- sessionName: name,
939
- argv: [tmux, "new-session", "-d", "-P", "-F", "#{session_id}", "-s", name, "sh", "-c", command],
940
- ownerIsolationProbe: opts.ownerIsolationProbe,
941
- onAttemptCreated: attempt => {
942
- ownerExecution = attempt;
943
- },
944
- previousBaseline,
945
- });
946
- if (!ownerExecution.nativeSessionId || ownerExecution.serverPid === undefined)
947
- throw new Error("gjc_lifecycle_owner_server_unverifiable");
948
- const tgt = `${ownerExecution.nativeSessionId}:`;
949
- await applyRequiredLifecycleTmuxMetadata(
950
- tmux,
951
- tgt,
952
- env,
953
- {
954
- sessionId: resumeId,
955
- sessionStateFile,
956
- project: resolvedResumeCwd,
957
- ownerGeneration: generation,
958
- ownerServerKey: ownerExecution.serverKey,
959
- },
960
- {
961
- nativeSessionId: ownerExecution.nativeSessionId,
962
- attemptSession: ownerExecution.attemptSession,
963
- serverPid: ownerExecution.serverPid,
964
- },
965
- );
966
- if (
967
- !ownerExecution.nativeSessionId ||
968
- ownerExecution.serverPid === undefined ||
969
- ownerExecution.serverStartTime === undefined ||
970
- !(await reproveLifecycleAttempt({
971
- tmux,
972
- env,
973
- serverKey: ownerExecution.serverKey,
974
- nativeSessionId: ownerExecution.nativeSessionId,
975
- attemptSession: ownerExecution.attemptSession,
976
- expectedServerPid: ownerExecution.serverPid,
977
- expectedServerStartTime: ownerExecution.serverStartTime,
978
- ownerIsolationProbe: opts.ownerIsolationProbe,
979
- }))
980
- )
981
- throw new Error("gjc_lifecycle_owner_server_unverifiable");
982
- if (!(await isLifecycleGenerationUnchanged(stateDir, resumeId, previousBaseline)))
983
- throw new Error("gjc_lifecycle_owner_generation_changed");
984
- await replaceOwnerGeneration(stateDir, resumeId, generation, previousBaseline);
985
- } catch (error) {
986
- let cleanupFailure: unknown;
987
- if (ownerExecution?.attemptCreated) {
988
- try {
989
- await cleanupLifecycleAttempt({
990
- tmux,
991
- env,
992
- serverKey: ownerExecution.serverKey,
993
- nativeSessionId: ownerExecution.nativeSessionId,
994
- attemptSession: ownerExecution.attemptSession,
995
- expectedServerPid: ownerExecution.serverPid,
996
- expectedServerStartTime: ownerExecution.serverStartTime,
997
- ownerIsolationProbe: opts.ownerIsolationProbe,
998
- });
999
- } catch (cleanupError) {
1000
- cleanupFailure = cleanupError;
1001
- }
1002
- }
1003
- if (cleanupFailure !== undefined)
1004
- throw new AggregateError([error, cleanupFailure], "gjc_lifecycle_cleanup_uncertain");
1005
- throw error;
1006
- }
1012
+ await completeLifecycleSpawnTransaction({
1013
+ tmux,
1014
+ env,
1015
+ sessionId: resumeId,
1016
+ generation,
1017
+ stateDir,
1018
+ cwd: resolvedResumeCwd,
1019
+ sessionName: name,
1020
+ sessionStateFile,
1021
+ argv: [tmux, "new-session", "-d", "-P", "-F", "#{session_id}", "-s", name, "sh", "-c", command],
1022
+ ownerIsolationProbe: opts.ownerIsolationProbe,
1023
+ });
1007
1024
 
1008
1025
  return {
1009
1026
  sessionId: resumeId,
@@ -1034,39 +1051,50 @@ export function outcomeToResponse(frame: SessionLifecycleRequest, outcome: Lifec
1034
1051
  };
1035
1052
  }
1036
1053
  const e = outcome.entry;
1054
+ if (e.state !== "success") throw new Error("invalid lifecycle success ledger entry");
1037
1055
  if (frame.type === "session_create") {
1056
+ if (typeof e.sessionId !== "string" || typeof e.endpointUrl !== "string")
1057
+ throw new Error("invalid create success ledger entry");
1038
1058
  return {
1039
1059
  type: "session_create_response",
1040
1060
  requestId: frame.requestId,
1041
1061
  status: "ok",
1042
1062
  lifecycleRequestId: frame.lifecycleRequestId,
1043
- sessionId: e.sessionId ?? e.intendedSessionId ?? "",
1063
+ sessionId: e.sessionId,
1044
1064
  matchedBy: "spawn_marker",
1045
- endpoint: { url: e.endpointUrl ?? "", token: "" },
1065
+ endpoint: { url: e.endpointUrl, token: "" },
1046
1066
  topic: { chatId: frame.chatId, threadId: "" },
1047
1067
  target: frame.target,
1048
1068
  };
1049
1069
  }
1050
1070
  if (frame.type === "session_close") {
1071
+ if (typeof e.sessionId !== "string" || typeof e.processGone !== "boolean")
1072
+ throw new Error("invalid close success ledger entry");
1051
1073
  return {
1052
1074
  type: "session_close_response",
1053
1075
  requestId: frame.requestId,
1054
1076
  status: "ok",
1055
- sessionId: e.sessionId ?? "",
1056
- processGone: e.processGone ?? false,
1077
+ sessionId: e.sessionId,
1078
+ processGone: e.processGone,
1057
1079
  historyPreserved: true,
1058
1080
  // The killed session's per-session endpoint record is reaped by the
1059
1081
  // daemon's dead-PID scan (scanRoots), so it is effectively stale.
1060
- endpointStale: e.processGone ?? false,
1082
+ endpointStale: e.processGone,
1061
1083
  };
1062
1084
  }
1085
+ if (
1086
+ typeof e.sessionId !== "string" ||
1087
+ typeof e.endpointUrl !== "string" ||
1088
+ (e.resumeMode !== "reattached" && e.resumeMode !== "cold_restarted")
1089
+ )
1090
+ throw new Error("invalid resume success ledger entry");
1063
1091
  return {
1064
1092
  type: "session_resume_response",
1065
1093
  requestId: frame.requestId,
1066
1094
  status: "ok",
1067
- sessionId: e.sessionId ?? "",
1068
- mode: outcome.mode ?? "reattached",
1069
- endpoint: { url: e.endpointUrl ?? "", token: "" },
1095
+ sessionId: e.sessionId,
1096
+ mode: outcome.mode ?? e.resumeMode,
1097
+ endpoint: { url: e.endpointUrl, token: "" },
1070
1098
  topic: { chatId: frame.chatId, threadId: "" },
1071
1099
  };
1072
1100
  }
@@ -1126,6 +1154,10 @@ function isSafeLifecycleId(value: unknown): value is string {
1126
1154
  return typeof value === "string" && !hasLoneUtf16Surrogate(value);
1127
1155
  }
1128
1156
 
1157
+ function isNonEmptySafeLifecycleId(value: unknown): value is string {
1158
+ return isSafeLifecycleId(value) && value.length > 0;
1159
+ }
1160
+
1129
1161
  /** The native server authenticates callbacks before redacting the control token. */
1130
1162
  type AuthenticatedNativeLifecycleRequest =
1131
1163
  | Omit<SessionCreateFrame, "token">
@@ -1149,8 +1181,8 @@ function isBoundedRequestFrame(frame: unknown): frame is AuthenticatedNativeLife
1149
1181
  switch (frame.type) {
1150
1182
  case "session_create":
1151
1183
  return (
1152
- isSafeLifecycleId(frame.lifecycleRequestId) &&
1153
- isSafeLifecycleId(frame.intendedSessionId) &&
1184
+ isNonEmptySafeLifecycleId(frame.lifecycleRequestId) &&
1185
+ isNonEmptySafeLifecycleId(frame.intendedSessionId) &&
1154
1186
  (typeof frame.startupPromptRef === "undefined" || typeof frame.startupPromptRef === "string") &&
1155
1187
  (typeof frame.modelPreset === "undefined" || typeof frame.modelPreset === "string") &&
1156
1188
  ((frame.target.kind === "worktree" &&
@@ -1231,32 +1263,29 @@ export function attachLifecycleControl(server: ControlServerLike, deps: Orchestr
1231
1263
  export function buildOrchestratorDeps(input: {
1232
1264
  pairedChatId: string;
1233
1265
  agentNotificationsDir: string;
1266
+ /** Required in-memory, 32-byte audit-v2 redaction key. */
1267
+ auditRedactionKey: Uint8Array;
1234
1268
  /** Root of saved session histories (`<agentDir>/sessions`), for resume resolution. */
1235
1269
  sessionsRoot?: string;
1236
1270
  env?: NodeJS.ProcessEnv;
1237
1271
  }): OrchestratorDeps {
1272
+ if (input.auditRedactionKey.byteLength !== 32) throw new Error("invalid_audit_redaction_key");
1238
1273
  const env = input.env ?? process.env;
1239
1274
  return {
1240
1275
  pairedChatId: input.pairedChatId,
1276
+ auditRedactionKey: input.auditRedactionKey,
1241
1277
  now: () => Date.now(),
1242
1278
  store: fileLedgerStore(path.join(input.agentNotificationsDir, "telegram-lifecycle-idempotency.json")),
1243
1279
  audit: fileAudit(path.join(input.agentNotificationsDir, "telegram-lifecycle-audit.jsonl")),
1280
+ isPsmuxProvider: () => resolveGjcTmuxBinary({ env }).isPsmux,
1244
1281
  allowCreate: createRateLimiter(3, 10 * 60 * 1000),
1245
- writeStartupPrompt: async (requestId, prompt) => {
1282
+ writeStartupPrompt: async (_requestId, prompt, _persistRef) => {
1246
1283
  if (prompt === undefined) return undefined;
1247
- const ref = path.join(input.agentNotificationsDir, `startup-prompt-${requestId}`);
1248
- fs.mkdirSync(path.dirname(ref), { recursive: true });
1249
- const fd = fs.openSync(ref, "w", 0o600);
1250
- fs.writeSync(fd, prompt);
1251
- fs.fsyncSync(fd);
1252
- fs.closeSync(fd);
1253
- return ref;
1284
+ throw new Error("startup_prompt_capability_transport_unavailable");
1254
1285
  },
1255
1286
  spawnCreate: daemonSpawnCreate(env),
1256
1287
  closeSession: daemonCloseSession(env),
1257
1288
  resumeSession: daemonResumeSession(env, { sessionsRoot: input.sessionsRoot }),
1258
- newLifecycleRequestId: () => `lc-${crypto.randomUUID()}`,
1259
- newSessionId: () => `s${crypto.randomUUID().slice(0, 8)}`,
1260
1289
  };
1261
1290
  }
1262
1291
 
@@ -1267,6 +1296,6 @@ export function buildOrchestratorDeps(input: {
1267
1296
  export const createNativeControlServer: LifecycleControlServerFactory = ({ token, ownerId, agentDir }) => {
1268
1297
  // Lazy require so loading this module (for the orchestrator / wiring / tests)
1269
1298
  // never eagerly resolves the native addon — only a real production start does.
1270
- const { NotificationControlServer } = require("@gajae-code/natives") as typeof import("@gajae-code/natives");
1271
- return new NotificationControlServer(token, ownerId, agentDir) as unknown as LifecycleControlServer;
1299
+ const { NotificationControlServer } = require("@gajae-code/natives") as NativeControlServerModule;
1300
+ return new NotificationControlServer(token, ownerId, agentDir);
1272
1301
  };