@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
@@ -1,9 +1,13 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
1
3
  import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@gajae-code/agent-core";
2
4
  import { prompt, untilAborted } from "@gajae-code/utils";
3
5
  import * as z from "zod/v4";
4
6
  import browserDescription from "../prompts/tools/browser.md" with { type: "text" };
5
7
  import type { ToolSession } from "../sdk";
6
8
  import { type BrowserActionStep, compileActionSteps } from "./browser/actions";
9
+ import { isChromeProfileExecutableForLaunch, isEdgeExecutable, resolveSystemChromeForProfile } from "./browser/launch";
10
+ import { chromeUserDataRoots, type DiscoveryEnv, defaultDiscoveryEnv } from "./browser/profile-discovery";
7
11
  import { acquireBrowser, type BrowserHandle, type BrowserKind, type BrowserKindTag } from "./browser/registry";
8
12
  import type { Observation, ScreenshotResult } from "./browser/tab-protocol";
9
13
  import { acquireTab, dropHeadlessTabs, getTab, releaseAllTabs, releaseTab, runInTab } from "./browser/tab-supervisor";
@@ -19,11 +23,17 @@ export type { Observation, ObservationEntry } from "./browser/tab-protocol";
19
23
  const DEFAULT_TAB_NAME = "main";
20
24
 
21
25
  const appSchema = z.object({
22
- path: z.string().describe("binary path to spawn").optional(),
26
+ path: z.string().describe("binary path to spawn (default: the installed Chrome/Chromium)").optional(),
23
27
  cdp_url: z.string().describe("existing cdp endpoint").optional(),
24
28
  browser: z.enum(["chrome"]).describe("existing browser profile mode").optional(),
25
- user_data_dir: z.string().describe("Chrome user data directory containing profiles").optional(),
26
- profile_directory: z.string().describe("Chrome profile directory name, e.g. Profile 10").optional(),
29
+ user_data_dir: z
30
+ .string()
31
+ .describe("non-default Chrome user data directory containing profiles (required for Chrome 136+ CDP)")
32
+ .optional(),
33
+ profile_directory: z
34
+ .string()
35
+ .describe('Chrome profile directory name, e.g. "Profile 10" (default "Default")')
36
+ .optional(),
27
37
  background: z.boolean().describe("prefer background/hidden Chrome profile launch when supported").optional(),
28
38
  no_focus: z.boolean().describe("avoid focusing Chrome during profile launch when supported").optional(),
29
39
  cdp_port: z.number().int().positive().describe("local CDP port for launched Chrome profile").optional(),
@@ -116,30 +126,129 @@ export interface BrowserToolDetails {
116
126
  meta?: OutputMeta;
117
127
  }
118
128
 
119
- export function resolveBrowserKindForTest(params: BrowserParams, session: ToolSession): BrowserKind {
120
- return resolveBrowserKind(params, session);
129
+ export function resolveBrowserKindForTest(
130
+ params: BrowserParams,
131
+ session: ToolSession,
132
+ signal?: AbortSignal,
133
+ discoveryEnv?: DiscoveryEnv,
134
+ ): Promise<BrowserKind> {
135
+ return resolveBrowserKind(params, session, signal, discoveryEnv);
136
+ }
137
+
138
+ /**
139
+ * Resolve guarded Chrome profile mode. The executable falls back to the
140
+ * installed Chrome/Chromium and the profile directory to `"Default"`.
141
+ * Chrome 136+ refuses remote debugging against its default data directory, so
142
+ * callers must explicitly provide a non-default user data directory.
143
+ */
144
+ async function resolveChromeProfileKind(
145
+ app: NonNullable<BrowserParams["app"]>,
146
+ session: ToolSession,
147
+ signal?: AbortSignal,
148
+ discoveryEnv?: DiscoveryEnv,
149
+ ): Promise<BrowserKind> {
150
+ const profileDirectory = app.profile_directory ?? "Default";
151
+ const exe = app.path ? resolveToCwd(app.path, session.cwd) : resolveSystemChromeForProfile();
152
+ if (!exe) {
153
+ throw new ToolError(
154
+ 'No Chrome/Chromium executable found for app.browser "chrome". Install Chrome, or pass app.path with the binary path.',
155
+ );
156
+ }
157
+ const canonicalExe = await canonicalPath(exe, process.platform, signal);
158
+ if (!isChromeProfileExecutableForLaunch(exe, canonicalExe)) {
159
+ throw new ToolError(
160
+ isEdgeExecutable(canonicalExe)
161
+ ? 'app.path for app.browser "chrome" must be Google Chrome or Chromium, not Microsoft Edge. Use Edge with app.path spawn mode and a separate profile, or pass a Chrome/Chromium executable.'
162
+ : 'app.path for app.browser "chrome" must be a Google Chrome or Chromium executable. Other Chromium-based browsers must use app.path spawn mode with their own separate profile.',
163
+ );
164
+ }
165
+ if (!app.user_data_dir) {
166
+ throw new ToolError(
167
+ 'app.user_data_dir is required for app.browser "chrome". Chrome 136+ disables remote debugging for the default Chrome data directory; pass a separate non-default user data directory, or attach to an already-authorized browser with app.cdp_url.',
168
+ );
169
+ }
170
+ const userDataDir = resolveChromeProfileUserDataDir(app.user_data_dir, session.cwd, discoveryEnv?.platform);
171
+ if (await isDefaultChromeUserDataDir(userDataDir, signal, discoveryEnv)) {
172
+ throw new ToolError(
173
+ `Refusing Chrome's default user data directory ${JSON.stringify(userDataDir)}. Chrome 136+ disables remote debugging there; pass a separate non-default app.user_data_dir, or use app.cdp_url for an already-authorized browser.`,
174
+ );
175
+ }
176
+ return {
177
+ kind: "chrome-profile",
178
+ path: exe,
179
+ userDataDir,
180
+ profileDirectory,
181
+ background: app.background ?? false,
182
+ noFocus: app.no_focus ?? false,
183
+ cdpPort: app.cdp_port,
184
+ };
121
185
  }
122
186
 
123
- function resolveBrowserKind(params: BrowserParams, session: ToolSession): BrowserKind {
187
+ async function canonicalPath(
188
+ candidate: string,
189
+ platform: NodeJS.Platform = process.platform,
190
+ signal?: AbortSignal,
191
+ ): Promise<string> {
192
+ const platformPath = platform === "win32" ? path.win32 : path.posix;
193
+ let resolved = platformPath.resolve(candidate);
194
+ if (platform === process.platform) {
195
+ throwIfAborted(signal);
196
+ try {
197
+ resolved = signal ? await untilAborted(signal, () => fs.realpath(resolved)) : await fs.realpath(resolved);
198
+ } catch {}
199
+ throwIfAborted(signal);
200
+ }
201
+ return platform === "win32" ? resolved.toLowerCase() : resolved;
202
+ }
203
+
204
+ function isDefaultChromeUserDataDir(
205
+ candidate: string,
206
+ signal?: AbortSignal,
207
+ discoveryEnv: DiscoveryEnv = defaultDiscoveryEnv(() => false),
208
+ ): Promise<boolean> {
209
+ return isDefaultChromeUserDataDirForTest(
210
+ candidate,
211
+ chromeUserDataRoots(discoveryEnv),
212
+ discoveryEnv.platform,
213
+ signal,
214
+ );
215
+ }
216
+
217
+ function resolveChromeProfileUserDataDir(
218
+ candidate: string,
219
+ cwd: string,
220
+ platform: NodeJS.Platform = process.platform,
221
+ ): string {
222
+ if (platform === process.platform) return resolveToCwd(candidate, cwd);
223
+ const platformPath = platform === "win32" ? path.win32 : path.posix;
224
+ return platformPath.isAbsolute(candidate) ? platformPath.resolve(candidate) : platformPath.resolve(cwd, candidate);
225
+ }
226
+
227
+ export async function isDefaultChromeUserDataDirForTest(
228
+ candidate: string,
229
+ roots: readonly string[],
230
+ platform: NodeJS.Platform = process.platform,
231
+ signal?: AbortSignal,
232
+ ): Promise<boolean> {
233
+ const canonicalCandidate = await canonicalPath(candidate, platform, signal);
234
+ for (const root of roots) {
235
+ if ((await canonicalPath(root, platform, signal)) === canonicalCandidate) return true;
236
+ }
237
+ return false;
238
+ }
239
+
240
+ async function resolveBrowserKind(
241
+ params: BrowserParams,
242
+ session: ToolSession,
243
+ signal?: AbortSignal,
244
+ discoveryEnv?: DiscoveryEnv,
245
+ ): Promise<BrowserKind> {
124
246
  const app = params.app;
125
247
  if (app?.cdp_url) {
126
248
  return { kind: "connected", cdpUrl: app.cdp_url.replace(/\/+$/, "") };
127
249
  }
128
250
  if (app?.browser === "chrome") {
129
- if (!app.path) throw new ToolError('app.path is required when app.browser is "chrome".');
130
- if (!app.user_data_dir) throw new ToolError('app.user_data_dir is required when app.browser is "chrome".');
131
- if (!app.profile_directory)
132
- throw new ToolError('app.profile_directory is required when app.browser is "chrome".');
133
- const exe = resolveToCwd(app.path, session.cwd);
134
- return {
135
- kind: "chrome-profile",
136
- path: exe,
137
- userDataDir: resolveToCwd(app.user_data_dir, session.cwd),
138
- profileDirectory: app.profile_directory,
139
- background: app.background ?? false,
140
- noFocus: app.no_focus ?? false,
141
- cdpPort: app.cdp_port,
142
- };
251
+ return resolveChromeProfileKind(app, session, signal, discoveryEnv);
143
252
  }
144
253
  if (app?.path) {
145
254
  const exe = resolveToCwd(app.path, session.cwd);
@@ -217,7 +326,7 @@ export class BrowserTool implements AgentTool<typeof browserSchema, BrowserToolD
217
326
  timeoutMs: number,
218
327
  signal?: AbortSignal,
219
328
  ): Promise<AgentToolResult<BrowserToolDetails>> {
220
- const kind = resolveBrowserKind(params, this.session);
329
+ const kind = await resolveBrowserKind(params, this.session, signal);
221
330
  details.browser = kind.kind;
222
331
 
223
332
  // If a tab with this name already exists on a different browser kind, fail fast — caller must close first.
@@ -153,7 +153,7 @@ describe("computer enforcement red-team probes", () => {
153
153
  observed: `code=${resultCode(permission)} message=${resultMessage(permission)} nativeScreenshotCalls=${permissionCalls}`,
154
154
  verdict:
155
155
  resultCode(permission) === "COMPUTER_PERMISSION_REQUIRED" &&
156
- resultMessage(permission).includes("screen-recording or accessibility permission")
156
+ resultMessage(permission).includes("Screen & System Audio Recording or Accessibility")
157
157
  ? "passed"
158
158
  : "failed",
159
159
  });
@@ -1120,10 +1120,11 @@ function mapComputerError(error: unknown, hotkey?: string): { code: string; mess
1120
1120
  COMPUTER_SUSPENDED: `Stop and wait for the user${hotkey ? ` (kill-switch hotkey: ${hotkey})` : ""}.`,
1121
1121
  COMPUTER_CANCELLED: `Stop and wait for the user${hotkey ? ` (kill-switch hotkey: ${hotkey})` : ""}.`,
1122
1122
  COMPUTER_PERMISSION_REQUIRED:
1123
- "The host needs screen-recording or accessibility permission. Ask the user to grant it.",
1123
+ "Grant Screen & System Audio Recording or Accessibility to the exact GJC launcher named in the diagnostic, then fully quit and relaunch GJC.",
1124
1124
  COMPUTER_DISABLED:
1125
1125
  "The computer tool is disabled or unsupported. Do not retry without enabling it on Apple Silicon macOS.",
1126
- COMPUTER_SCREENSHOT_FAILED: "Capture failed. Check screen-recording permission and retry the screenshot.",
1126
+ COMPUTER_SCREENSHOT_FAILED:
1127
+ "Capture failed after the current-process permission preflight passed. Check display availability and retry the screenshot.",
1127
1128
  COMPUTER_CURSOR_RESTORE_FAILED:
1128
1129
  "Input may have completed, but the cursor could not be restored. Stop and ask the user to inspect the desktop before retrying.",
1129
1130
  };
package/src/tools/cron.ts CHANGED
@@ -589,8 +589,19 @@ export class CronTool implements AgentTool<typeof cronSchema, CronToolDetails> {
589
589
  }
590
590
  }
591
591
 
592
+ #resolveOwnedJobManager(): AsyncJobManager | undefined {
593
+ const endpointId = this.session.getSessionId?.() ?? undefined;
594
+ return (
595
+ this.session.getAsyncJobManager?.() ?? AsyncJobManager.forEndpoint(endpointId) ?? AsyncJobManager.instance()
596
+ );
597
+ }
598
+
592
599
  async #create(params: CronParams): Promise<AgentToolResult<CronToolDetails>> {
593
- const manager = AsyncJobManager.instance();
600
+ // Cron cleanup is consumed by the owning AgentSession's lifecycle
601
+ // manager. A concurrent top-level session can be the process-global
602
+ // instance, so registering there would leave this session's timer
603
+ // running after new-session, switch, or disposal (review thread P1).
604
+ const manager = this.#resolveOwnedJobManager();
594
605
  if (!manager) {
595
606
  throw new ToolError("Async execution is disabled; cron is unavailable in this session.");
596
607
  }
@@ -166,7 +166,7 @@ const ALIBABA_IMAGE_GENERATION_URL = `${ALIBABA_TOKEN_PLAN_HOST}/api/v1/services
166
166
  const IMAGE_SYSTEM_INSTRUCTION =
167
167
  "You are an AI image generator. Generate images based on user descriptions. Focus on creating high-quality, visually appealing images that match the user's request.";
168
168
 
169
- type ImageProvider = "alibaba" | "antigravity" | "gemini" | "openai" | "openai-codex" | "openrouter" | (string & {});
169
+ type ImageProvider = "alibaba" | "antigravity" | "gemini" | "openai" | "openai-codex" | "openrouter";
170
170
  interface ImageApiKey {
171
171
  provider: ImageProvider;
172
172
  apiKey: string;
@@ -175,6 +175,19 @@ interface ImageApiKey {
175
175
  authCredentialType?: "api_key" | "oauth";
176
176
  }
177
177
 
178
+ export class UnsupportedImageProviderError extends Error {
179
+ readonly code = "unsupported_image_provider" as const;
180
+
181
+ constructor(
182
+ readonly provider: string,
183
+ readonly modelId: string,
184
+ readonly api: Model["api"],
185
+ ) {
186
+ super(`Image generation is not supported for provider "${provider}" with transport "${api}".`);
187
+ this.name = "UnsupportedImageProviderError";
188
+ }
189
+ }
190
+
178
191
  const responseModalitySchema = z.enum(["IMAGE", "TEXT"] as const);
179
192
  const aspectRatioSchema = z.enum(["1:1", "3:4", "4:3", "9:16", "16:9"] as const).describe("aspect ratio");
180
193
  const imageSizeSchema = z.enum(["1024x1024", "1536x1024", "1024x1536"] as const).describe("image size");
@@ -935,8 +948,9 @@ async function findImageApiKey(
935
948
  }
936
949
 
937
950
  /**
938
- * Map a resolved image model to its provider credentials. Each provider
939
- * branch mirrors the original credential-resolution path.
951
+ * Map a resolved image model to its provider credentials. Transport and image
952
+ * capability are validated before any credential lookup; unsupported models
953
+ * fail without forwarding their provider credential to another endpoint.
940
954
  */
941
955
  async function resolveCredentialsForImageModel(
942
956
  model: Model,
@@ -958,19 +972,23 @@ async function resolveCredentialsForImageModel(
958
972
  };
959
973
  }
960
974
 
961
- if (provider === "antigravity" || provider === "google-antigravity") {
975
+ if (
976
+ (provider === "antigravity" || provider === "google-antigravity") &&
977
+ model.api === "google-gemini-cli" &&
978
+ model.output?.includes("image")
979
+ ) {
962
980
  return await findAntigravityCredentials(modelRegistry, sessionId);
963
981
  }
964
- if (provider === "alibaba" || provider === "alibaba-token-plan") {
982
+ if ((provider === "alibaba" || provider === "alibaba-token-plan") && model.output?.includes("image")) {
965
983
  return await findAlibabaImageCredentials(modelRegistry, sessionId);
966
984
  }
967
- if (provider === "openrouter") {
985
+ if (provider === "openrouter" && model.output?.includes("image")) {
968
986
  const openRouterKey = await modelRegistry.getApiKey(model, sessionId);
969
987
  if (isAuthenticated(openRouterKey)) return { provider: "openrouter", apiKey: openRouterKey };
970
988
  const envKey = getEnvApiKey("openrouter");
971
989
  return envKey ? { provider: "openrouter", apiKey: envKey } : null;
972
990
  }
973
- if (provider === "gemini" || provider === "google") {
991
+ if (provider === "google" && model.api === "google-generative-ai" && model.output?.includes("image")) {
974
992
  const googleKey = await modelRegistry.getApiKey(model, sessionId);
975
993
  if (isAuthenticated(googleKey)) return { provider: "gemini", apiKey: googleKey };
976
994
  const envKey = getEnvApiKey("google");
@@ -979,14 +997,7 @@ async function resolveCredentialsForImageModel(
979
997
  return fallbackKey ? { provider: "gemini", apiKey: fallbackKey } : null;
980
998
  }
981
999
 
982
- // Fallback: try the model's own API key via the registry.
983
- const apiKey = await modelRegistry.getApiKey(model, sessionId);
984
- if (!isAuthenticated(apiKey)) return null;
985
- return {
986
- provider: provider as ImageProvider,
987
- apiKey,
988
- model,
989
- };
1000
+ throw new UnsupportedImageProviderError(model.provider, model.id, model.api);
990
1001
  }
991
1002
 
992
1003
  async function loadImageFromPath(imagePath: string, cwd: string): Promise<InlineImageData> {
@@ -1085,7 +1096,7 @@ function collectInlineImages(parts: GeminiPart[]): InlineImageData[] {
1085
1096
  return images;
1086
1097
  }
1087
1098
 
1088
- export function isOpenAIHostedImageModel(model: Model | undefined): model is Model {
1099
+ export function isOpenAIHostedImageModel(model: Model | undefined): boolean {
1089
1100
  if (!model) return false;
1090
1101
  // The hosted image_generation tool is only available over the Responses API.
1091
1102
  if (model.api !== "openai-responses" && model.api !== "openai-codex-responses") return false;
@@ -1,6 +1,7 @@
1
1
  import type { AgentTelemetryConfig, AgentTool } from "@gajae-code/agent-core";
2
2
  import type { Model, ServiceTier, ToolChoice } from "@gajae-code/ai/core";
3
3
  import { $env, logger } from "@gajae-code/utils";
4
+ import type { AsyncJobManager } from "../async";
4
5
  import type { PromptTemplate } from "../config/prompt-templates";
5
6
  import type { Settings } from "../config/settings";
6
7
  import type { Skill } from "../extensibility/skills";
@@ -217,6 +218,8 @@ export interface ToolSession {
217
218
  hasForegroundBashBackgroundRequestHandler?: () => boolean;
218
219
  /** Request that the active managed foreground bash call fold into a background job, if supported. */
219
220
  requestForegroundBashBackground?: () => boolean;
221
+ /** Get the session-owned or inherited async job manager. */
222
+ getAsyncJobManager?: () => AsyncJobManager | undefined;
220
223
  /** Get session ID */
221
224
  getSessionId?: () => string | null;
222
225
  /** Get credential-selection session identity. */
@@ -279,6 +282,11 @@ export interface ToolSession {
279
282
  agentOutputManager?: AgentOutputManager;
280
283
  /** Settings instance for passing to subagents */
281
284
  settings: Settings;
285
+ /**
286
+ * The session's REQUESTED effective agent directory, independent of the
287
+ * global Settings singleton (which can be reused across sessions).
288
+ */
289
+ getSessionAgentDir?: () => string;
282
290
  /** Live service-tier intent of the parent session, inherited by `inherit` subagents. */
283
291
  serviceTier?: ServiceTier;
284
292
  /** Whether the effective subagent tier grants fast mode for a resolved provider. */
package/src/tools/job.ts CHANGED
@@ -7,6 +7,7 @@ import { type AsyncJob, AsyncJobManager, isBackgroundJobSupportEnabled, jobElaps
7
7
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
8
8
  import type { Theme } from "../modes/theme/theme";
9
9
  import jobDescription from "../prompts/tools/job.md" with { type: "text" };
10
+ import { lookupOwnedRegistration, unregisterOwnedRegistration } from "../session/terminal-abort";
10
11
  import { Ellipsis, Hasher, type RenderCache, renderStatusLine, renderTreeList, truncateToWidth } from "../tui";
11
12
  import type { ToolSession } from "./index";
12
13
  import {
@@ -100,7 +101,10 @@ export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
100
101
  onUpdate?: AgentToolUpdateCallback<JobToolDetails>,
101
102
  _context?: AgentToolContext,
102
103
  ): Promise<AgentToolResult<JobToolDetails>> {
103
- const manager = AsyncJobManager.instance();
104
+ const manager =
105
+ this.session.getAsyncJobManager?.() ??
106
+ AsyncJobManager.forEndpoint(this.session.getSessionId?.() ?? undefined) ??
107
+ AsyncJobManager.instance();
104
108
  if (!manager) {
105
109
  return {
106
110
  content: [{ type: "text", text: "Async execution is disabled; no background jobs are available." }],
@@ -237,7 +241,7 @@ export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
237
241
  const PROGRESS_INTERVAL_MS = 500;
238
242
  const emitProgress = () => {
239
243
  if (!onUpdate) return;
240
- const snapshot = this.#snapshotJobs(allTrackedJobs);
244
+ const snapshot = this.#snapshotJobs(manager, allTrackedJobs);
241
245
  onUpdate({
242
246
  content: [{ type: "text", text: "" }],
243
247
  details: {
@@ -318,6 +322,7 @@ export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
318
322
  }
319
323
 
320
324
  #snapshotJobs(
325
+ manager: AsyncJobManager,
321
326
  jobs: {
322
327
  id: string;
323
328
  type: "bash" | "task";
@@ -331,7 +336,7 @@ export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
331
336
  ): JobSnapshot[] {
332
337
  const now = Date.now();
333
338
  return jobs.map(j => {
334
- const current = AsyncJobManager.instance()?.getJob(j.id);
339
+ const current = manager.getJob(j.id);
335
340
  const latest = current ?? j;
336
341
  return {
337
342
  id: latest.id,
@@ -366,9 +371,31 @@ export class JobTool implements AgentTool<typeof jobSchema, JobToolDetails> {
366
371
  seen.add(j.id);
367
372
  return true;
368
373
  });
369
- const jobResults = this.#snapshotJobs(uniqueJobs);
370
-
371
- manager.acknowledgeDeliveries(jobResults.filter(j => j.status !== "running").map(j => j.id));
374
+ const jobResults = this.#snapshotJobs(manager, uniqueJobs);
375
+
376
+ // Only COMPLETED/FAILED/CANCELLED jobs are terminal for ownership
377
+ // retirement: a paused subagent is not quiescent (settleOwnedWork
378
+ // cancels paused jobs before it can claim stopped_owned), so its
379
+ // ownership tuple must stay registered until it is actually cancelled
380
+ // — otherwise a scope:"owned" abort could find an empty causal set and
381
+ // report stopped_owned while the job remains visibly paused (review
382
+ // thread P2).
383
+ const terminalJobs = jobResults.filter(
384
+ j => j.status === "completed" || j.status === "failed" || j.status === "cancelled",
385
+ );
386
+ manager.acknowledgeDeliveries(terminalJobs.map(j => j.id));
387
+ // A terminal job whose deliveries were just acknowledged is
388
+ // synchronously consumed: its owned registration is settled and must
389
+ // not occupy the registry, otherwise the retained-policy tombstone
390
+ // treats it as a live policy occupant forever and its FIFO fallback can
391
+ // evict a genuinely running job's policy (review thread P2).
392
+ for (const job of terminalJobs) {
393
+ const generation = manager.getJob?.(job.id)?.generation;
394
+ if (!generation) continue;
395
+ // The endpoint disambiguates concurrent sessions' same job ids (review P1).
396
+ const registration = lookupOwnedRegistration(job.id, generation, this.session.getSessionId?.() ?? "local");
397
+ if (registration) unregisterOwnedRegistration(registration);
398
+ }
372
399
 
373
400
  const completed = jobResults.filter(j => j.status !== "running");
374
401
  const running = jobResults.filter(j => j.status === "running");
@@ -4,6 +4,7 @@ import * as z from "zod/v4";
4
4
  import { AsyncJobManager, isBackgroundJobSupportEnabled } from "../async";
5
5
  import monitorDescription from "../prompts/tools/monitor.md" with { type: "text" };
6
6
  import { truncateTail } from "../session/streaming-output";
7
+ import { lookupOwnedRegistration } from "../session/terminal-abort";
7
8
  import { BashTool } from "./bash";
8
9
  import type { ToolSession } from "./index";
9
10
  import { ToolError } from "./tool-errors";
@@ -106,13 +107,20 @@ export class MonitorTool implements AgentTool<typeof monitorSchema, MonitorToolD
106
107
  }
107
108
 
108
109
  async execute(
109
- _toolCallId: string,
110
+ toolCallId: string,
110
111
  params: MonitorParams,
111
112
  _signal?: AbortSignal,
112
113
  _onUpdate?: AgentToolUpdateCallback<MonitorToolDetails>,
113
114
  context?: AgentToolContext,
114
115
  ): Promise<AgentToolResult<MonitorToolDetails>> {
115
- const manager = AsyncJobManager.instance();
116
+ // The session's ENDPOINT-owned manager first: the monitor job is created
117
+ // in it, its generation is read from it, and non-persistent cancel must
118
+ // stop that exact job — the process-global instance may belong to a
119
+ // different concurrent top-level session (review thread P1).
120
+ const manager =
121
+ this.session.getAsyncJobManager?.() ??
122
+ AsyncJobManager.forEndpoint(this.session.getSessionId?.() ?? undefined) ??
123
+ AsyncJobManager.instance();
116
124
  if (!manager) {
117
125
  throw new ToolError("Async execution is disabled; the monitor tool is unavailable in this session.");
118
126
  }
@@ -169,8 +177,38 @@ export class MonitorTool implements AgentTool<typeof monitorSchema, MonitorToolD
169
177
  const suffix = count > 0 ? `\n(+${count} earlier lines)` : "";
170
178
  const notificationLine = formatMonitorNotificationLine(line);
171
179
  const content = `<task-notification>\nMonitor task ${jobId} (${params.kind}: ${params.description}) emitted latest state:\n${notificationLine.content}${suffix}\n</task-notification>`;
180
+ // Route the notification through the SAME owned-completion envelope
181
+ // and fresh-admission path as async results: a scope:"turn" abort
182
+ // that left this monitor running must resume the agent with a FRESH
183
+ // lineage (never the aborted attempt's), and scope:"owned" must drop
184
+ // it. The envelope is built from the tool-call lineage binding and
185
+ // the exact registered tuple; monitors without a registration stay
186
+ // ordinary. The standalone generation is NOT persisted — it lives in
187
+ // the envelope, which INTERNAL_DETAILS_FIELDS strips (review threads
188
+ // P1/P2).
189
+ const generation = manager.getJob(jobId)?.generation;
190
+ // Build the envelope from the RETAINED registration (which carries the
191
+ // complete lineage tuple), not the tool-call binding: the binding map
192
+ // is separately bounded and can evict a long-lived monitor's entry,
193
+ // but the registration keeps the lineage for owned classification
194
+ // (review thread P2).
195
+ // The lookup is ENDPOINT-scoped to THIS monitor's session: concurrent
196
+ // sessions have monitors with the same manager-local job id, and an
197
+ // endpoint-less fallback scan could attach a foreign session's
198
+ // registration (review thread P2).
199
+ const registration = generation
200
+ ? lookupOwnedRegistration(jobId, generation, this.session.getSessionId?.() ?? "local")
201
+ : undefined;
202
+ const ownedCompletion = registration
203
+ ? {
204
+ lineageIdHash: registration.lineageIdHash,
205
+ promptAttemptEpoch: registration.promptAttemptEpoch,
206
+ registration,
207
+ }
208
+ : undefined;
172
209
  const details = {
173
210
  taskId: jobId,
211
+ ...(ownedCompletion ? { ownedCompletions: [ownedCompletion] } : {}),
174
212
  kind: params.kind,
175
213
  description: params.description,
176
214
  monitor: true,
@@ -219,6 +257,7 @@ export class MonitorTool implements AgentTool<typeof monitorSchema, MonitorToolD
219
257
  ownerId,
220
258
  label,
221
259
  ctx: context,
260
+ toolCallId,
222
261
  shouldAcceptRawLine: () => !controller.closed,
223
262
  lifecycle: {
224
263
  onCancel: () => closeMonitor("purge"),
@@ -1,7 +1,11 @@
1
1
  import type { AgentTool, AgentToolResult } from "@gajae-code/agent-core";
2
2
  import { prompt, untilAborted } from "@gajae-code/utils";
3
3
  import * as z from "zod/v4";
4
- import { discoverRuntimeSkills, type RuntimeSkillDiscoveryCandidate } from "../extensibility/runtime-skill-discovery";
4
+ import {
5
+ describeDisabledSkillScopes,
6
+ discoverRuntimeSkills,
7
+ type RuntimeSkillDiscoveryCandidate,
8
+ } from "../extensibility/runtime-skill-discovery";
5
9
  import skillDiscoveryDescription from "../prompts/tools/skill-discovery.md" with { type: "text" };
6
10
  import type { ToolSession } from ".";
7
11
 
@@ -23,11 +27,18 @@ export interface SkillDiscoveryToolDetails {
23
27
  count: number;
24
28
  /**
25
29
  * Present only when zero candidates were returned AND discovery config gates
26
- * (`skills.enabled` / `skills.enablePiProject` / `skills.enablePiUser`)
30
+ * (`skills.enabled` / `skills.trustProjectSkills` / `skills.trustUserSkills`)
27
31
  * prevented some or all of the requested scope from being searched. Without
28
32
  * this, a disabled config is indistinguishable from "no skills exist".
29
33
  */
30
34
  notice?: string;
35
+ /**
36
+ * Human-readable diagnostics for skills that were scanned but not
37
+ * advertised (protected-name collisions with bundled workflow skills,
38
+ * include/ignore/disable policy filters, invalid frontmatter, shadowing,
39
+ * scan failures). Bounded; empty when nothing was filtered.
40
+ */
41
+ diagnostics?: string[];
31
42
  }
32
43
 
33
44
  export class SkillDiscoveryTool implements AgentTool<typeof skillDiscoverySchema, SkillDiscoveryToolDetails> {
@@ -65,16 +76,20 @@ export class SkillDiscoveryTool implements AgentTool<typeof skillDiscoverySchema
65
76
  ): Promise<AgentToolResult<SkillDiscoveryToolDetails>> {
66
77
  return untilAborted(signal, async () => {
67
78
  const source = input.source ?? "all";
68
- const candidates = await discoverRuntimeSkills({
79
+ const result = await discoverRuntimeSkills({
69
80
  cwd: this.#session.cwd,
70
81
  query: input.query,
71
82
  source,
72
83
  limit: input.limit,
73
84
  policy: this.#getRuntimeSkillPolicy(),
74
85
  });
75
- const details: SkillDiscoveryToolDetails = { candidates, count: candidates.length };
76
- if (candidates.length === 0) {
77
- const notice = this.#disabledPolicyNotice(source);
86
+ const details: SkillDiscoveryToolDetails = {
87
+ candidates: result.candidates,
88
+ count: result.candidates.length,
89
+ };
90
+ if (result.diagnostics.messages.length > 0) details.diagnostics = result.diagnostics.messages;
91
+ if (result.candidates.length === 0) {
92
+ const notice = describeDisabledSkillScopes(source, this.#getRuntimeSkillPolicy());
78
93
  if (notice) details.notice = notice;
79
94
  }
80
95
  return {
@@ -83,27 +98,4 @@ export class SkillDiscoveryTool implements AgentTool<typeof skillDiscoverySchema
83
98
  };
84
99
  });
85
100
  }
86
-
87
- /**
88
- * Explain an empty result that is caused by disabled discovery config rather
89
- * than by an actually empty skill catalog.
90
- */
91
- #disabledPolicyNotice(source: "all" | "project" | "user"): string | undefined {
92
- const policy = this.#getRuntimeSkillPolicy();
93
- if (policy.enabled !== true) {
94
- return "Runtime skill discovery is disabled: `skills.enabled` is false, so no skill directories were searched. Enable it with `gjc config set skills.enabled true` (project and user scopes additionally require `skills.enablePiProject` / `skills.enablePiUser`).";
95
- }
96
- const skipped: string[] = [];
97
- const commands: string[] = [];
98
- if ((source === "all" || source === "project") && policy.enablePiProject !== true) {
99
- skipped.push("project (`skills.enablePiProject` is false)");
100
- commands.push("`gjc config set skills.enablePiProject true`");
101
- }
102
- if ((source === "all" || source === "user") && policy.enablePiUser !== true) {
103
- skipped.push("user (`skills.enablePiUser` is false)");
104
- commands.push("`gjc config set skills.enablePiUser true`");
105
- }
106
- if (skipped.length === 0) return undefined;
107
- return `Skill discovery skipped disabled scope(s): ${skipped.join(", ")}. Enable them with ${commands.join(" and ")}.`;
108
- }
109
101
  }