@gajae-code/coding-agent 0.10.1 → 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 (474) hide show
  1. package/CHANGELOG.md +70 -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/gajae-pet-widget.d.ts +1 -0
  54. package/dist/types/modes/components/model-selector.d.ts +1 -0
  55. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  56. package/dist/types/modes/components/pet-capability.d.ts +37 -0
  57. package/dist/types/modes/components/pet-selector.d.ts +1 -1
  58. package/dist/types/modes/components/settings-selector.d.ts +15 -4
  59. package/dist/types/modes/components/welcome.d.ts +1 -1
  60. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  61. package/dist/types/modes/index.d.ts +0 -4
  62. package/dist/types/modes/interactive-mode.d.ts +5 -1
  63. package/dist/types/modes/runtime-init.d.ts +2 -2
  64. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  65. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  66. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  67. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  68. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  69. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  70. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  71. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  72. package/dist/types/modes/types.d.ts +16 -1
  73. package/dist/types/runtime-mcp/client.d.ts +2 -0
  74. package/dist/types/runtime-mcp/config.d.ts +5 -1
  75. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  76. package/dist/types/runtime-mcp/types.d.ts +4 -0
  77. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  78. package/dist/types/sdk/acp/index.d.ts +2 -0
  79. package/dist/types/sdk/broker/broker.d.ts +53 -0
  80. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  81. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  82. package/dist/types/sdk/broker/identity.d.ts +3 -0
  83. package/dist/types/sdk/broker/index.d.ts +8 -0
  84. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  85. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  86. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  87. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  88. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  89. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  90. package/dist/types/sdk/broker/transport.d.ts +9 -0
  91. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  92. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  93. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  94. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  95. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  96. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  97. package/dist/types/sdk/bus/config.d.ts +274 -0
  98. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  99. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  100. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  101. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  102. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  103. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  104. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  105. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  106. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  107. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  108. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  109. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  110. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  111. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  112. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  113. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  114. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  115. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  118. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  119. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  120. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  121. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  122. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  123. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  124. package/dist/types/sdk/cli/index.d.ts +1 -0
  125. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  126. package/dist/types/sdk/client/client.d.ts +1 -0
  127. package/dist/types/sdk/client/discovery.d.ts +27 -0
  128. package/dist/types/sdk/client/index.d.ts +2 -0
  129. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  130. package/dist/types/sdk/host/control/index.d.ts +2 -0
  131. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  132. package/dist/types/sdk/host/events.d.ts +35 -0
  133. package/dist/types/sdk/host/host.d.ts +35 -0
  134. package/dist/types/sdk/host/index.d.ts +4 -0
  135. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  136. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  137. package/dist/types/sdk/host/query/index.d.ts +3 -0
  138. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  139. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  140. package/dist/types/sdk/host/types.d.ts +32 -0
  141. package/dist/types/sdk/index.d.ts +6 -0
  142. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  143. package/dist/types/sdk/mcp/index.d.ts +1 -0
  144. package/dist/types/sdk/mcp/server.d.ts +37 -0
  145. package/dist/types/sdk/models.d.ts +44 -0
  146. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  147. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  148. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  149. package/dist/types/sdk/startup-capability.d.ts +50 -0
  150. package/dist/types/session/agent-session.d.ts +114 -21
  151. package/dist/types/session/default-model-selection.d.ts +25 -0
  152. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  153. package/dist/types/session/session-manager.d.ts +58 -1
  154. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  155. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  156. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  157. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  158. package/dist/types/tools/browser/launch.d.ts +22 -0
  159. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  160. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  161. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  162. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  163. package/dist/types/tools/browser/registry.d.ts +19 -0
  164. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  165. package/dist/types/tools/index.d.ts +8 -8
  166. package/package.json +34 -13
  167. package/scripts/build-sdk-package-smoke.ts +94 -0
  168. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  169. package/scripts/compile-args.ts +4 -2
  170. package/scripts/g005-daemon-smoke.ts +4 -5
  171. package/scripts/g011-daemon-path-smoke.ts +5 -5
  172. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  173. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  174. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  175. package/scripts/manifest-schema.ts +124 -0
  176. package/scripts/run-test-manifest.ts +153 -0
  177. package/scripts/run-threat-model-check.ts +157 -0
  178. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  179. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  180. package/src/append-only-mode.ts +1 -1
  181. package/src/cli/args.ts +43 -12
  182. package/src/cli/auth-gateway-cli.ts +2 -2
  183. package/src/cli/config-cli.ts +2 -1
  184. package/src/cli/daemon-cli.ts +63 -14
  185. package/src/cli/list-models.ts +1 -1
  186. package/src/cli/notify-cli.ts +288 -286
  187. package/src/cli.ts +21 -2
  188. package/src/commands/daemon.ts +50 -6
  189. package/src/commands/harness.ts +93 -36
  190. package/src/commands/launch.ts +5 -2
  191. package/src/commands/mcp-serve.ts +19 -12
  192. package/src/commands/notify.ts +36 -3
  193. package/src/commands/sdk.ts +426 -0
  194. package/src/commit/agentic/agent.ts +1 -0
  195. package/src/config/atomic-yaml-patch.ts +423 -0
  196. package/src/config/model-profile-activation.ts +240 -89
  197. package/src/config/model-profiles.ts +37 -34
  198. package/src/config/model-registry.ts +51 -26
  199. package/src/config/model-resolver.ts +138 -51
  200. package/src/config/model-selector-value.ts +50 -0
  201. package/src/config/models-config-schema.ts +14 -21
  202. package/src/config/settings-schema.ts +128 -10
  203. package/src/config/settings.ts +1120 -158
  204. package/src/coordinator-mcp/model-preset.ts +74 -20
  205. package/src/coordinator-mcp/server.ts +1597 -3052
  206. package/src/daemon/builtin.ts +8 -5
  207. package/src/daemon/control-types.ts +1 -1
  208. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  209. package/src/discovery/mcp-json.ts +327 -20
  210. package/src/extensibility/custom-tools/types.ts +1 -1
  211. package/src/extensibility/extensions/compact-handler.ts +3 -3
  212. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  213. package/src/extensibility/extensions/loader.ts +69 -5
  214. package/src/extensibility/extensions/runner.ts +112 -4
  215. package/src/extensibility/extensions/types.ts +176 -17
  216. package/src/extensibility/hooks/types.ts +1 -1
  217. package/src/extensibility/slash-commands.ts +3 -3
  218. package/src/gjc-runtime/launch-tmux.ts +170 -86
  219. package/src/gjc-runtime/psmux-detect.ts +82 -4
  220. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  221. package/src/gjc-runtime/team-runtime.ts +54 -35
  222. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  223. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -2
  224. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  225. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  226. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  227. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  228. package/src/harness-control-plane/operate.ts +9 -9
  229. package/src/harness-control-plane/owner.ts +283 -39
  230. package/src/harness-control-plane/receipts.ts +0 -1
  231. package/src/harness-control-plane/sdk-transport.ts +395 -0
  232. package/src/harness-control-plane/session-transport.ts +94 -0
  233. package/src/harness-control-plane/types.ts +1 -1
  234. package/src/internal-urls/docs-index.generated.ts +36 -37
  235. package/src/lsp/client.ts +42 -6
  236. package/src/lsp/index.ts +2 -2
  237. package/src/main.ts +299 -204
  238. package/src/modes/DESIGN.md +258 -0
  239. package/src/modes/acp/acp-agent.ts +1228 -2612
  240. package/src/modes/acp/acp-client-bridge.ts +2 -20
  241. package/src/modes/acp/acp-event-mapper.ts +18 -2
  242. package/src/modes/acp/acp-mode.ts +8 -36
  243. package/src/modes/acp/permission-mode.ts +25 -0
  244. package/src/modes/acp/startup-options.ts +6 -0
  245. package/src/modes/components/agent-dashboard.ts +37 -17
  246. package/src/modes/components/custom-editor.ts +1 -0
  247. package/src/modes/components/gajae-pet-widget.ts +169 -20
  248. package/src/modes/components/model-selector.ts +93 -35
  249. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  250. package/src/modes/components/pet-capability.ts +115 -0
  251. package/src/modes/components/pet-selector.ts +4 -6
  252. package/src/modes/components/settings-selector.ts +86 -11
  253. package/src/modes/components/welcome.ts +4 -4
  254. package/src/modes/controllers/command-controller.ts +1 -2
  255. package/src/modes/controllers/event-controller.ts +11 -16
  256. package/src/modes/controllers/extension-ui-controller.ts +357 -12
  257. package/src/modes/controllers/input-controller.ts +43 -13
  258. package/src/modes/controllers/selector-controller.ts +671 -44
  259. package/src/modes/index.ts +0 -22
  260. package/src/modes/interactive-mode.ts +108 -24
  261. package/src/modes/runtime-init.ts +298 -6
  262. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  263. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  264. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  265. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  266. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  267. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  268. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  269. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  270. package/src/modes/types.ts +16 -1
  271. package/src/runtime-mcp/client.ts +94 -19
  272. package/src/runtime-mcp/config.ts +27 -15
  273. package/src/runtime-mcp/manager.ts +343 -105
  274. package/src/runtime-mcp/oauth-flow.ts +42 -12
  275. package/src/runtime-mcp/transports/http.ts +49 -19
  276. package/src/runtime-mcp/transports/stdio.ts +47 -28
  277. package/src/runtime-mcp/types.ts +10 -0
  278. package/src/sdk/acp/adapter.ts +418 -0
  279. package/src/sdk/acp/index.ts +2 -0
  280. package/src/sdk/broker/broker.ts +642 -0
  281. package/src/sdk/broker/discovery.ts +94 -0
  282. package/src/sdk/broker/ensure.ts +249 -0
  283. package/src/sdk/broker/identity.ts +42 -0
  284. package/src/sdk/broker/index.ts +8 -0
  285. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  286. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  287. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  288. package/src/sdk/broker/lifecycle.ts +2157 -0
  289. package/src/sdk/broker/process-incarnation.ts +159 -0
  290. package/src/sdk/broker/runtime.ts +164 -0
  291. package/src/sdk/broker/session-index.ts +318 -0
  292. package/src/sdk/broker/state-version.ts +23 -0
  293. package/src/sdk/broker/transport.ts +125 -0
  294. package/src/sdk/bus/chat-command-policy.ts +107 -0
  295. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  296. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  297. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  298. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  299. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  300. package/src/sdk/bus/config.ts +433 -0
  301. package/src/sdk/bus/conversation-store.ts +391 -0
  302. package/src/sdk/bus/discord-conversation.ts +85 -0
  303. package/src/sdk/bus/discord-daemon.ts +2275 -0
  304. package/src/sdk/bus/discord-live-provider.ts +521 -0
  305. package/src/sdk/bus/discord-provider.ts +56 -0
  306. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  307. package/src/sdk/bus/index.ts +3943 -0
  308. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  309. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  310. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  311. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  312. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  313. package/src/sdk/bus/natives-augment.d.ts +38 -0
  314. package/src/sdk/bus/notification-orchestration.ts +535 -0
  315. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  316. package/src/sdk/bus/session-control.ts +333 -0
  317. package/src/sdk/bus/slack-conversation.ts +74 -0
  318. package/src/sdk/bus/slack-daemon.ts +2144 -0
  319. package/src/sdk/bus/slack-live-provider.ts +380 -0
  320. package/src/sdk/bus/slack-provider.ts +76 -0
  321. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  322. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  323. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  324. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  325. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  326. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  327. package/src/sdk/bus/telegram-setup.ts +663 -0
  328. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  329. package/src/sdk/cli/index.ts +1 -0
  330. package/src/sdk/cli/session-cli.ts +275 -0
  331. package/src/sdk/client/client.ts +1 -0
  332. package/src/sdk/client/discovery.ts +108 -0
  333. package/src/sdk/client/index.ts +2 -0
  334. package/src/sdk/host/control/dispatch.ts +367 -0
  335. package/src/sdk/host/control/index.ts +10 -0
  336. package/src/sdk/host/control/operations.ts +63 -0
  337. package/src/sdk/host/events.ts +91 -0
  338. package/src/sdk/host/host.ts +296 -0
  339. package/src/sdk/host/index.ts +4 -0
  340. package/src/sdk/host/query/cursor.ts +189 -0
  341. package/src/sdk/host/query/handlers.ts +533 -0
  342. package/src/sdk/host/query/index.ts +3 -0
  343. package/src/sdk/host/query/revision-store.ts +1126 -0
  344. package/src/sdk/host/reverse-leases.ts +325 -0
  345. package/src/sdk/host/types.ts +29 -0
  346. package/src/sdk/index.ts +13 -0
  347. package/src/sdk/lifecycle-session.ts +39 -0
  348. package/src/sdk/mcp/index.ts +1 -0
  349. package/src/sdk/mcp/server.ts +332 -0
  350. package/src/sdk/models.ts +168 -0
  351. package/src/sdk/protocol/adapter-validation.ts +48 -0
  352. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  353. package/src/sdk/protocol/operation-registry.ts +312 -0
  354. package/src/{sdk.ts → sdk/session.ts} +339 -212
  355. package/src/sdk/startup-capability.ts +189 -0
  356. package/src/session/agent-session.ts +2470 -866
  357. package/src/session/default-model-selection.ts +93 -0
  358. package/src/session/fallback-chain-controller.ts +136 -0
  359. package/src/session/session-manager.ts +447 -13
  360. package/src/session/session-storage.ts +8 -1
  361. package/src/setup/credential-auto-import.ts +290 -35
  362. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  363. package/src/slash-commands/builtin-registry.ts +33 -30
  364. package/src/task/executor.ts +62 -13
  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/telegram-send.ts +2 -2
  384. package/vendor/insane-search/MANIFEST.json +2 -1
  385. package/vendor/insane-search/engine/bias_check.py +4 -1
  386. package/vendor/insane-search/engine/phase0.py +26 -1
  387. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  388. package/dist/types/modes/bridge/auth.d.ts +0 -12
  389. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  390. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  391. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  392. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  393. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  394. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  395. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  396. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  397. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  398. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  399. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  400. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  401. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  402. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  403. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  404. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  405. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  406. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  407. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  408. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  409. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  410. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  411. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  412. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  413. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  414. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  415. package/dist/types/notifications/config.d.ts +0 -132
  416. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  417. package/src/modes/bridge/auth.ts +0 -41
  418. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  419. package/src/modes/bridge/bridge-mode.ts +0 -675
  420. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  421. package/src/modes/bridge/event-stream.ts +0 -70
  422. package/src/modes/rpc/host-tools.ts +0 -1
  423. package/src/modes/rpc/host-uris.ts +0 -1
  424. package/src/modes/rpc/rpc-client.ts +0 -1166
  425. package/src/modes/rpc/rpc-mode.ts +0 -1029
  426. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  427. package/src/modes/rpc/rpc-types.ts +0 -637
  428. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  429. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  430. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  431. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  432. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  433. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  434. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  435. package/src/modes/shared/agent-wire/responses.ts +0 -17
  436. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  437. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  438. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  439. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  440. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  441. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  442. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  443. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  444. package/src/notifications/config.ts +0 -219
  445. package/src/notifications/index.ts +0 -1835
  446. package/src/notifications/telegram-daemon-cli.ts +0 -243
  447. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  448. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  453. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  454. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  455. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  456. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  457. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  458. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  459. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  460. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  461. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  466. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  467. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  468. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  469. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  470. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  471. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  472. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  473. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  474. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
4
  import { getWorktreesDir } from "@gajae-code/utils/dirs";
5
- import { SPAWN_PROVENANCE_ENV } from "../notifications/config";
5
+ import { SPAWN_PROVENANCE_ENV } from "../sdk/bus/config";
6
6
  import type { WorkflowHudSummary } from "../skill-state/active-state";
7
7
  import { buildTeamHudSummary as buildWorkflowTeamHudSummary } from "../skill-state/workflow-hud";
8
8
  import { WORKFLOW_STATE_VERSION } from "../skill-state/workflow-state-contract";
@@ -208,7 +208,7 @@ export type GjcTeamNotificationDeliveryState =
208
208
  | "acknowledged";
209
209
 
210
210
  export type GjcTeamPaneAttemptResult = "sent" | "queued" | "deferred" | "failed";
211
- export type GjcTeamMailboxDeliveryTransportKind = "notifications_sdk" | "pane";
211
+ export type GjcTeamMailboxDeliveryTransportKind = "sdk" | "pane";
212
212
 
213
213
  export interface GjcTeamNotification {
214
214
  id: string;
@@ -235,7 +235,7 @@ export interface GjcTeamMailboxDeliveryInput {
235
235
  env: NodeJS.ProcessEnv;
236
236
  }
237
237
  export type GjcTeamMailboxDeliveryResult =
238
- | { transport: "notifications_sdk"; state: GjcTeamNotificationDeliveryState; reason?: string }
238
+ | { transport: "sdk"; state: GjcTeamNotificationDeliveryState; reason?: string }
239
239
  | { transport: "pane"; state: GjcTeamPaneAttemptResult; reason?: string };
240
240
  export interface GjcTeamMailboxDeliveryTransport {
241
241
  deliverMailboxMessage(input: GjcTeamMailboxDeliveryInput): Promise<GjcTeamMailboxDeliveryResult | null>;
@@ -1995,25 +1995,32 @@ function readCurrentTmuxLeaderContext(tmuxCommand: string, env: NodeJS.ProcessEn
1995
1995
  }
1996
1996
  return { sessionName, windowIndex, leaderPaneId, target: `${sessionName}:${windowIndex}` };
1997
1997
  }
1998
- type CommandPathResolver = (command: string) => string | null;
1999
-
2000
1998
  function isBunVirtualPath(candidate: string | undefined): boolean {
2001
- const normalized = candidate?.trim().replace(/\\/g, "/");
2002
- return normalized === "/$bunfs" || normalized?.startsWith("/$bunfs/") === true;
1999
+ const normalized = candidate?.trim().replace(/\\/g, "/").toLowerCase();
2000
+ return (
2001
+ normalized === "/$bunfs" ||
2002
+ normalized?.startsWith("/$bunfs/") === true ||
2003
+ normalized === "b:/~bun" ||
2004
+ normalized?.startsWith("b:/~bun/") === true
2005
+ );
2003
2006
  }
2004
2007
 
2005
- function resolveFallbackGjcWorkerCommand(
2006
- platform: NodeJS.Platform,
2007
- execPath: string,
2008
- which: CommandPathResolver,
2009
- ): string {
2010
- const pathModule = platform === "win32" ? path.win32 : path;
2011
- const quote = platform === "win32" ? powershellQuote : shellQuote;
2012
- const executable = execPath.trim();
2013
- if (executable && !isBunVirtualPath(executable) && pathModule.isAbsolute(executable)) return quote(executable);
2014
- const gjcPath = which("gjc")?.trim();
2015
- if (gjcPath && !isBunVirtualPath(gjcPath)) return quote(gjcPath);
2016
- return "gjc";
2008
+ function isAbsoluteRealPath(candidate: string | undefined, pathModule: typeof path): candidate is string {
2009
+ const normalized = candidate?.trim();
2010
+ return Boolean(normalized && !isBunVirtualPath(normalized) && pathModule.isAbsolute(normalized));
2011
+ }
2012
+ function isGjcExecutablePath(candidate: string | undefined, pathModule: typeof path): candidate is string {
2013
+ return isAbsoluteRealPath(candidate, pathModule) && /^gjc(?:[._-]|$)/i.test(pathModule.basename(candidate.trim()));
2014
+ }
2015
+
2016
+ function formatWorkerExecutable(platform: NodeJS.Platform, executable: string): string {
2017
+ return (platform === "win32" ? powershellQuote : shellQuote)(executable);
2018
+ }
2019
+
2020
+ function unresolvedWorkerAuthorityError(): Error {
2021
+ return new Error(
2022
+ "Unable to determine the GJC worker executable from this invocation. Set GJC_TEAM_WORKER_COMMAND to the exact GJC command, or launch GJC from a real executable path instead of a Bun virtual path.",
2023
+ );
2017
2024
  }
2018
2025
 
2019
2026
  export function resolveGjcWorkerCommand(
@@ -2022,24 +2029,36 @@ export function resolveGjcWorkerCommand(
2022
2029
  platform: NodeJS.Platform = process.platform,
2023
2030
  argv: string[] = process.argv,
2024
2031
  execPath = process.execPath,
2025
- which: CommandPathResolver = Bun.which,
2026
2032
  ): string {
2027
2033
  const explicit = env.GJC_TEAM_WORKER_COMMAND?.trim();
2028
- if (explicit) return explicit;
2029
- const entrypoint = argv[1];
2030
- if (isBunVirtualPath(entrypoint)) return resolveFallbackGjcWorkerCommand(platform, execPath, which);
2031
- if (!entrypoint) return "gjc";
2032
- const pathModule = platform === "win32" ? path.win32 : path;
2033
- const resolvedEntrypoint = pathModule.isAbsolute(entrypoint) ? entrypoint : pathModule.resolve(cwd, entrypoint);
2034
- if (platform === "win32") {
2035
- if (entrypoint.endsWith(".ts") || entrypoint.endsWith(".js") || entrypoint.endsWith(".mjs"))
2036
- return `${powershellQuote(execPath)} ${powershellQuote(resolvedEntrypoint)}`;
2037
- if (pathModule.basename(entrypoint).startsWith("gjc")) return powershellQuote(resolvedEntrypoint);
2038
- return "gjc";
2034
+ if (explicit) {
2035
+ if (isBunVirtualPath(explicit)) throw unresolvedWorkerAuthorityError();
2036
+ return explicit;
2037
+ }
2038
+
2039
+ const pathModule = platform === "win32" ? path.win32 : path.posix;
2040
+ const runtime = argv[0]?.trim();
2041
+ const entrypoint = argv[1]?.trim();
2042
+ const sourceEntrypoint = entrypoint && !isBunVirtualPath(entrypoint) && /\.(?:[cm]?[jt]s)$/i.test(entrypoint);
2043
+
2044
+ if (sourceEntrypoint) {
2045
+ const sourceRuntime = isAbsoluteRealPath(runtime, pathModule)
2046
+ ? runtime
2047
+ : isAbsoluteRealPath(execPath, pathModule)
2048
+ ? execPath.trim()
2049
+ : undefined;
2050
+ if (!sourceRuntime) throw unresolvedWorkerAuthorityError();
2051
+ const absoluteEntrypoint = pathModule.isAbsolute(entrypoint) ? entrypoint : pathModule.resolve(cwd, entrypoint);
2052
+ if (!isAbsoluteRealPath(absoluteEntrypoint, pathModule)) throw unresolvedWorkerAuthorityError();
2053
+ return `${formatWorkerExecutable(platform, sourceRuntime)} ${formatWorkerExecutable(platform, absoluteEntrypoint)}`;
2039
2054
  }
2040
- if (entrypoint.endsWith(".ts")) return `${shellQuote(execPath)} ${shellQuote(resolvedEntrypoint)}`;
2041
- if (path.basename(entrypoint).startsWith("gjc")) return shellQuote(path.resolve(cwd, entrypoint));
2042
- return "gjc";
2055
+
2056
+ const executable =
2057
+ (isGjcExecutablePath(entrypoint, pathModule) ? entrypoint : undefined) ??
2058
+ (isGjcExecutablePath(execPath, pathModule) ? execPath.trim() : undefined) ??
2059
+ (isGjcExecutablePath(runtime, pathModule) ? runtime : undefined);
2060
+ if (!executable) throw unresolvedWorkerAuthorityError();
2061
+ return formatWorkerExecutable(platform, executable);
2043
2062
  }
2044
2063
  /** @internal Exported for unit tests. */
2045
2064
  export function buildWorkerCommand(
@@ -4010,7 +4029,7 @@ async function attemptConfiguredMailboxTransport(
4010
4029
  env,
4011
4030
  });
4012
4031
  if (!result) return null;
4013
- if (result.transport === "notifications_sdk" && result.state === "failed") return null;
4032
+ if (result.transport === "sdk" && result.state === "failed") return null;
4014
4033
  return writeNotificationRecord(dir, {
4015
4034
  ...notification,
4016
4035
  delivery_state: result.state,
@@ -53,27 +53,63 @@ function isKnownNoServerDiagnostic(stderr: string): boolean {
53
53
  );
54
54
  }
55
55
 
56
- async function tmuxServerProof(socketKey: string, tmuxControlArgv?: string[]): Promise<TmuxServerProof> {
57
- void socketKey;
58
- if (!tmuxControlArgv?.length) return { state: "unverifiable" };
59
- const controlArgv = tmuxControlArgv;
56
+ interface TmuxListSessionsResult {
57
+ exitCode: number | null;
58
+ stdout: string;
59
+ stderr: string;
60
+ }
61
+
62
+ interface TmuxServerProofOptions {
63
+ platform?: NodeJS.Platform;
64
+ runListSessions?: (argv: string[]) => TmuxListSessionsResult;
65
+ }
66
+
67
+ function runTmuxListSessions(controlArgv: string[]): TmuxListSessionsResult {
60
68
  const subprocess = Bun.spawnSync([...controlArgv, "list-sessions", "-F", "#{pid}\t#{session_name}"], {
61
69
  stdout: "pipe",
62
70
  stderr: "pipe",
63
71
  });
64
- const stderr = Buffer.from(subprocess.stderr).toString();
72
+ return {
73
+ exitCode: subprocess.exitCode,
74
+ stdout: Buffer.from(subprocess.stdout).toString(),
75
+ stderr: Buffer.from(subprocess.stderr).toString(),
76
+ };
77
+ }
78
+
79
+ function parseTmuxSessionRows(stdout: string): { pid: number; sessionNames: string[] } | null {
80
+ const lines = stdout.split("\n");
81
+ if (lines[lines.length - 1] === "") lines.pop();
82
+ let pid: number | undefined;
83
+ const sessionNames: string[] = [];
84
+ for (const rawLine of lines) {
85
+ const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
86
+ const columns = line.split("\t");
87
+ if (columns.length !== 2 || !/^[1-9]\d*$/.test(columns[0]) || !columns[1].trim()) return null;
88
+ const rowPid = Number(columns[0]);
89
+ if (!Number.isSafeInteger(rowPid) || (pid !== undefined && pid !== rowPid)) return null;
90
+ pid = rowPid;
91
+ sessionNames.push(columns[1]);
92
+ }
93
+ return pid === undefined ? null : { pid, sessionNames };
94
+ }
95
+
96
+ /** Probes a tmux server using an injectable list-sessions runner for platform-bounded callers. */
97
+ export async function tmuxServerProof(
98
+ socketKey: string,
99
+ tmuxControlArgv?: string[],
100
+ options: TmuxServerProofOptions = {},
101
+ ): Promise<TmuxServerProof> {
102
+ void socketKey;
103
+ if (!tmuxControlArgv?.length) return { state: "unverifiable" };
104
+ const platform = options.platform ?? process.platform;
105
+ const subprocess = options.runListSessions?.(tmuxControlArgv) ?? runTmuxListSessions(tmuxControlArgv);
65
106
  if (subprocess.exitCode !== 0)
66
- return isKnownNoServerDiagnostic(stderr) ? { state: "absent" } : { state: "unverifiable" };
67
- const lines = Buffer.from(subprocess.stdout)
68
- .toString()
69
- .split("\n")
70
- .map(line => line.trim())
71
- .filter(Boolean);
72
- const [pidText] = lines[0]?.split("\t") ?? [];
73
- const pid = Number(pidText);
74
- const sessionNames = lines.map(line => line.split("\t")[1]).filter((name): name is string => Boolean(name));
75
- if (!Number.isSafeInteger(pid) || pid <= 0) return { state: "unverifiable" };
76
- if (process.platform !== "linux") {
107
+ return isKnownNoServerDiagnostic(subprocess.stderr) ? { state: "absent" } : { state: "unverifiable" };
108
+ if (!subprocess.stdout.trim()) return { state: "absent" };
109
+ const rows = parseTmuxSessionRows(subprocess.stdout);
110
+ if (!rows) return { state: "unverifiable" };
111
+ const { pid, sessionNames } = rows;
112
+ if (platform !== "linux") {
77
113
  return {
78
114
  state: "safe",
79
115
  pid,
@@ -82,7 +118,7 @@ async function tmuxServerProof(socketKey: string, tmuxControlArgv?: string[]): P
82
118
  sessionNames,
83
119
  };
84
120
  }
85
- const cgroup = classifyCgroup({ platform: process.platform, cgroupText: await readCgroup(String(pid)) });
121
+ const cgroup = classifyCgroup({ platform, cgroupText: await readCgroup(String(pid)) });
86
122
  const startTime = await readProcessStartTime(pid);
87
123
  if (!startTime) return { state: "unverifiable", pid, cgroup, sessionNames };
88
124
  return {
@@ -86,7 +86,10 @@ export function classifyCgroup(input: { platform: NodeJS.Platform; cgroupText?:
86
86
  diagnostic: "service_cgroup_inheritance",
87
87
  };
88
88
  const scope = paths.find(value => /(?:^|\/)(?:user|session|app|init|gjc)[^/]*\.scope(?:\/|$)/.test(value));
89
- if (scope) return { classification: "safe", scope };
89
+ const vteScope = paths.find(value =>
90
+ /^\/user\.slice\/user-(\d+)\.slice\/user@\1\.service(?:\/[^/]+)*\/vte-spawn-[A-Za-z0-9_.-]+\.scope$/.test(value),
91
+ );
92
+ if (scope || vteScope) return { classification: "safe", scope: scope ?? vteScope };
90
93
  if (paths.every(value => value === "/")) return { classification: "safe", scope: "/" };
91
94
  return {
92
95
  classification: "unverifiable",
@@ -1521,7 +1524,7 @@ export function isValidOwnerIntent(intent: unknown, request?: ObserveTerminalReq
1521
1524
  intent.generation === request.owner_generation &&
1522
1525
  intent.session_id === request.session_id &&
1523
1526
  intent.server_key === request.socket_key &&
1524
- intent.dispatch_id === request.operator_dispatch_id &&
1527
+ (request.operator_dispatch_id === undefined || intent.dispatch_id === request.operator_dispatch_id) &&
1525
1528
  request.signal === "SIGTERM"
1526
1529
  );
1527
1530
  }
@@ -49,6 +49,7 @@ import {
49
49
  type TmuxOwnerIsolationExecutionResult,
50
50
  type TmuxServerProof,
51
51
  } from "./tmux-owner-isolation";
52
+ import { buildWindowsPowerShellInnerCommand } from "./windows-powershell-command";
52
53
 
53
54
  export interface GjcTmuxSessionStatus {
54
55
  name: string;
@@ -128,6 +129,10 @@ export interface ForceCloseOwnerDependencies {
128
129
  const FORCE_CLOSE_VERDICT_TIMEOUT_MS = 5_000;
129
130
  const FORCE_CLOSE_VERDICT_POLL_MS = 50;
130
131
 
132
+ export interface CreateGjcTmuxSessionOptions {
133
+ platform?: NodeJS.Platform;
134
+ }
135
+
131
136
  export type CreateOwnerIsolationTestDependencies = {
132
137
  probe?: Partial<OwnerIsolationProbeSync>;
133
138
  execute?: (plan: PlanResponse, deps: TmuxOwnerIsolationExecutionDependencies) => TmuxOwnerIsolationExecutionResult;
@@ -354,15 +359,19 @@ export function statusGjcTmuxSession(sessionName: string, env: NodeJS.ProcessEnv
354
359
  throw new Error(`gjc_tmux_session_not_found:${sessionName}`);
355
360
  }
356
361
 
357
- export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcTmuxSessionStatus {
358
- const tmuxCommand = resolveGjcTmuxCommand(env);
362
+ export function createGjcTmuxSession(
363
+ env: NodeJS.ProcessEnv = process.env,
364
+ options: CreateGjcTmuxSessionOptions = {},
365
+ ): GjcTmuxSessionStatus {
366
+ const platform = options.platform ?? process.platform;
367
+ const tmuxCommand = resolveGjcTmuxCommand(env, platform);
359
368
  const sessionName = buildGjcTmuxSessionName(env);
360
369
  const cwd = process.cwd();
361
370
  const sessionId = env[GJC_COORDINATOR_SESSION_ID_ENV]?.trim() || sessionName;
362
371
  const stateFile =
363
372
  env[GJC_COORDINATOR_SESSION_STATE_FILE_ENV]?.trim() ||
364
373
  tmuxRuntimeSessionPath(cwd, env.GJC_SESSION_ID?.trim() || sessionId, buildGjcTmuxSessionSlug(sessionName));
365
- const stateDir = path.dirname(stateFile);
374
+ const stateDir = (platform === "win32" ? path.win32 : path).dirname(stateFile);
366
375
  const generation = crypto.randomUUID();
367
376
  const childEnvironment: Record<string, string> = {
368
377
  GJC_TMUX_LAUNCHED: "1",
@@ -373,12 +382,9 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
373
382
  [GJC_COORDINATOR_SESSION_STATE_FILE_ENV]: stateFile,
374
383
  };
375
384
  const shellQuote = (value: string): string => `'${value.replace(/'/g, `'\\''`)}'`;
376
- const powershellQuote = (value: string): string => `'${value.replace(/'/g, "''")}'`;
377
385
  const command =
378
- process.platform === "win32"
379
- ? `${Object.entries(childEnvironment)
380
- .map(([name, value]) => `$env:${name} = ${powershellQuote(value)}`)
381
- .join("; ")}; gjc`
386
+ platform === "win32"
387
+ ? buildWindowsPowerShellInnerCommand({ command: ["gjc"], environment: childEnvironment })
382
388
  : `exec env ${Object.entries(childEnvironment)
383
389
  .map(([name, value]) => `${name}=${shellQuote(value)}`)
384
390
  .join(" ")} gjc`;
@@ -388,11 +394,11 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
388
394
  "-d",
389
395
  "-s",
390
396
  sessionName,
391
- ...(process.platform === "win32" ? [] : ["-P", "-F", "#{session_id}"]),
397
+ ...(platform === "win32" ? [] : ["-P", "-F", "#{session_id}"]),
392
398
  command,
393
399
  ];
394
400
  function probeTmuxServer(tmuxCommand: string, env: NodeJS.ProcessEnv): TmuxServerProof {
395
- if (process.platform !== "linux") {
401
+ if (platform !== "linux") {
396
402
  return {
397
403
  state: "safe",
398
404
  pid: 1,
@@ -421,7 +427,7 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
421
427
  .split(/\s+/)[19];
422
428
  if (!startTime) return { state: "unverifiable" };
423
429
  const cgroup = classifyCgroup({
424
- platform: process.platform,
430
+ platform,
425
431
  cgroupText: fsSync.readFileSync(`/proc/${pid}/cgroup`, "utf8"),
426
432
  });
427
433
  return {
@@ -484,7 +490,7 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
484
490
  }
485
491
  }),
486
492
  };
487
- if (resolveGjcTmuxBinary({ env }).isPsmux)
493
+ if (resolveGjcTmuxBinary({ env, platform }).isPsmux)
488
494
  throw new Error("gjc_tmux_owner_isolation_native_session_identity_unavailable");
489
495
 
490
496
  const baseline = captureOwnerGenerationBaselineSync(stateDir, sessionId);
@@ -492,7 +498,7 @@ export function createGjcTmuxSession(env: NodeJS.ProcessEnv = process.env): GjcT
492
498
  {
493
499
  schema_version: 1,
494
500
  op: "plan",
495
- platform: process.platform,
501
+ platform,
496
502
  session_id: sessionId,
497
503
  owner_generation: generation,
498
504
  baseline,
@@ -174,6 +174,39 @@ function findReceiptGoal(
174
174
  return storyGoal ? { goal: storyGoal, receiptKind: "per-goal" } : null;
175
175
  }
176
176
 
177
+ /**
178
+ * A review-blocker replacement can stand in for a superseded validation-batch
179
+ * final only while validating the run's final aggregate receipt. Ordinary
180
+ * per-goal validation continues to require the original batch-close receipt.
181
+ */
182
+ function hasFreshReviewedBatchFinalReplacement(input: {
183
+ plan: UltragoalPlan;
184
+ ledger: readonly UltragoalLedgerEvent[];
185
+ deferredGoal: UltragoalGoal;
186
+ }): boolean {
187
+ const finalGoalId = input.deferredGoal.completionVerification?.validationBatch?.finalGoalId;
188
+ const finalGoal = finalGoalId ? input.plan.goals.find(goal => goal.id === finalGoalId) : undefined;
189
+ if (finalGoal?.status !== "superseded") return false;
190
+ const replacements = input.plan.goals.filter(
191
+ goal =>
192
+ goal.status === "complete" &&
193
+ goal.steering?.kind === "review_blocker" &&
194
+ goal.steering.blockedGoalId === finalGoal.id,
195
+ );
196
+ if (replacements.length !== 1) return false;
197
+ const replacement = replacements[0]!;
198
+ const receipt = replacement.completionVerification;
199
+ if (receipt?.receiptKind !== "per-goal") return false;
200
+ return (
201
+ validateCompletionReceipt({
202
+ plan: input.plan,
203
+ ledger: input.ledger,
204
+ goal: replacement,
205
+ receiptKind: "per-goal",
206
+ }).state === "active_verified_complete"
207
+ );
208
+ }
209
+
177
210
  export function validateCompletionReceipt(input: {
178
211
  plan: UltragoalPlan;
179
212
  ledger: readonly UltragoalLedgerEvent[];
@@ -267,12 +300,26 @@ export function validateCompletionReceipt(input: {
267
300
  goalId: input.goal.id,
268
301
  };
269
302
  }
270
- const priorDiagnostic = validateCompletionReceipt({
271
- plan: input.plan,
272
- ledger: input.ledger,
273
- goal: priorGoal,
274
- receiptKind: "per-goal",
275
- });
303
+ const priorDiagnostic =
304
+ priorGoal.completionVerification.validationBatch?.role === "deferred-member"
305
+ ? validateDeferredMemberReceiptFresh({
306
+ plan: input.plan,
307
+ ledger: input.ledger,
308
+ goal: priorGoal,
309
+ receipt: priorGoal.completionVerification,
310
+ receiptKind: "per-goal",
311
+ requireClose: !hasFreshReviewedBatchFinalReplacement({
312
+ plan: input.plan,
313
+ ledger: input.ledger,
314
+ deferredGoal: priorGoal,
315
+ }),
316
+ })
317
+ : validateCompletionReceipt({
318
+ plan: input.plan,
319
+ ledger: input.ledger,
320
+ goal: priorGoal,
321
+ receiptKind: "per-goal",
322
+ });
276
323
  if (priorDiagnostic.state !== "active_verified_complete") {
277
324
  return {
278
325
  state: priorDiagnostic.state,
@@ -9,6 +9,7 @@ import { DEFAULT_ULTRAGOAL_OBJECTIVE } from "./goal-mode-request";
9
9
  import {
10
10
  computeUltragoalPlanGeneration,
11
11
  findFreshBatchCloseReceipt,
12
+ findLedgerReceiptEvent,
12
13
  requiredUltragoalGoals,
13
14
  validateDeferredMemberReceiptFresh,
14
15
  validateReceiptFreshBase,
@@ -3451,7 +3452,12 @@ function canonicalChangeSetRows(value: unknown, fieldName: string): UltragoalCha
3451
3452
  if ("goalId" in record) throw new Error(`${fieldName}[${index}] must not contain goalId attribution`);
3452
3453
  const status = nonEmptyString(record.status);
3453
3454
  if (!status) throw new Error(`${fieldName}[${index}].status is required`);
3454
- return { path: normalizeRepoPath(pathValue), status: status as UltragoalChangeStatus };
3455
+ const oldPath = nonEmptyString(record.oldPath);
3456
+ return {
3457
+ path: normalizeRepoPath(pathValue),
3458
+ status: status as UltragoalChangeStatus,
3459
+ ...(oldPath ? { oldPath: normalizeRepoPath(oldPath) } : {}),
3460
+ };
3455
3461
  });
3456
3462
  }
3457
3463
 
@@ -3711,6 +3717,140 @@ function validateBatchCloseQualityGate(
3711
3717
  throw new Error("validationBatchClose.unionChangeSet.unionHash does not match declared union");
3712
3718
  requireNonEmptyString(close.coverageEvidence, "validationBatchClose.coverageEvidence");
3713
3719
  }
3720
+
3721
+ function hydrateReviewedBatchReplacementClose(input: {
3722
+ gate: JsonObject;
3723
+ plan: UltragoalPlan;
3724
+ goal: UltragoalGoal;
3725
+ metadata: UltragoalValidationBatchMetadata;
3726
+ ledger: readonly UltragoalLedgerEvent[];
3727
+ changeSet?: UltragoalChangeSet;
3728
+ }): JsonObject {
3729
+ const requested = qualityGateObject(input.gate.validationBatchClose);
3730
+ if (requested?.kind !== "review-blocker-replacement-close") return input.gate;
3731
+ const expectedKeys = new Set(["schemaVersion", "kind", "replacementGoalId", "coverageEvidence"]);
3732
+ if (Object.keys(requested).some(key => !expectedKeys.has(key)))
3733
+ throw new Error("review-blocker replacement close contains unsupported fields");
3734
+ const replacementGoalId = nonEmptyString(requested.replacementGoalId);
3735
+ const coverageEvidence = nonEmptyString(requested.coverageEvidence);
3736
+ if (requested.schemaVersion !== 1 || !replacementGoalId || !coverageEvidence)
3737
+ throw new Error("review-blocker replacement close is malformed");
3738
+ if (input.goal.status !== "active" || input.metadata.finalGoalId !== input.goal.id)
3739
+ throw new Error("review-blocker replacement close requires the active durable validation-batch final goal");
3740
+ if (!input.changeSet) throw new Error("review-blocker replacement close requires a current cumulative change set");
3741
+
3742
+ const replacements = input.plan.goals.filter(
3743
+ goal => goal.steering?.kind === "review_blocker" && goal.steering.blockedGoalId === input.goal.id,
3744
+ );
3745
+ if (replacements.length !== 1 || replacements[0]?.id !== replacementGoalId)
3746
+ throw new Error("review-blocker replacement close requires exactly the declared replacement");
3747
+ const replacement = replacements[0]!;
3748
+ const replacementReceipt = replacement.completionVerification;
3749
+ if (replacement.status !== "complete" || replacementReceipt?.receiptKind !== "per-goal")
3750
+ throw new Error("review-blocker replacement close requires a completed per-goal replacement receipt");
3751
+ const replacementDiagnostic = validateReceiptFreshBase({
3752
+ plan: input.plan,
3753
+ ledger: input.ledger,
3754
+ goal: replacement,
3755
+ receipt: replacementReceipt,
3756
+ receiptKind: "per-goal",
3757
+ });
3758
+ if (replacementDiagnostic) throw new Error(`review-blocker replacement close ${replacementDiagnostic.message}`);
3759
+ const replacementCheckpointIndex = input.ledger.findIndex(
3760
+ event => event.eventId === replacementReceipt.checkpointLedgerEventId,
3761
+ );
3762
+ const reviewRecordedIndex = input.ledger.findIndex(
3763
+ event =>
3764
+ event.event === "review_blockers_recorded" &&
3765
+ event.goalId === input.goal.id &&
3766
+ event.blockerGoalId === replacement.id,
3767
+ );
3768
+ const reactivatedIndex = input.ledger.findIndex(
3769
+ (event, index) =>
3770
+ index > replacementCheckpointIndex &&
3771
+ event.event === "goal_checkpointed" &&
3772
+ event.goalId === input.goal.id &&
3773
+ event.status === "active",
3774
+ );
3775
+ if (reviewRecordedIndex < 0 || reviewRecordedIndex >= replacementCheckpointIndex || reactivatedIndex < 0)
3776
+ throw new Error("review-blocker replacement close lacks durable supersession and reopening evidence");
3777
+
3778
+ const historicalRequiredGoalIds = input.plan.goals
3779
+ .filter(goal => goal.id !== input.goal.id && goal.status !== "superseded")
3780
+ .map(goal => goal.id);
3781
+ const aggregateGoals = input.plan.goals.filter(goal => {
3782
+ const receipt = goal.completionVerification;
3783
+ return goal.status === "complete" && receipt?.receiptKind === "final-aggregate";
3784
+ });
3785
+ const aggregateGoal = aggregateGoals.find(goal => {
3786
+ const receipt = goal.completionVerification!;
3787
+ const event = findLedgerReceiptEvent(input.ledger, receipt);
3788
+ return (
3789
+ event !== null &&
3790
+ hashStructuredValue(event.qualityGateJson) === receipt.qualityGateHash &&
3791
+ goal.updatedAt === receipt.verifiedAt &&
3792
+ receipt.basis.relevantGoalIdsBeforeCheckpoint.length === historicalRequiredGoalIds.length &&
3793
+ receipt.basis.relevantGoalIdsBeforeCheckpoint.every(
3794
+ (goalId, index) => goalId === historicalRequiredGoalIds[index],
3795
+ )
3796
+ );
3797
+ });
3798
+ if (!aggregateGoal)
3799
+ throw new Error(
3800
+ "review-blocker replacement close requires a fresh final-aggregate receipt covering required goals",
3801
+ );
3802
+
3803
+ const memberMetadataHashes: Record<string, string> = {};
3804
+ const memberChangeSetHashes: Record<string, string> = {};
3805
+ const memberReceipts: JsonObject[] = [];
3806
+ for (const memberId of input.metadata.memberIds) {
3807
+ const member = input.plan.goals.find(goal => goal.id === memberId);
3808
+ if (!member?.validationBatch)
3809
+ throw new Error(`review-blocker replacement close references missing batch member ${memberId}`);
3810
+ memberMetadataHashes[memberId] = member.validationBatch.metadataHash;
3811
+ if (memberId === input.goal.id) continue;
3812
+ const receipt = requireDeferredMemberReceiptFresh(
3813
+ input.plan,
3814
+ input.ledger,
3815
+ member,
3816
+ "review-blocker replacement close",
3817
+ );
3818
+ memberChangeSetHashes[memberId] = receipt.validationBatch.changeSetHash;
3819
+ memberReceipts.push({
3820
+ goalId: memberId,
3821
+ receiptId: receipt.receiptId,
3822
+ checkpointLedgerEventId: receipt.checkpointLedgerEventId,
3823
+ qualityGateHash: receipt.qualityGateHash,
3824
+ changeSetHash: receipt.validationBatch.changeSetHash,
3825
+ role: "deferred-member",
3826
+ });
3827
+ }
3828
+ const paths = input.changeSet.paths.map(row => ({ ...row }));
3829
+ memberChangeSetHashes[input.goal.id] = changeSetHashForPaths(paths);
3830
+ const unionHash = hashStructuredValue({
3831
+ memberChangeSetHashes,
3832
+ paths: paths.map(row => ({ path: row.path, status: row.status, oldPath: row.oldPath })),
3833
+ });
3834
+ return {
3835
+ ...input.gate,
3836
+ validationBatchClose: {
3837
+ schemaVersion: 1,
3838
+ kind: "validation-batch-close",
3839
+ batchId: input.metadata.batchId,
3840
+ finalGoalId: input.metadata.finalGoalId,
3841
+ memberIds: [...input.metadata.memberIds],
3842
+ memberMetadataHashes,
3843
+ memberReceipts,
3844
+ unionChangeSet: {
3845
+ source: "validation-batch",
3846
+ memberChangeSetHashes,
3847
+ paths,
3848
+ unionHash,
3849
+ },
3850
+ coverageEvidence,
3851
+ },
3852
+ };
3853
+ }
3714
3854
  async function readRequiredCompletionQualityGate(
3715
3855
  cwd: string,
3716
3856
  value: string | undefined,
@@ -3729,13 +3869,25 @@ async function readRequiredCompletionQualityGate(
3729
3869
  const gate = await readStructuredValue(cwd, value);
3730
3870
  const gateObject = qualityGateObject(gate);
3731
3871
  if (!gateObject) throw new Error("qualityGate must be a JSON object");
3732
- await validateCompletionQualityGate(cwd, gateObject, {
3872
+ const validationBatch = options.goal ? requireFreshValidationBatchMetadata(options.goal) : undefined;
3873
+ const hydratedGate =
3874
+ validationBatch && options.plan && options.goal && options.ledger
3875
+ ? hydrateReviewedBatchReplacementClose({
3876
+ gate: gateObject,
3877
+ plan: options.plan,
3878
+ goal: options.goal,
3879
+ metadata: validationBatch,
3880
+ ledger: options.ledger,
3881
+ changeSet: options.changeSet,
3882
+ })
3883
+ : gateObject;
3884
+ await validateCompletionQualityGate(cwd, hydratedGate, {
3733
3885
  changeSet: options.changeSet,
3734
3886
  plan: options.plan,
3735
3887
  goal: options.goal,
3736
3888
  ledger: options.ledger,
3737
3889
  });
3738
- return gate;
3890
+ return hydratedGate;
3739
3891
  }
3740
3892
 
3741
3893
  function validatePipelineCheckpointSafety(
@@ -0,0 +1,58 @@
1
+ import { Buffer } from "node:buffer";
2
+ import * as path from "node:path";
3
+
4
+ export const GJC_TMUX_LAUNCHED_ENV = "GJC_TMUX_LAUNCHED";
5
+
6
+ export interface WindowsPowerShellInnerCommandOptions {
7
+ command: readonly string[];
8
+ args?: readonly string[];
9
+ environment?: Record<string, string>;
10
+ tmuxExitMarkerPath?: string;
11
+ }
12
+
13
+ function powershellQuote(value: string): string {
14
+ return `'${value.replace(/'/g, "''")}'`;
15
+ }
16
+
17
+ function buildPowerShellTmuxExitMarkerFinally(markerPath: string): string {
18
+ const markerDir = path.win32.dirname(markerPath);
19
+ return [
20
+ "} finally {",
21
+ "\ttry {",
22
+ `\t\tNew-Item -ItemType Directory -Force -Path ${powershellQuote(markerDir)} -ErrorAction Stop | Out-Null`,
23
+ "\t\t$__gjcTmuxExitMarker = @{ schema_version = 1; source = 'tmux_inner_shell'; ended_at = (Get-Date).ToUniversalTime().ToString('o'); exit_code = $__gjcTmuxExitCode } | ConvertTo-Json -Compress",
24
+ `\t\tSet-Content -LiteralPath ${powershellQuote(markerPath)} -Value $__gjcTmuxExitMarker -Encoding UTF8 -ErrorAction Stop`,
25
+ "\t} catch {",
26
+ "\t}",
27
+ "}",
28
+ ].join("\n");
29
+ }
30
+
31
+ /** Builds the shared BOM-free UTF-16LE command for native Windows tmux-compatible panes. */
32
+ export function buildWindowsPowerShellInnerCommand({
33
+ command,
34
+ args = [],
35
+ environment,
36
+ tmuxExitMarkerPath,
37
+ }: WindowsPowerShellInnerCommandOptions): string {
38
+ const envLines = Object.entries({ [GJC_TMUX_LAUNCHED_ENV]: "1", ...(environment ?? {}) }).map(
39
+ ([key, value]) => `$env:${key} = ${powershellQuote(value)}`,
40
+ );
41
+ const resolvedCommand = command.map(powershellQuote).join(" ");
42
+ const innerArgs = args.map(powershellQuote).join(" ");
43
+ const invocation = `& ${resolvedCommand} ${innerArgs}`;
44
+ const exitLine = "if ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 }";
45
+ const script = tmuxExitMarkerPath
46
+ ? [
47
+ ...envLines,
48
+ "$__gjcTmuxExitCode = 1",
49
+ "try {",
50
+ `\t${invocation}`,
51
+ "\tif ($null -ne $LASTEXITCODE) { $__gjcTmuxExitCode = $LASTEXITCODE } else { $__gjcTmuxExitCode = 1 }",
52
+ buildPowerShellTmuxExitMarkerFinally(tmuxExitMarkerPath),
53
+ "exit $__gjcTmuxExitCode",
54
+ ].join("\n")
55
+ : [...envLines, invocation, exitLine].join("\n");
56
+ const encodedCommand = Buffer.from(script, "utf16le").toString("base64");
57
+ return `pwsh -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${encodedCommand}`;
58
+ }