@gajae-code/coding-agent 0.13.3 → 0.14.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 (599) hide show
  1. package/CHANGELOG.md +184 -2
  2. package/README.md +2 -0
  3. package/bin/gajaessi.js +4 -0
  4. package/dist/types/async/job-manager.d.ts +55 -2
  5. package/dist/types/async/support.d.ts +14 -0
  6. package/dist/types/capability/mcp.d.ts +6 -0
  7. package/dist/types/capability/types.d.ts +6 -0
  8. package/dist/types/cli/accounts-cli.d.ts +19 -0
  9. package/dist/types/cli/args.d.ts +3 -0
  10. package/dist/types/cli/config-cli.d.ts +6 -0
  11. package/dist/types/cli/crash-cli.d.ts +10 -0
  12. package/dist/types/cli/customize-doctor.d.ts +145 -0
  13. package/dist/types/cli/daemon-cli.d.ts +3 -1
  14. package/dist/types/cli/mcp-cli.d.ts +11 -0
  15. package/dist/types/cli/notify-cli.d.ts +1 -1
  16. package/dist/types/cli/root-flags.d.ts +12 -0
  17. package/dist/types/cli/setup-cli.d.ts +3 -1
  18. package/dist/types/cli/skills-cli.d.ts +2 -1
  19. package/dist/types/cli/update-cli.d.ts +19 -1
  20. package/dist/types/cli.d.ts +6 -0
  21. package/dist/types/commands/accounts.d.ts +40 -0
  22. package/dist/types/commands/crash.d.ts +24 -0
  23. package/dist/types/commands/customize.d.ts +22 -0
  24. package/dist/types/commands/daemon.d.ts +1 -1
  25. package/dist/types/commands/launch.d.ts +6 -0
  26. package/dist/types/commands/setup.d.ts +6 -0
  27. package/dist/types/commands/skills.d.ts +6 -1
  28. package/dist/types/commands/update.d.ts +7 -0
  29. package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
  30. package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
  31. package/dist/types/config/config-schema-version.d.ts +10 -0
  32. package/dist/types/config/file-lock.d.ts +18 -0
  33. package/dist/types/config/model-profile-activation.d.ts +3 -1
  34. package/dist/types/config/model-registry.d.ts +9 -1
  35. package/dist/types/config/models-config-schema.d.ts +2 -0
  36. package/dist/types/config/settings-schema.d.ts +70 -6
  37. package/dist/types/config/settings.d.ts +63 -0
  38. package/dist/types/config/skill-settings-defaults.d.ts +26 -0
  39. package/dist/types/config/task-delegation.d.ts +39 -0
  40. package/dist/types/config/update-channel.d.ts +10 -0
  41. package/dist/types/coordinator-mcp/server.d.ts +5 -1
  42. package/dist/types/crash/index-store.d.ts +87 -0
  43. package/dist/types/crash/nudge.d.ts +50 -0
  44. package/dist/types/crash/record-loader.d.ts +17 -0
  45. package/dist/types/crash/report.d.ts +134 -0
  46. package/dist/types/crash/sanitize.d.ts +25 -0
  47. package/dist/types/cursor.d.ts +13 -2
  48. package/dist/types/customization/import.d.ts +37 -0
  49. package/dist/types/customization/index.d.ts +4 -0
  50. package/dist/types/customization/inventory.d.ts +25 -0
  51. package/dist/types/customization/mutations.d.ts +32 -0
  52. package/dist/types/customization/types.d.ts +115 -0
  53. package/dist/types/daemon/control-types.d.ts +8 -1
  54. package/dist/types/daemon/operator-contract.d.ts +4 -4
  55. package/dist/types/discovery/claude.d.ts +39 -1
  56. package/dist/types/discovery/codex.d.ts +39 -1
  57. package/dist/types/discovery/index.d.ts +2 -0
  58. package/dist/types/discovery/mcp-compat.d.ts +30 -0
  59. package/dist/types/edit/renderer.d.ts +23 -0
  60. package/dist/types/extensibility/extensions/runner.d.ts +3 -0
  61. package/dist/types/extensibility/extensions/types.d.ts +21 -4
  62. package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
  63. package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
  64. package/dist/types/extensibility/hooks/loader.d.ts +19 -5
  65. package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
  66. package/dist/types/extensibility/skill-management.d.ts +107 -0
  67. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
  68. package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
  69. package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
  70. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
  71. package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
  72. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
  73. package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
  74. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
  75. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
  76. package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
  77. package/dist/types/hooks/events.d.ts +60 -0
  78. package/dist/types/hooks/normalize.d.ts +83 -0
  79. package/dist/types/hooks/skill-state.d.ts +9 -2
  80. package/dist/types/main.d.ts +1 -1
  81. package/dist/types/modes/acp/abort-scope.d.ts +13 -0
  82. package/dist/types/modes/acp/acp-agent.d.ts +7 -4
  83. package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
  84. package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
  85. package/dist/types/modes/components/customization/index.d.ts +1 -0
  86. package/dist/types/modes/components/gajae-pet-widget.d.ts +8 -30
  87. package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
  88. package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
  89. package/dist/types/modes/components/oauth-selector.d.ts +10 -4
  90. package/dist/types/modes/components/pet-capability.d.ts +11 -25
  91. package/dist/types/modes/components/status-line/gh.d.ts +6 -2
  92. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
  93. package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
  94. package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
  95. package/dist/types/modes/interactive-mode.d.ts +1 -0
  96. package/dist/types/modes/types.d.ts +1 -0
  97. package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
  98. package/dist/types/runtime-mcp/config.d.ts +9 -0
  99. package/dist/types/runtime-mcp/manager.d.ts +26 -1
  100. package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
  101. package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
  102. package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
  103. package/dist/types/runtime-mcp/protocol.d.ts +278 -0
  104. package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
  105. package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
  106. package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
  107. package/dist/types/runtime-mcp/types.d.ts +102 -10
  108. package/dist/types/sdk/acp/adapter.d.ts +26 -5
  109. package/dist/types/sdk/broker/broker.d.ts +3 -55
  110. package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
  111. package/dist/types/sdk/broker/session-index.d.ts +14 -5
  112. package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
  113. package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
  114. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
  115. package/dist/types/sdk/bus/config.d.ts +11 -0
  116. package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
  117. package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
  118. package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
  119. package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
  120. package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
  121. package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
  122. package/dist/types/sdk/bus/index.d.ts +85 -99
  123. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
  124. package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
  125. package/dist/types/sdk/bus/notification-service.d.ts +52 -0
  126. package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
  127. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
  128. package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
  129. package/dist/types/sdk/bus/session-control.d.ts +25 -1
  130. package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
  131. package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
  132. package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
  133. package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
  134. package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
  135. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
  136. package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
  137. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
  138. package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
  139. package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
  140. package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
  141. package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
  142. package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
  143. package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
  144. package/dist/types/sdk/cli/rows.d.ts +2 -11
  145. package/dist/types/sdk/cli/session-cli.d.ts +15 -25
  146. package/dist/types/sdk/client/client.d.ts +97 -1
  147. package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
  148. package/dist/types/sdk/host/control/index.d.ts +1 -1
  149. package/dist/types/sdk/host/control/operations.d.ts +18 -5
  150. package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
  151. package/dist/types/sdk/host/host.d.ts +15 -1
  152. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  153. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  154. package/dist/types/sdk/host/session-runtime.d.ts +127 -7
  155. package/dist/types/sdk/host/types.d.ts +1 -1
  156. package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
  157. package/dist/types/sdk/index.d.ts +2 -1
  158. package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
  159. package/dist/types/sdk/lifecycle/client.d.ts +59 -0
  160. package/dist/types/sdk/lifecycle/index.d.ts +3 -0
  161. package/dist/types/sdk/lifecycle/service.d.ts +232 -0
  162. package/dist/types/sdk/mcp/server.d.ts +9 -6
  163. package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
  164. package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
  165. package/dist/types/sdk/prompt-status.d.ts +10 -3
  166. package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
  167. package/dist/types/sdk/receipt-state.d.ts +17 -0
  168. package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
  169. package/dist/types/sdk/router/index.d.ts +1 -0
  170. package/dist/types/sdk/router/session-router.d.ts +152 -0
  171. package/dist/types/sdk/session-list.d.ts +22 -0
  172. package/dist/types/sdk/session-reconnect.d.ts +43 -1
  173. package/dist/types/sdk/session.d.ts +34 -1
  174. package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
  175. package/dist/types/session/account-inventory.d.ts +86 -0
  176. package/dist/types/session/agent-session.d.ts +145 -6
  177. package/dist/types/session/agent-storage.d.ts +10 -0
  178. package/dist/types/session/coordinator-tool-label.d.ts +28 -0
  179. package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
  180. package/dist/types/session/messages.d.ts +1 -1
  181. package/dist/types/session/secure-token-file.d.ts +3 -0
  182. package/dist/types/session/session-manager.d.ts +40 -1
  183. package/dist/types/session/startup-auth-config.d.ts +44 -0
  184. package/dist/types/session/terminal-abort.d.ts +378 -0
  185. package/dist/types/session/yield-queue.d.ts +7 -0
  186. package/dist/types/session-import/claude.d.ts +26 -0
  187. package/dist/types/session-import/codex.d.ts +88 -0
  188. package/dist/types/session-import/command.d.ts +35 -0
  189. package/dist/types/session-import/detect.d.ts +22 -0
  190. package/dist/types/session-import/index.d.ts +7 -0
  191. package/dist/types/session-import/provider-codex.d.ts +22 -0
  192. package/dist/types/session-import/provider-service.d.ts +38 -0
  193. package/dist/types/session-import/redact.d.ts +23 -0
  194. package/dist/types/session-import/service.d.ts +47 -0
  195. package/dist/types/session-import/types.d.ts +120 -0
  196. package/dist/types/setup/paseo/check.d.ts +16 -0
  197. package/dist/types/setup/paseo/install-saga.d.ts +115 -0
  198. package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
  199. package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
  200. package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
  201. package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
  202. package/dist/types/setup/paseo/provider-config.d.ts +35 -0
  203. package/dist/types/setup/paseo/remove.d.ts +14 -0
  204. package/dist/types/setup/paseo/result-types.d.ts +59 -0
  205. package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
  206. package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
  207. package/dist/types/skill-state/active-state.d.ts +5 -1
  208. package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
  209. package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
  210. package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
  211. package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
  212. package/dist/types/slash-commands/types.d.ts +7 -1
  213. package/dist/types/task/executor.d.ts +10 -0
  214. package/dist/types/task/index.d.ts +3 -1
  215. package/dist/types/tools/ask-answer-registry.d.ts +6 -3
  216. package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
  217. package/dist/types/tools/bash.d.ts +2 -6
  218. package/dist/types/tools/browser/attach.d.ts +11 -0
  219. package/dist/types/tools/browser/launch.d.ts +20 -0
  220. package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
  221. package/dist/types/tools/browser/render.d.ts +1 -0
  222. package/dist/types/tools/browser.d.ts +3 -1
  223. package/dist/types/tools/image-gen.d.ts +9 -2
  224. package/dist/types/tools/index.d.ts +8 -0
  225. package/dist/types/tools/monitor.d.ts +1 -1
  226. package/dist/types/tools/skill-discovery.d.ts +8 -1
  227. package/dist/types/tools/subagent.d.ts +2 -0
  228. package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
  229. package/dist/types/utils/herdr-pane.d.ts +76 -0
  230. package/package.json +19 -9
  231. package/scripts/build-binary.ts +2 -1
  232. package/scripts/build-sdk-package-smoke.ts +2 -13
  233. package/scripts/capture-sticky-viewport-showcase.ts +0 -1
  234. package/scripts/compile-args.ts +2 -0
  235. package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
  236. package/scripts/generate-sdk-operation-inventory.ts +28 -0
  237. package/scripts/generate-telegram-baseline-manifest.ts +1 -0
  238. package/scripts/generate-tool-catalog.ts +6 -4
  239. package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
  240. package/src/async/job-manager.ts +352 -17
  241. package/src/async/support.ts +25 -0
  242. package/src/autoresearch/dashboard.ts +28 -13
  243. package/src/capability/index.ts +3 -1
  244. package/src/capability/mcp.ts +6 -0
  245. package/src/capability/types.ts +6 -0
  246. package/src/cli/accounts-cli.ts +395 -0
  247. package/src/cli/args.ts +23 -0
  248. package/src/cli/auth-broker-cli.ts +136 -66
  249. package/src/cli/auth-gateway-cli.ts +94 -70
  250. package/src/cli/config-cli.ts +27 -2
  251. package/src/cli/crash-cli.ts +78 -0
  252. package/src/cli/customize-doctor.ts +1605 -0
  253. package/src/cli/daemon-cli.ts +12 -3
  254. package/src/cli/fast-help.ts +1 -0
  255. package/src/cli/mcp-cli.ts +128 -60
  256. package/src/cli/notify-cli.ts +8 -14
  257. package/src/cli/root-flags.ts +8 -0
  258. package/src/cli/setup-cli.ts +145 -0
  259. package/src/cli/skills-cli.ts +38 -2
  260. package/src/cli/update-cli.ts +167 -12
  261. package/src/cli.ts +4 -0
  262. package/src/commands/accounts.ts +71 -0
  263. package/src/commands/crash.ts +35 -0
  264. package/src/commands/customize.ts +84 -0
  265. package/src/commands/daemon.ts +2 -2
  266. package/src/commands/deep-interview.ts +2 -0
  267. package/src/commands/launch.ts +1 -0
  268. package/src/commands/mcp.ts +12 -7
  269. package/src/commands/ralplan.ts +2 -0
  270. package/src/commands/sdk.ts +65 -32
  271. package/src/commands/setup.ts +5 -0
  272. package/src/commands/skills.ts +14 -4
  273. package/src/commands/ultragoal.ts +10 -1
  274. package/src/commands/update.ts +26 -15
  275. package/src/config/atomic-yaml-patch-worker.ts +57 -0
  276. package/src/config/atomic-yaml-patch.ts +769 -29
  277. package/src/config/config-schema-version.ts +10 -0
  278. package/src/config/file-lock.ts +70 -1
  279. package/src/config/mcp-schema.json +52 -14
  280. package/src/config/model-profile-activation.ts +20 -1
  281. package/src/config/model-profiles.ts +29 -19
  282. package/src/config/model-registry.ts +132 -21
  283. package/src/config/models-config-schema.ts +1 -1
  284. package/src/config/settings-schema.ts +76 -6
  285. package/src/config/settings.ts +4038 -199
  286. package/src/config/skill-settings-defaults.ts +41 -3
  287. package/src/config/task-delegation.ts +87 -0
  288. package/src/config/update-channel.ts +23 -0
  289. package/src/coordinator-mcp/server.ts +377 -308
  290. package/src/crash/index-store.ts +723 -0
  291. package/src/crash/nudge.ts +89 -0
  292. package/src/crash/record-loader.ts +149 -0
  293. package/src/crash/report.ts +551 -0
  294. package/src/crash/sanitize.ts +129 -0
  295. package/src/cursor.ts +36 -10
  296. package/src/customization/import.ts +946 -0
  297. package/src/customization/index.ts +4 -0
  298. package/src/customization/inventory.ts +335 -0
  299. package/src/customization/mutations.ts +141 -0
  300. package/src/customization/types.ts +223 -0
  301. package/src/daemon/control-types.ts +8 -1
  302. package/src/daemon/operator-contract.ts +6 -6
  303. package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
  304. package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
  305. package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
  306. package/src/discovery/claude-hooks.ts +38 -0
  307. package/src/discovery/claude.ts +142 -209
  308. package/src/discovery/codex-hooks.ts +38 -0
  309. package/src/discovery/codex.ts +132 -198
  310. package/src/discovery/helpers.ts +8 -1
  311. package/src/discovery/index.ts +2 -0
  312. package/src/discovery/mcp-compat.ts +234 -0
  313. package/src/discovery/mcp-json.ts +6 -0
  314. package/src/edit/renderer.ts +40 -0
  315. package/src/edit/streaming.ts +4 -2
  316. package/src/exec/bash-executor.ts +24 -20
  317. package/src/export/html/index.ts +51 -2
  318. package/src/extensibility/extensions/loader.ts +9 -1
  319. package/src/extensibility/extensions/runner.ts +17 -4
  320. package/src/extensibility/extensions/types.ts +31 -6
  321. package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
  322. package/src/extensibility/gjc-plugins/installer.ts +9 -5
  323. package/src/extensibility/gjc-plugins/observability.ts +8 -2
  324. package/src/extensibility/gjc-plugins/registry.ts +13 -2
  325. package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
  326. package/src/extensibility/gjc-plugins/schema.ts +222 -39
  327. package/src/extensibility/hooks/loader.ts +154 -10
  328. package/src/extensibility/runtime-skill-discovery.ts +257 -60
  329. package/src/extensibility/skill-management.ts +368 -0
  330. package/src/extensibility/skills.ts +52 -16
  331. package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
  332. package/src/gjc-runtime/launch-worktree.ts +56 -2
  333. package/src/gjc-runtime/linux-proc.ts +7 -1
  334. package/src/gjc-runtime/ralplan-runtime.ts +100 -164
  335. package/src/gjc-runtime/session-state-lock.ts +992 -0
  336. package/src/gjc-runtime/session-state-sidecar.ts +644 -142
  337. package/src/gjc-runtime/state-writer.ts +39 -14
  338. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
  339. package/src/gjc-runtime/ultragoal-guard.ts +11 -4
  340. package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
  341. package/src/gjc-runtime/workflow-settings.ts +596 -0
  342. package/src/goals/tools/goal-tool.ts +6 -1
  343. package/src/hooks/events.ts +291 -0
  344. package/src/hooks/native-skill-hook.ts +4 -0
  345. package/src/hooks/normalize.ts +369 -0
  346. package/src/hooks/skill-state.ts +165 -46
  347. package/src/internal-urls/docs-index.generated.ts +40 -32
  348. package/src/main.ts +32 -5
  349. package/src/migrate/mcp-mapper.ts +25 -2
  350. package/src/modes/acp/abort-scope.ts +29 -0
  351. package/src/modes/acp/acp-agent.ts +423 -98
  352. package/src/modes/components/assistant-message.ts +6 -1
  353. package/src/modes/components/customization/customization-dashboard.ts +443 -0
  354. package/src/modes/components/customization/import-wizard.ts +372 -0
  355. package/src/modes/components/customization/index.ts +1 -0
  356. package/src/modes/components/gajae-pet-widget.ts +539 -213
  357. package/src/modes/components/irc-sidebar.ts +11 -0
  358. package/src/modes/components/iterm-pet-transport.ts +585 -0
  359. package/src/modes/components/oauth-selector.ts +277 -86
  360. package/src/modes/components/pet-capability.ts +39 -40
  361. package/src/modes/components/settings-selector.ts +9 -0
  362. package/src/modes/components/status-line/gh.ts +45 -1
  363. package/src/modes/components/status-line/segments.ts +16 -1
  364. package/src/modes/components/tool-status-header.ts +13 -3
  365. package/src/modes/controllers/command-controller.ts +20 -8
  366. package/src/modes/controllers/extension-ui-controller.ts +56 -257
  367. package/src/modes/controllers/input-controller.ts +10 -0
  368. package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
  369. package/src/modes/controllers/selector-controller.ts +177 -72
  370. package/src/modes/controllers/stt-controller.ts +3 -3
  371. package/src/modes/interactive-mode.ts +88 -16
  372. package/src/modes/print-mode.ts +35 -6
  373. package/src/modes/runtime-init.ts +21 -68
  374. package/src/modes/types.ts +1 -0
  375. package/src/modes/utils/injected-user-submission.ts +25 -0
  376. package/src/modes/utils/terminal-bell.ts +15 -1
  377. package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
  378. package/src/prompts/agent-fragments/restricted-bash.md +1 -1
  379. package/src/prompts/agents/critic.md +1 -1
  380. package/src/prompts/system/rlm-research.md +1 -1
  381. package/src/prompts/system/system-prompt.md +0 -2
  382. package/src/prompts/tools/bash.md +7 -1
  383. package/src/prompts/tools/browser.md +1 -1
  384. package/src/prompts/tools/cron.md +6 -6
  385. package/src/prompts/tools/read.md +0 -2
  386. package/src/prompts/tools/skill-discovery.md +4 -2
  387. package/src/runtime-mcp/client.ts +427 -23
  388. package/src/runtime-mcp/config.ts +37 -5
  389. package/src/runtime-mcp/manager-pool.test.ts +56 -0
  390. package/src/runtime-mcp/manager.ts +52 -2
  391. package/src/runtime-mcp/oauth-discovery.ts +13 -0
  392. package/src/runtime-mcp/oauth-flow.ts +46 -1
  393. package/src/runtime-mcp/pool-key.ts +5 -1
  394. package/src/runtime-mcp/pool.test.ts +9 -0
  395. package/src/runtime-mcp/protocol.test.ts +353 -0
  396. package/src/runtime-mcp/protocol.ts +624 -0
  397. package/src/runtime-mcp/scope-config.ts +78 -0
  398. package/src/runtime-mcp/tool-bridge.ts +44 -10
  399. package/src/runtime-mcp/transports/http.ts +84 -13
  400. package/src/runtime-mcp/types.ts +123 -12
  401. package/src/sdk/acp/adapter.ts +328 -97
  402. package/src/sdk/broker/broker.ts +160 -741
  403. package/src/sdk/broker/ensure.ts +9 -1
  404. package/src/sdk/broker/lifecycle.ts +510 -116
  405. package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
  406. package/src/sdk/broker/process-incarnation.ts +19 -0
  407. package/src/sdk/broker/session-index.ts +516 -117
  408. package/src/sdk/broker/startup-failure.ts +28 -5
  409. package/src/sdk/broker/transport.ts +1 -13
  410. package/src/sdk/bus/chat-daemon-cli.ts +4 -2
  411. package/src/sdk/bus/chat-daemon-control.ts +67 -6
  412. package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
  413. package/src/sdk/bus/config.ts +13 -0
  414. package/src/sdk/bus/conversation-store.ts +59 -171
  415. package/src/sdk/bus/daemon-paths.ts +20 -0
  416. package/src/sdk/bus/discord-conversation.ts +2 -0
  417. package/src/sdk/bus/discord-daemon.ts +524 -126
  418. package/src/sdk/bus/discord-live-provider.ts +206 -79
  419. package/src/sdk/bus/existing-thread-readiness.ts +4 -97
  420. package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
  421. package/src/sdk/bus/index.ts +2480 -456
  422. package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
  423. package/src/sdk/bus/lifecycle-commands.ts +2 -2
  424. package/src/sdk/bus/managed-daemon.ts +2 -145
  425. package/src/sdk/bus/notification-service.ts +196 -0
  426. package/src/sdk/bus/operator-runtime.ts +1 -1
  427. package/src/sdk/bus/prompt-reconciliation.ts +24 -15
  428. package/src/sdk/bus/reconciliation-store.ts +553 -24
  429. package/src/sdk/bus/session-control.ts +49 -3
  430. package/src/sdk/bus/slack-conversation.ts +4 -0
  431. package/src/sdk/bus/slack-daemon.ts +733 -134
  432. package/src/sdk/bus/slack-live-provider.ts +65 -15
  433. package/src/sdk/bus/slack-provider.ts +4 -0
  434. package/src/sdk/bus/slack-thread-binding.ts +9 -104
  435. package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
  436. package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
  437. package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
  438. package/src/sdk/bus/telegram-daemon-control.ts +3 -13
  439. package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
  440. package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
  441. package/src/sdk/bus/telegram-daemon.ts +2552 -2280
  442. package/src/sdk/bus/telegram-reference.ts +1 -226
  443. package/src/sdk/bus/telegram-setup.ts +2 -2
  444. package/src/sdk/bus/threaded-render.ts +1 -0
  445. package/src/sdk/bus/topic-registry.ts +279 -146
  446. package/src/sdk/cli/rows.ts +2 -35
  447. package/src/sdk/cli/session-cli.ts +776 -700
  448. package/src/sdk/client/client.ts +892 -1
  449. package/src/sdk/host/control/dispatch.ts +93 -58
  450. package/src/sdk/host/control/index.ts +1 -1
  451. package/src/sdk/host/control/operations.ts +18 -10
  452. package/src/sdk/host/control/runtime-gate.ts +40 -0
  453. package/src/sdk/host/host.ts +63 -12
  454. package/src/sdk/host/query/handlers.ts +66 -7
  455. package/src/sdk/host/reverse-leases.ts +2 -2
  456. package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
  457. package/src/sdk/host/session-runtime.test.ts +2787 -34
  458. package/src/sdk/host/session-runtime.ts +1489 -101
  459. package/src/sdk/host/surface-policy.ts +12 -8
  460. package/src/sdk/host/types.ts +1 -1
  461. package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
  462. package/src/sdk/host/websocket-transport.ts +85 -50
  463. package/src/sdk/index.ts +2 -1
  464. package/src/sdk/lifecycle/broker-client.ts +53 -0
  465. package/src/sdk/lifecycle/client.ts +234 -0
  466. package/src/sdk/lifecycle/index.ts +3 -0
  467. package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
  468. package/src/sdk/lifecycle/service.ts +720 -0
  469. package/src/sdk/mcp/server.ts +226 -188
  470. package/src/sdk/prompt-deadline-lease.ts +55 -0
  471. package/src/sdk/prompt-deadline-manager.ts +148 -0
  472. package/src/sdk/prompt-status.ts +11 -3
  473. package/src/sdk/protocol/operation-inventory.generated.json +272 -129
  474. package/src/sdk/protocol/operation-registry.ts +71 -8
  475. package/src/sdk/receipt-state.ts +43 -0
  476. package/src/sdk/reconciliation-extensions.ts +14 -0
  477. package/src/sdk/router/index.ts +1 -0
  478. package/src/sdk/router/session-router.ts +1658 -0
  479. package/src/sdk/session-list.ts +93 -0
  480. package/src/sdk/session-reconnect.ts +45 -1
  481. package/src/sdk/session.ts +716 -120
  482. package/src/sdk/transport/serve-cli.ts +18 -34
  483. package/src/session/account-inventory.ts +603 -0
  484. package/src/session/agent-session.ts +2857 -582
  485. package/src/session/agent-storage.ts +35 -0
  486. package/src/session/blob-store.ts +32 -1
  487. package/src/session/coordinator-tool-label.ts +40 -0
  488. package/src/session/internal/managed-session-scope.ts +4 -0
  489. package/src/session/internal/managed-session-storage.ts +173 -12
  490. package/src/session/messages.ts +1 -1
  491. package/src/session/secure-token-file.ts +80 -0
  492. package/src/session/session-manager.ts +730 -58
  493. package/src/session/session-storage.ts +25 -16
  494. package/src/session/startup-auth-config.ts +297 -0
  495. package/src/session/terminal-abort.ts +1253 -0
  496. package/src/session/yield-queue.ts +57 -15
  497. package/src/session-import/claude.ts +334 -0
  498. package/src/session-import/codex.ts +1033 -0
  499. package/src/session-import/command.ts +77 -0
  500. package/src/session-import/detect.ts +133 -0
  501. package/src/session-import/index.ts +7 -0
  502. package/src/session-import/provider-codex.ts +327 -0
  503. package/src/session-import/provider-service.ts +457 -0
  504. package/src/session-import/redact.ts +128 -0
  505. package/src/session-import/service.ts +1264 -0
  506. package/src/session-import/types.ts +148 -0
  507. package/src/setup/paseo/check.ts +213 -0
  508. package/src/setup/paseo/install-saga.ts +293 -0
  509. package/src/setup/paseo/json-publisher.ts +263 -0
  510. package/src/setup/paseo/orchestration-preferences.ts +86 -0
  511. package/src/setup/paseo/paseo-ownership.ts +224 -0
  512. package/src/setup/paseo/paseo-setup.ts +253 -0
  513. package/src/setup/paseo/provider-config.ts +139 -0
  514. package/src/setup/paseo/remove.ts +183 -0
  515. package/src/setup/paseo/result-types.ts +79 -0
  516. package/src/setup/paseo/setup-deps.ts +175 -0
  517. package/src/setup/paseo/skills-bridge.ts +260 -0
  518. package/src/skill-state/active-state.ts +21 -11
  519. package/src/slash-commands/acp-builtins.ts +9 -1
  520. package/src/slash-commands/builtin-registry.ts +98 -16
  521. package/src/slash-commands/helpers/credential-switch.ts +143 -0
  522. package/src/slash-commands/helpers/mcp.ts +9 -3
  523. package/src/slash-commands/helpers/usage-report.ts +61 -56
  524. package/src/slash-commands/types.ts +7 -2
  525. package/src/task/executor.ts +30 -11
  526. package/src/task/index.ts +66 -7
  527. package/src/task/render.ts +23 -9
  528. package/src/tools/ask-answer-registry.ts +23 -7
  529. package/src/tools/ask.ts +8 -4
  530. package/src/tools/bash-sleep-advisory.ts +115 -0
  531. package/src/tools/bash.ts +98 -18
  532. package/src/tools/browser/attach.ts +71 -3
  533. package/src/tools/browser/launch.ts +86 -13
  534. package/src/tools/browser/profile-discovery.ts +57 -7
  535. package/src/tools/browser/render.ts +8 -1
  536. package/src/tools/browser.ts +130 -21
  537. package/src/tools/computer.enforcement.test.ts +1 -1
  538. package/src/tools/computer.ts +3 -2
  539. package/src/tools/cron.ts +12 -1
  540. package/src/tools/image-gen.ts +27 -16
  541. package/src/tools/index.ts +8 -0
  542. package/src/tools/job.ts +33 -6
  543. package/src/tools/monitor.ts +41 -2
  544. package/src/tools/skill-discovery.ts +21 -29
  545. package/src/tools/subagent.ts +142 -24
  546. package/src/tools/tool-catalog.generated.ts +6 -6
  547. package/src/tools/ultragoal-ask-guard.ts +10 -3
  548. package/src/utils/herdr-pane.ts +345 -0
  549. package/src/utils/title-generator.ts +2 -0
  550. package/src/web/scrapers/index.ts +6 -4
  551. package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
  552. package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
  553. package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
  554. package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
  555. package/dist/types/runtime/lazy-service.test.d.ts +0 -1
  556. package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
  557. package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
  558. package/dist/types/runtime-mcp/config.test.d.ts +0 -1
  559. package/dist/types/runtime-mcp/http.test.d.ts +0 -1
  560. package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
  561. package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
  562. package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
  563. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
  564. package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
  565. package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
  566. package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
  567. package/dist/types/sdk/elevation/audit.d.ts +0 -93
  568. package/dist/types/sdk/elevation/capability.d.ts +0 -3
  569. package/dist/types/sdk/elevation/digest.d.ts +0 -72
  570. package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
  571. package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
  572. package/dist/types/sdk/elevation/owner.d.ts +0 -48
  573. package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
  574. package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
  575. package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
  576. package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
  577. package/dist/types/session/auth-broker-config.d.ts +0 -13
  578. package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
  579. package/dist/types/skills/skills.test.d.ts +0 -1
  580. package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
  581. package/dist/types/task/token-log.test.d.ts +0 -1
  582. package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
  583. package/dist/types/tools/descriptors.test.d.ts +0 -1
  584. package/scripts/g005-daemon-smoke.ts +0 -180
  585. package/scripts/g011-daemon-path-smoke.ts +0 -153
  586. package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
  587. package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
  588. package/src/sdk/bus/telegram-cli.ts +0 -212
  589. package/src/sdk/elevation/allowlist.ts +0 -54
  590. package/src/sdk/elevation/audit.ts +0 -208
  591. package/src/sdk/elevation/capability.ts +0 -41
  592. package/src/sdk/elevation/digest.ts +0 -129
  593. package/src/sdk/elevation/dispatch-receipt.ts +0 -184
  594. package/src/sdk/elevation/grant-ledger.ts +0 -1142
  595. package/src/sdk/elevation/owner.ts +0 -109
  596. package/src/session/auth-broker-config.ts +0 -109
  597. /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
  598. /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
  599. /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
@@ -0,0 +1,596 @@
1
+ /**
2
+ * Single source of precedence for the workflow settings surfaces.
3
+ *
4
+ * Every workflow runtime (ralplan, ultragoal, deep-interview) reads its
5
+ * settings through {@link resolveWorkflowSetting}; no runtime hand-rolls file
6
+ * discovery, YAML/JSON parsing, or key extraction. The precedence is fixed:
7
+ *
8
+ * 1. project `.gjc/config.yml`
9
+ * 2. user `<agentDir>/config.yml` (default `~/.gjc/agent/config.yml`)
10
+ * 3. built-in default
11
+ *
12
+ * Project configuration always beats user configuration, and `config.yml` is
13
+ * the primary settings surface: the legacy `settings.json` files (project and
14
+ * config-root) are retired, their workflow values migrated into `config.yml` by
15
+ * Settings once. The retained legacy source still applies while the migration
16
+ * has NOT durably recorded ownership/completion for its key: the project source
17
+ * until the per-key migrated-keys marker records the key, the config-root
18
+ * source until the migration retires it. A completed migration owns the value
19
+ * (a later `gjc config unset` sticks), so an owned key is never resurrected;
20
+ * the project legacy sits above the agent config.yml, the config-root legacy
21
+ * below it. Settings therefore writes exactly what the runtimes read: `gjc
22
+ * config set gjc.ralplan.maxIterations 7` is honored by ralplan.
23
+ *
24
+ * `config.yml` uses the nested schema form (`gjc: { ralplan: { maxIterations } }`);
25
+ * flat dotted keys are honored only while parsing a legacy `settings.json`
26
+ * during migration (see Settings) or the retained-legacy fallback layer.
27
+ *
28
+ * This module must stay pure and acyclic: it imports only path helpers and the
29
+ * pure `gjcRoot`/`dirs` utilities, never `Settings`, discovery/capability
30
+ * loaders, or workflow runtimes. All config/agent paths are constructed inside
31
+ * each resolver call (never at module scope) because `dirs.ts` caches directory
32
+ * resolution at module load.
33
+ */
34
+
35
+ import * as fs from "node:fs/promises";
36
+ import * as path from "node:path";
37
+ import {
38
+ getAgentDir,
39
+ getConfigRootDir,
40
+ isEnoent,
41
+ resolveEquivalentPath,
42
+ standardizeMacOSPath,
43
+ } from "@gajae-code/utils";
44
+ import { YAML } from "bun";
45
+ import { gjcRoot } from "./session-layout";
46
+
47
+ export type WorkflowSettingKey =
48
+ | "gjc.deepInterview.ambiguityThreshold"
49
+ | "gjc.ralplan.autoHandoff"
50
+ | "gjc.ralplan.maxIterations"
51
+ | "gjc.ralplan.maxReviewPassesPerLane"
52
+ | "gjc.ultragoal.nudgeBudget";
53
+
54
+ export type WorkflowSettingLayer = "project-config" | "agent-config";
55
+
56
+ export type WorkflowSettingParseResult<T> = { kind: "valid"; value: T } | { kind: "invalid"; reason: string };
57
+
58
+ export type WorkflowSettingDiagnosticStatus = "missing-file" | "empty-document" | "missing-key" | "invalid" | "valid";
59
+
60
+ export interface WorkflowSettingDiagnostic {
61
+ layer: WorkflowSettingLayer;
62
+ /** Lexical absolute candidate; missing paths stay actionable. */
63
+ path: string;
64
+ format: "yaml" | "json";
65
+ status: WorkflowSettingDiagnosticStatus;
66
+ classification?: "read" | "syntax" | "shape" | "value";
67
+ reason?: string;
68
+ }
69
+
70
+ export interface ResolveWorkflowSettingOptions<T> {
71
+ defaultValue: T;
72
+ parse: (value: unknown) => WorkflowSettingParseResult<T>;
73
+ /** Omitted means "continue"; ralplan passes "throw" explicitly. */
74
+ invalidPolicy?: "throw" | "continue";
75
+ /**
76
+ * The session's effective agent directory. Defaults to the process-global
77
+ * `getAgentDir()`; an SDK embedder that created the session with
78
+ * `createAgentSession({ agentDir })` must pass that directory here so the
79
+ * agent-config layer matches the profile `Settings.init` loaded and
80
+ * migrated, instead of inheriting an unrelated default-profile value.
81
+ */
82
+ agentDir?: string;
83
+ }
84
+
85
+ export interface WorkflowSettingResolution<T> {
86
+ value: T;
87
+ /** Canonical realpath for a winning existing file, or "default". */
88
+ source: string;
89
+ diagnostics: readonly WorkflowSettingDiagnostic[];
90
+ }
91
+
92
+ export type WorkflowSettingInvalidClassification = "read" | "syntax" | "shape" | "value";
93
+
94
+ /** Raised under the strict ("throw") invalid policy; stable properties for callers. */
95
+ export class WorkflowSettingError extends Error {
96
+ readonly diagnostic: WorkflowSettingDiagnostic;
97
+ readonly path: string;
98
+ readonly layer: WorkflowSettingLayer;
99
+ readonly classification: WorkflowSettingInvalidClassification;
100
+ readonly reason: string;
101
+
102
+ constructor(
103
+ diagnostic: WorkflowSettingDiagnostic & {
104
+ classification: WorkflowSettingInvalidClassification;
105
+ reason: string;
106
+ },
107
+ ) {
108
+ super(`invalid workflow setting at ${diagnostic.path}: ${diagnostic.reason}`);
109
+ this.name = "WorkflowSettingError";
110
+ this.diagnostic = diagnostic;
111
+ this.path = diagnostic.path;
112
+ this.layer = diagnostic.layer;
113
+ this.classification = diagnostic.classification;
114
+ this.reason = diagnostic.reason;
115
+ }
116
+ }
117
+
118
+ type ResolverCandidate = {
119
+ layer: WorkflowSettingLayer;
120
+ format: "yaml" | "json";
121
+ buildPath: (cwd: string) => string;
122
+ /** Optional per-key guard consulted before a legacy fallback value is used. */
123
+ migrationOwned?: (key: WorkflowSettingKey) => Promise<boolean>;
124
+ };
125
+
126
+ const LAYER_CANDIDATES: ReadonlyArray<ResolverCandidate> = [
127
+ { layer: "project-config", format: "yaml", buildPath: cwd => path.resolve(gjcRoot(cwd), "config.yml") },
128
+ ];
129
+
130
+ /**
131
+ * The project migration's per-key ownership marker (`.gjc/state/
132
+ * settings.json.migrated-keys`): a key recorded there was migrated into project
133
+ * config.yml and is owned by that surface. Deleting config.yml afterwards must
134
+ * NOT resurrect the retained legacy value (the removal sticks), so the legacy
135
+ * fallback layer is suppressed for marked keys. A missing or malformed marker
136
+ * reads as no ownership.
137
+ */
138
+ async function projectKeyMigrated(cwd: string, key: WorkflowSettingKey): Promise<boolean> {
139
+ let raw: string;
140
+ try {
141
+ raw = await Bun.file(path.join(gjcRoot(cwd), "state", "settings.json.migrated-keys")).text();
142
+ } catch (error) {
143
+ // Only a MISSING marker reads as no ownership. A non-ENOENT read
144
+ // failure (EACCES, transient I/O) must fail closed: reporting unowned
145
+ // would let the resolver reactivate a stale retained value after the
146
+ // key was unset from project config.yml (an invalid strict value could
147
+ // make ralplan exit 2 again).
148
+ if (isEnoent(error)) return false;
149
+ throw error;
150
+ }
151
+ try {
152
+ const parsed = JSON.parse(raw) as unknown;
153
+ return Array.isArray(parsed) && parsed.includes(key);
154
+ } catch {
155
+ return false;
156
+ }
157
+ }
158
+
159
+ /**
160
+ * True when two paths refer to the SAME physical file (lexical path identity
161
+ * first, then dev/ino for symlink/hardlink aliases) - mirrors the migration's
162
+ * `#configRootCollidesWithProjectSource` so the resolver's aliasing guard never
163
+ * disagrees with it.
164
+ */
165
+ async function filesAreSamePhysicalFile(a: string, b: string): Promise<boolean> {
166
+ if (path.resolve(a) === path.resolve(b)) return true;
167
+ const [statA, statB] = await Promise.all([fs.stat(a).catch(() => null), fs.stat(b).catch(() => null)]);
168
+ return !!statA && !!statB && statA.dev === statB.dev && statA.ino === statB.ino;
169
+ }
170
+
171
+ /**
172
+ * True when a legacy migration source still exists on disk. The retained source
173
+ * keeps the legacy fallback candidate eligible: the migration is incomplete
174
+ * until ownership is durably recorded (the project per-key migrated-keys
175
+ * marker, or the config-root source's retirement on completion), and an
176
+ * incomplete migration must not silently drop the previously effective
177
+ * override - including when the migration target is PRESENT but could not be
178
+ * published to (e.g. an unwritable project `.gjc` or config root). The per-key
179
+ * ownership marker consulted per candidate suppresses a key the migration DID
180
+ * complete for, so a deliberate `gjc config unset` still sticks.
181
+ */
182
+ async function legacySourceExists(sourcePath: string): Promise<boolean> {
183
+ try {
184
+ await fs.stat(sourcePath);
185
+ return true;
186
+ } catch (error) {
187
+ // Only ENOENT means absence. A non-ENOENT failure (EACCES, transient
188
+ // I/O) RETAINS the candidate: the normal read-error policy then
189
+ // surfaces the unreadable explicit settings source (strict ralplan
190
+ // callers exit 2) instead of silently treating it as absence.
191
+ if (isEnoent(error)) return false;
192
+ return true;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Extract a workflow key from a parsed settings document. Flat dotted keys are
198
+ * honored only while parsing a legacy `settings.json` during migration (see
199
+ * Settings) - `config.yml` uses the nested (schema) form, so the public
200
+ * Settings/config CLI path (which addresses nested paths) can manage every
201
+ * effective override. Flat keys are checked before the nested `gjc: { ... }`
202
+ * shape (flat wins); an explicitly present `undefined` value counts as present.
203
+ */
204
+ export function extractWorkflowSetting(
205
+ document: unknown,
206
+ key: WorkflowSettingKey,
207
+ options: { flat?: boolean } = {},
208
+ ): { present: boolean; value: unknown; malformedParent?: boolean } {
209
+ if (!document || typeof document !== "object" || Array.isArray(document)) {
210
+ return { present: false, value: undefined };
211
+ }
212
+ const settings = document as Record<string, unknown>;
213
+ if (options.flat !== false && Object.hasOwn(settings, key)) return { present: true, value: settings[key] };
214
+
215
+ const segments = key.split(".");
216
+ if (segments.length < 2 || segments[0] !== "gjc") return { present: false, value: undefined };
217
+ // A PRESENT but non-mapping `gjc` (or any intermediate segment) is a
218
+ // malformed parent, not a missing key: strict callers must surface it as an
219
+ // invalid shape instead of silently continuing to a lower layer/default.
220
+ const hasGjc = Object.hasOwn(settings, "gjc");
221
+ const gjc = settings.gjc;
222
+ if (gjc === null || typeof gjc !== "object" || Array.isArray(gjc)) {
223
+ return hasGjc
224
+ ? { present: false, value: undefined, malformedParent: true }
225
+ : { present: false, value: undefined };
226
+ }
227
+ let current: unknown = gjc;
228
+ for (let index = 1; index < segments.length; index++) {
229
+ const record = current as Record<string, unknown>;
230
+ if (!Object.hasOwn(record, segments[index]!)) return { present: false, value: undefined };
231
+ const next = record[segments[index]!];
232
+ if (index < segments.length - 1 && (next === null || typeof next !== "object" || Array.isArray(next))) {
233
+ return { present: false, value: undefined, malformedParent: true };
234
+ }
235
+ current = next;
236
+ }
237
+ return { present: true, value: current };
238
+ }
239
+
240
+ /**
241
+ * Strict-invalid retention evidence files, written by the config-root and
242
+ * project migrations when they abort on an invalid STRICT ralplan legacy value
243
+ * (see Settings). The retained legacy sources are never read by this resolver,
244
+ * so the evidence is the only way the invalid value stays visible to strict
245
+ * callers. A project evidence slot sits at the project layer's precedence, an
246
+ * agent (config-root) evidence slot at the agent layer's.
247
+ */
248
+ const STRICT_INVALID_EVIDENCE_FILENAME = "settings.json.strict-invalid";
249
+
250
+ async function readRetainedStrictEvidence(
251
+ evidencePath: string,
252
+ key: WorkflowSettingKey,
253
+ ): Promise<{ value?: unknown; source: string; malformed: boolean } | null> {
254
+ let raw: string;
255
+ try {
256
+ raw = await Bun.file(evidencePath).text();
257
+ } catch {
258
+ return null;
259
+ }
260
+ try {
261
+ const parsed = JSON.parse(raw) as {
262
+ version?: unknown;
263
+ malformed?: unknown;
264
+ key?: unknown;
265
+ value?: unknown;
266
+ keys?: unknown;
267
+ source?: unknown;
268
+ };
269
+ const source = typeof parsed.source === "string" ? parsed.source : evidencePath;
270
+ // A malformed-source marker applies to every strict key: the file cannot
271
+ // be parsed, so no key can be trusted.
272
+ if (parsed.malformed === true) return { source, malformed: true };
273
+ if (parsed.version === 2 && Array.isArray(parsed.keys)) {
274
+ for (const rawEntry of parsed.keys) {
275
+ if (!rawEntry || typeof rawEntry !== "object") continue;
276
+ const entry = rawEntry as { key?: unknown; value?: unknown };
277
+ if (entry.key === key) return { value: entry.value, source, malformed: false };
278
+ }
279
+ return null;
280
+ }
281
+ // v1 single-key compatibility.
282
+ if (parsed.key === key) return { value: parsed.value, source, malformed: false };
283
+ return null;
284
+ } catch {
285
+ return null;
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Resolve a workflow setting across the fixed three-layer precedence (project
291
+ * `.gjc/config.yml`, then user `<agentDir>/config.yml`, then the built-in
292
+ * default). Returns the first valid configured value, otherwise
293
+ * {@link options.defaultValue} with `source: "default"`. Diagnostics are
294
+ * retained for unit tests and optional logging; runtime public wrappers expose
295
+ * their existing compact result shapes.
296
+ */
297
+ export async function resolveWorkflowSetting<T>(
298
+ cwd: string,
299
+ key: WorkflowSettingKey,
300
+ options: ResolveWorkflowSettingOptions<T>,
301
+ ): Promise<WorkflowSettingResolution<T>> {
302
+ const invalidPolicy = options.invalidPolicy ?? "continue";
303
+ const diagnostics: WorkflowSettingDiagnostic[] = [];
304
+
305
+ const invalid = (
306
+ layer: WorkflowSettingLayer,
307
+ candidatePath: string,
308
+ format: "yaml" | "json",
309
+ classification: WorkflowSettingInvalidClassification,
310
+ reason: string,
311
+ ): WorkflowSettingDiagnostic & { classification: WorkflowSettingInvalidClassification; reason: string } => ({
312
+ layer,
313
+ path: candidatePath,
314
+ format,
315
+ status: "invalid",
316
+ classification,
317
+ reason,
318
+ });
319
+ // Legacy fallback layers: while the migration has NOT durably recorded
320
+ // ownership/completion for a key, the retained legacy settings.json still
321
+ // holds the previously effective override - whether its config.yml target is
322
+ // absent (the migration could not publish), future-schema (read-only, skipped
323
+ // by the migration), or PRESENT but non-publishable (an unwritable project
324
+ // `.gjc` or config root rejected the write, so the source was retained). A
325
+ // completed migration owns the value instead: the project per-key
326
+ // migrated-keys marker suppresses an owned key (a later `gjc config unset`
327
+ // sticks), and the config-root source is retired on completion. The project
328
+ // legacy sits above the agent config.yml (it was the previously effective
329
+ // project override); the config-root legacy sits below it (the agent
330
+ // config.yml is the current machine-global surface).
331
+ const projectSettingsJson = path.resolve(gjcRoot(cwd), "settings.json");
332
+ const agentSettingsJson = path.resolve(getConfigRootDir(), "settings.json");
333
+ const legacyCandidates: ResolverCandidate[] = [];
334
+ if (await legacySourceExists(projectSettingsJson)) {
335
+ legacyCandidates.push({
336
+ layer: "project-config",
337
+ format: "json",
338
+ buildPath: () => projectSettingsJson,
339
+ // A key already migrated into config.yml is owned by that surface:
340
+ // deleting the file afterwards must not resurrect the retained value.
341
+ migrationOwned: key => projectKeyMigrated(cwd, key),
342
+ });
343
+ }
344
+ // When the config-root source ALIASES the project source (GJC run from the
345
+ // config root itself, or a symlink/hardlink to it), a project-owned key must
346
+ // not resurrect through the agent slot either after `gjc config unset`
347
+ // removed it from config.yml.
348
+ const configRootAliasesProject = await filesAreSamePhysicalFile(projectSettingsJson, agentSettingsJson);
349
+ // The machine-global config-root legacy belongs ONLY to the environment-
350
+ // selected global agent profile: an isolated SDK/tenant profile
351
+ // (`options.agentDir` differing from `getAgentDir()`) must not inherit the
352
+ // host's legacy override - the migration deliberately refuses to consume
353
+ // the machine-global source for custom scopes, so it stays present and
354
+ // would defeat profile isolation if applied here.
355
+ const agentLayerIsGlobal =
356
+ options.agentDir === undefined || path.resolve(options.agentDir) === path.resolve(getAgentDir());
357
+ if (agentLayerIsGlobal && (await legacySourceExists(agentSettingsJson))) {
358
+ legacyCandidates.push({
359
+ layer: "agent-config",
360
+ format: "json",
361
+ buildPath: () => agentSettingsJson,
362
+ ...(configRootAliasesProject
363
+ ? { migrationOwned: (key: WorkflowSettingKey) => projectKeyMigrated(cwd, key) }
364
+ : {}),
365
+ });
366
+ }
367
+ // The session's effective agent directory (SDK sessions pass their
368
+ // `createAgentSession({ agentDir })` profile); the process-global
369
+ // `getAgentDir()` is the default for CLI flows.
370
+ const agentCandidate: ResolverCandidate = {
371
+ layer: "agent-config",
372
+ format: "yaml",
373
+ buildPath: () => path.resolve(options.agentDir ?? getAgentDir(), "config.yml"),
374
+ };
375
+ const candidates = [
376
+ LAYER_CANDIDATES[0]!,
377
+ ...legacyCandidates.filter(candidate => candidate.layer === "project-config"),
378
+ agentCandidate,
379
+ ...legacyCandidates.filter(candidate => candidate.layer === "agent-config"),
380
+ ];
381
+ for (const candidate of candidates) {
382
+ // The project layer exhausted its candidates without producing a value
383
+ // (the project config.yml yielded nothing): before consulting the agent
384
+ // layer, a retained-invalid PROJECT legacy value must fail loudly instead
385
+ // of silently deferring to the agent/default - but a valid project
386
+ // config.yml value already returned above, so it still wins. An OWNED
387
+ // project key (deliberately unset) is exempt: its strict error is
388
+ // irrelevant and must not exit 2.
389
+ if (candidate.layer === "agent-config" && invalidPolicy === "throw" && !(await projectKeyMigrated(cwd, key))) {
390
+ const retained = await readRetainedStrictEvidence(
391
+ path.join(gjcRoot(cwd), "state", STRICT_INVALID_EVIDENCE_FILENAME),
392
+ key,
393
+ );
394
+ if (retained) {
395
+ throw new WorkflowSettingError({
396
+ layer: "project-config",
397
+ path: retained.source,
398
+ format: "json",
399
+ status: "invalid",
400
+ classification: retained.malformed ? "syntax" : "value",
401
+ reason: retained.malformed
402
+ ? `retained malformed project .gjc/settings.json; repair or remove the source and reload`
403
+ : `retained invalid ${key} value from the retired project .gjc/settings.json; repair or remove the source and reload`,
404
+ });
405
+ }
406
+ }
407
+ const candidatePath = candidate.buildPath(cwd);
408
+
409
+ // A key the migration already owns is not eligible for the retained
410
+ // legacy fallback: consult the per-key ownership marker BEFORE reading or
411
+ // parsing the candidate, so a deliberately unset owned key falls through
412
+ // to the lower layer/default even when the retained source is malformed
413
+ // (a stale global malformed marker or the pre-ownership JSON parse must
414
+ // not exit 2 for a key config.yml owns).
415
+ if (candidate.migrationOwned && (await candidate.migrationOwned(key))) {
416
+ diagnostics.push({
417
+ layer: candidate.layer,
418
+ path: candidatePath,
419
+ format: candidate.format,
420
+ status: "missing-key",
421
+ });
422
+ continue;
423
+ }
424
+
425
+ let raw: string;
426
+ try {
427
+ raw = await Bun.file(candidatePath).text();
428
+ } catch (error) {
429
+ if (isEnoent(error)) {
430
+ diagnostics.push({
431
+ layer: candidate.layer,
432
+ path: candidatePath,
433
+ format: candidate.format,
434
+ status: "missing-file",
435
+ });
436
+ continue;
437
+ }
438
+ const reason = error instanceof Error ? error.message : String(error);
439
+ const diagnostic = invalid(candidate.layer, candidatePath, candidate.format, "read", reason);
440
+ if (invalidPolicy === "throw") throw new WorkflowSettingError(diagnostic);
441
+ diagnostics.push(diagnostic);
442
+ continue;
443
+ }
444
+
445
+ const trimmed = raw.trim();
446
+ // Only a genuinely EMPTY config.yml is "no explicit settings" (an empty
447
+ // YAML document). The literal text `undefined` is a parse error below.
448
+ if (trimmed === "") {
449
+ diagnostics.push({
450
+ layer: candidate.layer,
451
+ path: candidatePath,
452
+ format: candidate.format,
453
+ status: "empty-document",
454
+ });
455
+ continue;
456
+ }
457
+
458
+ let parsed: unknown;
459
+ if (candidate.format === "json") {
460
+ // A retained legacy settings.json must be parsed as JSON (its file
461
+ // contract) - JSON-invalid but YAML-valid content (unquoted keys,
462
+ // comments) must not supply a workflow value, and a strict caller must
463
+ // fail closed instead of bypassing the malformed-source evidence.
464
+ try {
465
+ parsed = JSON.parse(raw);
466
+ } catch {
467
+ const diagnostic = invalid(candidate.layer, candidatePath, candidate.format, "syntax", "malformed JSON");
468
+ if (invalidPolicy === "throw") throw new WorkflowSettingError(diagnostic);
469
+ diagnostics.push(diagnostic);
470
+ continue;
471
+ }
472
+ } else {
473
+ try {
474
+ parsed = YAML.parse(raw);
475
+ } catch {
476
+ // Stable, caller-agnostic reason; the underlying parse detail is not
477
+ // part of the runtime error contract.
478
+ const diagnostic = invalid(candidate.layer, candidatePath, candidate.format, "syntax", "malformed YAML");
479
+ if (invalidPolicy === "throw") throw new WorkflowSettingError(diagnostic);
480
+ diagnostics.push(diagnostic);
481
+ continue;
482
+ }
483
+ }
484
+
485
+ // Only an EMPTY document (no content) is "no explicit settings": a
486
+ // parsed YAML/JSON `null` root is malformed per Settings.#loadYaml
487
+ // (which keeps the config read-only until repaired), so the strict
488
+ // contract must fail closed on it instead of continuing to defaults.
489
+ if (parsed === undefined) {
490
+ diagnostics.push({
491
+ layer: candidate.layer,
492
+ path: candidatePath,
493
+ format: candidate.format,
494
+ status: "empty-document",
495
+ });
496
+ continue;
497
+ }
498
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
499
+ const diagnostic = invalid(
500
+ candidate.layer,
501
+ candidatePath,
502
+ candidate.format,
503
+ "shape",
504
+ `expected a settings mapping, got ${parsed === null ? "null" : Array.isArray(parsed) ? "an array" : typeof parsed}`,
505
+ );
506
+ if (invalidPolicy === "throw") throw new WorkflowSettingError(diagnostic);
507
+ diagnostics.push(diagnostic);
508
+ continue;
509
+ }
510
+
511
+ // config.yml uses the nested schema form; flat dotted keys belong only to
512
+ // legacy settings.json parsing (during migration, or the retained-legacy
513
+ // fallback layer while a migration target is absent).
514
+ const extracted = extractWorkflowSetting(parsed, key, { flat: candidate.format === "json" });
515
+ if (extracted.malformedParent) {
516
+ // A present non-mapping parent (e.g. `gjc: "invalid"` or
517
+ // `gjc: { ralplan: [] }`) is a malformed explicit layer: strict
518
+ // ralplan fails closed (exit 2) instead of silently treating the key
519
+ // as missing and falling to a lower layer/default.
520
+ const diagnostic = invalid(
521
+ candidate.layer,
522
+ candidatePath,
523
+ candidate.format,
524
+ "shape",
525
+ `expected a settings mapping for ${key}, got a non-mapping parent`,
526
+ );
527
+ if (invalidPolicy === "throw") throw new WorkflowSettingError(diagnostic);
528
+ diagnostics.push(diagnostic);
529
+ continue;
530
+ }
531
+ if (!extracted.present) {
532
+ diagnostics.push({
533
+ layer: candidate.layer,
534
+ path: candidatePath,
535
+ format: candidate.format,
536
+ status: "missing-key",
537
+ });
538
+ continue;
539
+ }
540
+
541
+ // Mirror Settings' schema scalar coercion before the workflow parser: a
542
+ // quoted numeric string for a number workflow key (e.g.
543
+ // `gjc.ralplan.maxIterations: "7"`) is coerced to a number, exactly as
544
+ // reconcileSettingsSchema treats number settings. Enum workflow keys
545
+ // never carry numeric strings, so the coercion is a no-op there.
546
+ const coercedValue =
547
+ typeof extracted.value === "string" &&
548
+ extracted.value.trim() !== "" &&
549
+ Number.isFinite(Number(extracted.value))
550
+ ? Number(extracted.value)
551
+ : extracted.value;
552
+ const parsedValue = options.parse(coercedValue);
553
+ if (parsedValue.kind === "valid") {
554
+ return {
555
+ value: parsedValue.value,
556
+ source: standardizeMacOSPath(resolveEquivalentPath(candidatePath)),
557
+ diagnostics,
558
+ };
559
+ }
560
+
561
+ const diagnostic = invalid(candidate.layer, candidatePath, candidate.format, "value", parsedValue.reason);
562
+ if (invalidPolicy === "throw") throw new WorkflowSettingError(diagnostic);
563
+ diagnostics.push(diagnostic);
564
+ }
565
+
566
+ // Both config.yml layers produced no value. A config-root migration that
567
+ // retained an invalid STRICT ralplan legacy value (so `gjc ralplan` can
568
+ // still fail loudly) persists agent-layer evidence; strict callers surface
569
+ // it here - after the project layer had its chance to win - instead of
570
+ // silently falling back to the default. Tolerant callers never abort on
571
+ // invalid values, so the evidence only ever records ralplan keys. Like the
572
+ // legacy candidate, the machine-global evidence applies only to the
573
+ // environment-selected global profile: an isolated SDK/tenant profile must
574
+ // fall through to its own defaults instead of inheriting the host's
575
+ // retained failure.
576
+ if (invalidPolicy === "throw" && agentLayerIsGlobal) {
577
+ const retained = await readRetainedStrictEvidence(
578
+ path.resolve(getConfigRootDir(), STRICT_INVALID_EVIDENCE_FILENAME),
579
+ key,
580
+ );
581
+ if (retained) {
582
+ throw new WorkflowSettingError({
583
+ layer: "agent-config",
584
+ path: retained.source,
585
+ format: "json",
586
+ status: "invalid",
587
+ classification: retained.malformed ? "syntax" : "value",
588
+ reason: retained.malformed
589
+ ? `retained malformed config-root settings.json; repair or remove the source and reload`
590
+ : `retained invalid ${key} value from the retired config-root settings.json; repair or remove the source and reload`,
591
+ });
592
+ }
593
+ }
594
+
595
+ return { value: options.defaultValue, source: "default", diagnostics };
596
+ }
@@ -99,7 +99,10 @@ async function executeGoalOperation(session: ToolSession, params: GoalToolInput)
99
99
  }
100
100
  if (params.op === "pause") {
101
101
  try {
102
- await assertUltragoalPauseAllowed(session.cwd);
102
+ await assertUltragoalPauseAllowed(
103
+ session.cwd,
104
+ session.getSessionAgentDir?.() ?? session.settings?.getAgentDir?.(),
105
+ );
103
106
  } catch (error) {
104
107
  throw new ToolError(error instanceof Error ? error.message : String(error));
105
108
  }
@@ -112,6 +115,7 @@ async function executeGoalOperation(session: ToolSession, params: GoalToolInput)
112
115
  cwd: session.cwd,
113
116
  currentGoal: session.getGoalModeState?.()?.goal ?? null,
114
117
  sessionId: session.getSessionId?.(),
118
+ agentDir: session.getSessionAgentDir?.() ?? session.settings?.getAgentDir?.(),
115
119
  });
116
120
  } catch (error) {
117
121
  throw new ToolError(error instanceof Error ? error.message : String(error));
@@ -124,6 +128,7 @@ async function executeGoalOperation(session: ToolSession, params: GoalToolInput)
124
128
  cwd: session.cwd,
125
129
  currentGoal: session.getGoalModeState?.()?.goal ?? null,
126
130
  sessionId: session.getSessionId?.(),
131
+ agentDir: session.getSessionAgentDir?.() ?? session.settings?.getAgentDir?.(),
127
132
  });
128
133
  } catch (error) {
129
134
  throw new ToolError(error instanceof Error ? error.message : String(error));