@gajae-code/coding-agent 0.18.7 → 0.18.9

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 (344) hide show
  1. package/CHANGELOG.md +377 -1
  2. package/dist/types/async/endpoint-id.d.ts +16 -0
  3. package/dist/types/async/job-manager.d.ts +1 -1
  4. package/dist/types/async/support.d.ts +0 -14
  5. package/dist/types/capability/mcp.d.ts +2 -0
  6. package/dist/types/capability/skill.d.ts +2 -0
  7. package/dist/types/capability/types.d.ts +2 -0
  8. package/dist/types/cli/public-command-errors.d.ts +3 -1
  9. package/dist/types/cli/setup-cli.d.ts +1 -1
  10. package/dist/types/commands/deep-interview.d.ts +3 -0
  11. package/dist/types/commands/mcp-serve.d.ts +4 -0
  12. package/dist/types/config/autorouting-tier-map.d.ts +348 -9
  13. package/dist/types/config/file-lock.d.ts +1 -0
  14. package/dist/types/config/model-bindings-applier.d.ts +2 -0
  15. package/dist/types/config/model-profile-activation.d.ts +11 -3
  16. package/dist/types/config/model-registry.d.ts +4 -9
  17. package/dist/types/config/skill-settings-defaults.d.ts +2 -0
  18. package/dist/types/cursor-delete-path.d.ts +1 -0
  19. package/dist/types/cursor-mcp-name.d.ts +8 -0
  20. package/dist/types/customization/inventory.d.ts +2 -0
  21. package/dist/types/debug/report-bundle-parent.d.ts +2 -0
  22. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.d.ts +1 -0
  23. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.d.ts +31 -0
  24. package/dist/types/defaults/gjc-skills.generated.d.ts +5 -6
  25. package/dist/types/discovery/helpers.d.ts +6 -1
  26. package/dist/types/discovery/mcp-json.d.ts +1 -0
  27. package/dist/types/eval/py/kernel.d.ts +18 -0
  28. package/dist/types/export/html/css-color.d.ts +2 -0
  29. package/dist/types/export/html/html-export-destination.d.ts +2 -0
  30. package/dist/types/export/html/template.generated.d.ts +1 -1
  31. package/dist/types/extensibility/extensions/function-hooks-internal.d.ts +5 -0
  32. package/dist/types/extensibility/extensions/types.d.ts +7 -0
  33. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +14 -1
  34. package/dist/types/extensibility/plugins/marketplace/cache.d.ts +2 -0
  35. package/dist/types/extensibility/plugins/plugin-link-path.d.ts +2 -0
  36. package/dist/types/extensibility/runtime-skill-discovery.d.ts +3 -1
  37. package/dist/types/extensibility/skill-management.d.ts +4 -1
  38. package/dist/types/extensibility/skills.d.ts +2 -0
  39. package/dist/types/gjc-runtime/deep-interview-crystallize.d.ts +74 -0
  40. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +11 -0
  41. package/dist/types/gjc-runtime/gc-runtime.d.ts +5 -0
  42. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -3
  43. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +0 -5
  44. package/dist/types/gjc-runtime/sidecar-bootstrap-env.d.ts +6 -0
  45. package/dist/types/gjc-runtime/state-argv.d.ts +1 -1
  46. package/dist/types/gjc-runtime/state-migrations.d.ts +8 -0
  47. package/dist/types/gjc-runtime/state-runtime.d.ts +95 -0
  48. package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
  49. package/dist/types/gjc-runtime/tmux-common.d.ts +8 -5
  50. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -0
  51. package/dist/types/internal-urls/skill-path.d.ts +1 -0
  52. package/dist/types/lsp/config.d.ts +8 -5
  53. package/dist/types/lsp/workspace-path.d.ts +1 -0
  54. package/dist/types/modes/acp/acp-agent.d.ts +7 -0
  55. package/dist/types/modes/components/custom-editor.d.ts +6 -0
  56. package/dist/types/modes/components/customization/customization-dashboard.d.ts +1 -0
  57. package/dist/types/modes/components/extensions/state-manager.d.ts +4 -3
  58. package/dist/types/modes/controllers/input-controller.d.ts +9 -0
  59. package/dist/types/modes/interactive-mode.d.ts +1 -0
  60. package/dist/types/modes/utils/interrupt-ownership.d.ts +3 -0
  61. package/dist/types/modes/utils/keybinding-matchers.d.ts +1 -0
  62. package/dist/types/modes/utils/macos-option-forwarding.d.ts +17 -0
  63. package/dist/types/progress/collect-project-progress.d.ts +38 -0
  64. package/dist/types/progress/progress-contract.d.ts +154 -0
  65. package/dist/types/progress/progress-snapshot.d.ts +11 -0
  66. package/dist/types/progress/project-progress.d.ts +141 -0
  67. package/dist/types/progress/render-progress.d.ts +28 -0
  68. package/dist/types/runtime-mcp/manager.d.ts +2 -1
  69. package/dist/types/runtime-mcp/mcp-redirect.d.ts +9 -0
  70. package/dist/types/runtime-mcp/oauth-public-url.d.ts +3 -0
  71. package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +1 -0
  72. package/dist/types/runtime-mcp/project-host-values.d.ts +27 -0
  73. package/dist/types/runtime-mcp/smithery-registry.d.ts +24 -0
  74. package/dist/types/runtime-mcp/types.d.ts +6 -0
  75. package/dist/types/sdk/acp/adapter.d.ts +1 -1
  76. package/dist/types/sdk/broker/broker-exit.d.ts +6 -2
  77. package/dist/types/sdk/broker/broker.d.ts +24 -2
  78. package/dist/types/sdk/broker/doctor-restart.d.ts +5 -0
  79. package/dist/types/sdk/broker/ensure.d.ts +14 -1
  80. package/dist/types/sdk/broker/session-index.d.ts +12 -6
  81. package/dist/types/sdk/bus/index.d.ts +12 -1
  82. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -1
  83. package/dist/types/sdk/client/client.d.ts +2 -0
  84. package/dist/types/sdk/host/query/handlers.d.ts +3 -0
  85. package/dist/types/sdk/index.d.ts +1 -0
  86. package/dist/types/sdk/router/session-router.d.ts +2 -0
  87. package/dist/types/sdk/session-list.d.ts +1 -1
  88. package/dist/types/sdk/session.d.ts +8 -0
  89. package/dist/types/session/agent-session.d.ts +38 -9
  90. package/dist/types/session/artifacts.d.ts +2 -2
  91. package/dist/types/session/internal/managed-gc-retirement-codec.d.ts +32 -0
  92. package/dist/types/session/internal/managed-session-scope.d.ts +79 -2
  93. package/dist/types/session/internal/managed-session-storage.d.ts +26 -1
  94. package/dist/types/session/internal/managed-task-owner-cleanup.d.ts +62 -0
  95. package/dist/types/session/internal/task-artifact-owner-access.d.ts +2 -0
  96. package/dist/types/session/internal/task-artifact-owner-transcript.d.ts +9 -1
  97. package/dist/types/session/session-manager.d.ts +31 -5
  98. package/dist/types/session/session-retirement.d.ts +31 -7
  99. package/dist/types/session/session-storage.d.ts +69 -2
  100. package/dist/types/session/task-artifact-owner-codec.d.ts +2 -0
  101. package/dist/types/setup/credential-auto-import.d.ts +1 -1
  102. package/dist/types/setup/credential-import.d.ts +6 -4
  103. package/dist/types/skill-state/active-state.d.ts +38 -0
  104. package/dist/types/skill-state/workflow-mutation-guard.d.ts +3 -0
  105. package/dist/types/slash-commands/helpers/progress-report.d.ts +8 -0
  106. package/dist/types/task/executor.d.ts +3 -0
  107. package/dist/types/task/isolation-dir.d.ts +26 -0
  108. package/dist/types/tools/ast-edit-write-path.d.ts +13 -0
  109. package/dist/types/tools/bash-skill-urls.d.ts +1 -1
  110. package/dist/types/tools/browser/cdp-url.d.ts +2 -0
  111. package/dist/types/tools/github-side-effect.d.ts +22 -0
  112. package/dist/types/tools/index.d.ts +3 -0
  113. package/dist/types/tools/monitor-mutation.d.ts +9 -0
  114. package/dist/types/tools/python.d.ts +9 -1
  115. package/dist/types/tools/recipe/recipe-guard.d.ts +7 -0
  116. package/dist/types/tools/restricted-cwd.d.ts +1 -0
  117. package/dist/types/tools/todo-write.d.ts +6 -0
  118. package/dist/types/utils/tools-checksum.d.ts +7 -0
  119. package/package.json +7 -7
  120. package/scripts/generate-sdk-operation-inventory.ts +21 -0
  121. package/scripts/verify-managed-empty-stop.ts +28 -0
  122. package/src/async/endpoint-id.ts +26 -0
  123. package/src/async/job-manager.ts +247 -132
  124. package/src/async/support.ts +0 -25
  125. package/src/capability/index.ts +15 -0
  126. package/src/capability/mcp.ts +2 -0
  127. package/src/capability/skill.ts +2 -0
  128. package/src/capability/types.ts +2 -0
  129. package/src/cli/auth-broker-cli.ts +1 -1
  130. package/src/cli/customize-doctor.ts +15 -2
  131. package/src/cli/doctor/repairs.ts +4 -1
  132. package/src/cli/doctor-supervisor.ts +3 -0
  133. package/src/cli/public-command-errors.ts +21 -1
  134. package/src/cli/public-command-registry.ts +28 -6
  135. package/src/cli/setup-cli.ts +4 -4
  136. package/src/cli/skills-cli.ts +5 -0
  137. package/src/commands/deep-interview.ts +47 -8
  138. package/src/commands/mcp-serve.ts +7 -0
  139. package/src/commands/sdk.ts +455 -397
  140. package/src/config/autorouting-tier-map.ts +117 -7
  141. package/src/config/file-lock.ts +316 -79
  142. package/src/config/mcp-schema.json +4 -0
  143. package/src/config/model-bindings-applier.ts +20 -0
  144. package/src/config/model-profile-activation.ts +240 -46
  145. package/src/config/model-registry.ts +47 -153
  146. package/src/config/skill-settings-defaults.ts +7 -0
  147. package/src/coordinator-mcp/policy.ts +3 -2
  148. package/src/coordinator-mcp/server.ts +2 -0
  149. package/src/cursor-delete-path.ts +10 -0
  150. package/src/cursor-mcp-name.ts +15 -0
  151. package/src/cursor.ts +13 -2
  152. package/src/customization/inventory.ts +4 -13
  153. package/src/dap/config.ts +2 -2
  154. package/src/debug/report-bundle-parent.ts +22 -0
  155. package/src/debug/report-bundle.ts +3 -0
  156. package/src/debug/system-info.ts +13 -1
  157. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +10 -6
  158. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.ts +67 -4
  159. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/version-manager.ts +80 -0
  160. package/src/defaults/gjc/skills/deep-interview/SKILL.md +105 -10
  161. package/src/defaults/gjc/skills/ralplan/SKILL.md +6 -4
  162. package/src/defaults/gjc-defaults.test.ts +18 -1
  163. package/src/defaults/gjc-defaults.ts +3 -0
  164. package/src/defaults/gjc-skills.generated.ts +58 -36
  165. package/src/discovery/agents.ts +6 -1
  166. package/src/discovery/builtin.ts +13 -1
  167. package/src/discovery/helpers.ts +171 -29
  168. package/src/discovery/mcp-json.ts +26 -12
  169. package/src/discovery/ssh.ts +1 -1
  170. package/src/discovery/substitute-plugin-root.ts +3 -1
  171. package/src/edit/file-read-cache.ts +1 -1
  172. package/src/eval/py/executor.ts +796 -154
  173. package/src/eval/py/kernel.ts +79 -13
  174. package/src/eval/py/tool-bridge.ts +4 -0
  175. package/src/export/html/css-color.ts +9 -0
  176. package/src/export/html/html-export-destination.ts +16 -0
  177. package/src/export/html/index.ts +7 -10
  178. package/src/export/html/template.generated.ts +1 -1
  179. package/src/extensibility/extensions/function-hooks-internal.ts +27 -0
  180. package/src/extensibility/extensions/runner.ts +15 -1
  181. package/src/extensibility/extensions/types.ts +7 -0
  182. package/src/extensibility/gjc-plugins/mcp-policy.ts +2 -1
  183. package/src/extensibility/gjc-plugins/runtime-adapters.ts +85 -8
  184. package/src/extensibility/plugins/manager.ts +3 -2
  185. package/src/extensibility/plugins/marketplace/cache.ts +15 -0
  186. package/src/extensibility/plugins/marketplace/manager.ts +11 -3
  187. package/src/extensibility/plugins/plugin-link-path.ts +12 -0
  188. package/src/extensibility/runtime-skill-discovery.ts +20 -2
  189. package/src/extensibility/skill-management.ts +9 -2
  190. package/src/extensibility/skills.ts +6 -1
  191. package/src/gjc-runtime/deep-interview-crystallize.ts +1814 -0
  192. package/src/gjc-runtime/deep-interview-recorder.ts +20 -2
  193. package/src/gjc-runtime/deep-interview-runtime.ts +1415 -13
  194. package/src/gjc-runtime/deep-interview-stage.ts +98 -21
  195. package/src/gjc-runtime/gc-runtime.ts +206 -9
  196. package/src/gjc-runtime/launch-worktree.ts +70 -9
  197. package/src/gjc-runtime/psmux-detect.ts +28 -4
  198. package/src/gjc-runtime/ralplan-runtime.ts +447 -52
  199. package/src/gjc-runtime/session-state-sidecar.ts +3 -2
  200. package/src/gjc-runtime/sidecar-bootstrap-env.ts +19 -0
  201. package/src/gjc-runtime/state-argv.ts +2 -0
  202. package/src/gjc-runtime/state-migrations.ts +91 -29
  203. package/src/gjc-runtime/state-runtime.ts +3716 -135
  204. package/src/gjc-runtime/state-writer.ts +105 -16
  205. package/src/gjc-runtime/tmux-common.ts +8 -5
  206. package/src/gjc-runtime/ultragoal-runtime.ts +16 -4
  207. package/src/gjc-runtime/workflow-manifest.generated.json +70 -42
  208. package/src/gjc-runtime/workflow-manifest.ts +54 -21
  209. package/src/harness-control-plane/operate.ts +12 -4
  210. package/src/harness-control-plane/owner.ts +5 -1
  211. package/src/hashline/parser.ts +48 -9
  212. package/src/hashline/recovery.ts +13 -4
  213. package/src/internal-urls/docs-index.generated.ts +20 -19
  214. package/src/internal-urls/skill-path.ts +19 -0
  215. package/src/internal-urls/skill-protocol.ts +2 -0
  216. package/src/lsp/config.ts +12 -63
  217. package/src/lsp/edits.ts +6 -0
  218. package/src/lsp/workspace-path.ts +51 -0
  219. package/src/main.ts +195 -31
  220. package/src/memories/index.ts +88 -7
  221. package/src/modes/acp/acp-agent.ts +88 -4
  222. package/src/modes/components/custom-editor.ts +14 -0
  223. package/src/modes/components/customization/customization-dashboard.ts +12 -0
  224. package/src/modes/components/extensions/extension-dashboard.ts +2 -2
  225. package/src/modes/components/extensions/state-manager.ts +15 -5
  226. package/src/modes/components/hook-editor.ts +1 -1
  227. package/src/modes/components/hook-selector.ts +1 -1
  228. package/src/modes/components/model-selector.ts +1 -4
  229. package/src/modes/components/provider-onboarding-selector.ts +1 -1
  230. package/src/modes/components/status-line/segments.ts +4 -0
  231. package/src/modes/controllers/event-controller.ts +11 -4
  232. package/src/modes/controllers/input-controller.ts +76 -31
  233. package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -16
  234. package/src/modes/controllers/selector-controller.ts +24 -15
  235. package/src/modes/controllers/todo-command-controller.ts +1 -1
  236. package/src/modes/interactive-mode.ts +5 -1
  237. package/src/modes/runtime-init.ts +4 -0
  238. package/src/modes/utils/abort-message.ts +3 -1
  239. package/src/modes/utils/interrupt-ownership.ts +12 -0
  240. package/src/modes/utils/keybinding-matchers.ts +4 -0
  241. package/src/modes/utils/macos-option-forwarding.ts +80 -0
  242. package/src/progress/collect-project-progress.ts +153 -0
  243. package/src/progress/progress-contract.ts +172 -0
  244. package/src/progress/progress-snapshot.ts +140 -0
  245. package/src/progress/project-progress.ts +446 -0
  246. package/src/progress/render-progress.ts +209 -0
  247. package/src/prompts/system/master-mode.md +1 -0
  248. package/src/prompts/tools/skill-discovery.md +1 -1
  249. package/src/runtime-mcp/client.ts +4 -2
  250. package/src/runtime-mcp/config-writer.ts +10 -6
  251. package/src/runtime-mcp/config.ts +1 -0
  252. package/src/runtime-mcp/json-rpc.ts +2 -1
  253. package/src/runtime-mcp/manager.ts +29 -11
  254. package/src/runtime-mcp/mcp-redirect.ts +73 -0
  255. package/src/runtime-mcp/oauth-flow.ts +14 -2
  256. package/src/runtime-mcp/oauth-public-url.ts +14 -0
  257. package/src/runtime-mcp/plugin-network-boundary.ts +4 -0
  258. package/src/runtime-mcp/pool.ts +6 -0
  259. package/src/runtime-mcp/project-host-values.ts +46 -0
  260. package/src/runtime-mcp/smithery-registry.ts +22 -3
  261. package/src/runtime-mcp/transports/http.ts +4 -3
  262. package/src/runtime-mcp/types.ts +6 -0
  263. package/src/sdk/acp/adapter.ts +95 -8
  264. package/src/sdk/broker/broker-exit.ts +52 -23
  265. package/src/sdk/broker/broker.ts +81 -6
  266. package/src/sdk/broker/doctor-restart.ts +4 -0
  267. package/src/sdk/broker/ensure.ts +31 -2
  268. package/src/sdk/broker/lifecycle.ts +711 -66
  269. package/src/sdk/broker/session-index.ts +191 -81
  270. package/src/sdk/bus/chat-daemon-cli.ts +38 -1
  271. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  272. package/src/sdk/bus/index.ts +238 -43
  273. package/src/sdk/bus/telegram-daemon-contract.ts +6 -1
  274. package/src/sdk/cli/session-cli.ts +17 -3
  275. package/src/sdk/client/client.ts +28 -8
  276. package/src/sdk/host/query/handlers.ts +9 -1
  277. package/src/sdk/host/session-runtime.test.ts +2705 -303
  278. package/src/sdk/host/session-runtime.ts +490 -143
  279. package/src/sdk/host/surface-policy.ts +1 -0
  280. package/src/sdk/index.ts +8 -0
  281. package/src/sdk/lifecycle-session.ts +3 -1
  282. package/src/sdk/prompt-deadline-manager.ts +15 -0
  283. package/src/sdk/protocol/operation-inventory.generated.json +146 -0
  284. package/src/sdk/protocol/operation-registry.ts +9 -2
  285. package/src/sdk/router/session-router.ts +82 -18
  286. package/src/sdk/session-list.ts +1 -0
  287. package/src/sdk/session.ts +69 -45
  288. package/src/session/agent-session.ts +679 -238
  289. package/src/session/artifacts.ts +176 -71
  290. package/src/session/internal/managed-gc-retirement-codec.ts +319 -0
  291. package/src/session/internal/managed-session-scope.ts +3779 -462
  292. package/src/session/internal/managed-session-storage.ts +501 -78
  293. package/src/session/internal/managed-task-owner-cleanup.ts +473 -0
  294. package/src/session/internal/task-artifact-owner-access.ts +19 -3
  295. package/src/session/internal/task-artifact-owner-transcript.ts +547 -1
  296. package/src/session/session-manager.ts +951 -133
  297. package/src/session/session-retirement.ts +573 -14
  298. package/src/session/session-storage.ts +447 -15
  299. package/src/session/task-artifact-owner-codec.ts +71 -8
  300. package/src/session/task-artifact-owner-retirement.ts +21 -19
  301. package/src/setup/credential-auto-import.ts +12 -3
  302. package/src/setup/credential-import.ts +176 -5
  303. package/src/setup/paseo/announce.ts +6 -1
  304. package/src/skill-state/active-state.ts +145 -2
  305. package/src/skill-state/workflow-mutation-guard.ts +102 -10
  306. package/src/slash-commands/builtin-registry.ts +39 -9
  307. package/src/slash-commands/helpers/mcp.ts +8 -4
  308. package/src/slash-commands/helpers/progress-report.ts +23 -0
  309. package/src/stt/setup.ts +3 -5
  310. package/src/task/commands.ts +3 -1
  311. package/src/task/executor.ts +4 -0
  312. package/src/task/index.ts +6 -0
  313. package/src/task/isolation-dir.ts +143 -0
  314. package/src/task/worktree.ts +16 -7
  315. package/src/tools/ask.ts +205 -6
  316. package/src/tools/ast-edit-write-path.ts +68 -0
  317. package/src/tools/ast-edit.ts +10 -1
  318. package/src/tools/bash-allowed-prefixes.ts +15 -0
  319. package/src/tools/bash-skill-urls.ts +56 -3
  320. package/src/tools/bash.ts +48 -79
  321. package/src/tools/browser/cdp-url.ts +18 -0
  322. package/src/tools/browser.ts +8 -1
  323. package/src/tools/descriptors.ts +5 -1
  324. package/src/tools/eval.ts +56 -36
  325. package/src/tools/gh.ts +10 -0
  326. package/src/tools/github-side-effect.ts +112 -0
  327. package/src/tools/image-gen.ts +1 -1
  328. package/src/tools/index.ts +3 -0
  329. package/src/tools/monitor-mutation.ts +27 -0
  330. package/src/tools/monitor.ts +7 -0
  331. package/src/tools/python.ts +188 -66
  332. package/src/tools/recipe/index.ts +9 -0
  333. package/src/tools/recipe/recipe-guard.ts +19 -0
  334. package/src/tools/restricted-cwd.ts +10 -0
  335. package/src/tools/skill-discovery.ts +5 -0
  336. package/src/tools/skill.ts +28 -1
  337. package/src/tools/todo-write.ts +10 -1
  338. package/src/tools/tool-catalog.generated.ts +1 -1
  339. package/src/tools/write.ts +1 -0
  340. package/src/utils/external-editor.ts +3 -2
  341. package/src/utils/tools-checksum.ts +34 -0
  342. package/src/utils/tools-manager.ts +24 -6
  343. package/src/web/insane/url-guard.ts +2 -1
  344. package/src/web/search/providers/codex.ts +3 -2
@@ -1,31 +1,6 @@
1
- import * as path from "node:path";
2
- import { resolveEquivalentPath } from "@gajae-code/utils";
3
1
  import type { Settings } from "../config/settings";
4
2
 
5
3
  export function isBackgroundJobSupportEnabled(settings: Pick<Settings, "get">): boolean {
6
4
  void settings;
7
5
  return true;
8
6
  }
9
-
10
- /**
11
- * Single source of truth for the AsyncJobManager endpoint key.
12
- *
13
- * A session with an explicit provider session id is keyed by (provider id,
14
- * transcript path); everything else is keyed by its logical session id. The
15
- * transcript component is canonicalized so a path alias — symlink, `..`
16
- * segment, or unresolved relative path — cannot register the manager under one
17
- * key at construction and look it up under another across a session-identity
18
- * transition, stranding ownership.
19
- *
20
- * Both the SDK constructor and AgentSession's transition rekeying must derive
21
- * the key here; duplicating the shape lets the two drift apart silently.
22
- */
23
- export function asyncJobEndpointId(
24
- providerSessionId: string | undefined,
25
- sessionId: string,
26
- sessionFile: string | undefined,
27
- ): string {
28
- return providerSessionId !== undefined && sessionFile !== undefined
29
- ? JSON.stringify(["async-job-endpoint", providerSessionId, resolveEquivalentPath(path.resolve(sessionFile))])
30
- : sessionId;
31
- }
@@ -22,6 +22,7 @@ import {
22
22
  } from "@gajae-code/utils";
23
23
 
24
24
  import type { Settings } from "../config/settings";
25
+ import { resolveGlobalUserSkillLinkTrust, resolveSkillScopeTrust } from "../config/skill-settings-defaults";
25
26
  import { clearCache as clearFsCache, findRepoRoot, cacheStats as fsCacheStats, invalidate as invalidateFs } from "./fs";
26
27
  import type {
27
28
  Capability,
@@ -73,6 +74,17 @@ const EXPLICIT_HOME_PROVIDER_ROOTS = [
73
74
 
74
75
  const ANCESTOR_SCOPED_PROJECT_PROVIDERS = new Set(["agents", "agents-md", "cline"]);
75
76
 
77
+ function resolveExternalUserSkillSymlinkTrust(settings: Settings | undefined): boolean {
78
+ const userOwnedTrust = resolveGlobalUserSkillLinkTrust({
79
+ trustUserSkills:
80
+ typeof settings?.getGlobal === "function" ? settings.getGlobal("skills.trustUserSkills") : undefined,
81
+ enablePiUser: typeof settings?.getGlobal === "function" ? settings.getGlobal("skills.enablePiUser") : undefined,
82
+ });
83
+ const effectiveScopeTrust =
84
+ typeof settings?.getGroup === "function" ? resolveSkillScopeTrust(settings.getGroup("skills"), "user") : true;
85
+ return userOwnedTrust && effectiveScopeTrust;
86
+ }
87
+
76
88
  function isWithinOrEqual(root: string, candidate: string): boolean {
77
89
  const relative = path.relative(root, candidate);
78
90
  return relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative));
@@ -413,6 +425,7 @@ export async function loadCapability<T>(capabilityId: string, options: LoadOptio
413
425
  const ordinaryOptions: LoadOptions = options.isolatedHome ? { ...options, isolatedHome: false } : options;
414
426
  const cwd = ordinaryOptions.cwd ?? getProjectDir();
415
427
  const home = getTrustedHomeDir();
428
+ const activeSettings = ordinaryOptions.settings ?? settingsByCwd.get(path.normalize(cwd));
416
429
  const userAgentDir = ordinaryOptions.agentDir ? path.resolve(ordinaryOptions.agentDir) : getAgentDir();
417
430
  const profileAuthority =
418
431
  ordinaryOptions.profileAuthority ??
@@ -429,6 +442,7 @@ export async function loadCapability<T>(capabilityId: string, options: LoadOptio
429
442
  repoRoot,
430
443
  isolatedHome: false,
431
444
  settings: ordinaryOptions.settings,
445
+ allowExternalUserSkillSymlinks: resolveExternalUserSkillSymlinkTrust(activeSettings),
432
446
  bypassCache: ordinaryOptions.bypassCache,
433
447
  };
434
448
  const providers = filterProviders(capability, ordinaryOptions);
@@ -521,6 +535,7 @@ export async function loadCapabilityForHome<T>(
521
535
  isolatedHome,
522
536
  homeIdentity,
523
537
  settings: isolatedOptions.settings,
538
+ allowExternalUserSkillSymlinks: resolveExternalUserSkillSymlinkTrust(isolatedOptions.settings),
524
539
  };
525
540
 
526
541
  return await loadImpl(capability, providers, ctx, isolatedOptions);
@@ -41,6 +41,8 @@ export interface MCPServer {
41
41
  url?: string;
42
42
  /** HTTP headers (for HTTP transport) */
43
43
  headers?: Record<string, string>;
44
+ /** Persisted public-network requirement for an HTTP MCP endpoint. */
45
+ publicNetwork?: boolean;
44
46
  /** Authentication configuration */
45
47
  auth?: {
46
48
  type: "oauth" | "apikey";
@@ -41,6 +41,8 @@ export interface Skill {
41
41
  name: string;
42
42
  /** Absolute path to skill file */
43
43
  path: string;
44
+ /** Lexical path used to discover the file, preserving symlink provenance for management operations. */
45
+ discoveryPath?: string;
44
46
  /** Skill content (markdown) */
45
47
  /** Lazily load the markdown body when the caller needs prompt content. */
46
48
  loadContent?: () => Promise<string>;
@@ -44,6 +44,8 @@ export interface LoadContext {
44
44
  bypassCache?: boolean;
45
45
  /** Owning session settings for provider policy decisions. */
46
46
  settings?: Settings;
47
+ /** User-owned permission to follow skill links outside a user scan root. */
48
+ allowExternalUserSkillSymlinks?: boolean;
47
49
  }
48
50
 
49
51
  /**
@@ -467,7 +467,7 @@ async function runImport(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
467
467
  if (!target) {
468
468
  throw new Error("Usage: gjc auth-broker import <file|dir> [--provider=<id>] [--include-disabled] [--dry-run]");
469
469
  }
470
- const resolvedTarget = path.resolve(target.startsWith("~") ? target.replace(/^~/, os.homedir()) : target);
470
+ const resolvedTarget = path.resolve(target.startsWith("~") ? target.replace(/^~/, () => os.homedir()) : target);
471
471
  const { entries, skipped } = await loadImportPlan(resolvedTarget, flags.provider, flags.includeDisabled === true);
472
472
 
473
473
  if (flags.json) {
@@ -32,7 +32,7 @@ import { type SlashCommand, slashCommandCapability } from "../capability/slash-c
32
32
  import { type CustomTool, toolCapability } from "../capability/tool";
33
33
  import type { Capability, LoadContext, LoadResult, SourceMeta } from "../capability/types";
34
34
  import { Settings, type Settings as SettingsInstance } from "../config/settings";
35
- import { resolveSkillScopeTrust } from "../config/skill-settings-defaults";
35
+ import { resolveGlobalUserSkillLinkTrust, resolveSkillScopeTrust } from "../config/skill-settings-defaults";
36
36
  import { getEmbeddedDefaultGjcSkills } from "../defaults/gjc-defaults";
37
37
  import { initializeWithSettings, loadCapability } from "../discovery";
38
38
  import { inspectClaudeConvention } from "../discovery/claude";
@@ -683,6 +683,10 @@ async function collectSkills(cwd: string, activeSettings: SettingsInstance): Pro
683
683
  ...activeSettings.getGroup("skills"),
684
684
  cwd,
685
685
  disabledExtensions: activeSettings.get("disabledExtensions"),
686
+ allowExternalUserSkillSymlinks: resolveGlobalUserSkillLinkTrust({
687
+ trustUserSkills: activeSettings.getGlobal("skills.trustUserSkills"),
688
+ enablePiUser: activeSettings.getGlobal("skills.enablePiUser"),
689
+ }),
686
690
  });
687
691
  for (const skill of result.skills) loadedNames.add(getSkillFilesystemIdentity(skill.name));
688
692
  }
@@ -798,7 +802,16 @@ async function collectSkills(cwd: string, activeSettings: SettingsInstance): Pro
798
802
  for (const dir of [...customDirs].sort()) {
799
803
  const scan = await scanSkillsFromDir(
800
804
  { cwd, home: os.homedir(), repoRoot: null },
801
- { dir: expandTilde(dir), providerId: "custom", level: "user", requireDescription: true },
805
+ {
806
+ dir: expandTilde(dir),
807
+ providerId: "custom",
808
+ level: "user",
809
+ requireDescription: true,
810
+ allowExternalUserSkillSymlinks: resolveGlobalUserSkillLinkTrust({
811
+ trustUserSkills: activeSettings.getGlobal("skills.trustUserSkills"),
812
+ enablePiUser: activeSettings.getGlobal("skills.enablePiUser"),
813
+ }),
814
+ },
802
815
  );
803
816
  for (const skill of scan.items) {
804
817
  const base: Omit<CustomizeDoctorItem, "status" | "reason" | "detail" | "remediation"> = {
@@ -954,7 +954,10 @@ export async function executeSelectedDoctorRepair(
954
954
  },
955
955
  afterChecks,
956
956
  };
957
- const preEffect = outcome.kind === "owner_unavailable" || outcome.kind === "prepare_refused";
957
+ const preEffect =
958
+ outcome.kind === "owner_unavailable" ||
959
+ outcome.kind === "prepare_refused" ||
960
+ outcome.kind === "attach_only_refused";
958
961
  return {
959
962
  repair: {
960
963
  ...plan,
@@ -74,6 +74,9 @@ const WORKER_ENV_KEYS = [
74
74
  "XDG_DATA_HOME",
75
75
  "XDG_STATE_HOME",
76
76
  "XDG_CACHE_HOME",
77
+ // SDK_BROKER_AUTOSTART_ENV (sdk/broker/ensure.ts), kept literal so this supervisor stays
78
+ // import-light. A supervisor-owned broker must stay unrestartable from the doctor worker.
79
+ "GJC_SDK_BROKER_AUTOSTART",
77
80
  ] as const;
78
81
 
79
82
  const COMPILED = /(?:\/\$bunfs\/|\/~BUN\/|\/%7EBUN\/)/i.test(import.meta.url);
@@ -20,6 +20,7 @@ export type PublicFailureKind =
20
20
  | "timeout"
21
21
  | "wait_timeout"
22
22
  | "uncertain_after_send"
23
+ | "busy"
23
24
  | "daemon_unhealthy"
24
25
  | "daemon_stale"
25
26
  | "daemon_mixed"
@@ -100,6 +101,10 @@ export const PUBLIC_COMMAND_DIAGNOSTICS = {
100
101
  "The macOS open-file limit is below the recommended minimum; increase it before starting additional concurrent work.",
101
102
  sdk_resource_gone:
102
103
  "The requested resource is not available from this session endpoint; this reports absent resource state, not an empty result.",
104
+ sdk_unknown_operation:
105
+ "The --op value is not a known SDK operation id for this command. Per-session control ids include turn.prompt, turn.steer, turn.follow_up, turn.abort and turn.abort_and_prompt.",
106
+ sdk_scope_requires_repository:
107
+ "The selected session-list scope requires a Git repository. Run inside a checkout, pass --repo <path>, or use --scope cwd or --scope all.",
103
108
  router_cleanup_failed: "SDK session Router cleanup failed.",
104
109
  broker_cleanup_failed: "SDK broker client cleanup failed.",
105
110
  // The broker reports this code from several distinct causes, so the text names none
@@ -162,6 +167,7 @@ const messages: Record<PublicFailureKind, string> = {
162
167
  timeout: "The operation timed out; its outcome requires reconciliation.",
163
168
  wait_timeout: "Waiting timed out after the operation was accepted. Do not replay it.",
164
169
  uncertain_after_send: "The request was sent but its outcome is uncertain. Reconcile before any replay.",
170
+ busy: "The session is running a turn and refused the request.",
165
171
  daemon_unhealthy: "The selected daemon is unhealthy.",
166
172
  daemon_stale: "The selected daemon has stale runtime state.",
167
173
  daemon_mixed: "Some daemon targets failed. Do not repeat mutations that already succeeded.",
@@ -282,6 +288,9 @@ export function classifyPublicCommandFailure(
282
288
  else if (kind === "uncertain_after_send") {
283
289
  category = "uncertain";
284
290
  outcomeCertainty = "unknown";
291
+ } else if (kind === "busy") {
292
+ category = "unavailable";
293
+ if (outcomeCertainty === "not-applied") retryability = "yes";
285
294
  } else if (
286
295
  [
287
296
  "unavailable",
@@ -325,7 +334,18 @@ export function classifyPublicCommandFailure(
325
334
  nextSteps.push(step("Wait for the existing restart to finish, then inspect status; do not restart again."));
326
335
  const session = references.find(ref => ref.kind === "sessionId");
327
336
  const operation = references.find(ref => ref.kind === "operationRef");
328
- if (
337
+ if (kind === "busy" && canonical[0] === "sdk" && outcomeCertainty === "not-applied") {
338
+ // A refused-before-execution request has no operation record to reconcile:
339
+ // point at the busy turn instead of a status lookup that can only say unknown.
340
+ nextSteps.push(
341
+ step(
342
+ "Steer the active turn with `sdk session raw control <sessionId> --op turn.steer`, or wait until the session is idle before sending again.",
343
+ session && executableValue(session.value)
344
+ ? ["sdk", "session", "inspect", session.value]
345
+ : ["sdk", "session", "list"],
346
+ ),
347
+ );
348
+ } else if (
329
349
  canonical[0] === "sdk" &&
330
350
  session &&
331
351
  operation &&
@@ -81,6 +81,9 @@ const argument = (description: string, extra: Partial<PublicArgumentDescriptor>
81
81
  ...extra,
82
82
  });
83
83
  const agentDir = stringFlag("SDK broker/state directory (default: the configured agent directory).");
84
+ const attachOnly = booleanFlag(
85
+ "Attach only to a live SDK broker; never start, retire or restart one (same as GJC_SDK_BROKER_AUTOSTART=0).",
86
+ );
84
87
  const repo = stringFlag("Workspace directory for scope or saved-session resolution (default: current directory).");
85
88
  const exactSessionRepo = stringFlag(
86
89
  "Accepted for compatibility only; ignored because the exact session ID selects the broker target.",
@@ -187,7 +190,8 @@ function node(path: string, input: NodeInput): PublicCommandDescriptor {
187
190
  examples: [{ syntax: example ?? `gjc ${path} --help --json`, executable: false }],
188
191
  };
189
192
  }
190
- const sessionFlags = { "agent-dir": agentDir };
193
+ const guideFlags = { "agent-dir": agentDir };
194
+ const sessionFlags = { "agent-dir": agentDir, "attach-only": attachOnly };
191
195
  const observeDaemonFlags = {
192
196
  all: booleanFlag("Target all registered daemon kinds."),
193
197
  verbose: booleanFlag("Show runtime detail and the full roots list.", { char: "v" }),
@@ -212,7 +216,7 @@ const daemonArgs = {
212
216
  export const PUBLIC_COMMANDS: readonly PublicCommandDescriptor[] = [
213
217
  node("sdk", {
214
218
  description: "Discover SDK transports, sessions, search, spawn and advisory guides.",
215
- children: ["serve", "search", "spawn", "session", "guides"],
219
+ children: ["serve", "broker", "search", "spawn", "session", "guides"],
216
220
  syntax: "<command>",
217
221
  constraints: [
218
222
  "A public child command is required unless requesting help or root evidence retrieval.",
@@ -242,6 +246,24 @@ export const PUBLIC_COMMANDS: readonly PublicCommandDescriptor[] = [
242
246
  ],
243
247
  example: "gjc sdk serve --stdio",
244
248
  }),
249
+ node("sdk broker", {
250
+ description: "Run the SDK broker under an external supervisor.",
251
+ children: ["run"],
252
+ syntax: "<command>",
253
+ }),
254
+ node("sdk broker run", {
255
+ description:
256
+ "Run the SDK broker in the foreground for a supervisor (systemd, launchd); stable contract, never detaches.",
257
+ flags: { "agent-dir": agentDir },
258
+ syntax: "[--agent-dir <dir>]",
259
+ risk: "Owns the broker for the agent directory; clients should run attach-only (GJC_SDK_BROKER_AUTOSTART=0) so they never start a competing one.",
260
+ constraints: [
261
+ "Stays in the foreground until SIGTERM or SIGINT, stops gracefully, then exits with the signal status (143 or 130).",
262
+ "Exits 1 without serving when another live broker owns the agent directory (it never retires it) or startup fails.",
263
+ "Exits 1 if it loses its discovery root or cannot renew its heartbeat while serving; a broker.shutdown request exits 0.",
264
+ ],
265
+ example: "gjc sdk broker run --agent-dir ~/.gjc/agent",
266
+ }),
245
267
  node("sdk search", {
246
268
  description: "Search broker-visible sessions in an exact repo, pwd or global scope.",
247
269
  syntax: "[--scope repo|pwd|global] [--repo <dir>] [--limit <N>] [--cursor <cursor>]",
@@ -442,7 +464,7 @@ export const PUBLIC_COMMANDS: readonly PublicCommandDescriptor[] = [
442
464
  node("sdk guides refresh", {
443
465
  description: "Fetch and verify an allowlisted HTTPS guide manifest and advisory cache.",
444
466
  flags: {
445
- ...sessionFlags,
467
+ ...guideFlags,
446
468
  url: stringFlag("HTTPS allowlisted manifest URL.", { required: true }),
447
469
  "timeout-ms": positive("Bounded refresh timeout in milliseconds."),
448
470
  },
@@ -451,14 +473,14 @@ export const PUBLIC_COMMANDS: readonly PublicCommandDescriptor[] = [
451
473
  "A fallback cache or bundled selection is an operational refresh failure, not online refresh success.",
452
474
  ],
453
475
  }),
454
- node("sdk guides list", { description: "List guides from the verified advisory selection.", flags: sessionFlags }),
476
+ node("sdk guides list", { description: "List guides from the verified advisory selection.", flags: guideFlags }),
455
477
  node("sdk guides show", {
456
478
  description: "Read a verified guide by ID.",
457
479
  args: { guideId: argument("Exact guide ID from guides list.") },
458
- flags: sessionFlags,
480
+ flags: guideFlags,
459
481
  syntax: "<guideId>",
460
482
  }),
461
- node("sdk guides status", { description: "Report guide cache and selection status.", flags: sessionFlags }),
483
+ node("sdk guides status", { description: "Report guide cache and selection status.", flags: guideFlags }),
462
484
  node("sdk guides trust", { description: "Show the static guide trust policy; no refresh or cache mutation." }),
463
485
  node("daemon", {
464
486
  description: "Manage Telegram, Discord and Slack background daemons, not the SDK broker.",
@@ -766,7 +766,7 @@ async function confirmImport(count: number): Promise<boolean> {
766
766
  }
767
767
 
768
768
  /**
769
- * Discover existing Claude Code / Codex CLI credentials and import them into the
769
+ * Discover existing Claude Code / Codex CLI / Kiro CLI credentials and import them into the
770
770
  * gjc credential store after a redacted preview + confirmation. Falls back to
771
771
  * manual-setup guidance when nothing importable is found.
772
772
  */
@@ -834,7 +834,7 @@ export async function handleCredentialsSetup(
834
834
  for (const line of formatDiscoverySummary(filteredResult)) process.stdout.write(` ${line}\n`);
835
835
  process.stdout.write(
836
836
  chalk.yellow(
837
- `\nNo importable Claude/Codex credentials found. Continue with manual setup:\n` +
837
+ `\nNo importable Claude/Codex/Kiro CLI credentials found. Continue with manual setup:\n` +
838
838
  ` ${APP_NAME} setup provider (add an API-compatible provider)\n` +
839
839
  ` ${APP_NAME} (then /login) (interactive OAuth/subscription login)\n`,
840
840
  ),
@@ -930,7 +930,7 @@ ${chalk.bold("Components:")}
930
930
  provider Optional: add a preset, OpenAI-compatible, or Anthropic-compatible API provider
931
931
  python Optional: verify a Python 3 interpreter is reachable for code execution
932
932
  stt Optional: install speech-to-text dependencies (openai-whisper, recording tools)
933
- credentials Optional: import existing Claude Code / Codex CLI credentials
933
+ credentials Optional: import existing Claude Code / Codex CLI / Kiro CLI credentials
934
934
 
935
935
 
936
936
  ${chalk.bold("Provider example:")}
@@ -998,7 +998,7 @@ ${chalk.bold("Examples:")}
998
998
  ${APP_NAME} setup stt Install speech-to-text dependencies
999
999
  ${APP_NAME} setup stt --check Check if STT dependencies are available
1000
1000
  ${APP_NAME} setup python --check Check if Python execution is available
1001
- ${APP_NAME} setup credentials Discover & import existing Claude/Codex credentials
1001
+ ${APP_NAME} setup credentials Discover & import existing Claude/Codex/Kiro CLI credentials
1002
1002
  ${APP_NAME} setup credentials --dry-run Preview importable credentials (redacted)
1003
1003
  ${APP_NAME} setup credentials --yes Import without an interactive prompt
1004
1004
  ${APP_NAME} setup paseo Register GJC as a Paseo ACP provider
@@ -3,6 +3,7 @@
3
3
  * filesystem-discovered custom skills.
4
4
  */
5
5
  import { Settings } from "../config/settings";
6
+ import { resolveGlobalUserSkillLinkTrust } from "../config/skill-settings-defaults";
6
7
  import {
7
8
  DEFAULT_GJC_DEFINITION_NAMES,
8
9
  type EmbeddedDefaultGjcSkill,
@@ -111,6 +112,10 @@ export async function runSkillsCommand(cmd: SkillsCommandArgs): Promise<void> {
111
112
  ...settings.getGroup("skills"),
112
113
  disabledExtensions: settings.get("disabledExtensions"),
113
114
  },
115
+ allowExternalUserSkillSymlinks: resolveGlobalUserSkillLinkTrust({
116
+ trustUserSkills: settings.getGlobal("skills.trustUserSkills"),
117
+ enablePiUser: settings.getGlobal("skills.enablePiUser"),
118
+ }),
114
119
  });
115
120
  if (cmd.flags?.json) {
116
121
  writeJson({
@@ -7,37 +7,71 @@ export default class DeepInterview extends Command {
7
7
 
8
8
  All deep-interview state operations go through this command — no gjc state needed:
9
9
  read Print the persisted envelope, revision, content sha, and any pending draft
10
- write One-shot incremental JSON merge into state (--reset replaces; the locked
11
- intent contract survives a reset)
12
- stage Stage one JSON transition draft (--for <transition> --input '<json>'|@file)
10
+ write One-shot incremental JSON merge into state; required --input '<json>'|@file
11
+ must use the {"state":{...}} shape (--reset replaces; the locked intent
12
+ contract survives a reset)
13
+ kickoff Seed an interviewing session; --trace and --json are supported alongside
14
+ --quick|--standard|--deep
15
+ write-spec Persist a final spec through --write; --force only overwrites corrupt state
16
+ stage Stage one JSON transition draft; required --for <transition> and --input
17
+ '<json>'|@file use the {"state":{...}} shape
13
18
  check Dry-run the staged draft against current state (same merge apply performs)
14
19
  apply Commit the staged draft with runtime-owned revision+sha CAS
15
20
  discard Remove the pending draft
16
21
  clear Clear deep-interview state for the session (lifecycle passthrough)
22
+ approve-execution Record the user's separate, explicit approval for a ready canonical Crystal
17
23
  handoff Hand off to the next workflow skill (lifecycle passthrough)
24
+ --crystallize Promote a bounded authenticated conversation snapshot into a versioned
25
+ Crystal; required --input '<crystallize JSON>'|@file and --slug <slug>
26
+
27
+ Crystallize input must be a JSON object with these required fields (optional prior, removed_ids,
28
+ resolved_open_gaps, resolved_conflicts, and their anchors may extend the object):
29
+ {"snapshot":{"revision":N,"start":N,"end":N,"digest":"<sha256>","messages":[...]},
30
+ "current_revision":N,"items":[{"id":"...","kind":"goal|constraint|decision|acceptance_criterion|non_goal",
31
+ "classification":"confirmed|inferred|disputed","statement":"...","anchor":{"message_index":N,"quote":"..."}}],
32
+ "open_gaps":[],"conflicts":[]}
33
+ Confirmed items require a verbatim user anchor; inferred/disputed items must not be treated as
34
+ confirmed. The raw --input payload is bounded to 1 MiB; items are capped at 128 and each text
35
+ field at 10,000 characters, and snapshot messages must be contiguous, ordered, and cover
36
+ start..end (maximum 200 messages). The
37
+ digest/current_revision must match the live authenticated transcript. A ready Crystal persists as
38
+ deep-interview-<slug>-v<spec_version>.md;
39
+ needs-questions, stale, or superseded Crystal input does not publish a spec. Crystallize always
40
+ leaves execution_approval as not-approved; approve-execution is a separate explicit transition.
18
41
 
19
42
  Ambiguity is runtime-owned: apply/write derive current_ambiguity from the latest valid scored
20
43
  round and clamp it to the deterministic floor. Sessions resolve from --session-id, payload
21
- session_id, or GJC_SESSION_ID.`;
44
+ session_id, or GJC_SESSION_ID. A relative GJC_SESSION_FILE is resolved against the requested
45
+ workspace cwd, never the process launch directory.`;
22
46
  static strict = false;
23
47
  static flags = {
24
48
  quick: Flags.boolean({ description: "Seed a quick deep-interview run" }),
25
49
  standard: Flags.boolean({ description: "Seed a standard deep-interview run" }),
26
50
  deep: Flags.boolean({ description: "Seed a deep deep-interview run" }),
51
+ crystallize: Flags.boolean({ description: "Crystallize a bounded conversation snapshot into a versioned spec" }),
27
52
  trace: Flags.boolean({ description: "Run a bounded trace evidence pre-step before interview questions" }),
28
53
  threshold: Flags.string({ description: "Override ambiguity threshold for kickoff" }),
29
54
  "threshold-source": Flags.string({ description: "Describe the threshold override source" }),
30
55
  "session-id": Flags.string({
31
56
  description: "Route state/spec handoff through a session-scoped .gjc/_session-{sessionid} directory",
32
57
  }),
33
- input: Flags.string({ description: "JSON payload (or @file) for the write/stage verbs" }),
58
+ input: Flags.string({
59
+ description:
60
+ 'Required JSON object (or @file): generic api uses --input; write/stage use {"state":{...}}; crystallize uses snapshot/current_revision/items; payload <=1 MiB',
61
+ }),
34
62
  for: Flags.string({
35
63
  description: "Transition for stage: initialize-context | record-round | update-facts | merge-state",
36
64
  }),
37
65
  reset: Flags.boolean({ description: "With write: replace state instead of incremental merge" }),
38
- write: Flags.boolean({ description: "Persist a final deep-interview spec through the sanctioned GJC CLI/API" }),
66
+ write: Flags.boolean({
67
+ description:
68
+ "Persist a final deep-interview spec through the sanctioned GJC CLI/API (requires --spec; positional write requires --input)",
69
+ }),
39
70
  stage: Flags.string({ description: 'Spec stage for --write (currently "final")' }),
40
- slug: Flags.string({ description: "Safe slug for .gjc/_session-{sessionid}/specs/deep-interview-<slug>.md" }),
71
+ slug: Flags.string({
72
+ description:
73
+ "Required with --crystallize; safe slug for .gjc/_session-{sessionid}/specs/deep-interview-<slug>.md",
74
+ }),
41
75
  spec: Flags.string({ description: "Final spec markdown or a path to the final spec markdown" }),
42
76
  handoff: Flags.string({ description: 'After --write, hand off to a workflow target (currently "ralplan")' }),
43
77
  deliberate: Flags.boolean({
@@ -48,13 +82,18 @@ session_id, or GJC_SESSION_ID.`;
48
82
  };
49
83
  static examples = [
50
84
  '$ gjc deep-interview --trace --standard "<idea>"',
85
+ '$ gjc deep-interview --trace --standard "<idea>" --json',
51
86
  "$ gjc deep-interview read --json",
52
- '$ gjc deep-interview write --input \'{"state":{"threshold":0.05}}\' --json',
87
+ '$ gjc deep-interview write --input \'{"state":{"threshold":0.05,"threshold_source":"default"}}\' --json',
53
88
  '$ gjc deep-interview stage --for record-round --input \'{"state":{"rounds":[{"round":1,"round_key":"r1"}]}}\' --json',
54
89
  "$ gjc deep-interview check --json",
55
90
  "$ gjc deep-interview apply --json",
91
+ "$ gjc deep-interview approve-execution --json",
56
92
  "$ gjc deep-interview --write --stage final --slug my-feature --spec ./final-spec.md",
93
+ "$ gjc deep-interview --write --stage final --slug my-feature --spec ./final-spec.md --force",
57
94
  "$ gjc deep-interview --write --stage final --slug my-feature --spec ./final-spec.md --deliberate",
95
+ '$ gjc deep-interview --crystallize --input \'{"snapshot":{"revision":1,"start":0,"end":0,"digest":"<64-hex-sha256>","messages":[{"index":0,"role":"user","content":"Build audit reports"}]},"current_revision":1,"items":[{"id":"goal:reports","kind":"goal","classification":"confirmed","statement":"Build audit reports","anchor":{"message_index":0,"quote":"Build audit reports"}}],"open_gaps":[],"conflicts":[]}\' --slug audit-reports --json',
96
+ "$ gjc deep-interview --crystallize --input @conversation.json --slug my-feature --json",
58
97
  ];
59
98
 
60
99
  async run(): Promise<void> {
@@ -7,6 +7,7 @@ import {
7
7
  } from "../coordinator/contract";
8
8
  import { runCoordinatorMcpStdio } from "../coordinator-mcp/server";
9
9
  import { type BrokerDiscovery, readBrokerDiscovery } from "../sdk/broker/discovery";
10
+ import { SDK_BROKER_AUTOSTART_ENV } from "../sdk/broker/ensure";
10
11
  import { UnsupportedStateVersionError } from "../sdk/broker/state-version";
11
12
  import { runSdkMcpStdio, SDK_MCP_TOOL_NAMES } from "../sdk/mcp/server";
12
13
 
@@ -104,6 +105,10 @@ export default class McpServe extends Command {
104
105
  static flags = {
105
106
  json: Flags.boolean({ char: "j", description: "Emit machine-readable JSON", default: false }),
106
107
  check: Flags.boolean({ description: "Validate server configuration and print a smoke summary", default: false }),
108
+ "attach-only": Flags.boolean({
109
+ description: "Attach only to a live SDK broker; never start one (same as GJC_SDK_BROKER_AUTOSTART=0)",
110
+ default: false,
111
+ }),
107
112
  };
108
113
 
109
114
  async run(): Promise<void> {
@@ -122,6 +127,8 @@ export default class McpServe extends Command {
122
127
  return;
123
128
  }
124
129
 
130
+ if (flags["attach-only"]) process.env[SDK_BROKER_AUTOSTART_ENV] = "0";
131
+
125
132
  if (flags.check) {
126
133
  if (!flags.json) {
127
134
  const serverName = server === "sdk" ? "gjc-sdk-mcp" : COORDINATOR_MCP_SERVER_NAME;