@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,368 @@
1
+ /**
2
+ * Authoritative skill management contracts for native `.gjc` skills.
3
+ *
4
+ * Canonical skill locations are project `<project>/.gjc/skills/` and global
5
+ * `~/.gjc/agent/skills/` (plus legacy user roots). Claude Code / Codex layouts
6
+ * are explicit import sources into `.gjc` and are enumerated separately by
7
+ * `listConventionSkillImportSources`; they are never loaded as ordinary runtime
8
+ * skills.
9
+ *
10
+ * These contracts are the reusable behavior the `/extensions` surface (#4291)
11
+ * and SDK consumers build on: discovery with provenance + enablement state,
12
+ * writing a skill file into a scope, and per-skill enable/disable. The import
13
+ * preview/apply transaction and the UI itself are owned by #4291.
14
+ */
15
+ import * as fs from "node:fs/promises";
16
+ import * as os from "node:os";
17
+ import * as path from "node:path";
18
+ import { parseFrontmatter } from "@gajae-code/utils";
19
+ import { findRepoRoot } from "../capability/fs";
20
+ import type { Skill as CapabilitySkill } from "../capability/skill";
21
+ import { resolveSkillScopeTrust } from "../config/skill-settings-defaults";
22
+ import { scanClaudeProjectSkills, scanClaudeUserSkills } from "../discovery/claude";
23
+ import { scanCodexProjectSkills, scanCodexUserSkills } from "../discovery/codex";
24
+ import { compareSkillOrder, SOURCE_PATHS, scanSkillsFromDir } from "../discovery/helpers";
25
+ import { CANONICAL_GJC_WORKFLOW_SKILLS } from "../skill-state/canonical-skills";
26
+ export type SkillScope = "project" | "user";
27
+ export type ConventionSkillHost = "claude" | "codex";
28
+
29
+ export interface SkillManagementPolicy {
30
+ enabled?: boolean;
31
+ trustProjectSkills?: boolean;
32
+ trustUserSkills?: boolean;
33
+ ignoredSkills?: string[];
34
+ includeSkills?: string[];
35
+ disabledExtensions?: string[];
36
+ }
37
+
38
+ export type SkillDisabledReason = "protected" | "scope-trust" | "ignored" | "include" | "disabled-extension";
39
+
40
+ /** A discovered native skill with provenance and enablement state. */
41
+ export interface ManagedSkillRecord {
42
+ name: string;
43
+ description: string;
44
+ path: string;
45
+ scope: SkillScope;
46
+ /** Canonical source label, e.g. "project .gjc/skills" or "user ~/.gjc/agent/skills". */
47
+ source: string;
48
+ hidden: boolean;
49
+ enabled: boolean;
50
+ disabledReason?: SkillDisabledReason;
51
+ }
52
+
53
+ /** A Claude Code / Codex skill enumerated as an explicit import source into `.gjc`. */
54
+ export interface ConventionSkillImportSource {
55
+ host: ConventionSkillHost;
56
+ scope: SkillScope;
57
+ name: string;
58
+ description: string;
59
+ path: string;
60
+ }
61
+
62
+ export interface WriteNativeSkillInput {
63
+ cwd: string;
64
+ home?: string;
65
+ scope: SkillScope;
66
+ name: string;
67
+ content: string;
68
+ }
69
+
70
+ export interface WriteNativeSkillReceipt {
71
+ name: string;
72
+ scope: SkillScope;
73
+ directory: string;
74
+ path: string;
75
+ }
76
+
77
+ /** Raised when a write targets one of the four bundled workflow skill names. */
78
+ export class SkillNameProtectedError extends Error {
79
+ readonly code = "SKILL_NAME_PROTECTED";
80
+ constructor(name: string) {
81
+ super(
82
+ `skill "${name}" is a bundled GJC workflow skill (${CANONICAL_GJC_WORKFLOW_SKILLS.join(", ")}) and cannot be written as a custom skill`,
83
+ );
84
+ this.name = "SkillNameProtectedError";
85
+ }
86
+ }
87
+
88
+ /** Raised when skill content has no parseable frontmatter or lacks a description. */
89
+ export class SkillFrontmatterError extends Error {
90
+ readonly code = "SKILL_FRONTMATTER_INVALID";
91
+ constructor(message: string) {
92
+ super(message);
93
+ this.name = "SkillFrontmatterError";
94
+ }
95
+ }
96
+
97
+ const BUILT_IN_SKILL_NAMES = new Set<string>(CANONICAL_GJC_WORKFLOW_SKILLS);
98
+
99
+ function getRuntimeHome(): string {
100
+ return process.env.HOME || os.homedir();
101
+ }
102
+
103
+ /** Ancestor directories from `cwd` (inclusive) up to `stop` (inclusive), excluding `home`. */
104
+ function ancestorDirs(cwd: string, stop: string, home: string): string[] {
105
+ const dirs: string[] = [];
106
+ let current = path.resolve(cwd);
107
+ const resolvedStop = path.resolve(stop);
108
+ const resolvedHome = path.resolve(home);
109
+ while (true) {
110
+ if (current !== resolvedHome) {
111
+ dirs.push(current);
112
+ }
113
+ if (current === resolvedStop) break;
114
+ const parent = path.dirname(current);
115
+ if (parent === current) break;
116
+ current = parent;
117
+ }
118
+ return dirs;
119
+ }
120
+
121
+ /**
122
+ * Canonical project skill directories in precedence order: `.gjc/skills` in
123
+ * every ancestor from `cwd` up to the repo root (closest first).
124
+ */
125
+ export async function getProjectSkillDirs(
126
+ cwd: string,
127
+ home: string,
128
+ ): Promise<{ dirs: string[]; repoRoot: string | null }> {
129
+ const repoRoot = await findRepoRoot(cwd);
130
+ const walkDirs = ancestorDirs(cwd, path.resolve(repoRoot ?? cwd), home);
131
+ return { dirs: walkDirs.map(dir => path.join(dir, ".gjc", "skills")), repoRoot };
132
+ }
133
+
134
+ /** Canonical user skill directories in precedence order (same resolution as runtime discovery). */
135
+ export function getUserSkillDirs(home: string): string[] {
136
+ return [
137
+ ...new Set([
138
+ path.join(home, SOURCE_PATHS.native.userAgent, "skills"),
139
+ path.join(home, SOURCE_PATHS.native.userBase, "skills"),
140
+ path.join(home, ".gjc", "skills"),
141
+ ]),
142
+ ];
143
+ }
144
+
145
+ /**
146
+ * The canonical directory a write targets for a scope: the repo root (or `cwd`)
147
+ * `.gjc/skills` for project scope, the canonical `<config>/agent/skills` user
148
+ * root for user scope (honoring `GJC_CONFIG_DIR` / `PI_CONFIG_DIR`).
149
+ */
150
+ export async function resolveNativeSkillScopeDir(
151
+ cwd: string,
152
+ scope: SkillScope,
153
+ home = getRuntimeHome(),
154
+ ): Promise<string> {
155
+ if (scope === "user") return path.join(home, SOURCE_PATHS.native.userAgent, "skills");
156
+ const repoRoot = await findRepoRoot(cwd);
157
+ return path.join(repoRoot ?? path.resolve(cwd), ".gjc", "skills");
158
+ }
159
+
160
+ function matchesPattern(name: string, patterns: string[] | undefined): boolean {
161
+ if (!patterns || patterns.length === 0) return false;
162
+ return patterns.some(pattern => new Bun.Glob(pattern).match(name));
163
+ }
164
+
165
+ function isDisabledByExtension(name: string, disabledExtensions: string[] | undefined): boolean {
166
+ return (disabledExtensions ?? []).some(id => id === `skill:${name}`);
167
+ }
168
+
169
+ /**
170
+ * Authoritative discovery of native skills with provenance and enablement
171
+ * state. Unlike runtime session discovery, this lists every scanned skill —
172
+ * including disabled, shadowed, and protected ones — so `/extensions` and SDK
173
+ * consumers can show and toggle the full catalog.
174
+ */
175
+ export async function listNativeSkillsForManagement(options: {
176
+ cwd: string;
177
+ home?: string;
178
+ policy?: SkillManagementPolicy;
179
+ }): Promise<ManagedSkillRecord[]> {
180
+ const home = options.home ?? getRuntimeHome();
181
+ const policy = options.policy;
182
+ const projectTrusted = resolveSkillScopeTrust(policy ?? {}, "project");
183
+ const userTrusted = resolveSkillScopeTrust(policy ?? {}, "user");
184
+
185
+ const scanJobs: Array<Promise<{ dir: string; items: CapabilitySkill[] }>> = [];
186
+ const projectDirs = await getProjectSkillDirs(options.cwd, home);
187
+ if (projectTrusted) {
188
+ for (const dir of projectDirs.dirs) {
189
+ scanJobs.push(
190
+ scanSkillsFromDir(
191
+ { cwd: options.cwd, home, repoRoot: projectDirs.repoRoot },
192
+ { dir, providerId: "runtime", level: "project", requireDescription: true },
193
+ ).then(result => ({ dir, items: result.items })),
194
+ );
195
+ }
196
+ }
197
+ if (userTrusted) {
198
+ for (const dir of getUserSkillDirs(home)) {
199
+ scanJobs.push(
200
+ scanSkillsFromDir(
201
+ { cwd: options.cwd, home, repoRoot: home },
202
+ { dir, providerId: "runtime", level: "user", requireDescription: true },
203
+ ).then(result => ({ dir, items: result.items })),
204
+ );
205
+ }
206
+ }
207
+
208
+ const records: ManagedSkillRecord[] = [];
209
+ const seenNames = new Set<string>();
210
+ const seenPaths = new Set<string>();
211
+
212
+ for (const { dir, items } of await Promise.all(scanJobs)) {
213
+ const scope: SkillScope = path.resolve(dir).startsWith(`${path.resolve(home)}${path.sep}`) ? "user" : "project";
214
+ const source = scope === "project" ? "project .gjc/skills" : `user ${dir}`;
215
+ for (const skill of items) {
216
+ const realPath = await safeRealpath(skill.path);
217
+ if (seenPaths.has(realPath)) continue;
218
+
219
+ let disabledReason: SkillDisabledReason | undefined;
220
+ let enabled = true;
221
+ if (BUILT_IN_SKILL_NAMES.has(skill.name)) {
222
+ enabled = false;
223
+ disabledReason = "protected";
224
+ } else if (!(scope === "project" ? projectTrusted : userTrusted)) {
225
+ enabled = false;
226
+ disabledReason = "scope-trust";
227
+ } else if (matchesPattern(skill.name, policy?.ignoredSkills)) {
228
+ enabled = false;
229
+ disabledReason = "ignored";
230
+ } else if (policy?.includeSkills?.length && !matchesPattern(skill.name, policy.includeSkills)) {
231
+ enabled = false;
232
+ disabledReason = "include";
233
+ } else if (isDisabledByExtension(skill.name, policy?.disabledExtensions)) {
234
+ enabled = false;
235
+ disabledReason = "disabled-extension";
236
+ }
237
+
238
+ if (!seenNames.has(skill.name)) {
239
+ seenNames.add(skill.name);
240
+ records.push({
241
+ name: skill.name,
242
+ description: typeof skill.frontmatter?.description === "string" ? skill.frontmatter.description : "",
243
+ path: skill.path,
244
+ scope,
245
+ source,
246
+ hidden: skill.frontmatter?.hide === true,
247
+ enabled,
248
+ disabledReason,
249
+ });
250
+ }
251
+ seenPaths.add(realPath);
252
+ }
253
+ }
254
+
255
+ records.sort((a, b) => compareSkillOrder(a.name, a.path, b.name, b.path));
256
+ return records;
257
+ }
258
+
259
+ /**
260
+ * Write a native skill into the canonical `.gjc` scope directory. The content
261
+ * must parse as frontmatter with a non-empty `description`; the effective name
262
+ * comes from `frontmatter.name` when present, else the requested `name`. Bundled
263
+ * workflow skill names are rejected.
264
+ */
265
+ export async function writeNativeSkill(input: WriteNativeSkillInput): Promise<WriteNativeSkillReceipt> {
266
+ const name = input.name.trim();
267
+ if (!name) throw new SkillFrontmatterError("skill name is required");
268
+
269
+ const { frontmatter } = parseFrontmatter(input.content, { source: "<skill-content>" });
270
+ if (!frontmatter) throw new SkillFrontmatterError("skill content must start with a YAML frontmatter block (---)");
271
+ const description = typeof frontmatter.description === "string" ? frontmatter.description.trim() : "";
272
+ if (!description) throw new SkillFrontmatterError("skill frontmatter must include a non-empty description");
273
+
274
+ const effectiveName =
275
+ typeof frontmatter.name === "string" && frontmatter.name.trim() ? frontmatter.name.trim() : name;
276
+ if (BUILT_IN_SKILL_NAMES.has(effectiveName)) throw new SkillNameProtectedError(effectiveName);
277
+
278
+ const directory = await resolveNativeSkillScopeDir(input.cwd, input.scope, input.home ?? getRuntimeHome());
279
+ const skillDir = path.join(directory, effectiveName);
280
+ await fs.mkdir(skillDir, { recursive: true });
281
+ const filePath = path.join(skillDir, "SKILL.md");
282
+ await Bun.write(filePath, `${input.content.trimEnd()}\n`);
283
+ return { name: effectiveName, scope: input.scope, directory, path: filePath };
284
+ }
285
+
286
+ /** Whether a skill is enabled under the current policy (disabledExtensions/ignored/scope trust). */
287
+ export function isNativeSkillEnabled(name: string, policy: SkillManagementPolicy | undefined): boolean {
288
+ if (BUILT_IN_SKILL_NAMES.has(name)) return true;
289
+ if (isDisabledByExtension(name, policy?.disabledExtensions)) return false;
290
+ if (matchesPattern(name, policy?.ignoredSkills)) return false;
291
+ if (policy?.includeSkills?.length && !matchesPattern(name, policy.includeSkills)) return false;
292
+ return true;
293
+ }
294
+
295
+ /**
296
+ * Toggle per-skill enablement by adding/removing the `skill:<name>` entry in
297
+ * `disabledExtensions`. Returns the updated list; the caller persists it through
298
+ * Settings. Bundled workflow skill names cannot be disabled.
299
+ */
300
+ export function setNativeSkillEnabled(name: string, enabled: boolean, disabledExtensions: string[]): string[] {
301
+ const id = `skill:${name}`;
302
+ const next = new Set(disabledExtensions);
303
+ if (BUILT_IN_SKILL_NAMES.has(name)) return [...next];
304
+ if (enabled) {
305
+ next.delete(id);
306
+ } else {
307
+ next.add(id);
308
+ }
309
+ return [...next];
310
+ }
311
+
312
+ /**
313
+ * Enumerate Claude Code / Codex skills (project and user scope) as explicit
314
+ * import sources into `.gjc`. This only reads the foreign layouts for
315
+ * inspection/import; nothing is loaded into sessions and user-home content is
316
+ * never used without an explicit import action (#4291).
317
+ */
318
+ export async function listConventionSkillImportSources(options: {
319
+ cwd: string;
320
+ home?: string;
321
+ host?: ConventionSkillHost | "all";
322
+ }): Promise<ConventionSkillImportSource[]> {
323
+ const home = options.home ?? getRuntimeHome();
324
+ const hosts: ConventionSkillHost[] = options.host === "all" || !options.host ? ["claude", "codex"] : [options.host];
325
+ const repoRoot = await findRepoRoot(options.cwd);
326
+ const ctx = { cwd: options.cwd, home, repoRoot };
327
+
328
+ const sources: ConventionSkillImportSource[] = [];
329
+ const seen = new Set<string>();
330
+ for (const host of hosts) {
331
+ const scan = host === "claude" ? scanClaudeSkills : scanCodexSkills;
332
+ const results = await scan(ctx);
333
+ for (const skill of results.items) {
334
+ const key = `${host}:${skill.level}:${skill.name}`;
335
+ if (seen.has(key)) continue;
336
+ seen.add(key);
337
+ sources.push({
338
+ host,
339
+ scope: skill.level,
340
+ name: skill.name,
341
+ description: typeof skill.frontmatter?.description === "string" ? skill.frontmatter.description : "",
342
+ path: skill.path,
343
+ });
344
+ }
345
+ }
346
+ sources.sort((a, b) => compareSkillOrder(a.name, a.path, b.name, b.path));
347
+ return sources;
348
+ }
349
+
350
+ async function scanClaudeSkills(ctx: { cwd: string; home: string; repoRoot: string | null }) {
351
+ const project = await scanClaudeProjectSkills(ctx);
352
+ const user = await scanClaudeUserSkills(ctx);
353
+ return { items: [...project.items, ...user.items] };
354
+ }
355
+
356
+ async function scanCodexSkills(ctx: { cwd: string; home: string; repoRoot: string | null }) {
357
+ const project = await scanCodexProjectSkills(ctx);
358
+ const user = await scanCodexUserSkills(ctx);
359
+ return { items: [...project.items, ...user.items] };
360
+ }
361
+
362
+ async function safeRealpath(filePath: string): Promise<string> {
363
+ try {
364
+ return await fs.realpath(filePath);
365
+ } catch {
366
+ return filePath;
367
+ }
368
+ }
@@ -4,9 +4,11 @@ import { getProjectDir } from "@gajae-code/utils";
4
4
  import { skillCapability } from "../capability/skill";
5
5
  import type { SourceMeta } from "../capability/types";
6
6
  import type { SkillsSettings } from "../config/settings";
7
+ import { resolveSkillScopeTrust } from "../config/skill-settings-defaults";
7
8
  import { type Skill as CapabilitySkill, loadCapability } from "../discovery";
8
9
  import { compareSkillOrder, scanSkillsFromDir } from "../discovery/helpers";
9
10
  import type { SkillPromptDetails } from "../session/messages";
11
+ import { CANONICAL_GJC_WORKFLOW_SKILLS } from "../skill-state/canonical-skills";
10
12
  import { expandTilde } from "../tools/path-utils";
11
13
  import type { LoadedSubskillActivation } from "./gjc-plugins";
12
14
  import { buildSubskillInjection } from "./gjc-plugins/injection";
@@ -108,6 +110,15 @@ export interface LoadSkillsOptions extends SkillsSettings {
108
110
  cwd?: string;
109
111
  }
110
112
 
113
+ /**
114
+ * Skill providers loaded into sessions. Only native `.gjc` skills are live
115
+ * filesystem skills; Claude/Codex convention skills are explicit import
116
+ * sources into `.gjc` (see skill-management.ts) and are never loaded directly.
117
+ */
118
+ const LOADABLE_SKILL_PROVIDERS = new Set(["native"]);
119
+
120
+ const BUILT_IN_SKILL_NAMES = new Set<string>(CANONICAL_GJC_WORKFLOW_SKILLS);
121
+
111
122
  /**
112
123
  * Load skills from all configured locations.
113
124
  * Returns skills and any validation warnings.
@@ -116,8 +127,6 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
116
127
  const {
117
128
  cwd = getProjectDir(),
118
129
  enabled = true,
119
- enablePiUser = true,
120
- enablePiProject = true,
121
130
  customDirectories = [],
122
131
  ignoredSkills = [],
123
132
  includeSkills = [],
@@ -129,17 +138,24 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
129
138
  return { skills: [], warnings: [] };
130
139
  }
131
140
 
132
- // GJC only accepts native `.gjc` skills. Other providers may still exist for
133
- // their own capabilities, but their skill surfaces are intentionally ignored.
141
+ const projectTrusted = resolveSkillScopeTrust(options, "project");
142
+ const userTrusted = resolveSkillScopeTrust(options, "user");
143
+
144
+ // Skill scope trust decides which canonical locations are loaded: project
145
+ // scope covers `.gjc/skills` (walk-up), user scope covers `~/.gjc/agent/skills`
146
+ // and the legacy user roots. Claude/Codex convention skills are import
147
+ // sources into `.gjc`, never loaded directly.
134
148
  function isSourceEnabled(source: SourceMeta): boolean {
135
149
  const { provider, level } = source;
136
- if (provider !== "native") return false;
137
- if (level === "user") return enablePiUser;
138
- if (level === "project") return enablePiProject;
150
+ if (!LOADABLE_SKILL_PROVIDERS.has(provider)) return false;
151
+ if (level === "user") return userTrusted;
152
+ if (level === "project") return projectTrusted;
139
153
  return false;
140
154
  }
141
155
 
142
- // Use capability API to load all skills
156
+ // Use capability API to load all skills. `all` (rather than `items`) keeps
157
+ // shadowed duplicates so this function can apply the documented precedence
158
+ // itself: project scope beats user scope.
143
159
  const result = await loadCapability<CapabilitySkill>(skillCapability.id, { cwd, disabledExtensions });
144
160
 
145
161
  const skillMap = new Map<string, Skill>();
@@ -161,14 +177,23 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
161
177
  const disabledSkillNames = new Set(
162
178
  (disabledExtensions ?? []).filter(id => id.startsWith("skill:")).map(id => id.slice(6)),
163
179
  );
164
- // Filter skills by source and patterns first
165
- const filteredSkills = result.items.filter(capSkill => {
166
- if (disabledSkillNames.has(capSkill.name)) return false;
167
- if (!isSourceEnabled(capSkill._source)) return false;
168
- if (matchesIgnorePatterns(capSkill.name)) return false;
169
- if (!matchesIncludePatterns(capSkill.name)) return false;
170
- return true;
171
- });
180
+
181
+ // Apply scope trust and policy filters, then order candidates by documented
182
+ // precedence. `all` is already in native provider order with project dirs
183
+ // before user dirs; a stable sort by level lifts every project item above
184
+ // every user item, giving: project `.gjc/skills` > user roots.
185
+ const filteredSkills = result.all
186
+ .filter(capSkill => {
187
+ if (!isSourceEnabled(capSkill._source)) return false;
188
+ if (disabledSkillNames.has(capSkill.name)) return false;
189
+ if (matchesIgnorePatterns(capSkill.name)) return false;
190
+ if (!matchesIncludePatterns(capSkill.name)) return false;
191
+ return true;
192
+ })
193
+ .sort((a, b) => {
194
+ const levelOrder = { project: 0, user: 1 } as const;
195
+ return levelOrder[a.level] - levelOrder[b.level];
196
+ });
172
197
 
173
198
  // Batch resolve all real paths in parallel
174
199
  const realPaths = await Promise.all(
@@ -191,6 +216,17 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
191
216
  continue;
192
217
  }
193
218
 
219
+ // A project-controlled copy of a bundled workflow skill name is a potential
220
+ // workflow-routing hijack: warn, and let the session merge keep the bundled
221
+ // definition authoritative (sdk/session.ts). User-scope copies are not
222
+ // warned about: installed defaults legitimately mirror bundled skills.
223
+ if (capSkill.level === "project" && BUILT_IN_SKILL_NAMES.has(capSkill.name)) {
224
+ collisionWarnings.push({
225
+ skillPath: capSkill.path,
226
+ message: `name collision: "${capSkill.name}" is a bundled GJC workflow skill; the bundled definition takes precedence in sessions and this project copy is never used`,
227
+ });
228
+ }
229
+
194
230
  const existing = skillMap.get(capSkill.name);
195
231
  if (existing) {
196
232
  collisionWarnings.push({
@@ -1,8 +1,7 @@
1
1
  import { createHash, randomBytes } from "node:crypto";
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
- import { getConfigRootDir } from "@gajae-code/utils";
5
- import { YAML } from "bun";
4
+ import { isSettingsInitialized, Settings } from "../config/settings";
6
5
  import { syncSkillActiveState } from "../skill-state/active-state";
7
6
  import { deriveDeepInterviewHud } from "../skill-state/workflow-hud";
8
7
  import { WORKFLOW_STATE_VERSION } from "../skill-state/workflow-state-contract";
@@ -25,6 +24,7 @@ import { resolveGjcSessionForWrite, writeSessionActivityMarker } from "./session
25
24
  import { runNativeStateCommand } from "./state-runtime";
26
25
  import { appendJsonl, readExistingStateForMutation, writeArtifact, writeWorkflowEnvelopeAtomic } from "./state-writer";
27
26
  import { assertSafePathComponent, CommandError, flagValue, hasFlag } from "./workflow-cli-common";
27
+ import { resolveWorkflowSetting } from "./workflow-settings";
28
28
 
29
29
  export * from "./deep-interview-recorder";
30
30
 
@@ -346,62 +346,37 @@ interface DeepInterviewSpecWriteSummary {
346
346
  };
347
347
  }
348
348
 
349
- async function readSettingsAmbiguityThreshold(
350
- settingsPath: string,
351
- ): Promise<{ threshold: number; source: string } | undefined> {
352
- let raw: string;
353
- try {
354
- raw = await fs.readFile(settingsPath, "utf-8");
355
- } catch (error) {
356
- const err = error as NodeJS.ErrnoException;
357
- if (err.code === "ENOENT") return undefined;
358
- return undefined;
359
- }
360
- let parsed: unknown;
361
- try {
362
- parsed = JSON.parse(raw);
363
- } catch {
364
- return undefined;
365
- }
366
- const candidate = (parsed as { gjc?: { deepInterview?: { ambiguityThreshold?: unknown } } })?.gjc?.deepInterview
367
- ?.ambiguityThreshold;
368
- if (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate <= 0 || candidate > 1) {
369
- return undefined;
370
- }
371
- return { threshold: candidate, source: settingsPath };
372
- }
373
-
374
- function modernSettingsPath(): string {
375
- const configDir = process.env.GJC_CODING_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
376
- if (configDir) return path.join(configDir, "config.yml");
377
- return path.join(getConfigRootDir(), "agent", "config.yml");
378
- }
379
-
380
- async function readModernSettingsAmbiguityThreshold(): Promise<{ threshold: number; source: string } | undefined> {
381
- const modernConfigPath = modernSettingsPath();
382
- let parsed: unknown;
383
- try {
384
- parsed = YAML.parse(await fs.readFile(modernConfigPath, "utf-8"));
385
- } catch {
386
- return undefined;
387
- }
388
- const candidate = (parsed as { gjc?: { deepInterview?: { ambiguityThreshold?: unknown } } })?.gjc?.deepInterview
389
- ?.ambiguityThreshold;
390
- if (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate <= 0 || candidate > 1)
391
- return undefined;
392
- return { threshold: candidate, source: modernConfigPath };
393
- }
394
-
349
+ /**
350
+ * Resolve the configured ambiguity threshold through the shared five-layer
351
+ * resolver: project `.gjc/config.yml` > project `.gjc/settings.json` > user
352
+ * `getAgentDir()/config.yml` > legacy config-root `settings.json` > default.
353
+ * Project configuration beats user configuration, and invalid optional files
354
+ * continue to lower layers (tolerant contract). Returns `undefined` when the
355
+ * resolver falls back to the default so the resolution flags (`--quick`/
356
+ * `--standard`/`--deep`) still apply.
357
+ */
395
358
  async function resolveConfiguredAmbiguityThreshold(
396
359
  cwd: string,
360
+ agentDir?: string,
397
361
  ): Promise<{ threshold: number; source: string } | undefined> {
398
- const modernValue = await readModernSettingsAmbiguityThreshold();
399
- if (modernValue) return modernValue;
400
- const projectSettings = path.join(cwd, ".gjc", "settings.json");
401
- const projectValue = await readSettingsAmbiguityThreshold(projectSettings);
402
- if (projectValue) return projectValue;
403
- const userSettings = path.join(getConfigRootDir(), "settings.json");
404
- return await readSettingsAmbiguityThreshold(userSettings);
362
+ const resolution = await resolveWorkflowSetting(cwd, "gjc.deepInterview.ambiguityThreshold", {
363
+ defaultValue: DEFAULT_AMBIGUITY_THRESHOLD,
364
+ parse: value => {
365
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0 || value > 1) {
366
+ return {
367
+ kind: "invalid",
368
+ reason: "expected gjc.deepInterview.ambiguityThreshold to be a number in (0, 1]",
369
+ };
370
+ }
371
+ return { kind: "valid", value };
372
+ },
373
+ // The session's effective agent profile: an SDK session created with
374
+ // `createAgentSession({ agentDir })` resolves against that directory
375
+ // instead of the process-global default.
376
+ agentDir: agentDir ?? (isSettingsInitialized() ? Settings.instance.getAgentDir() : undefined),
377
+ });
378
+ if (resolution.source === "default") return undefined;
379
+ return { threshold: resolution.value, source: resolution.source };
405
380
  }
406
381
 
407
382
  function englishLanguagePreference(): DeepInterviewLanguagePreference {
@@ -502,7 +477,11 @@ async function resolveSpecWriteArgs(args: readonly string[], cwd: string): Promi
502
477
  };
503
478
  }
504
479
 
505
- async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): Promise<ResolvedDeepInterviewArgs> {
480
+ async function resolveDeepInterviewArgs(
481
+ args: readonly string[],
482
+ cwd: string,
483
+ agentDir?: string,
484
+ ): Promise<ResolvedDeepInterviewArgs> {
506
485
  const session = resolveGjcSessionForWrite(cwd, {
507
486
  flagValue: flagValue(args, "--session-id"),
508
487
  envSessionId: process.env.GJC_SESSION_ID,
@@ -531,7 +510,7 @@ async function resolveDeepInterviewArgs(args: readonly string[], cwd: string): P
531
510
  threshold = parsed;
532
511
  thresholdSource = flagValue(args, "--threshold-source")?.trim() || "flag:--threshold";
533
512
  } else {
534
- const configured = await resolveConfiguredAmbiguityThreshold(cwd);
513
+ const configured = await resolveConfiguredAmbiguityThreshold(cwd, agentDir);
535
514
  if (configured) {
536
515
  threshold = configured.threshold;
537
516
  thresholdSource = configured.source;
@@ -823,7 +802,11 @@ async function syncDeepInterviewHud(options: {
823
802
  }
824
803
  }
825
804
 
826
- async function handleSpecWrite(args: readonly string[], cwd: string): Promise<DeepInterviewCommandResult> {
805
+ async function handleSpecWrite(
806
+ args: readonly string[],
807
+ cwd: string,
808
+ agentDir?: string,
809
+ ): Promise<DeepInterviewCommandResult> {
827
810
  const resolved = await resolveSpecWriteArgs(args, cwd);
828
811
  const persisted = await persistDeepInterviewSpec(cwd, resolved);
829
812
  const shouldHandoff = resolved.deliberate || resolved.handoff === "ralplan";
@@ -843,7 +826,7 @@ async function handleSpecWrite(args: readonly string[], cwd: string): Promise<De
843
826
  const ralplanArgs = ["--deliberate", "--json"];
844
827
  if (resolved.sessionId) ralplanArgs.push("--session-id", resolved.sessionId);
845
828
  ralplanArgs.push(persisted.path);
846
- const ralplanResult = await runNativeRalplanCommand(ralplanArgs, cwd);
829
+ const ralplanResult = await runNativeRalplanCommand(ralplanArgs, cwd, { agentDir });
847
830
  if (ralplanResult.status !== 0) {
848
831
  throw new DeepInterviewCommandError(
849
832
  ralplanResult.status,
@@ -890,12 +873,13 @@ async function handleSpecWrite(args: readonly string[], cwd: string): Promise<De
890
873
  export async function runNativeDeepInterviewCommand(
891
874
  args: string[],
892
875
  cwd = process.cwd(),
876
+ options: { agentDir?: string } = {},
893
877
  ): Promise<DeepInterviewCommandResult> {
894
878
  try {
895
879
  const [firstArg, ...restArgs] = args;
896
880
  if (isDeepInterviewStageVerb(firstArg)) return await runDeepInterviewStageCommand(firstArg, restArgs, cwd);
897
- if (isDeepInterviewSpecWriteInvocation(args)) return await handleSpecWrite(args, cwd);
898
- const resolved = await resolveDeepInterviewArgs(args, cwd);
881
+ if (isDeepInterviewSpecWriteInvocation(args)) return await handleSpecWrite(args, cwd, options.agentDir);
882
+ const resolved = await resolveDeepInterviewArgs(args, cwd, options.agentDir);
899
883
  if (!resolved.idea) {
900
884
  throw new DeepInterviewCommandError(
901
885
  2,