@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,4 @@
1
+ export * from "./import";
2
+ export * from "./inventory";
3
+ export * from "./mutations";
4
+ export * from "./types";
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Inventory aggregation for the `/extensions` umbrella customization surface.
3
+ *
4
+ * Status authority is the runtime's own contracts, not a parallel state model:
5
+ * - Skills: `listNativeSkillsForManagement` (#4285) — the authoritative
6
+ * discovery/policy model (trust, include/ignore, disabledExtensions,
7
+ * bundled-name protection). A narrow supplemental scan flags SKILL.md files
8
+ * the management loader rejects as `invalid` rows.
9
+ * - Hooks: canonical `<root>/hooks/<pre|post>/` layout with the runtime's
10
+ * project-first, first-wins dedupe key (`<type>:<tool>:<name>`); losers are
11
+ * shown as `shadowed`.
12
+ * - MCPs: canonical config files for both scopes with the runtime's
13
+ * project-first precedence and the union of disabled markers; malformed
14
+ * files surface as `invalid` rows without leaking raw JSON.
15
+ *
16
+ * All display fields are secret-safe: env/header values are never rendered,
17
+ * and command/argument text is masked for token-shaped assignments.
18
+ */
19
+ import type { Dirent } from "node:fs";
20
+ import * as fs from "node:fs/promises";
21
+ import * as path from "node:path";
22
+ import { parseFrontmatter } from "@gajae-code/utils";
23
+ import { mcpCapability } from "../capability/mcp";
24
+ import { listNativeSkillsForManagement, type SkillManagementPolicy } from "../extensibility/skill-management";
25
+ import { readMCPConfigFile } from "../runtime-mcp/config-writer";
26
+ import type { CustomizationSurface, GjcScope, InventoryRow, InventoryStatus } from "./types";
27
+ import { resolveScopePaths, scopeLabel } from "./types";
28
+
29
+ /** Frontmatter key written by the import flow to record provenance. */
30
+ export const IMPORTED_FROM_FRONTMATTER_KEY = "x-gjc-imported-from";
31
+
32
+ export interface LoadCustomizationInventoryOptions {
33
+ cwd: string;
34
+ /** Runtime home override (tests); defaults to the process home. */
35
+ home?: string;
36
+ /** Skill management policy snapshot (trust, include/ignore, disabledExtensions). */
37
+ policy?: SkillManagementPolicy;
38
+ /** Disabled extension ids (`skill:<name>` / `mcp:<name>`) from settings. */
39
+ disabledExtensions?: string[];
40
+ }
41
+
42
+ export interface CustomizationInventory {
43
+ rows: InventoryRow[];
44
+ warnings: string[];
45
+ }
46
+
47
+ /** Stable row identity used for selection and mutations. */
48
+ export function inventoryRowId(surface: CustomizationSurface, scope: GjcScope, rowPath: string): string {
49
+ return `${surface}:${scope}:${rowPath}`;
50
+ }
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Display redaction
54
+ // ---------------------------------------------------------------------------
55
+
56
+ function redactServerForDisplay(server: Record<string, unknown>): Record<string, unknown> {
57
+ return {
58
+ type: typeof server.type === "string" ? server.type : undefined,
59
+ enabled: typeof server.enabled === "boolean" ? server.enabled : undefined,
60
+ autoload: typeof server.autoload === "boolean" ? server.autoload : undefined,
61
+ sharing: typeof server.sharing === "string" ? server.sharing : undefined,
62
+ timeout: typeof server.timeout === "number" ? server.timeout : undefined,
63
+ command: server.command === undefined ? undefined : "[command redacted]",
64
+ args: server.args === undefined ? undefined : "[arguments redacted]",
65
+ url: server.url === undefined ? undefined : "[URL redacted]",
66
+ envKeys: server.env && typeof server.env === "object" ? Object.keys(server.env) : undefined,
67
+ headerKeys: server.headers && typeof server.headers === "object" ? Object.keys(server.headers) : undefined,
68
+ };
69
+ }
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // Skills
73
+ // ---------------------------------------------------------------------------
74
+
75
+ async function readImportMarker(skillPath: string): Promise<string | null> {
76
+ try {
77
+ const content = await fs.readFile(skillPath, "utf-8");
78
+ const { frontmatter } = parseFrontmatter(content, { level: "off" });
79
+ // parseFrontmatter camelCases keys: x-gjc-imported-from → xGjcImportedFrom.
80
+ const marker = frontmatter[IMPORTED_FROM_FRONTMATTER_KEY] ?? frontmatter.xGjcImportedFrom;
81
+ return typeof marker === "string" ? marker : null;
82
+ } catch {
83
+ return null;
84
+ }
85
+ }
86
+
87
+ function importedProductLabel(marker: string): string {
88
+ return marker === "claude-code" ? "Claude Code" : marker === "codex" ? "Codex" : marker;
89
+ }
90
+
91
+ async function loadSkillRows(options: LoadCustomizationInventoryOptions, _warnings: string[]): Promise<InventoryRow[]> {
92
+ const rows: InventoryRow[] = [];
93
+ const records = await listNativeSkillsForManagement({
94
+ cwd: options.cwd,
95
+ home: options.home,
96
+ policy: options.policy,
97
+ });
98
+ const managedPaths = new Set<string>();
99
+ for (const record of records) {
100
+ managedPaths.add(path.resolve(record.path));
101
+ const scope: GjcScope = record.scope === "project" ? "project" : "global";
102
+ const marker = await readImportMarker(record.path);
103
+ let status: InventoryStatus;
104
+ const diagnostics: string[] = [];
105
+ if (options.policy?.enabled === false) {
106
+ status = "disabled";
107
+ diagnostics.push("native skills are disabled globally (skills.enabled=false)");
108
+ } else if (record.enabled) {
109
+ status = marker ? "imported" : "enabled";
110
+ } else if (record.disabledReason === "protected") {
111
+ // Bundled workflow skills are always active; the name is protected.
112
+ status = "enabled";
113
+ diagnostics.push("bundled GJC workflow skill — protected name, always available");
114
+ } else {
115
+ status = "disabled";
116
+ if (record.disabledReason) diagnostics.push(`disabled (${record.disabledReason})`);
117
+ }
118
+ const provenance = marker ? `${record.source} · imported from ${importedProductLabel(marker)}` : record.source;
119
+ rows.push({
120
+ id: inventoryRowId("skills", scope, record.path),
121
+ surface: "skills",
122
+ name: record.name,
123
+ displayName: record.name,
124
+ status,
125
+ provenance,
126
+ path: record.path,
127
+ scope,
128
+ description: record.description || undefined,
129
+ diagnostics: diagnostics.length > 0 ? diagnostics : undefined,
130
+ raw: { name: record.name, source: record.source, hidden: record.hidden },
131
+ });
132
+ }
133
+
134
+ // Narrow supplemental pass: flag SKILL.md files the management loader
135
+ // rejected (missing/invalid frontmatter) as invalid rows with remediation.
136
+ for (const scope of ["project", "global"] as const) {
137
+ const skillsDir = resolveScopePaths(scope, options.cwd).skillsDir;
138
+ let dirNames: string[];
139
+ try {
140
+ dirNames = (await fs.readdir(skillsDir, { withFileTypes: true }))
141
+ .filter(entry => entry.isDirectory() && !entry.name.startsWith("."))
142
+ .map(entry => entry.name)
143
+ .sort();
144
+ } catch {
145
+ continue;
146
+ }
147
+ for (const dirName of dirNames) {
148
+ const skillPath = path.join(skillsDir, dirName, "SKILL.md");
149
+ if (managedPaths.has(path.resolve(skillPath))) continue;
150
+ try {
151
+ const stat = await fs.lstat(skillPath);
152
+ if (stat.isSymbolicLink() || !stat.isFile()) continue;
153
+ const content = await fs.readFile(skillPath, "utf-8");
154
+ const { frontmatter } = parseFrontmatter(content, { level: "off" });
155
+ const description = typeof frontmatter.description === "string" ? frontmatter.description.trim() : "";
156
+ if (description) continue; // valid but shadowed/deduped — authority is the loader
157
+ rows.push({
158
+ id: inventoryRowId("skills", scope, skillPath),
159
+ surface: "skills",
160
+ name: dirName,
161
+ displayName: dirName,
162
+ status: "invalid",
163
+ provenance: `${scopeLabel(scope)} skills`,
164
+ path: skillPath,
165
+ scope,
166
+ diagnostics: ["invalid skill frontmatter: add a YAML frontmatter block with a non-empty description"],
167
+ raw: { name: dirName },
168
+ });
169
+ } catch {
170
+ // Unreadable files are simply not listed; the loader remains authority.
171
+ }
172
+ }
173
+ }
174
+ return rows;
175
+ }
176
+
177
+ // ---------------------------------------------------------------------------
178
+ // Hooks
179
+ // ---------------------------------------------------------------------------
180
+
181
+ const HOOK_PHASES = ["pre", "post"] as const;
182
+
183
+ async function loadHookRows(options: LoadCustomizationInventoryOptions, _warnings: string[]): Promise<InventoryRow[]> {
184
+ const rows: InventoryRow[] = [];
185
+ // Runtime semantics: project-first, first-wins on `<type>:<tool>:<name>`.
186
+ const seen = new Set<string>();
187
+ for (const scope of ["project", "global"] as const) {
188
+ const hooksDir = resolveScopePaths(scope, options.cwd).hooksDir;
189
+ for (const phase of HOOK_PHASES) {
190
+ const phaseDir = path.join(hooksDir, phase);
191
+ let entries: Dirent[];
192
+ try {
193
+ entries = await fs.readdir(phaseDir, { withFileTypes: true });
194
+ } catch {
195
+ continue;
196
+ }
197
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
198
+ if (entry.name.startsWith(".") || !entry.isFile()) continue;
199
+ const hookPath = path.join(phaseDir, entry.name);
200
+ const baseName = entry.name.includes(".") ? entry.name.slice(0, entry.name.lastIndexOf(".")) : entry.name;
201
+ const key = `${phase}:${baseName}:${entry.name}`;
202
+ const shadowed = seen.has(key);
203
+ seen.add(key);
204
+ rows.push({
205
+ id: inventoryRowId("hooks", scope, hookPath),
206
+ surface: "hooks",
207
+ name: entry.name,
208
+ displayName: `${phase}/${entry.name}`,
209
+ status: shadowed ? "shadowed" : "enabled",
210
+ provenance: `${scopeLabel(scope)} hooks/${phase}`,
211
+ path: hookPath,
212
+ scope,
213
+ description: `${phase}-tool hook for ${baseName}`,
214
+ diagnostics: shadowed ? ["shadowed by the same hook at higher-precedence scope"] : undefined,
215
+ raw: { name: entry.name, type: phase, tool: baseName },
216
+ });
217
+ }
218
+ }
219
+ }
220
+ return rows;
221
+ }
222
+
223
+ // ---------------------------------------------------------------------------
224
+ // MCPs
225
+ // ---------------------------------------------------------------------------
226
+
227
+ function mcpDescription(name: string, server: Record<string, unknown>): string {
228
+ if (typeof server.command === "string" && server.command) {
229
+ return `stdio MCP "${name}" (command redacted)`;
230
+ }
231
+ const type = typeof server.type === "string" ? server.type : "http";
232
+ return `${type} MCP "${name}" (endpoint redacted)`;
233
+ }
234
+
235
+ async function loadMcpRows(options: LoadCustomizationInventoryOptions, warnings: string[]): Promise<InventoryRow[]> {
236
+ const rows: InventoryRow[] = [];
237
+ const disabledExtensions = new Set(
238
+ (options.disabledExtensions ?? []).filter(id => id.startsWith("mcp:")).map(id => id.slice("mcp:".length)),
239
+ );
240
+ const scopeConfigs = await Promise.all(
241
+ (["project", "global"] as const).map(async scope => {
242
+ const configPath = resolveScopePaths(scope, options.cwd).mcpConfigPath;
243
+ const config = await readMCPConfigFile(configPath).catch(() => null);
244
+ return { scope, configPath, config };
245
+ }),
246
+ );
247
+ const disabledServers = new Set(
248
+ scopeConfigs.flatMap(({ config }) => (Array.isArray(config?.disabledServers) ? config.disabledServers : [])),
249
+ );
250
+ // Runtime semantics: project scope wins; the user-global entry is shadowed.
251
+ const seen = new Set<string>();
252
+ for (const { scope, configPath: mcpConfigPath, config } of scopeConfigs) {
253
+ if (config === null) {
254
+ let exists = false;
255
+ try {
256
+ exists = (await fs.lstat(mcpConfigPath)).isFile();
257
+ } catch {
258
+ exists = false;
259
+ }
260
+ if (exists) {
261
+ warnings.push(`${mcpConfigPath} is malformed; fix or remove it to manage MCP servers`);
262
+ rows.push({
263
+ id: inventoryRowId("mcps", scope, mcpConfigPath),
264
+ surface: "mcps",
265
+ name: path.basename(mcpConfigPath),
266
+ displayName: path.basename(mcpConfigPath),
267
+ status: "invalid",
268
+ provenance: `${scopeLabel(scope)} MCP config`,
269
+ path: mcpConfigPath,
270
+ scope,
271
+ diagnostics: ["malformed MCP config file; fix or remove it (contents not shown)"],
272
+ raw: { path: mcpConfigPath },
273
+ });
274
+ }
275
+ continue;
276
+ }
277
+ const servers = config.mcpServers ?? {};
278
+ for (const [name, server] of Object.entries(servers).sort(([a], [b]) => a.localeCompare(b))) {
279
+ const shadowed = seen.has(name);
280
+ seen.add(name);
281
+ const record = server as unknown as Record<string, unknown>;
282
+ const validationError = mcpCapability.validate?.({
283
+ name,
284
+ ...record,
285
+ } as Parameters<NonNullable<typeof mcpCapability.validate>>[0]);
286
+ const isDisabled = disabledExtensions.has(name) || disabledServers.has(name) || record.enabled === false;
287
+ const status: InventoryStatus = validationError
288
+ ? "invalid"
289
+ : shadowed
290
+ ? "shadowed"
291
+ : isDisabled
292
+ ? "disabled"
293
+ : "enabled";
294
+ rows.push({
295
+ id: inventoryRowId("mcps", scope, `${mcpConfigPath}#${name}`),
296
+ surface: "mcps",
297
+ name,
298
+ displayName: name,
299
+ status,
300
+ provenance: `${scopeLabel(scope)} mcp.json`,
301
+ path: mcpConfigPath,
302
+ scope,
303
+ description: mcpDescription(name, record),
304
+ diagnostics: validationError
305
+ ? [validationError]
306
+ : shadowed
307
+ ? ["shadowed by the same server at higher-precedence scope"]
308
+ : undefined,
309
+ raw: redactServerForDisplay(record),
310
+ });
311
+ }
312
+ }
313
+ return rows;
314
+ }
315
+
316
+ // ---------------------------------------------------------------------------
317
+ // Aggregate
318
+ // ---------------------------------------------------------------------------
319
+
320
+ /**
321
+ * Load the full Skills/Hooks/MCPs inventory for the `/extensions` dashboard.
322
+ * Reads only the canonical `.gjc` scopes; foreign Claude/Codex layouts are
323
+ * import sources handled by the explicit import flow, never managed entries.
324
+ */
325
+ export async function loadCustomizationInventory(
326
+ options: LoadCustomizationInventoryOptions,
327
+ ): Promise<CustomizationInventory> {
328
+ const warnings: string[] = [];
329
+ const [skills, hooks, mcps] = await Promise.all([
330
+ loadSkillRows(options, warnings),
331
+ loadHookRows(options, warnings),
332
+ loadMcpRows(options, warnings),
333
+ ]);
334
+ return { rows: [...skills, ...hooks, ...mcps], warnings };
335
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Safe mutations for the `/extensions` umbrella customization surface
3
+ * (issue #4291). Every operation goes through the same canonical
4
+ * loaders/writers the runtime and CLI use — no parallel state model.
5
+ *
6
+ * - Skills: enable/disable via the authoritative `setNativeSkillEnabled`
7
+ * policy contract (the caller persists the returned `disabledExtensions`
8
+ * list through Settings); remove targets the exact discovered SKILL.md
9
+ * path identity with bundled-name and symlink protection.
10
+ * - MCPs: enable/disable via the `enabled` flag and remove via the canonical
11
+ * config writer (atomic write, cache invalidation included).
12
+ * - Hooks: remove only, by exact discovered path; enable/disable is not part
13
+ * of the canonical hook contract and is rejected by the UI with a
14
+ * diagnostic.
15
+ */
16
+ import * as fs from "node:fs/promises";
17
+ import * as path from "node:path";
18
+ import { setNativeSkillEnabled } from "../extensibility/skill-management";
19
+ import {
20
+ readMCPConfigFile,
21
+ removeMCPServer,
22
+ setServerDisabled,
23
+ writeMCPConfigFile,
24
+ } from "../runtime-mcp/config-writer";
25
+ import { CANONICAL_GJC_WORKFLOW_SKILLS } from "../skill-state/canonical-skills";
26
+
27
+ const BUNDLED_SKILL_NAMES: ReadonlySet<string> = new Set(CANONICAL_GJC_WORKFLOW_SKILLS);
28
+
29
+ export type MutationResult = { ok: true } | { ok: false; reason: string };
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // Skills
33
+ // ---------------------------------------------------------------------------
34
+
35
+ /**
36
+ * Toggle a native skill through the authoritative policy contract. Returns
37
+ * the updated `disabledExtensions` list; the caller persists it via Settings.
38
+ * Bundled workflow skill names cannot be disabled.
39
+ */
40
+ export function setSkillEnabled(
41
+ name: string,
42
+ enabled: boolean,
43
+ disabledExtensions: string[],
44
+ ): MutationResult & { disabledExtensions?: string[] } {
45
+ if (!enabled && BUNDLED_SKILL_NAMES.has(name)) {
46
+ return { ok: false, reason: `"${name}" is a protected bundled workflow skill name` };
47
+ }
48
+ return { ok: true, disabledExtensions: setNativeSkillEnabled(name, enabled, disabledExtensions) };
49
+ }
50
+
51
+ /**
52
+ * Remove a native skill by its exact discovered SKILL.md path identity.
53
+ * Fails when the discovered file is absent, refuses symlinked directories or
54
+ * files, and never removes protected bundled workflow skill names.
55
+ */
56
+ export async function removeSkill(record: { name: string; path: string }): Promise<MutationResult> {
57
+ if (BUNDLED_SKILL_NAMES.has(record.name)) {
58
+ return { ok: false, reason: `"${record.name}" is a protected bundled workflow skill name` };
59
+ }
60
+ const dir = path.dirname(record.path);
61
+ try {
62
+ const fileStat = await fs.lstat(record.path);
63
+ if (fileStat.isSymbolicLink())
64
+ return { ok: false, reason: `refusing to remove symlinked skill file: ${record.path}` };
65
+ if (!fileStat.isFile())
66
+ return { ok: false, reason: `discovered skill file is not a regular file: ${record.path}` };
67
+ const dirStat = await fs.lstat(dir);
68
+ if (dirStat.isSymbolicLink())
69
+ return { ok: false, reason: `refusing to remove symlinked skill directory: ${dir}` };
70
+ if (!dirStat.isDirectory()) return { ok: false, reason: `not a skill directory: ${dir}` };
71
+ } catch {
72
+ return { ok: false, reason: `discovered skill file is absent: ${record.path}` };
73
+ }
74
+ await fs.rm(dir, { recursive: true, force: false });
75
+ return { ok: true };
76
+ }
77
+
78
+ // ---------------------------------------------------------------------------
79
+ // MCPs
80
+ // ---------------------------------------------------------------------------
81
+
82
+ /** Toggle a server through the canonical disabledServers denylist. */
83
+ export async function setMcpServerEnabled(
84
+ mcpConfigPath: string,
85
+ name: string,
86
+ enabled: boolean,
87
+ disabledExtensions: string[] = [],
88
+ ): Promise<MutationResult> {
89
+ const config = await readMCPConfigFile(mcpConfigPath).catch(() => null);
90
+ if (!config) return { ok: false, reason: `${mcpConfigPath} is malformed; fix or remove it first` };
91
+ const server = config.mcpServers?.[name];
92
+ if (!server) return { ok: false, reason: `server "${name}" not found in ${mcpConfigPath}` };
93
+ if (enabled && server.enabled === false) {
94
+ const updatedServer = { ...server };
95
+ delete updatedServer.enabled;
96
+ await writeMCPConfigFile(mcpConfigPath, {
97
+ ...config,
98
+ mcpServers: { ...config.mcpServers, [name]: updatedServer },
99
+ });
100
+ }
101
+ await setServerDisabled(mcpConfigPath, name, !enabled);
102
+ const id = `mcp:${name}`;
103
+ const nextDisabledExtensions = enabled
104
+ ? disabledExtensions.filter(entry => entry !== id)
105
+ : disabledExtensions.includes(id)
106
+ ? disabledExtensions
107
+ : [...disabledExtensions, id];
108
+ return { ok: true, disabledExtensions: nextDisabledExtensions } as MutationResult & {
109
+ disabledExtensions: string[];
110
+ };
111
+ }
112
+
113
+ /** Remove a server via the canonical config writer. */
114
+ export async function removeMcpServerEntry(mcpConfigPath: string, name: string): Promise<MutationResult> {
115
+ try {
116
+ await removeMCPServer(mcpConfigPath, name);
117
+ return { ok: true };
118
+ } catch (error) {
119
+ return { ok: false, reason: (error as Error).message };
120
+ }
121
+ }
122
+
123
+ // ---------------------------------------------------------------------------
124
+ // Hooks
125
+ // ---------------------------------------------------------------------------
126
+
127
+ /**
128
+ * Remove a hook by its exact discovered path. Refuses symlinks, non-files,
129
+ * and paths that do not exist (no silent success).
130
+ */
131
+ export async function removeHookFile(hookPath: string): Promise<MutationResult> {
132
+ try {
133
+ const stat = await fs.lstat(hookPath);
134
+ if (stat.isSymbolicLink()) return { ok: false, reason: `refusing to remove symlinked hook: ${hookPath}` };
135
+ if (!stat.isFile()) return { ok: false, reason: `not a hook file: ${hookPath}` };
136
+ await fs.rm(hookPath, { force: false });
137
+ return { ok: true };
138
+ } catch (error) {
139
+ return { ok: false, reason: (error as Error).message };
140
+ }
141
+ }