@gajae-code/coding-agent 0.14.2 → 0.15.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 (345) hide show
  1. package/CHANGELOG.md +120 -1
  2. package/dist/types/async/job-manager.d.ts +4 -1
  3. package/dist/types/autoresearch/dashboard.d.ts +29 -4
  4. package/dist/types/autoresearch/data-context.d.ts +25 -0
  5. package/dist/types/autoresearch/git.d.ts +65 -7
  6. package/dist/types/autoresearch/harness.d.ts +58 -0
  7. package/dist/types/autoresearch/prompts.d.ts +51 -0
  8. package/dist/types/autoresearch/runs.d.ts +173 -0
  9. package/dist/types/autoresearch/types.d.ts +9 -139
  10. package/dist/types/capability/types.d.ts +20 -0
  11. package/dist/types/cli/accounts-cli.d.ts +1 -0
  12. package/dist/types/commands/{rlm.d.ts → autoresearch.d.ts} +2 -4
  13. package/dist/types/config/autorouting-contract.d.ts +146 -0
  14. package/dist/types/config/autorouting-generator.d.ts +40 -0
  15. package/dist/types/config/autorouting-tier-map.d.ts +16844 -0
  16. package/dist/types/config/autorouting.d.ts +35 -0
  17. package/dist/types/config/model-discovery-manager.d.ts +8 -1
  18. package/dist/types/config/model-registry.d.ts +30 -1
  19. package/dist/types/config/provider-selection-policy.d.ts +23 -0
  20. package/dist/types/config/settings-schema.d.ts +61 -3
  21. package/dist/types/config/settings.d.ts +3 -0
  22. package/dist/types/coordinator/contract.d.ts +1 -1
  23. package/dist/types/coordinator-mcp/durability.d.ts +29 -0
  24. package/dist/types/coordinator-mcp/event-webhook.d.ts +50 -0
  25. package/dist/types/coordinator-mcp/question-state.d.ts +1 -1
  26. package/dist/types/coordinator-mcp/server.d.ts +14 -0
  27. package/dist/types/crash/index-store.d.ts +3 -0
  28. package/dist/types/crash/record-loader.d.ts +2 -0
  29. package/dist/types/crash/upstream/relay.d.ts +5 -3
  30. package/dist/types/cursor.d.ts +12 -0
  31. package/dist/types/defaults/gjc-defaults.d.ts +35 -1
  32. package/dist/types/defaults/gjc-skills.generated.d.ts +1 -1
  33. package/dist/types/discovery/helpers.d.ts +1 -1
  34. package/dist/types/edit/index.d.ts +2 -1
  35. package/dist/types/eval/py/executor.d.ts +2 -0
  36. package/dist/types/extensibility/extensions/loader.d.ts +32 -0
  37. package/dist/types/extensibility/gjc-plugins/types.d.ts +1 -1
  38. package/dist/types/extensibility/skills.d.ts +2 -0
  39. package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +194 -0
  40. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  41. package/dist/types/gjc-runtime/psmux-detect.d.ts +1 -1
  42. package/dist/types/gjc-runtime/python-transcript.d.ts +19 -0
  43. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +2 -8
  44. package/dist/types/gjc-runtime/session-layout.d.ts +6 -3
  45. package/dist/types/gjc-runtime/state-renderer.d.ts +0 -22
  46. package/dist/types/gjc-runtime/state-schema.d.ts +7 -7
  47. package/dist/types/gjc-runtime/tmux-common.d.ts +2 -2
  48. package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +38 -1
  49. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +2 -24
  50. package/dist/types/gjc-runtime/ultragoal-validation-policy.d.ts +73 -0
  51. package/dist/types/gjc-runtime/workflow-recovery-projection.d.ts +100 -0
  52. package/dist/types/hooks/skill-keywords.d.ts +1 -1
  53. package/dist/types/main.d.ts +0 -10
  54. package/dist/types/modes/acp/acp-agent.d.ts +13 -6
  55. package/dist/types/modes/components/model-selector.d.ts +14 -0
  56. package/dist/types/modes/components/skill-hud/render.d.ts +6 -1
  57. package/dist/types/modes/components/smart-routing-panel.d.ts +82 -0
  58. package/dist/types/modes/controllers/selector-controller.d.ts +14 -0
  59. package/dist/types/modes/interactive-mode.d.ts +3 -0
  60. package/dist/types/modes/types.d.ts +9 -0
  61. package/dist/types/rlm/artifacts.d.ts +4 -4
  62. package/dist/types/runtime/optional-runtime-services.d.ts +2 -1
  63. package/dist/types/runtime/workspace-tree-service.d.ts +5 -1
  64. package/dist/types/runtime-mcp/config.d.ts +6 -0
  65. package/dist/types/runtime-mcp/manager.d.ts +10 -0
  66. package/dist/types/sdk/acp/adapter.d.ts +0 -4
  67. package/dist/types/sdk/broker/broker.d.ts +1 -1
  68. package/dist/types/sdk/broker/lifecycle.d.ts +57 -2
  69. package/dist/types/sdk/broker/session-index.d.ts +15 -0
  70. package/dist/types/sdk/bus/chat-daemon-control.d.ts +6 -0
  71. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -0
  72. package/dist/types/sdk/bus/index.d.ts +8 -0
  73. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +2 -0
  74. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -2
  75. package/dist/types/sdk/client/client.d.ts +39 -4
  76. package/dist/types/sdk/host/host.d.ts +1 -0
  77. package/dist/types/sdk/host/internal-autorouting-state.d.ts +3 -0
  78. package/dist/types/sdk/host/model-pin.d.ts +29 -0
  79. package/dist/types/sdk/host/session-runtime.d.ts +2 -1
  80. package/dist/types/sdk/lifecycle-session.d.ts +13 -0
  81. package/dist/types/sdk/router/session-router.d.ts +27 -1
  82. package/dist/types/sdk/session.d.ts +11 -1
  83. package/dist/types/session/agent-session.d.ts +36 -6
  84. package/dist/types/session/artifacts.d.ts +16 -1
  85. package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
  86. package/dist/types/session/session-manager.d.ts +84 -2
  87. package/dist/types/session/session-staging-paths.d.ts +3 -0
  88. package/dist/types/skill-state/canonical-skills.d.ts +1 -1
  89. package/dist/types/skill-state/workflow-hud.d.ts +12 -21
  90. package/dist/types/skill-state/workflow-mutation-guard.d.ts +1 -0
  91. package/dist/types/slash-commands/helpers/autorouting-status.d.ts +8 -0
  92. package/dist/types/system-prompt.d.ts +23 -0
  93. package/dist/types/task/executor.d.ts +35 -4
  94. package/dist/types/task/index.d.ts +17 -3
  95. package/dist/types/task/receipt.d.ts +3 -1
  96. package/dist/types/task/types.d.ts +144 -0
  97. package/dist/types/tools/atomic-file-write.d.ts +72 -0
  98. package/dist/types/tools/descriptors.d.ts +1 -0
  99. package/dist/types/tools/index.d.ts +36 -1
  100. package/dist/types/tools/move-session.d.ts +40 -0
  101. package/dist/types/tools/python.d.ts +12 -0
  102. package/dist/types/tools/resource-gc.d.ts +0 -3
  103. package/dist/types/tools/search.d.ts +8 -1
  104. package/dist/types/tools/skill.d.ts +9 -4
  105. package/dist/types/tools/subagent.d.ts +33 -3
  106. package/dist/types/utils/xml-escape.d.ts +2 -0
  107. package/dist/types/workflow/workflow-intent-diff.d.ts +2 -2
  108. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +1 -1
  109. package/package.json +11 -12
  110. package/scripts/build-sdk-package-smoke.ts +7 -5
  111. package/scripts/check-autorouting-tier-map.ts +183 -0
  112. package/scripts/generate-sdk-operation-inventory.ts +12 -0
  113. package/scripts/generate-tool-catalog.ts +40 -5
  114. package/src/async/job-manager.ts +5 -2
  115. package/src/autoresearch/dashboard.ts +134 -314
  116. package/src/autoresearch/data-context.ts +35 -0
  117. package/src/autoresearch/git.ts +186 -26
  118. package/src/autoresearch/{helpers.ts → harness.ts} +65 -40
  119. package/src/autoresearch/{prompt-setup.md → prompts/prompt-setup.md} +7 -7
  120. package/src/autoresearch/prompts/prompt.md +103 -0
  121. package/src/autoresearch/prompts.ts +126 -0
  122. package/src/autoresearch/runs.ts +708 -0
  123. package/src/autoresearch/types.ts +9 -150
  124. package/src/capability/index.ts +4 -4
  125. package/src/capability/types.ts +20 -0
  126. package/src/cli/accounts-cli.ts +21 -5
  127. package/src/cli/config-cli.ts +25 -1
  128. package/src/cli/fast-help.ts +1 -2
  129. package/src/cli/list-models.ts +5 -8
  130. package/src/cli/setup-cli.ts +8 -0
  131. package/src/cli.ts +2 -21
  132. package/src/commands/autoresearch.ts +33 -0
  133. package/src/commands/coordinator.ts +15 -0
  134. package/src/commands/launch.ts +2 -4
  135. package/src/commands/quick-lane.ts +1 -1
  136. package/src/commands/sdk.ts +24 -0
  137. package/src/commands/state.ts +1 -1
  138. package/src/config/autorouting-contract.ts +474 -0
  139. package/src/config/autorouting-generator.ts +238 -0
  140. package/src/config/autorouting-tier-map.ts +6108 -0
  141. package/src/config/autorouting.ts +120 -0
  142. package/src/config/model-discovery-manager.ts +42 -11
  143. package/src/config/model-registry.ts +348 -68
  144. package/src/config/provider-selection-policy.ts +60 -9
  145. package/src/config/settings-schema.ts +195 -6
  146. package/src/config/settings.ts +62 -1
  147. package/src/config.ts +2 -3
  148. package/src/coordinator/contract.ts +0 -1
  149. package/src/coordinator-mcp/codex-handoff.ts +68 -42
  150. package/src/coordinator-mcp/durability.ts +200 -0
  151. package/src/coordinator-mcp/event-webhook.ts +278 -0
  152. package/src/coordinator-mcp/question-state.ts +109 -46
  153. package/src/coordinator-mcp/server.ts +932 -504
  154. package/src/crash/index-store.ts +126 -22
  155. package/src/crash/record-loader.ts +7 -0
  156. package/src/crash/upstream/relay.ts +82 -34
  157. package/src/cursor.ts +84 -1
  158. package/src/debug/index.ts +26 -0
  159. package/src/defaults/gjc/skills/autoresearch/SKILL.md +116 -0
  160. package/src/defaults/gjc/skills/autoresearch/auto-critic.md +46 -0
  161. package/src/defaults/gjc/skills/autoresearch/auto-iterate.md +42 -0
  162. package/src/defaults/gjc/skills/deep-interview/SKILL.md +17 -37
  163. package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -18
  164. package/src/defaults/gjc/skills/ultragoal/SKILL.md +6 -17
  165. package/src/defaults/gjc/skills/ultragoal/ai-slop-cleaner.md +2 -2
  166. package/src/defaults/gjc-defaults.ts +89 -2
  167. package/src/defaults/gjc-skills.generated.ts +24 -17
  168. package/src/discovery/builtin.ts +18 -5
  169. package/src/discovery/helpers.ts +6 -6
  170. package/src/edit/index.ts +5 -2
  171. package/src/eval/py/executor.ts +8 -0
  172. package/src/extensibility/extensions/loader.ts +135 -13
  173. package/src/extensibility/extensions/wrapper.ts +1 -2
  174. package/src/extensibility/gjc-plugins/schema.ts +1 -1
  175. package/src/extensibility/runtime-skill-discovery.ts +2 -2
  176. package/src/extensibility/skill-management.ts +2 -3
  177. package/src/extensibility/skills.ts +16 -8
  178. package/src/gjc-runtime/autoresearch-runtime.ts +1509 -0
  179. package/src/gjc-runtime/gc-render.ts +0 -1
  180. package/src/gjc-runtime/gc-runtime.ts +1 -11
  181. package/src/gjc-runtime/launch-tmux.ts +3 -3
  182. package/src/gjc-runtime/psmux-detect.ts +2 -2
  183. package/src/gjc-runtime/python-transcript.ts +58 -0
  184. package/src/gjc-runtime/ralplan-runtime.ts +6 -18
  185. package/src/gjc-runtime/session-layout.ts +18 -7
  186. package/src/gjc-runtime/session-state-sidecar.ts +58 -9
  187. package/src/gjc-runtime/state-renderer.ts +0 -38
  188. package/src/gjc-runtime/state-runtime.ts +43 -22
  189. package/src/gjc-runtime/state-schema.ts +1 -1
  190. package/src/gjc-runtime/tmux-common.ts +7 -7
  191. package/src/gjc-runtime/ultragoal-change-set.ts +232 -11
  192. package/src/gjc-runtime/ultragoal-runtime.ts +309 -114
  193. package/src/gjc-runtime/ultragoal-validation-policy.ts +247 -0
  194. package/src/gjc-runtime/workflow-command-ref.ts +15 -11
  195. package/src/gjc-runtime/workflow-manifest.generated.json +413 -532
  196. package/src/gjc-runtime/workflow-manifest.ts +43 -83
  197. package/src/gjc-runtime/workflow-recovery-projection.ts +616 -0
  198. package/src/hooks/skill-keywords.ts +3 -3
  199. package/src/hooks/skill-state.ts +2 -2
  200. package/src/internal-urls/docs-index.generated.ts +26 -24
  201. package/src/lsp/index.ts +25 -5
  202. package/src/main.ts +2 -27
  203. package/src/modes/acp/acp-agent.ts +200 -75
  204. package/src/modes/components/model-selector.ts +216 -13
  205. package/src/modes/components/oauth-selector.ts +5 -5
  206. package/src/modes/components/skill-hud/render.ts +173 -35
  207. package/src/modes/components/smart-routing-panel.ts +531 -0
  208. package/src/modes/components/tool-status-header.ts +6 -3
  209. package/src/modes/controllers/command-controller.ts +17 -7
  210. package/src/modes/controllers/input-controller.ts +44 -9
  211. package/src/modes/controllers/runtime-mcp-command-controller.ts +4 -0
  212. package/src/modes/controllers/selector-controller.ts +298 -65
  213. package/src/modes/interactive-mode.ts +8 -1
  214. package/src/modes/shared/agent-wire/workflow-gate-types.ts +1 -1
  215. package/src/modes/types.ts +9 -1
  216. package/src/prompts/agents/planner.md +1 -1
  217. package/src/prompts/system/system-prompt.md +1 -1
  218. package/src/prompts/system/volatile-project-context.md +2 -1
  219. package/src/prompts/tools/move-session.md +15 -0
  220. package/src/prompts/tools/python.md +12 -0
  221. package/src/prompts/tools/skill-discovery.md +1 -1
  222. package/src/prompts/tools/skill.md +2 -2
  223. package/src/prompts/tools/task-summary.md +1 -0
  224. package/src/prompts/tools/task.md +6 -0
  225. package/src/rlm/artifacts.ts +12 -10
  226. package/src/runtime/optional-runtime-services.ts +3 -2
  227. package/src/runtime/workspace-tree-service.ts +11 -3
  228. package/src/runtime-mcp/config.ts +8 -1
  229. package/src/runtime-mcp/manager.ts +33 -0
  230. package/src/sdk/acp/adapter.ts +48 -1
  231. package/src/sdk/broker/broker.ts +30 -2
  232. package/src/sdk/broker/discovery.ts +217 -2
  233. package/src/sdk/broker/lifecycle.ts +385 -59
  234. package/src/sdk/broker/session-index.ts +243 -48
  235. package/src/sdk/broker/transport.ts +1 -0
  236. package/src/sdk/bus/chat-daemon-control.ts +8 -2
  237. package/src/sdk/bus/chat-daemon-runtime.ts +5 -0
  238. package/src/sdk/bus/index.ts +208 -11
  239. package/src/sdk/bus/kind-aware-reconciliation.ts +16 -0
  240. package/src/sdk/bus/reconciliation-store.ts +27 -5
  241. package/src/sdk/bus/telegram-daemon-contract.ts +12 -2
  242. package/src/sdk/client/client.ts +204 -22
  243. package/src/sdk/host/host.ts +16 -0
  244. package/src/sdk/host/internal-autorouting-state.ts +13 -0
  245. package/src/sdk/host/model-pin.ts +101 -0
  246. package/src/sdk/host/reverse-leases.ts +2 -1
  247. package/src/sdk/host/session-runtime.test.ts +224 -1
  248. package/src/sdk/host/session-runtime.ts +125 -37
  249. package/src/sdk/lifecycle/service.ts +3 -1
  250. package/src/sdk/lifecycle-session.ts +42 -1
  251. package/src/sdk/protocol/operation-inventory.generated.json +66 -0
  252. package/src/sdk/router/session-router.ts +375 -36
  253. package/src/sdk/session.ts +547 -47
  254. package/src/session/account-inventory.ts +1 -1
  255. package/src/session/agent-session.ts +765 -189
  256. package/src/session/artifacts.ts +234 -4
  257. package/src/session/internal/managed-session-storage.ts +91 -4
  258. package/src/session/provider-safety-stop-hint.ts +3 -2
  259. package/src/session/session-manager.ts +775 -16
  260. package/src/session/session-staging-paths.ts +8 -0
  261. package/src/setup/hermes/templates/operator-instructions.v1.md +0 -1
  262. package/src/setup/host-plugin-setup.ts +2 -2
  263. package/src/skill-state/active-state.ts +2 -2
  264. package/src/skill-state/canonical-skills.ts +1 -1
  265. package/src/skill-state/initial-phase.ts +1 -1
  266. package/src/skill-state/workflow-hud.ts +41 -41
  267. package/src/skill-state/workflow-mutation-guard.ts +26 -7
  268. package/src/slash-commands/builtin-registry.ts +77 -0
  269. package/src/slash-commands/helpers/autorouting-status.ts +55 -0
  270. package/src/system-prompt.ts +102 -5
  271. package/src/task/discovery.ts +2 -3
  272. package/src/task/executor.ts +617 -43
  273. package/src/task/index.ts +262 -15
  274. package/src/task/receipt.ts +30 -0
  275. package/src/task/render.ts +11 -1
  276. package/src/task/types.ts +316 -0
  277. package/src/tools/atomic-file-write.ts +594 -0
  278. package/src/tools/bisect.ts +3 -2
  279. package/src/tools/descriptors.test.ts +3 -0
  280. package/src/tools/descriptors.ts +24 -0
  281. package/src/tools/image-gen.ts +5 -1
  282. package/src/tools/index.ts +62 -5
  283. package/src/tools/move-session.ts +107 -0
  284. package/src/tools/python.ts +205 -0
  285. package/src/tools/read.ts +88 -15
  286. package/src/tools/renderers.ts +2 -0
  287. package/src/tools/resource-gc.ts +8 -177
  288. package/src/tools/search.ts +30 -6
  289. package/src/tools/skill-discovery.ts +1 -0
  290. package/src/tools/skill.ts +37 -7
  291. package/src/tools/subagent-render.ts +119 -13
  292. package/src/tools/subagent.ts +91 -74
  293. package/src/tools/tool-catalog.generated.ts +64 -2
  294. package/src/tools/write.ts +16 -12
  295. package/src/utils/xml-escape.ts +14 -0
  296. package/src/web/search/providers/codex.ts +2 -2
  297. package/src/workflow/workflow-intent-diff.ts +13 -12
  298. package/src/workflow/workflow-intent-report-consumer.ts +6 -6
  299. package/dist/types/autoresearch/helpers.d.ts +0 -24
  300. package/dist/types/autoresearch/index.d.ts +0 -2
  301. package/dist/types/autoresearch/state.d.ts +0 -17
  302. package/dist/types/autoresearch/storage.d.ts +0 -142
  303. package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
  304. package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
  305. package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
  306. package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
  307. package/dist/types/commands/team.d.ts +0 -24
  308. package/dist/types/gjc-runtime/team-gc.d.ts +0 -7
  309. package/dist/types/gjc-runtime/team-launch.d.ts +0 -61
  310. package/dist/types/gjc-runtime/team-notify.d.ts +0 -45
  311. package/dist/types/gjc-runtime/team-runtime.d.ts +0 -336
  312. package/dist/types/gjc-runtime/team-store.d.ts +0 -168
  313. package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +0 -43
  314. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +0 -92
  315. package/dist/types/gjc-runtime/team-workers.d.ts +0 -83
  316. package/dist/types/rlm/index.d.ts +0 -47
  317. package/dist/types/rlm/preset.d.ts +0 -23
  318. package/dist/types/rlm/python-tool.d.ts +0 -16
  319. package/src/autoresearch/command-resume.md +0 -14
  320. package/src/autoresearch/index.ts +0 -536
  321. package/src/autoresearch/prompt.md +0 -103
  322. package/src/autoresearch/resume-message.md +0 -10
  323. package/src/autoresearch/state.ts +0 -273
  324. package/src/autoresearch/storage.ts +0 -699
  325. package/src/autoresearch/tools/init-experiment.ts +0 -272
  326. package/src/autoresearch/tools/log-experiment.ts +0 -524
  327. package/src/autoresearch/tools/run-experiment.ts +0 -475
  328. package/src/autoresearch/tools/update-notes.ts +0 -109
  329. package/src/commands/rlm.ts +0 -19
  330. package/src/commands/team.ts +0 -238
  331. package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +0 -42
  332. package/src/defaults/gjc/skills/team/SKILL.md +0 -467
  333. package/src/gjc-runtime/team-gc.ts +0 -49
  334. package/src/gjc-runtime/team-launch.ts +0 -404
  335. package/src/gjc-runtime/team-notify.ts +0 -326
  336. package/src/gjc-runtime/team-runtime.ts +0 -5923
  337. package/src/gjc-runtime/team-store.ts +0 -878
  338. package/src/gjc-runtime/team-worker-heartbeat.ts +0 -149
  339. package/src/gjc-runtime/team-worker-memory-guard.ts +0 -363
  340. package/src/gjc-runtime/team-workers.ts +0 -1123
  341. package/src/prompts/system/rlm-report-command.md +0 -1
  342. package/src/prompts/system/rlm-research.md +0 -23
  343. package/src/rlm/index.ts +0 -365
  344. package/src/rlm/preset.ts +0 -76
  345. package/src/rlm/python-tool.ts +0 -68
@@ -1,7 +1,12 @@
1
- import type { AgentToolResult } from "@gajae-code/agent-core";
2
- import type { ExtensionAPI, ExtensionContext } from "../extensibility/extensions";
3
- import type { SessionEntry } from "../session/session-manager";
4
- import type { TruncationResult } from "../session/streaming-output";
1
+ /**
2
+ * Shared types for the rebuilt autoresearch capability modules.
3
+ *
4
+ * These mirror the deleted extension's `types.ts` surface (metrics, ASI,
5
+ * experiment statuses) without the extension-only runtime types (dashboards,
6
+ * tool factories, session entries). The mission/verdict/ledger types live in
7
+ * `gjc-runtime/autoresearch-runtime.ts`; run storage and dashboard models live
8
+ * in `runs.ts` / `dashboard.ts`.
9
+ */
5
10
 
6
11
  export type MetricDirection = "lower" | "higher";
7
12
  export type ExperimentStatus = "keep" | "discard" | "crash" | "checks_failed";
@@ -20,149 +25,3 @@ export interface MetricDef {
20
25
  name: string;
21
26
  unit: string;
22
27
  }
23
-
24
- export interface ExperimentResult {
25
- runNumber: number | null;
26
- commit: string;
27
- metric: number;
28
- metrics: NumericMetricMap;
29
- status: ExperimentStatus;
30
- description: string;
31
- timestamp: number;
32
- segment: number;
33
- confidence: number | null;
34
- asi?: ASIData;
35
- modifiedPaths: string[];
36
- scopeDeviations: string[];
37
- justification: string | null;
38
- flagged: boolean;
39
- flaggedReason: string | null;
40
- }
41
-
42
- export interface ExperimentState {
43
- results: ExperimentResult[];
44
- bestMetric: number | null;
45
- bestDirection: MetricDirection;
46
- metricName: string;
47
- metricUnit: string;
48
- secondaryMetrics: MetricDef[];
49
- name: string | null;
50
- goal: string | null;
51
- currentSegment: number;
52
- maxExperiments: number | null;
53
- confidence: number | null;
54
- scopePaths: string[];
55
- offLimits: string[];
56
- constraints: string[];
57
- notes: string;
58
- branch: string | null;
59
- baselineCommit: string | null;
60
- sessionId: number | null;
61
- }
62
-
63
- export interface RunExperimentProgressDetails {
64
- phase: "running";
65
- elapsed: string;
66
- truncation?: TruncationResult;
67
- fullOutputPath?: string;
68
- runDirectory?: string;
69
- }
70
-
71
- export interface RunDetails {
72
- runNumber: number;
73
- runDirectory: string;
74
- benchmarkLogPath: string;
75
- command: string;
76
- exitCode: number | null;
77
- durationSeconds: number;
78
- passed: boolean;
79
- crashed: boolean;
80
- timedOut: boolean;
81
- tailOutput: string;
82
- parsedMetrics: NumericMetricMap | null;
83
- parsedPrimary: number | null;
84
- parsedAsi: ASIData | null;
85
- metricName: string;
86
- metricUnit: string;
87
- preRunDirtyPaths: string[];
88
- abandonedPriorRun: number | null;
89
- truncation?: TruncationResult;
90
- fullOutputPath?: string;
91
- }
92
-
93
- export interface LogDetails {
94
- experiment: ExperimentResult;
95
- state: ExperimentState;
96
- wallClockSeconds: number | null;
97
- scopeDeviations: string[];
98
- justification: string | null;
99
- flaggedRuns: Array<{ runId: number; reason: string }>;
100
- }
101
-
102
- export interface PendingRunSummary {
103
- command: string;
104
- durationSeconds: number | null;
105
- parsedAsi: ASIData | null;
106
- parsedMetrics: NumericMetricMap | null;
107
- parsedPrimary: number | null;
108
- passed: boolean;
109
- preRunDirtyPaths: string[];
110
- runDirectory: string;
111
- runNumber: number;
112
- exitCode: number | null;
113
- timedOut: boolean;
114
- }
115
-
116
- export interface RunningExperiment {
117
- startedAt: number;
118
- command: string;
119
- runDirectory: string;
120
- runNumber: number;
121
- }
122
-
123
- export interface AutoresearchRuntime {
124
- autoresearchMode: boolean;
125
- autoResumeArmed: boolean;
126
- dashboardExpanded: boolean;
127
- lastAutoResumePendingRunNumber: number | null;
128
- lastRunDuration: number | null;
129
- lastRunAsi: ASIData | null;
130
- lastRunArtifactDir: string | null;
131
- lastRunNumber: number | null;
132
- lastRunSummary: PendingRunSummary | null;
133
- runningExperiment: RunningExperiment | null;
134
- state: ExperimentState;
135
- goal: string | null;
136
- }
137
-
138
- export interface AutoresearchControlEntryData {
139
- mode: "on" | "off" | "clear";
140
- goal?: string;
141
- }
142
-
143
- export interface ReconstructedControlState {
144
- autoresearchMode: boolean;
145
- goal: string | null;
146
- lastMode: AutoresearchControlEntryData["mode"] | null;
147
- }
148
-
149
- export interface RuntimeStore {
150
- clear(sessionKey: string): void;
151
- ensure(sessionKey: string): AutoresearchRuntime;
152
- }
153
-
154
- export interface DashboardController {
155
- clear(ctx: ExtensionContext): void;
156
- requestRender(): void;
157
- showOverlay(ctx: ExtensionContext, runtime: AutoresearchRuntime): Promise<void>;
158
- updateWidget(ctx: ExtensionContext, runtime: AutoresearchRuntime): void;
159
- }
160
-
161
- export interface AutoresearchToolFactoryOptions {
162
- dashboard: DashboardController;
163
- getRuntime(ctx: ExtensionContext): AutoresearchRuntime;
164
- pi: ExtensionAPI;
165
- }
166
-
167
- export type AutoresearchToolResult<TDetails> = AgentToolResult<TDetails>;
168
- export type SessionEntries = SessionEntry[];
@@ -6,9 +6,8 @@
6
6
  * - Registering providers (where to find it)
7
7
  * - Loading items for a capability across all providers
8
8
  */
9
- import * as os from "node:os";
10
9
  import * as path from "node:path";
11
- import { getProjectDir, logger } from "@gajae-code/utils";
10
+ import { getAgentDir, getProjectDir, getTrustedHomeDir, logger } from "@gajae-code/utils";
12
11
 
13
12
  import type { Settings } from "../config/settings";
14
13
  import { clearCache as clearFsCache, findRepoRoot, cacheStats as fsCacheStats, invalidate as invalidateFs } from "./fs";
@@ -237,9 +236,10 @@ export async function loadCapability<T>(capabilityId: string, options: LoadOptio
237
236
  }
238
237
 
239
238
  const cwd = options.cwd ?? getProjectDir();
240
- const home = os.homedir();
239
+ const home = getTrustedHomeDir();
240
+ const userAgentDir = options.agentDir ? path.resolve(options.agentDir) : getAgentDir();
241
241
  const repoRoot = await findRepoRoot(cwd);
242
- const ctx: LoadContext = { cwd, home, repoRoot };
242
+ const ctx: LoadContext = { cwd, home, userAgentDir, repoRoot };
243
243
  const providers = filterProviders(capability, options);
244
244
 
245
245
  return await loadImpl(capability, providers, ctx, options);
@@ -15,6 +15,20 @@ export interface LoadContext {
15
15
  cwd: string;
16
16
  /** User home directory */
17
17
  home: string;
18
+ /**
19
+ * GJC's user-scope config directory: the resolved agent directory
20
+ * (`getAgentDir()`), which `--agent-dir`, `GJC_CODING_AGENT_DIR` and
21
+ * `setAgentDir()` redirect away from `<home>/.gjc/agent`. `loadCapability`
22
+ * always sets it; ad-hoc contexts built for path scanning may omit it, and
23
+ * consumers then fall back to the same process-wide `getAgentDir()`.
24
+ *
25
+ * A native surface whose write path targets the agent directory resolves its
26
+ * user scope from here, or discovery reads a different file than the one the
27
+ * writer produced: `gjc mcp add` (user scope) writes `getMCPConfigPath("user")`
28
+ * under this directory. Surfaces whose writers are home-relative (skills) keep
29
+ * resolving from `home`.
30
+ */
31
+ userAgentDir?: string;
18
32
  /** Git repository root (directory containing .git), or null if not in a repo */
19
33
  repoRoot: string | null;
20
34
  }
@@ -67,6 +81,12 @@ export interface LoadOptions {
67
81
  excludeProviders?: string[];
68
82
  /** Custom cwd. Default: getProjectDir() */
69
83
  cwd?: string;
84
+ /**
85
+ * Agent directory backing `LoadContext.userAgentDir`. Default: getAgentDir().
86
+ * Set it when loading for a session whose agent directory differs from the
87
+ * process-wide one (`createAgentSession({ agentDir })`).
88
+ */
89
+ agentDir?: string;
70
90
  /** Include items even if they fail validation. Default: false */
71
91
  includeInvalid?: boolean;
72
92
  /** Include items disabled via settings. Default: false */
@@ -10,6 +10,8 @@ import {
10
10
  type AuthStorage,
11
11
  type CredentialInventoryRecord,
12
12
  type CredentialRemovalTarget,
13
+ OAuthCredentialSelectorError,
14
+ type OAuthPinTarget,
13
15
  resolveOAuthStorageProvider,
14
16
  } from "@gajae-code/ai/core";
15
17
  import { getAgentDir } from "@gajae-code/utils";
@@ -45,6 +47,10 @@ class AccountsCommandError extends Error {
45
47
  this.name = "AccountsCommandError";
46
48
  }
47
49
  }
50
+ export function toAccountsCommandError(error: unknown): AccountsCommandError | undefined {
51
+ if (error instanceof OAuthCredentialSelectorError) return new AccountsCommandError(error.message);
52
+ return undefined;
53
+ }
48
54
 
49
55
  function writeJson(value: unknown): void {
50
56
  process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
@@ -264,7 +270,12 @@ async function runPin(
264
270
  ) {
265
271
  throw new AccountsCommandError(`Provider ${provider} is not configured; no pin was written.`);
266
272
  }
267
- const target = storage.resolveOAuthPinTarget(provider, selector);
273
+ let target: OAuthPinTarget;
274
+ try {
275
+ target = storage.resolveOAuthPinTarget(provider, selector);
276
+ } catch (error) {
277
+ throw toAccountsCommandError(error) ?? error;
278
+ }
268
279
  const canonicalSelector = `${target.canonicalSelector.kind}:${target.canonicalSelector.value}`;
269
280
  await writePersistentPin(provider, canonicalSelector, false, startupAuth.credentialStoreIdentity);
270
281
  if (flags.json) writeJson({ ok: true, provider, selector: canonicalSelector });
@@ -276,6 +287,7 @@ function accountMatches(row: CredentialInventoryRecord, rawAccount: string): boo
276
287
  const value = rawAccount.trim();
277
288
  if (value.length === 0) return false;
278
289
  if (/^[1-9]\d*$/.test(value) && row.id === Number(value)) return true;
290
+ if (/^id:[1-9]\d*$/i.test(value) && row.id === Number(value.slice(3))) return true;
279
291
  const identity = inventoryIdentity(row);
280
292
  return identity?.toLowerCase() === value.toLowerCase();
281
293
  }
@@ -286,7 +298,6 @@ function removalCandidates(
286
298
  ): Array<{ row: CredentialInventoryRecord; target: CredentialRemovalTarget }> {
287
299
  const targetById = new Map(targets.map(target => [target.id, target]));
288
300
  return inventory
289
- .filter(row => row.credentialKind === "oauth")
290
301
  .map(row => ({ row, target: targetById.get(row.id) }))
291
302
  .filter((entry): entry is { row: CredentialInventoryRecord; target: CredentialRemovalTarget } => !!entry.target);
292
303
  }
@@ -299,10 +310,10 @@ function throwLogoutResolutionError(
299
310
  const lines =
300
311
  candidates.length > 0
301
312
  ? ["Safe candidates:", ...candidates.map(candidate => formatCandidate(candidate.row))]
302
- : ["No OAuth account candidates found."];
313
+ : ["No removable credentials found."];
303
314
  const prefix = account
304
315
  ? `Account ${JSON.stringify(account)} for ${provider} was missing or ambiguous.`
305
- : `No removable OAuth accounts found for ${provider}.`;
316
+ : `No removable stored credentials found for ${provider}.`;
306
317
  throw new AccountsCommandError(`${prefix} No credentials were removed.\n${lines.join("\n")}`);
307
318
  }
308
319
 
@@ -340,7 +351,7 @@ async function runLogout(providerArg: string | undefined, flags: AccountsCommand
340
351
  if (flags.json) writeJson({ ok: true, provider, removedIds: [...result.ids] });
341
352
  else
342
353
  writeText([
343
- `Removed ${result.ids.length} OAuth account${result.ids.length === 1 ? "" : "s"} from ${provider}.`,
354
+ `Removed ${result.ids.length} stored credential${result.ids.length === 1 ? "" : "s"} from ${provider}.`,
344
355
  ]);
345
356
  } finally {
346
357
  storage.close();
@@ -388,6 +399,11 @@ export async function runAccountsCommand(cmd: AccountsCommandArgs): Promise<void
388
399
  writeJsonFailure(error);
389
400
  return;
390
401
  }
402
+ if (error instanceof AccountsCommandError) {
403
+ process.stderr.write(`${error.message}\n`);
404
+ process.exitCode = 1;
405
+ return;
406
+ }
391
407
  throw error;
392
408
  }
393
409
  }
@@ -11,6 +11,11 @@ import { APP_NAME, getAgentDir } from "@gajae-code/utils";
11
11
  import { YAML } from "bun";
12
12
  import chalk from "chalk";
13
13
  import { AtomicYamlReplaceError, AtomicYamlRetargetError } from "../config/atomic-yaml-patch";
14
+ import {
15
+ validateAutoroutingLocal,
16
+ validateAutoroutingProvenance,
17
+ validateAutoroutingSetup,
18
+ } from "../config/autorouting-contract";
14
19
  import { resolveModelProfileName } from "../config/model-profile-contract";
15
20
  import { mergeModelProfiles } from "../config/model-profiles";
16
21
  import { ModelsConfigFile } from "../config/model-registry";
@@ -208,7 +213,10 @@ function getTypeDisplay(def: CliSettingDef): string {
208
213
  case "array":
209
214
  return "(array)";
210
215
  case "record":
216
+ case "constrained-record":
211
217
  return "(record)";
218
+ case "optional-object":
219
+ return "(object)";
212
220
  default:
213
221
  return "(string)";
214
222
  }
@@ -264,7 +272,9 @@ function parseAndSetValue(path: SettingPath, rawValue: string): void {
264
272
  parsedValue = parsed;
265
273
  break;
266
274
  }
267
- case "record": {
275
+ case "record":
276
+ case "constrained-record":
277
+ case "optional-object": {
268
278
  let parsed: unknown;
269
279
  try {
270
280
  parsed = JSON.parse(trimmed);
@@ -280,6 +290,17 @@ function parseAndSetValue(path: SettingPath, rawValue: string): void {
280
290
  default:
281
291
  parsedValue = trimmed;
282
292
  }
293
+ const issues =
294
+ path === "task.autorouting.tiers"
295
+ ? validateAutoroutingLocal({ tiers: parsedValue })
296
+ : path === "task.autorouting.setup"
297
+ ? validateAutoroutingSetup(parsedValue)
298
+ : path === "task.autorouting.provenance"
299
+ ? validateAutoroutingProvenance(parsedValue)
300
+ : [];
301
+ if (issues.length > 0) {
302
+ throw new Error(`Invalid value for ${path}: ${issues.map(issue => `${issue.path}: ${issue.detail}`).join("; ")}`);
303
+ }
283
304
 
284
305
  settings.set(path, parsedValue as SettingValue<typeof path>);
285
306
  }
@@ -581,6 +602,9 @@ function matchesSettingType(path: SettingPath, value: unknown): boolean {
581
602
  case "array":
582
603
  return Array.isArray(value);
583
604
  case "record":
605
+ case "constrained-record":
606
+ return value !== null && typeof value === "object" && !Array.isArray(value);
607
+ case "optional-object":
584
608
  return value !== null && typeof value === "object" && !Array.isArray(value);
585
609
  }
586
610
  }
@@ -12,9 +12,9 @@ export function getExtraHelpText(): string {
12
12
  ${APP_NAME} auth-gateway - Run an auth-gateway forward proxy
13
13
  ${APP_NAME} harness - Run harness control-plane commands
14
14
  ${APP_NAME} coordinator - Manage coordinator/runtime coordination helpers
15
- ${APP_NAME} team - Run tmux-backed coordinated execution
16
15
  ${APP_NAME} ultragoal - Run durable goal execution workflow
17
16
  ${APP_NAME} ralplan - Run consensus planning workflow
17
+ ${APP_NAME} autoresearch - Run autonomous research workflow
18
18
  ${APP_NAME} deep-interview - Run requirements interview workflow
19
19
  ${APP_NAME} skills - List/read embedded workflow skills
20
20
  ${APP_NAME} config - List, get, and set configuration values
@@ -25,7 +25,6 @@ export function getExtraHelpText(): string {
25
25
  ${APP_NAME} mcp-serve - Serve the MCP integration endpoint
26
26
  ${APP_NAME} contribute-pr - Prepare contribution/PR workflow artifacts
27
27
  ${APP_NAME} migrate - Run migration helpers
28
- ${APP_NAME} rlm - Run RLM helpers
29
28
  ${APP_NAME} update - Update GJC installation artifacts
30
29
  ${APP_NAME} plugin - Install, remove, and list plugins
31
30
  ${APP_NAME} web-search - Search the web from the CLI (alias: q)
@@ -69,17 +69,14 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
69
69
  }
70
70
 
71
71
  const filteredCanonical = modelRegistry
72
- .getCanonicalModels({ availableOnly: true, candidates: filteredModels })
73
- .map(record => {
74
- const selected = modelRegistry.resolveCanonicalModel(record.id, {
75
- availableOnly: true,
76
- candidates: filteredModels,
77
- });
72
+ .getCanonicalModelSelections({ availableOnly: true, candidates: filteredModels })
73
+ .map(selection => {
74
+ const selected = selection.model;
78
75
  if (!selected) return undefined;
79
76
  return {
80
- canonical: record.id,
77
+ canonical: selection.record.id,
81
78
  selected: `${selected.provider}/${selected.id}`,
82
- variants: String(record.variants.length),
79
+ variants: String(selection.record.variants.length),
83
80
  context: formatNumber(selected.contextWindow),
84
81
  maxOut: formatNumber(selected.maxTokens),
85
82
  } satisfies CanonicalRow;
@@ -596,6 +596,14 @@ async function handleDefaultsSetup(flags: { json?: boolean; check?: boolean; for
596
596
  console.log(chalk.dim(`Target: ${result.targetRoot}`));
597
597
  console.log(chalk.dim(`Written: ${result.written}; skipped: ${result.skipped}`));
598
598
  console.log(chalk.dim(inspectGuidance));
599
+ const quarantined = result.retired.filter(entry => entry.status === "quarantined");
600
+ for (const entry of quarantined) {
601
+ console.log(
602
+ chalk.dim(
603
+ `Retired: \`${entry.name}\` is no longer a bundled workflow skill; moved to ${entry.quarantinedTo} so it is no longer discoverable.`,
604
+ ),
605
+ );
606
+ }
599
607
  if (result.skipped > 0 && !flags.force) {
600
608
  console.log(
601
609
  chalk.dim(
package/src/cli.ts CHANGED
@@ -42,10 +42,10 @@ export const commands: CommandEntry[] = [
42
42
  { name: "accounts", load: () => import("./commands/accounts").then(m => m.default) },
43
43
  { name: "harness", load: () => import("./commands/harness").then(m => m.default) },
44
44
  { name: "coordinator", load: () => import("./commands/coordinator").then(m => m.default) },
45
- { name: "team", load: () => import("./commands/team").then(m => m.default) },
46
45
  { name: "ultragoal", load: () => import("./commands/ultragoal").then(m => m.default) },
47
46
  { name: "gc", load: () => import("./commands/gc").then(m => m.default) },
48
47
  { name: "crash", load: () => import("./commands/crash").then(m => m.default) },
48
+ { name: "autoresearch", load: () => import("./commands/autoresearch").then(m => m.default) },
49
49
  { name: "ralplan", load: () => import("./commands/ralplan").then(m => m.default) },
50
50
  { name: "config", load: () => import("./commands/config").then(m => m.default) },
51
51
  { name: "stats", load: () => import("./commands/stats").then(m => m.default) },
@@ -63,7 +63,6 @@ export const commands: CommandEntry[] = [
63
63
  },
64
64
  { name: "deep-interview", load: () => import("./commands/deep-interview").then(m => m.default) },
65
65
  { name: "migrate", load: () => import("./commands/migrate").then(m => m.default) },
66
- { name: "rlm", load: () => import("./commands/rlm").then(m => m.default) },
67
66
  { name: "update", load: () => import("./commands/update").then(m => m.default) },
68
67
  { name: "read", load: () => import("./commands/read").then(m => m.default) },
69
68
  { name: "customize", load: () => import("./commands/customize").then(m => m.default) },
@@ -350,25 +349,7 @@ export function normalizeResumeAlias(argv: readonly string[]): string[] {
350
349
 
351
350
  function routeLegacyRootArgv(argv: readonly string[]): string[] | undefined {
352
351
  if (argv[0] === "coordinator-mcp") return ["mcp-serve", "coordinator", ...argv.slice(1)];
353
- if (argv[0] !== "--team") return undefined;
354
- const sizeValues: string[] = [];
355
- const remaining: string[] = [];
356
- for (let index = 1; index < argv.length; index++) {
357
- const arg = argv[index] ?? "";
358
- if (arg === "--team-size") {
359
- sizeValues.push(argv[index + 1] ?? "");
360
- index++;
361
- } else if (arg.startsWith("--team-size=")) {
362
- sizeValues.push(arg.slice("--team-size=".length));
363
- } else {
364
- remaining.push(arg);
365
- }
366
- }
367
- const size = sizeValues[0];
368
- if (sizeValues.length !== 1 || !size || !/^[1-9]\d*$/.test(size)) {
369
- return ["team", "0", "invalid legacy --team-size"];
370
- }
371
- return ["team", size, ...remaining];
352
+ return undefined;
372
353
  }
373
354
 
374
355
  /**
@@ -0,0 +1,33 @@
1
+ import { Command, renderCommandHelp } from "@gajae-code/utils/cli";
2
+ import { ensureWorkflowSettingsMigrated } from "../config/settings";
3
+ import { runNativeAutoresearchCommand } from "../gjc-runtime/autoresearch-runtime";
4
+
5
+ export default class Autoresearch extends Command {
6
+ static description = "Run native GJC Autoresearch workflow commands";
7
+ static strict = false;
8
+ static examples = [
9
+ "$ gjc autoresearch intake --spec <deep-interview-spec.md> --json",
10
+ "$ gjc autoresearch --spec <deep-interview-spec.md> --json",
11
+ '$ gjc autoresearch "<goal>"',
12
+ "$ gjc autoresearch",
13
+ "$ gjc autoresearch read --json",
14
+ "$ gjc autoresearch clear --json",
15
+ "$ gjc autoresearch write --goal <goal> --mode web --slug <slug> --json",
16
+ ];
17
+ static delegateHelp = true;
18
+
19
+ async run(): Promise<void> {
20
+ // A read-only help request must not perform the workflow-settings
21
+ // migration (which can create/drain agent.db, write config.yml, and
22
+ // retire legacy settings.json): render help before the trigger.
23
+ if (this.argv.includes("--help") || this.argv.includes("-h")) {
24
+ renderCommandHelp("gjc", "autoresearch", Autoresearch);
25
+ return;
26
+ }
27
+ await ensureWorkflowSettingsMigrated(process.cwd());
28
+ const result = await runNativeAutoresearchCommand(this.argv, process.cwd());
29
+ if (result.stdout) process.stdout.write(result.stdout);
30
+ if (result.stderr) process.stderr.write(result.stderr);
31
+ process.exitCode = result.status;
32
+ }
33
+ }
@@ -4,6 +4,7 @@ import {
4
4
  COORDINATOR_MCP_SERVER_NAME,
5
5
  COORDINATOR_MCP_TOOL_NAMES,
6
6
  } from "../coordinator/contract";
7
+ import { parseEventWebhookConfig } from "../coordinator-mcp/event-webhook";
7
8
  import { buildCoordinatorMcpConfig } from "../coordinator-mcp/policy";
8
9
 
9
10
  function writeJson(value: unknown): void {
@@ -54,6 +55,20 @@ function coordinatorDoctorPayload(): {
54
55
  status: config.namespace.profile && config.namespace.repo ? "pass" : "warn",
55
56
  detail: `profile=${config.namespace.profile ?? "<unset>"} repo=${config.namespace.repo ?? "<unset>"}`,
56
57
  });
58
+ let eventWebhookStatus: "pass" | "fail" = "pass";
59
+ let eventWebhookDetail = "unset; coordinator behavior unchanged";
60
+ try {
61
+ const parsed = parseEventWebhookConfig();
62
+ if (parsed) {
63
+ eventWebhookDetail = `opt-in webhook delivery enabled for ${parsed.url}${
64
+ parsed.sessionIds ? ` scoped to ${parsed.sessionIds.size} session(s)` : ""
65
+ }`;
66
+ }
67
+ } catch (error) {
68
+ eventWebhookStatus = "fail";
69
+ eventWebhookDetail = error instanceof Error ? error.message : "coordinator_event_webhook_invalid";
70
+ }
71
+ checks.push({ id: "event_webhook", status: eventWebhookStatus, detail: eventWebhookDetail });
57
72
  return { ok: checks.every(check => check.status !== "fail"), checks };
58
73
  }
59
74
 
@@ -2,12 +2,11 @@
2
2
  * Root command for the coding agent CLI.
3
3
  */
4
4
 
5
- import * as fs from "node:fs/promises";
6
- import * as path from "node:path";
7
5
  import { APP_NAME, setProjectDir } from "@gajae-code/utils";
8
6
  import { Args, Command } from "@gajae-code/utils/cli";
9
7
  import { assertLocalLaunchArgs, parseArgs } from "../cli/args";
10
8
  import { ROOT_LAUNCH_FLAGS } from "../cli/root-flags";
9
+ import { writeCoordinatorAtomic } from "../coordinator-mcp/durability";
11
10
  import { launchDefaultTmuxIfNeeded } from "../gjc-runtime/launch-tmux";
12
11
  import { type PreparedLaunchWorktree, prepareLaunchWorktree } from "../gjc-runtime/launch-worktree";
13
12
  import {
@@ -54,8 +53,7 @@ export async function persistCoordinatorLaunchFailure(
54
53
  ? { owner_generation: env[GJC_TMUX_OWNER_GENERATION_ENV] ?? null }
55
54
  : {}),
56
55
  };
57
- await fs.mkdir(path.dirname(stateFile), { recursive: true });
58
- await Bun.write(stateFile, `${JSON.stringify(payload, null, 2)}\n`);
56
+ await writeCoordinatorAtomic(stateFile, `${JSON.stringify(payload, null, 2)}\n`);
59
57
  }
60
58
 
61
59
  export default class Index extends Command {
@@ -26,7 +26,7 @@ export default class QuickLane extends Command {
26
26
  static examples = [
27
27
  `$ gjc quick-lane classify "add validation to processKeywordDetector"`,
28
28
  `$ gjc quick-lane classify --json "fix src/hooks/bridge.ts"`,
29
- `$ gjc quick-lane classify "team make it better"`,
29
+ `$ gjc quick-lane classify "autoresearch the caching layer"`,
30
30
  ];
31
31
 
32
32
  async run(): Promise<void> {
@@ -5,6 +5,7 @@ import * as path from "node:path";
5
5
  import { logger } from "@gajae-code/utils";
6
6
  import { Args, CliParseError, Command, Flags, renderCommandHelp } from "@gajae-code/utils/cli";
7
7
  import type { Args as ParsedArgs } from "../cli/args";
8
+ import { parseModelString } from "../config/model-resolver";
8
9
  import { Settings } from "../config/settings";
9
10
  import { applyStartupModelProfiles, createSessionManager } from "../main";
10
11
  import { initializeExtensions } from "../modes/runtime-init";
@@ -56,8 +57,16 @@ export async function lifecycleArgs(
56
57
  messages: [],
57
58
  fileArgs: [],
58
59
  unknownFlags: new Map(),
60
+ ...(process.env.GJC_SDK_TEST_IN_MEMORY_SESSION === "1" ? { noSession: true } : {}),
59
61
  ...(request.operation === "session.resume" ? { resume: request.sessionPath } : {}),
60
62
  ...(request.modelPreset ? { mpreset: request.modelPreset } : {}),
63
+ // Explicit model pin (#4707): coordinator-resolved `provider/model`
64
+ // selector applied exactly like CLI `--model`. createAgentSession
65
+ // resolves it through the same staged selector resolver, and startup
66
+ // model-profile application then overrides the activated profile with
67
+ // this explicit selection (main.ts applyStartupModelProfilesWithPolicy),
68
+ // matching `gjc --mpreset p --model m` precedence.
69
+ ...(request.modelId ? { model: request.modelId } : {}),
61
70
  ...(request.operation === "session.fork"
62
71
  ? {
63
72
  fork: request.sourceSessionPath ?? request.sourceSessionId,
@@ -554,6 +563,7 @@ export async function runSessionHost(
554
563
  ...(mcpConfigPath ? { mcpConfigPath } : {}),
555
564
  ...(mcpStartupTimeoutMs !== undefined ? { mcpStartupTimeoutMs } : {}),
556
565
  ...(request.readiness ? { readiness: request.readiness } : {}),
566
+ ...(request.modelId ? { modelId: request.modelId } : {}),
557
567
  });
558
568
  } catch (error) {
559
569
  throw await registrationFailure(error);
@@ -674,6 +684,7 @@ export async function runSessionHost(
674
684
  };
675
685
 
676
686
  try {
687
+ const startupThinkingLevel = request.modelId ? parseModelString(request.modelId)?.thinkingLevel : undefined;
677
688
  const modelProfileStartup =
678
689
  process.env.GJC_SDK_TEST_HANG_MODEL_PROFILE === cwd
679
690
  ? new Promise<void>(() => {})
@@ -682,6 +693,7 @@ export async function runSessionHost(
682
693
  settings: session.settings,
683
694
  modelRegistry: session.modelRegistry,
684
695
  parsedArgs: parsed,
696
+ startupThinkingLevel,
685
697
  });
686
698
  await beforeCutoff(modelProfileStartup);
687
699
  throwIfCutoff();
@@ -720,6 +732,18 @@ export async function runSessionHost(
720
732
  // Readiness is published; the session is live. Memory startup issues one LLM
721
733
  // request per queued rollout, so it must run outside the readiness window and
722
734
  // its failure must never take the session down.
735
+ if (process.env.GJC_SDK_TEST_EXIT_AFTER_READY === cwd) {
736
+ process.stderr.write("GJC_SDK_TEST_EXIT_AFTER_READY\n");
737
+ process.exit(7);
738
+ }
739
+ if (process.env.GJC_SDK_TEST_REJECT_AFTER_READY === cwd) {
740
+ // Simulates the post-readiness liveness watcher rejecting. With the
741
+ // post-ready startup receipt removed, this unhandled rejection kills the
742
+ // host without writing any startup receipt; the broker must classify the
743
+ // death from published ready authority plus proven exit.
744
+ void Promise.reject(new Error("GJC_SDK_TEST_REJECT_AFTER_READY"));
745
+ await Bun.sleep(5_000);
746
+ }
723
747
  startMemoryBackendAfterReadiness(startDeferredMemoryBackend);
724
748
  process.once("SIGTERM", stop);
725
749
  process.once("SIGINT", stop);
@@ -11,7 +11,7 @@ export default class State extends Command {
11
11
  "$ gjc state clear --mode deep-interview",
12
12
  "$ gjc state deep-interview read --json",
13
13
  '$ gjc state ralplan write --input \'{"phase":"planner","active":true}\' --json',
14
- "$ gjc state team contract",
14
+ "$ gjc state autoresearch contract",
15
15
  "$ gjc state deep-interview handoff --to ralplan --json",
16
16
  "$ gjc state doctor --skill ralplan --json",
17
17
  ];