@cjhyy/code-shell-core 0.5.0-rc.1 → 0.6.0-rc.1

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 (528) hide show
  1. package/README.md +13 -10
  2. package/dist/agent/agent-definition-registry.d.ts +21 -3
  3. package/dist/agent/agent-definition-registry.js +49 -18
  4. package/dist/agent/agent-definition.d.ts +32 -0
  5. package/dist/agent/agent-definition.js +49 -4
  6. package/dist/arena/arena.js +11 -12
  7. package/dist/arena/context/context-tools.js +47 -6
  8. package/dist/arena/context/within-root.d.ts +7 -0
  9. package/dist/arena/context/within-root.js +15 -0
  10. package/dist/arena/iterate/phases/argue.js +8 -2
  11. package/dist/arena/iterate/phases/revise.js +1 -1
  12. package/dist/arena/iterate/phases/tournament.js +3 -3
  13. package/dist/arena/ledger.js +9 -1
  14. package/dist/arena/phases/adjudication.js +1 -4
  15. package/dist/arena/phases/build-consensus.js +1 -4
  16. package/dist/arena/phases/cross-review.js +2 -8
  17. package/dist/arena/phases/debate-rounds.js +1 -4
  18. package/dist/arena/phases/participant-research.js +1 -4
  19. package/dist/arena/phases/planning-detail-expansion.js +8 -10
  20. package/dist/arena/planner.js +0 -1
  21. package/dist/arena/providers/docs.d.ts +1 -0
  22. package/dist/arena/providers/docs.js +5 -2
  23. package/dist/arena/providers/repo.d.ts +1 -0
  24. package/dist/arena/providers/repo.js +5 -2
  25. package/dist/arena/strategies/utils.d.ts +1 -4
  26. package/dist/arena/strategies/utils.js +7 -51
  27. package/dist/arena/transitions.d.ts +7 -2
  28. package/dist/arena/transitions.js +9 -4
  29. package/dist/arena/types.d.ts +8 -2
  30. package/dist/automation/cron-expr.d.ts +41 -0
  31. package/dist/automation/cron-expr.js +169 -0
  32. package/dist/automation/index.d.ts +41 -0
  33. package/dist/automation/index.js +39 -0
  34. package/dist/automation/runner.d.ts +84 -0
  35. package/dist/automation/runner.js +92 -0
  36. package/dist/automation/scheduler.d.ts +194 -0
  37. package/dist/automation/scheduler.js +623 -0
  38. package/dist/automation/store.d.ts +39 -0
  39. package/dist/automation/store.js +122 -0
  40. package/dist/automation/write-policy.d.ts +34 -0
  41. package/dist/automation/write-policy.js +113 -0
  42. package/dist/automation/write-run.d.ts +51 -0
  43. package/dist/automation/write-run.js +38 -0
  44. package/dist/capability-control/disabled-lists.d.ts +25 -0
  45. package/dist/capability-control/disabled-lists.js +57 -0
  46. package/dist/capability-control/index.d.ts +5 -0
  47. package/dist/capability-control/index.js +3 -0
  48. package/dist/capability-control/overlay.d.ts +64 -0
  49. package/dist/capability-control/overlay.js +116 -0
  50. package/dist/capability-control/project.d.ts +65 -0
  51. package/dist/capability-control/project.js +147 -0
  52. package/dist/capability-control/service.d.ts +70 -0
  53. package/dist/capability-control/service.js +147 -0
  54. package/dist/capability-control/types.d.ts +62 -0
  55. package/dist/capability-control/types.js +17 -0
  56. package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
  57. package/dist/cc-orchestrator/agent-adapter.js +133 -0
  58. package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
  59. package/dist/cc-orchestrator/cc-capability.js +53 -0
  60. package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
  61. package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
  62. package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
  63. package/dist/cc-orchestrator/codex-session-history.js +187 -0
  64. package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
  65. package/dist/cc-orchestrator/external-agent-changes.js +214 -0
  66. package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
  67. package/dist/cc-orchestrator/external-agent-driver.js +69 -0
  68. package/dist/cc-orchestrator/index.d.ts +8 -0
  69. package/dist/cc-orchestrator/index.js +8 -0
  70. package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
  71. package/dist/cc-orchestrator/relevance-judge.js +29 -0
  72. package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
  73. package/dist/cc-orchestrator/session-discovery.js +125 -0
  74. package/dist/cc-orchestrator/session-history.d.ts +19 -0
  75. package/dist/cc-orchestrator/session-history.js +67 -0
  76. package/dist/cli/agent-server-stdio.d.ts +26 -1
  77. package/dist/cli/agent-server-stdio.js +221 -28
  78. package/dist/cli/agent-server-tcp.d.ts +20 -0
  79. package/dist/cli/agent-server-tcp.js +134 -0
  80. package/dist/cli/graceful-shutdown.d.ts +27 -0
  81. package/dist/cli/graceful-shutdown.js +30 -0
  82. package/dist/context/compaction.d.ts +56 -0
  83. package/dist/context/compaction.js +209 -15
  84. package/dist/context/manager.d.ts +0 -20
  85. package/dist/context/manager.js +25 -41
  86. package/dist/cost-tracker.js +5 -61
  87. package/dist/credentials/cipher.d.ts +49 -0
  88. package/dist/credentials/cipher.js +45 -0
  89. package/dist/credentials/cookie-jar.d.ts +24 -0
  90. package/dist/credentials/cookie-jar.js +40 -0
  91. package/dist/credentials/index.d.ts +7 -0
  92. package/dist/credentials/index.js +5 -0
  93. package/dist/credentials/inject-credential-tool.d.ts +20 -0
  94. package/dist/credentials/inject-credential-tool.js +130 -0
  95. package/dist/credentials/store.d.ts +72 -0
  96. package/dist/credentials/store.js +184 -0
  97. package/dist/credentials/types.d.ts +56 -0
  98. package/dist/credentials/use-credential-tool.d.ts +29 -0
  99. package/dist/credentials/use-credential-tool.js +205 -0
  100. package/dist/credentials/use-gate.d.ts +56 -0
  101. package/dist/credentials/use-gate.js +52 -0
  102. package/dist/cron/cron-runtime.d.ts +2 -0
  103. package/dist/cron/cron-runtime.js +2 -0
  104. package/dist/cron/cron-store.d.ts +2 -0
  105. package/dist/cron/cron-store.js +2 -0
  106. package/dist/cron/scheduler.d.ts +5 -32
  107. package/dist/cron/scheduler.js +5 -113
  108. package/dist/data/model-metadata.d.ts +77 -0
  109. package/dist/data/model-metadata.js +56 -0
  110. package/dist/data/model-metadata.json +216 -0
  111. package/dist/data/openrouter-models.d.ts +18 -7
  112. package/dist/data/openrouter-models.js +35 -8
  113. package/dist/data/openrouter-sync.js +1 -1
  114. package/dist/engine/aux-key.d.ts +10 -0
  115. package/dist/engine/aux-key.js +11 -0
  116. package/dist/engine/dynamic-tool-defs.d.ts +19 -0
  117. package/dist/engine/dynamic-tool-defs.js +36 -0
  118. package/dist/engine/engine.d.ts +431 -108
  119. package/dist/engine/engine.js +1630 -279
  120. package/dist/engine/friendly-error.d.ts +18 -0
  121. package/dist/engine/friendly-error.js +63 -0
  122. package/dist/engine/goal.d.ts +187 -0
  123. package/dist/engine/goal.js +196 -0
  124. package/dist/engine/image-compression.d.ts +81 -0
  125. package/dist/engine/image-compression.js +186 -0
  126. package/dist/engine/image-policy.d.ts +165 -0
  127. package/dist/engine/image-policy.js +189 -0
  128. package/dist/engine/model-connections-pool.d.ts +17 -0
  129. package/dist/engine/model-connections-pool.js +66 -0
  130. package/dist/engine/model-facade.d.ts +10 -0
  131. package/dist/engine/model-facade.js +25 -0
  132. package/dist/engine/patch-orphaned-tools.js +3 -0
  133. package/dist/engine/reactive-threshold.d.ts +13 -0
  134. package/dist/engine/reactive-threshold.js +17 -0
  135. package/dist/engine/resolve-llm-config.d.ts +16 -0
  136. package/dist/engine/resolve-llm-config.js +44 -0
  137. package/dist/engine/runtime.js +9 -1
  138. package/dist/engine/sandbox-cache-key.d.ts +10 -0
  139. package/dist/engine/sandbox-cache-key.js +9 -0
  140. package/dist/engine/sandbox-config.d.ts +31 -0
  141. package/dist/engine/sandbox-config.js +38 -0
  142. package/dist/engine/session-title.d.ts +13 -0
  143. package/dist/engine/session-title.js +34 -0
  144. package/dist/engine/session-usage.d.ts +19 -0
  145. package/dist/engine/session-usage.js +25 -0
  146. package/dist/engine/steer-queue.d.ts +32 -0
  147. package/dist/engine/steer-queue.js +26 -0
  148. package/dist/engine/streaming-tool-queue.d.ts +12 -0
  149. package/dist/engine/streaming-tool-queue.js +50 -10
  150. package/dist/engine/turn-loop.d.ts +94 -9
  151. package/dist/engine/turn-loop.js +775 -342
  152. package/dist/engine/types.d.ts +175 -0
  153. package/dist/engine/types.js +13 -0
  154. package/dist/external-agents/config.d.ts +2 -0
  155. package/dist/external-agents/config.js +15 -0
  156. package/dist/external-agents/types.d.ts +31 -0
  157. package/dist/external-agents/types.js +1 -0
  158. package/dist/git/parse-log.d.ts +13 -0
  159. package/dist/git/parse-log.js +21 -0
  160. package/dist/git/utils.d.ts +8 -6
  161. package/dist/git/utils.js +62 -26
  162. package/dist/git/worktree.d.ts +48 -0
  163. package/dist/git/worktree.js +111 -20
  164. package/dist/hooks/events.d.ts +23 -1
  165. package/dist/hooks/goal-stop-hook.d.ts +58 -0
  166. package/dist/hooks/goal-stop-hook.js +279 -0
  167. package/dist/hooks/hook-output.d.ts +33 -0
  168. package/dist/hooks/hook-output.js +79 -0
  169. package/dist/hooks/registry.d.ts +15 -0
  170. package/dist/hooks/registry.js +57 -1
  171. package/dist/hooks/shell-runner.d.ts +2 -0
  172. package/dist/hooks/shell-runner.js +48 -18
  173. package/dist/index.d.ts +79 -11
  174. package/dist/index.js +89 -6
  175. package/dist/llm/capabilities/param-specs.d.ts +14 -0
  176. package/dist/llm/capabilities/param-specs.js +62 -0
  177. package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
  178. package/dist/llm/capabilities/reasoning-control.js +38 -0
  179. package/dist/llm/capabilities/rules.js +37 -3
  180. package/dist/llm/capabilities/types.d.ts +32 -2
  181. package/dist/llm/clamp-max-tokens.d.ts +11 -0
  182. package/dist/llm/clamp-max-tokens.js +17 -0
  183. package/dist/llm/client-base.d.ts +69 -5
  184. package/dist/llm/client-base.js +185 -25
  185. package/dist/llm/client-factory.d.ts +3 -3
  186. package/dist/llm/client-factory.js +2 -2
  187. package/dist/llm/model-cache.js +4 -2
  188. package/dist/llm/model-pool.d.ts +29 -11
  189. package/dist/llm/model-pool.js +36 -20
  190. package/dist/llm/provider-auth.d.ts +41 -0
  191. package/dist/llm/provider-auth.js +76 -0
  192. package/dist/llm/provider-catalog.d.ts +6 -2
  193. package/dist/llm/providers/anthropic.d.ts +32 -2
  194. package/dist/llm/providers/anthropic.js +207 -18
  195. package/dist/llm/providers/openai.d.ts +47 -2
  196. package/dist/llm/providers/openai.js +478 -71
  197. package/dist/llm/reasoning-setting.d.ts +51 -0
  198. package/dist/llm/reasoning-setting.js +40 -0
  199. package/dist/llm/stop-reason.d.ts +13 -0
  200. package/dist/llm/stop-reason.js +21 -0
  201. package/dist/llm/stream-watchdog.js +5 -1
  202. package/dist/llm/strip-vision.d.ts +32 -0
  203. package/dist/llm/strip-vision.js +94 -0
  204. package/dist/llm/token-counter.js +9 -2
  205. package/dist/llm/types.d.ts +9 -6
  206. package/dist/logging/logger.js +18 -4
  207. package/dist/logging/sanitize-messages.d.ts +10 -0
  208. package/dist/logging/sanitize-messages.js +112 -0
  209. package/dist/lsp/client.js +28 -8
  210. package/dist/lsp/manager.d.ts +1 -1
  211. package/dist/lsp/manager.js +42 -11
  212. package/dist/lsp/root-path.d.ts +9 -0
  213. package/dist/lsp/root-path.js +12 -0
  214. package/dist/model-catalog/builtin.d.ts +12 -0
  215. package/dist/model-catalog/builtin.js +407 -0
  216. package/dist/model-catalog/gen-connections.d.ts +20 -0
  217. package/dist/model-catalog/gen-connections.js +28 -0
  218. package/dist/model-catalog/index.d.ts +41 -0
  219. package/dist/model-catalog/index.js +90 -0
  220. package/dist/model-catalog/params.d.ts +20 -0
  221. package/dist/model-catalog/params.js +45 -0
  222. package/dist/model-catalog/resolve.d.ts +48 -0
  223. package/dist/model-catalog/resolve.js +33 -0
  224. package/dist/model-catalog/save-entry.d.ts +32 -0
  225. package/dist/model-catalog/save-entry.js +104 -0
  226. package/dist/model-catalog/types.d.ts +561 -0
  227. package/dist/model-catalog/types.js +93 -0
  228. package/dist/model-catalog/upsert.d.ts +9 -0
  229. package/dist/model-catalog/upsert.js +8 -0
  230. package/dist/onboarding.d.ts +12 -82
  231. package/dist/onboarding.js +75 -333
  232. package/dist/plugins/gitOps.d.ts +53 -0
  233. package/dist/plugins/gitOps.js +130 -5
  234. package/dist/plugins/installer/checkUpdate.d.ts +16 -0
  235. package/dist/plugins/installer/checkUpdate.js +32 -0
  236. package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
  237. package/dist/plugins/installer/codex/convertAgents.js +55 -0
  238. package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
  239. package/dist/plugins/installer/codex/convertCommands.js +46 -0
  240. package/dist/plugins/installer/codex/convertMcp.d.ts +11 -0
  241. package/dist/plugins/installer/codex/convertMcp.js +85 -0
  242. package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
  243. package/dist/plugins/installer/codex/convertSkills.js +33 -0
  244. package/dist/plugins/installer/detectFormat.d.ts +2 -0
  245. package/dist/plugins/installer/detectFormat.js +6 -0
  246. package/dist/plugins/installer/install.d.ts +7 -0
  247. package/dist/plugins/installer/install.js +123 -0
  248. package/dist/plugins/installer/installFromArchive.d.ts +43 -0
  249. package/dist/plugins/installer/installFromArchive.js +134 -0
  250. package/dist/plugins/installer/installFromSource.d.ts +13 -0
  251. package/dist/plugins/installer/installFromSource.js +51 -0
  252. package/dist/plugins/installer/list.d.ts +9 -0
  253. package/dist/plugins/installer/list.js +30 -0
  254. package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
  255. package/dist/plugins/installer/loadPluginAgents.js +27 -0
  256. package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
  257. package/dist/plugins/installer/loadPluginMcp.js +107 -0
  258. package/dist/plugins/installer/parseSource.d.ts +20 -0
  259. package/dist/plugins/installer/parseSource.js +74 -0
  260. package/dist/plugins/installer/paths.d.ts +5 -0
  261. package/dist/plugins/installer/paths.js +25 -0
  262. package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
  263. package/dist/plugins/installer/pruneDisabled.js +73 -0
  264. package/dist/plugins/installer/types.d.ts +52 -0
  265. package/dist/plugins/installer/types.js +28 -0
  266. package/dist/plugins/installer/uninstall.d.ts +2 -0
  267. package/dist/plugins/installer/uninstall.js +18 -0
  268. package/dist/plugins/installer/unzip.d.ts +14 -0
  269. package/dist/plugins/installer/unzip.js +82 -0
  270. package/dist/plugins/installer/update.d.ts +28 -0
  271. package/dist/plugins/installer/update.js +97 -0
  272. package/dist/plugins/loadPluginHooks.d.ts +54 -1
  273. package/dist/plugins/loadPluginHooks.js +83 -1
  274. package/dist/plugins/marketplaceManager.d.ts +15 -1
  275. package/dist/plugins/marketplaceManager.js +58 -4
  276. package/dist/plugins/pluginCommandHook.js +34 -14
  277. package/dist/plugins/pluginContent.d.ts +30 -0
  278. package/dist/plugins/pluginContent.js +83 -0
  279. package/dist/plugins/pluginInstaller.d.ts +34 -0
  280. package/dist/plugins/pluginInstaller.js +168 -35
  281. package/dist/plugins/schemas.js +41 -6
  282. package/dist/plugins/types.d.ts +10 -0
  283. package/dist/preset/index.d.ts +7 -1
  284. package/dist/preset/index.js +112 -6
  285. package/dist/product/types.d.ts +1 -1
  286. package/dist/prompt/composer.d.ts +31 -0
  287. package/dist/prompt/composer.js +95 -25
  288. package/dist/prompt/instruction-scanner.js +5 -3
  289. package/dist/prompt/section-loader.js +1 -0
  290. package/dist/prompt/sections/base.md +1 -0
  291. package/dist/prompt/sections/browser.md +10 -0
  292. package/dist/prompt/sections/coding.md +4 -0
  293. package/dist/prompt/sections/orchestration.md +8 -0
  294. package/dist/protocol/chat-session-manager.d.ts +15 -2
  295. package/dist/protocol/chat-session-manager.js +46 -0
  296. package/dist/protocol/chat-session.d.ts +82 -0
  297. package/dist/protocol/chat-session.js +121 -1
  298. package/dist/protocol/client.d.ts +27 -0
  299. package/dist/protocol/client.js +38 -0
  300. package/dist/protocol/redact.d.ts +50 -0
  301. package/dist/protocol/redact.js +71 -0
  302. package/dist/protocol/server.d.ts +153 -2
  303. package/dist/protocol/server.js +807 -39
  304. package/dist/protocol/tcp-transport.d.ts +45 -0
  305. package/dist/protocol/tcp-transport.js +74 -0
  306. package/dist/protocol/transport.js +3 -2
  307. package/dist/protocol/types.d.ts +69 -0
  308. package/dist/protocol/types.js +22 -0
  309. package/dist/quota/credentials.d.ts +3 -0
  310. package/dist/quota/credentials.js +80 -0
  311. package/dist/quota/index.d.ts +36 -0
  312. package/dist/quota/index.js +155 -0
  313. package/dist/quota/types.d.ts +48 -0
  314. package/dist/quota/types.js +13 -0
  315. package/dist/remote/bridge.d.ts +11 -2
  316. package/dist/remote/bridge.js +61 -33
  317. package/dist/review/review-prompt.d.ts +28 -0
  318. package/dist/review/review-prompt.js +81 -0
  319. package/dist/run/ArtifactTracker.js +5 -4
  320. package/dist/run/EngineRunner.d.ts +27 -1
  321. package/dist/run/EngineRunner.js +46 -8
  322. package/dist/run/FileRunStore.js +40 -11
  323. package/dist/run/RunApprovalBackend.js +25 -5
  324. package/dist/run/RunLock.d.ts +28 -2
  325. package/dist/run/RunLock.js +49 -7
  326. package/dist/run/RunManager.d.ts +12 -0
  327. package/dist/run/RunManager.js +86 -3
  328. package/dist/run/RunQueue.d.ts +1 -0
  329. package/dist/run/RunQueue.js +8 -2
  330. package/dist/run/factory.d.ts +8 -1
  331. package/dist/run/factory.js +1 -0
  332. package/dist/run/index.d.ts +2 -2
  333. package/dist/run/index.js +1 -1
  334. package/dist/run/redirect-target.d.ts +7 -0
  335. package/dist/run/redirect-target.js +13 -0
  336. package/dist/run/types.js +1 -1
  337. package/dist/runtime/background-shell.d.ts +139 -0
  338. package/dist/runtime/background-shell.js +495 -0
  339. package/dist/runtime/output-clean.d.ts +24 -0
  340. package/dist/runtime/output-clean.js +41 -0
  341. package/dist/runtime/ring-file.d.ts +64 -0
  342. package/dist/runtime/ring-file.js +174 -0
  343. package/dist/runtime/safe-spawn.js +15 -34
  344. package/dist/runtime/spawn-common.d.ts +148 -0
  345. package/dist/runtime/spawn-common.js +303 -0
  346. package/dist/runtime/truncate-output.d.ts +22 -0
  347. package/dist/runtime/truncate-output.js +49 -0
  348. package/dist/runtime/utf8-cut.d.ts +11 -0
  349. package/dist/runtime/utf8-cut.js +23 -0
  350. package/dist/services/auto-dream.d.ts +4 -0
  351. package/dist/services/auto-dream.js +26 -26
  352. package/dist/services/browser-open.d.ts +13 -0
  353. package/dist/services/browser-open.js +16 -0
  354. package/dist/services/diagnostics.d.ts +1 -2
  355. package/dist/services/diagnostics.js +12 -7
  356. package/dist/services/dream-consolidation.d.ts +57 -0
  357. package/dist/services/dream-consolidation.js +151 -0
  358. package/dist/services/extract-memories.d.ts +14 -1
  359. package/dist/services/extract-memories.js +45 -6
  360. package/dist/services/memory-orchestrator.d.ts +21 -0
  361. package/dist/services/memory-orchestrator.js +125 -32
  362. package/dist/services/notifier.d.ts +8 -0
  363. package/dist/services/notifier.js +39 -25
  364. package/dist/services/oauth.js +5 -7
  365. package/dist/services/session-memory-sort.d.ts +8 -0
  366. package/dist/services/session-memory-sort.js +9 -0
  367. package/dist/services/session-memory.js +30 -19
  368. package/dist/session/file-history.d.ts +124 -1
  369. package/dist/session/file-history.js +232 -9
  370. package/dist/session/memory.d.ts +116 -2
  371. package/dist/session/memory.js +250 -28
  372. package/dist/session/session-manager.d.ts +63 -1
  373. package/dist/session/session-manager.js +186 -5
  374. package/dist/session/simple-diff.d.ts +23 -0
  375. package/dist/session/simple-diff.js +84 -0
  376. package/dist/session/transcript.d.ts +25 -1
  377. package/dist/session/transcript.js +35 -2
  378. package/dist/session/undo-target.d.ts +67 -0
  379. package/dist/session/undo-target.js +144 -0
  380. package/dist/settings/disk-defaults.d.ts +42 -0
  381. package/dist/settings/disk-defaults.js +33 -0
  382. package/dist/settings/feature-flags.d.ts +64 -0
  383. package/dist/settings/feature-flags.js +61 -0
  384. package/dist/settings/manager.d.ts +101 -1
  385. package/dist/settings/manager.js +345 -15
  386. package/dist/settings/migrate-config.d.ts +45 -0
  387. package/dist/settings/migrate-config.js +125 -0
  388. package/dist/settings/personalization.d.ts +19 -0
  389. package/dist/settings/personalization.js +7 -0
  390. package/dist/settings/schema-export.d.ts +25 -0
  391. package/dist/settings/schema-export.js +38 -0
  392. package/dist/settings/schema.d.ts +1827 -396
  393. package/dist/settings/schema.js +361 -81
  394. package/dist/skills/scanner.d.ts +9 -0
  395. package/dist/skills/scanner.js +30 -2
  396. package/dist/stt/resolve-transcribe.d.ts +31 -0
  397. package/dist/stt/resolve-transcribe.js +108 -0
  398. package/dist/stt/transcribe.d.ts +51 -0
  399. package/dist/stt/transcribe.js +65 -0
  400. package/dist/tool-system/browser-bridge.d.ts +226 -0
  401. package/dist/tool-system/browser-bridge.js +163 -0
  402. package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
  403. package/dist/tool-system/builtin/add-marketplace.js +76 -0
  404. package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
  405. package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
  406. package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
  407. package/dist/tool-system/builtin/agent-notifications.js +9 -3
  408. package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
  409. package/dist/tool-system/builtin/agent-output-file.js +72 -0
  410. package/dist/tool-system/builtin/agent-registry.d.ts +23 -0
  411. package/dist/tool-system/builtin/agent-registry.js +16 -4
  412. package/dist/tool-system/builtin/agent.d.ts +50 -11
  413. package/dist/tool-system/builtin/agent.js +576 -73
  414. package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
  415. package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
  416. package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
  417. package/dist/tool-system/builtin/apply-patch/index.js +7 -3
  418. package/dist/tool-system/builtin/arena.js +6 -7
  419. package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
  420. package/dist/tool-system/builtin/background-jobs.js +124 -0
  421. package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
  422. package/dist/tool-system/builtin/background-shell-tools.js +108 -0
  423. package/dist/tool-system/builtin/background-work.d.ts +67 -0
  424. package/dist/tool-system/builtin/background-work.js +86 -0
  425. package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
  426. package/dist/tool-system/builtin/bash-output-style.js +40 -0
  427. package/dist/tool-system/builtin/bash.d.ts +5 -2
  428. package/dist/tool-system/builtin/bash.js +98 -62
  429. package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
  430. package/dist/tool-system/builtin/browser-tools.js +312 -0
  431. package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
  432. package/dist/tool-system/builtin/cancel-goal.js +64 -0
  433. package/dist/tool-system/builtin/check-quota.d.ts +15 -0
  434. package/dist/tool-system/builtin/check-quota.js +34 -0
  435. package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
  436. package/dist/tool-system/builtin/complete-goal.js +45 -0
  437. package/dist/tool-system/builtin/config.js +7 -0
  438. package/dist/tool-system/builtin/cron.d.ts +7 -0
  439. package/dist/tool-system/builtin/cron.js +105 -9
  440. package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
  441. package/dist/tool-system/builtin/drive-claude-code.js +157 -0
  442. package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
  443. package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
  444. package/dist/tool-system/builtin/edit.d.ts +2 -1
  445. package/dist/tool-system/builtin/edit.js +21 -12
  446. package/dist/tool-system/builtin/eol.d.ts +29 -0
  447. package/dist/tool-system/builtin/eol.js +37 -0
  448. package/dist/tool-system/builtin/file-cache.d.ts +6 -0
  449. package/dist/tool-system/builtin/file-cache.js +8 -0
  450. package/dist/tool-system/builtin/generate-image.d.ts +60 -0
  451. package/dist/tool-system/builtin/generate-image.js +374 -0
  452. package/dist/tool-system/builtin/generate-video.d.ts +55 -0
  453. package/dist/tool-system/builtin/generate-video.js +361 -0
  454. package/dist/tool-system/builtin/grep.js +6 -2
  455. package/dist/tool-system/builtin/image-providers.d.ts +86 -0
  456. package/dist/tool-system/builtin/image-providers.js +190 -0
  457. package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
  458. package/dist/tool-system/builtin/image-uploader.js +74 -0
  459. package/dist/tool-system/builtin/index.d.ts +24 -1
  460. package/dist/tool-system/builtin/index.js +310 -25
  461. package/dist/tool-system/builtin/mcp-tools.js +23 -3
  462. package/dist/tool-system/builtin/memory.js +45 -7
  463. package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
  464. package/dist/tool-system/builtin/notebook-edit.js +1 -1
  465. package/dist/tool-system/builtin/powershell.js +4 -1
  466. package/dist/tool-system/builtin/read.d.ts +2 -1
  467. package/dist/tool-system/builtin/read.js +11 -3
  468. package/dist/tool-system/builtin/repl.js +4 -1
  469. package/dist/tool-system/builtin/skill.js +9 -0
  470. package/dist/tool-system/builtin/sleep.js +12 -5
  471. package/dist/tool-system/builtin/task.js +4 -1
  472. package/dist/tool-system/builtin/tool-search.js +25 -7
  473. package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
  474. package/dist/tool-system/builtin/update-automation-memory.js +60 -0
  475. package/dist/tool-system/builtin/video-providers.d.ts +154 -0
  476. package/dist/tool-system/builtin/video-providers.js +235 -0
  477. package/dist/tool-system/builtin/view-image.d.ts +18 -0
  478. package/dist/tool-system/builtin/view-image.js +96 -0
  479. package/dist/tool-system/builtin/web-fetch.js +12 -2
  480. package/dist/tool-system/builtin/web-search.d.ts +4 -1
  481. package/dist/tool-system/builtin/web-search.js +57 -10
  482. package/dist/tool-system/builtin/worktree.d.ts +2 -1
  483. package/dist/tool-system/builtin/worktree.js +31 -4
  484. package/dist/tool-system/builtin/write.d.ts +2 -1
  485. package/dist/tool-system/builtin/write.js +1 -1
  486. package/dist/tool-system/context.d.ts +166 -6
  487. package/dist/tool-system/executor.d.ts +3 -2
  488. package/dist/tool-system/executor.js +197 -119
  489. package/dist/tool-system/investigation-guard.d.ts +4 -1
  490. package/dist/tool-system/investigation-guard.js +20 -4
  491. package/dist/tool-system/mcp-manager.d.ts +78 -16
  492. package/dist/tool-system/mcp-manager.js +357 -28
  493. package/dist/tool-system/path-policy.d.ts +99 -0
  494. package/dist/tool-system/path-policy.js +578 -0
  495. package/dist/tool-system/permission.d.ts +36 -1
  496. package/dist/tool-system/permission.js +322 -117
  497. package/dist/tool-system/plan-mode-allowlist.d.ts +32 -0
  498. package/dist/tool-system/plan-mode-allowlist.js +65 -0
  499. package/dist/tool-system/registry.d.ts +1 -0
  500. package/dist/tool-system/registry.js +26 -1
  501. package/dist/tool-system/sandbox/index.d.ts +8 -0
  502. package/dist/tool-system/sandbox/index.js +7 -2
  503. package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
  504. package/dist/tool-system/validate-tool-metadata.js +63 -0
  505. package/dist/tool-system/validation.d.ts +10 -0
  506. package/dist/tool-system/validation.js +16 -3
  507. package/dist/types.d.ts +301 -15
  508. package/dist/updater.js +20 -9
  509. package/dist/utils/envUtils.d.ts +0 -9
  510. package/dist/utils/envUtils.js +3 -28
  511. package/dist/utils/exec.d.ts +40 -0
  512. package/dist/utils/exec.js +144 -0
  513. package/dist/utils/format.js +4 -2
  514. package/dist/utils/json.d.ts +12 -0
  515. package/dist/utils/json.js +92 -0
  516. package/dist/utils/lockfile.js +9 -2
  517. package/dist/utils/theme.d.ts +7 -1
  518. package/dist/utils/theme.js +5 -3
  519. package/dist/utils/toolDisplay.js +0 -1
  520. package/package.json +14 -7
  521. package/dist/agent/coordinator.d.ts +0 -49
  522. package/dist/agent/coordinator.js +0 -77
  523. package/dist/settings/manager.test.js +0 -73
  524. package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
  525. package/dist/tool-system/builtin/remote-trigger.js +0 -54
  526. package/dist/tool-system/builtin/send-message.d.ts +0 -6
  527. package/dist/tool-system/builtin/send-message.js +0 -47
  528. /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
@@ -0,0 +1,123 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { mkdir, writeFile, readFile, readdir, cp, rm, rename, } from "node:fs/promises";
3
+ import { join, relative } from "node:path";
4
+ import { detectPluginFormat } from "./detectFormat.js";
5
+ import { pluginInstallDir, pluginsRoot, assertSafePluginName } from "./paths.js";
6
+ import { CodexPluginManifest, PluginInstallError } from "./types.js";
7
+ import { convertCodexAgentToml } from "./codex/convertAgents.js";
8
+ import { resolveCodexMcpServers } from "./codex/convertMcp.js";
9
+ import { copyCodexSkills } from "./codex/convertSkills.js";
10
+ import { copyCodexCommands } from "./codex/convertCommands.js";
11
+ import { appendInstallEntry, pluginInstallKey } from "../installedPlugins.js";
12
+ /**
13
+ * Install a local plugin directory into ~/.code-shell/plugins/<name>/.
14
+ * Builds into a temp sibling dir, then renames into place — a conversion
15
+ * failure leaves nothing behind. `installedAt` is passed in (caller stamps the
16
+ * timestamp) to keep this function pure of the unavailable Date.now().
17
+ */
18
+ export async function installPluginFromPath(sourceDir, name, installedAt) {
19
+ assertSafePluginName(name);
20
+ if (!existsSync(sourceDir) || !statSync(sourceDir).isDirectory()) {
21
+ throw new PluginInstallError(`source is not a directory: ${sourceDir}`);
22
+ }
23
+ const finalDir = pluginInstallDir(name);
24
+ if (existsSync(finalDir)) {
25
+ throw new PluginInstallError(`plugin '${name}' already installed; uninstall first or rename the source`);
26
+ }
27
+ await mkdir(pluginsRoot(), { recursive: true });
28
+ const tmpDir = join(pluginsRoot(), `.tmp-${name}-${process.pid}`);
29
+ await rm(tmpDir, { recursive: true, force: true });
30
+ await mkdir(tmpDir, { recursive: true });
31
+ try {
32
+ const format = detectPluginFormat(sourceDir);
33
+ let meta;
34
+ if (format === "cc") {
35
+ // Async cp: a recursive copy of a whole plugin dir is the dominant cost
36
+ // here; awaiting it yields the event loop so the Electron main process
37
+ // keeps answering IPC (no UI freeze during install).
38
+ await cp(sourceDir, tmpDir, { recursive: true });
39
+ // Read the declared version from .claude-plugin/plugin.json so the
40
+ // install record (and the UI's "installed version" chip) shows e.g.
41
+ // "v0.1.0" instead of falling back to the literal "local". Best-effort:
42
+ // CC plugins commonly omit version, and the file may be absent/malformed.
43
+ const version = await readCcPluginVersion(sourceDir);
44
+ meta = { name, format: "cc", version, source: sourceDir, installedAt };
45
+ }
46
+ else {
47
+ const manifest = CodexPluginManifest.parse(JSON.parse(await readFile(join(sourceDir, ".codex-plugin", "plugin.json"), "utf-8")));
48
+ // skills (verbatim copy)
49
+ await copyCodexSkills(sourceDir, tmpDir);
50
+ // agents (TOML → MD)
51
+ await convertAgentsInto(sourceDir, tmpDir, name);
52
+ // prompts/ (+ commands/) → commands/ (Codex slash commands == CC commands)
53
+ await copyCodexCommands(sourceDir, tmpDir);
54
+ // mcp → mcp-servers.json keyed <plugin>:<server>
55
+ const servers = resolveCodexMcpServers(sourceDir, manifest.mcpServers);
56
+ const keyed = {};
57
+ for (const [serverName, cfg] of Object.entries(servers)) {
58
+ const key = `${name}:${serverName}`;
59
+ keyed[key] = { ...cfg, name: key };
60
+ }
61
+ if (Object.keys(keyed).length > 0) {
62
+ await writeFile(join(tmpDir, "mcp-servers.json"), JSON.stringify(keyed, null, 2));
63
+ }
64
+ meta = { name, format: "codex", version: manifest.version, source: sourceDir, installedAt };
65
+ }
66
+ await writeFile(join(tmpDir, ".cs-meta.json"), JSON.stringify(meta, null, 2));
67
+ await rename(tmpDir, finalDir);
68
+ // Register so existing loaders (scanInstalledPlugins / loadPluginHooks)
69
+ // discover this local install. Marketplace tag "local" distinguishes it
70
+ // from cache/marketplace installs.
71
+ appendInstallEntry(pluginInstallKey(name, "local"), {
72
+ scope: "user",
73
+ installPath: finalDir,
74
+ version: meta.version ?? "local",
75
+ installedAt,
76
+ lastUpdated: installedAt,
77
+ });
78
+ return finalDir;
79
+ }
80
+ catch (err) {
81
+ await rm(tmpDir, { recursive: true, force: true });
82
+ throw err;
83
+ }
84
+ }
85
+ /**
86
+ * Best-effort read of a CC plugin's declared version from
87
+ * <sourceDir>/.claude-plugin/plugin.json. Returns undefined when the file is
88
+ * absent, unparseable, or has no string `version` — the caller then records the
89
+ * install without a version (UI shows the source tag instead of a number).
90
+ */
91
+ async function readCcPluginVersion(sourceDir) {
92
+ try {
93
+ const raw = await readFile(join(sourceDir, ".claude-plugin", "plugin.json"), "utf-8");
94
+ const v = JSON.parse(raw).version;
95
+ return typeof v === "string" && v.length > 0 ? v : undefined;
96
+ }
97
+ catch {
98
+ return undefined;
99
+ }
100
+ }
101
+ /** Walk <sourceDir>/agents/**.toml → <destDir>/agents/**.md (structure preserved). */
102
+ async function convertAgentsInto(sourceDir, destDir, pluginName) {
103
+ const agentsSrc = join(sourceDir, "agents");
104
+ if (!existsSync(agentsSrc))
105
+ return;
106
+ const walk = async (dir) => {
107
+ for (const dirent of await readdir(dir, { withFileTypes: true })) {
108
+ const abs = join(dir, dirent.name);
109
+ if (dirent.isDirectory()) {
110
+ await walk(abs);
111
+ continue;
112
+ }
113
+ if (!dirent.name.endsWith(".toml"))
114
+ continue;
115
+ const rel = relative(agentsSrc, abs).replace(/\.toml$/, ".md");
116
+ const outPath = join(destDir, "agents", rel);
117
+ await mkdir(join(outPath, ".."), { recursive: true });
118
+ const md = convertCodexAgentToml(await readFile(abs, "utf-8"), rel, pluginName);
119
+ await writeFile(outPath, md);
120
+ }
121
+ };
122
+ await walk(agentsSrc);
123
+ }
@@ -0,0 +1,43 @@
1
+ /** Options for the unified local-install entry. */
2
+ export interface InstallLocalOptions {
3
+ /**
4
+ * When the target name is already installed, replace it instead of throwing
5
+ * "already installed". The replace is atomic (rename-backup + rollback via
6
+ * {@link reinstallAtomic}), so a failed overwrite keeps the old version and
7
+ * its registration intact. Unlike a manual uninstall+install, this preserves
8
+ * the user's disable flags in settings (an upgrade is not a removal).
9
+ */
10
+ overwrite?: boolean;
11
+ }
12
+ /**
13
+ * Install a local plugin from a .zip archive.
14
+ *
15
+ * Mirrors installFromSource (the git path): extract to a private temp dir,
16
+ * locate the plugin root inside it, hand off to the local installer (which
17
+ * does CC/Codex detect + convert + register), then always clean up the temp
18
+ * dir. On any failure nothing is left behind.
19
+ *
20
+ * `name` is optional — when omitted it is derived from the plugin manifest
21
+ * (`name` field) or, failing that, the archive's top-level directory. The
22
+ * caller stamps `installedAt` to keep this pure of the unavailable Date.now().
23
+ */
24
+ export declare function installPluginFromArchive(zipPath: string, installedAt: string, name?: string, options?: InstallLocalOptions): Promise<{
25
+ dir: string;
26
+ name: string;
27
+ }>;
28
+ /**
29
+ * Unified local-install entry for the desktop/UI: takes either a directory or
30
+ * a .zip and installs it as a global plugin, deriving the name when not given.
31
+ * The host (which has Date.now) stamps `installedAt`.
32
+ *
33
+ * For a directory we still run findPluginRoot/deriveName so a user can point at
34
+ * a repo checkout whose plugin sits one level down, and so the name comes from
35
+ * the manifest rather than forcing the caller to guess it.
36
+ */
37
+ export declare function installLocalPlugin(input: {
38
+ kind: "dir" | "zip";
39
+ path: string;
40
+ }, installedAt: string, name?: string, options?: InstallLocalOptions): Promise<{
41
+ dir: string;
42
+ name: string;
43
+ }>;
@@ -0,0 +1,134 @@
1
+ import { existsSync, statSync } from "node:fs";
2
+ import { mkdtemp, readFile, readdir, rm } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { extractZip } from "./unzip.js";
6
+ import { installPluginFromPath } from "./install.js";
7
+ import { reinstallAtomic } from "./update.js";
8
+ import { pluginInstallDir } from "./paths.js";
9
+ import { PluginInstallError } from "./types.js";
10
+ /**
11
+ * Install `root` as plugin `name`, atomically replacing an already-installed
12
+ * plugin of the same name when `overwrite` is set. When no same-name plugin
13
+ * exists this is a plain install (overwrite is a no-op). `root` must stay valid
14
+ * for the duration of the call (zip callers keep their extracted temp dir alive
15
+ * until this resolves).
16
+ */
17
+ async function installRootMaybeOverwrite(root, resolvedName, installedAt, overwrite) {
18
+ const finalDir = pluginInstallDir(resolvedName);
19
+ if (overwrite && existsSync(finalDir)) {
20
+ await reinstallAtomic(resolvedName, root, () => installPluginFromPath(root, resolvedName, installedAt));
21
+ return finalDir;
22
+ }
23
+ return installPluginFromPath(root, resolvedName, installedAt);
24
+ }
25
+ /**
26
+ * Install a local plugin from a .zip archive.
27
+ *
28
+ * Mirrors installFromSource (the git path): extract to a private temp dir,
29
+ * locate the plugin root inside it, hand off to the local installer (which
30
+ * does CC/Codex detect + convert + register), then always clean up the temp
31
+ * dir. On any failure nothing is left behind.
32
+ *
33
+ * `name` is optional — when omitted it is derived from the plugin manifest
34
+ * (`name` field) or, failing that, the archive's top-level directory. The
35
+ * caller stamps `installedAt` to keep this pure of the unavailable Date.now().
36
+ */
37
+ export async function installPluginFromArchive(zipPath, installedAt, name, options) {
38
+ if (!existsSync(zipPath) || !statSync(zipPath).isFile()) {
39
+ throw new PluginInstallError(`archive is not a file: ${zipPath}`);
40
+ }
41
+ const tmp = await mkdtemp(join(tmpdir(), "cs-tmp-zip-"));
42
+ try {
43
+ await extractZip(zipPath, tmp);
44
+ const root = await findPluginRoot(tmp);
45
+ const resolvedName = normalizePluginName(name ?? (await deriveName(root)));
46
+ // Overwrite (when set) runs inside this try so the extracted `root` is still
47
+ // present while reinstallAtomic installs from it; the finally removes tmp.
48
+ const dir = await installRootMaybeOverwrite(root, resolvedName, installedAt, options?.overwrite ?? false);
49
+ return { dir, name: resolvedName };
50
+ }
51
+ finally {
52
+ await rm(tmp, { recursive: true, force: true });
53
+ }
54
+ }
55
+ /**
56
+ * Unified local-install entry for the desktop/UI: takes either a directory or
57
+ * a .zip and installs it as a global plugin, deriving the name when not given.
58
+ * The host (which has Date.now) stamps `installedAt`.
59
+ *
60
+ * For a directory we still run findPluginRoot/deriveName so a user can point at
61
+ * a repo checkout whose plugin sits one level down, and so the name comes from
62
+ * the manifest rather than forcing the caller to guess it.
63
+ */
64
+ export async function installLocalPlugin(input, installedAt, name, options) {
65
+ if (input.kind === "zip") {
66
+ return installPluginFromArchive(input.path, installedAt, name, options);
67
+ }
68
+ if (!existsSync(input.path) || !statSync(input.path).isDirectory()) {
69
+ throw new PluginInstallError(`source is not a directory: ${input.path}`);
70
+ }
71
+ const root = await findPluginRoot(input.path);
72
+ const resolvedName = normalizePluginName(name ?? (await deriveName(root)));
73
+ const dir = await installRootMaybeOverwrite(root, resolvedName, installedAt, options?.overwrite ?? false);
74
+ return { dir, name: resolvedName };
75
+ }
76
+ /**
77
+ * A plugin root is a dir that holds a recognizable manifest or component dir.
78
+ * Zip archives commonly wrap everything in a single top-level folder, so if
79
+ * `dir` itself isn't a plugin root but contains exactly one subdirectory, dive
80
+ * one level. Only one level — deeper nesting is treated as malformed.
81
+ */
82
+ async function findPluginRoot(dir) {
83
+ if (looksLikePluginRoot(dir))
84
+ return dir;
85
+ const entries = await readdir(dir, { withFileTypes: true });
86
+ const subDirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith("."));
87
+ if (subDirs.length === 1) {
88
+ const nested = join(dir, subDirs[0].name);
89
+ if (looksLikePluginRoot(nested))
90
+ return nested;
91
+ }
92
+ throw new PluginInstallError("no plugin found in archive (expected .claude-plugin/plugin.json, .codex-plugin/plugin.json, or a skills/commands/agents/hooks directory)");
93
+ }
94
+ function looksLikePluginRoot(dir) {
95
+ return (existsSync(join(dir, ".claude-plugin", "plugin.json")) ||
96
+ existsSync(join(dir, ".codex-plugin", "plugin.json")) ||
97
+ ["skills", "commands", "agents", "hooks"].some((d) => existsSync(join(dir, d))));
98
+ }
99
+ /** Read the `name` field from a CC or Codex manifest; fall back to the dir name. */
100
+ async function deriveName(root) {
101
+ for (const rel of [
102
+ [".claude-plugin", "plugin.json"],
103
+ [".codex-plugin", "plugin.json"],
104
+ ]) {
105
+ const manifestPath = join(root, ...rel);
106
+ if (!existsSync(manifestPath))
107
+ continue;
108
+ try {
109
+ const parsed = JSON.parse(await readFile(manifestPath, "utf-8"));
110
+ if (typeof parsed.name === "string" && parsed.name.trim())
111
+ return parsed.name.trim();
112
+ }
113
+ catch {
114
+ // Malformed manifest → fall through to dir-name derivation.
115
+ }
116
+ }
117
+ return root.split(/[\\/]/).filter(Boolean).pop() ?? "plugin";
118
+ }
119
+ /**
120
+ * Coerce an arbitrary derived name into a safe single path segment:
121
+ * lowercase, only [a-z0-9._-], collapse the rest to '-'. assertSafePluginName
122
+ * (called by installPluginFromPath) rejects separators outright; this makes a
123
+ * manifest name like "My Plugin" usable instead of erroring.
124
+ */
125
+ function normalizePluginName(raw) {
126
+ const cleaned = raw
127
+ .trim()
128
+ .toLowerCase()
129
+ .replace(/[^a-z0-9._-]+/g, "-")
130
+ .replace(/^[-.]+|[-.]+$/g, "");
131
+ if (!cleaned)
132
+ throw new PluginInstallError(`cannot derive a valid plugin name from: ${JSON.stringify(raw)}`);
133
+ return cleaned;
134
+ }
@@ -0,0 +1,13 @@
1
+ import type { ParsedSource } from "./parseSource.js";
2
+ /**
3
+ * Remote install orchestrator: a thin bridge over the existing pieces. Clone
4
+ * the git source to a private temp dir, hand the (sub)directory to the local
5
+ * installer (which does CC/Codex detect + convert + register), then rewrite
6
+ * the recorded `.cs-meta.json` source back to the original git string so
7
+ * `plugin list`/`update` see the git source instead of the throwaway clone.
8
+ *
9
+ * Guarantees: on any failure nothing is left behind — the temp clone is always
10
+ * removed, and `installPluginFromPath` itself leaves no half-built install dir.
11
+ * See spec docs/superpowers/specs/2026-05-29-plugin-remote-install-design.md.
12
+ */
13
+ export declare function installPluginFromSource(parsed: ParsedSource, name: string, installedAt: string): Promise<string>;
@@ -0,0 +1,51 @@
1
+ import { existsSync, mkdtempSync, readFileSync, writeFileSync, rmSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { tmpdir } from "node:os";
4
+ import { gitClone, gitRevParseHead } from "../gitOps.js";
5
+ import { installPluginFromPath } from "./install.js";
6
+ import { pluginMetaPath } from "./paths.js";
7
+ import { PluginInstallError } from "./types.js";
8
+ /**
9
+ * Remote install orchestrator: a thin bridge over the existing pieces. Clone
10
+ * the git source to a private temp dir, hand the (sub)directory to the local
11
+ * installer (which does CC/Codex detect + convert + register), then rewrite
12
+ * the recorded `.cs-meta.json` source back to the original git string so
13
+ * `plugin list`/`update` see the git source instead of the throwaway clone.
14
+ *
15
+ * Guarantees: on any failure nothing is left behind — the temp clone is always
16
+ * removed, and `installPluginFromPath` itself leaves no half-built install dir.
17
+ * See spec docs/superpowers/specs/2026-05-29-plugin-remote-install-design.md.
18
+ */
19
+ export async function installPluginFromSource(parsed, name, installedAt) {
20
+ if (parsed.kind !== "remote") {
21
+ throw new PluginInstallError("installPluginFromSource expects a remote source");
22
+ }
23
+ const tmp = mkdtempSync(join(tmpdir(), "cs-tmp-clone-"));
24
+ try {
25
+ const clone = await gitClone(parsed.url, tmp, { ref: parsed.ref, full: true });
26
+ if (!clone.ok) {
27
+ throw new PluginInstallError(`clone failed: ${clone.error}`);
28
+ }
29
+ const realSrc = parsed.subdir ? join(tmp, parsed.subdir) : tmp;
30
+ if (!existsSync(realSrc) || !statSync(realSrc).isDirectory()) {
31
+ throw new PluginInstallError(`subdir not found in repo: ${parsed.subdir}`);
32
+ }
33
+ const dir = await installPluginFromPath(realSrc, name, installedAt);
34
+ // Rewrite source: realSrc is the throwaway clone path; record the git
35
+ // string so list/update can re-clone later.
36
+ const metaPath = pluginMetaPath(name);
37
+ const meta = JSON.parse(readFileSync(metaPath, "utf-8"));
38
+ meta.source = parsed.raw;
39
+ // Record the cloned repo's HEAD sha so `checkPluginUpdate` can compare it
40
+ // against `git ls-remote` later. A failed rev-parse only means "can't check
41
+ // updates", never an install failure — so omit commit and carry on.
42
+ const head = await gitRevParseHead(tmp);
43
+ if (head.ok)
44
+ meta.commit = head.stdout;
45
+ writeFileSync(metaPath, JSON.stringify(meta, null, 2));
46
+ return dir;
47
+ }
48
+ finally {
49
+ rmSync(tmp, { recursive: true, force: true });
50
+ }
51
+ }
@@ -0,0 +1,9 @@
1
+ export interface PluginListRow {
2
+ name: string;
3
+ format: "cc" | "codex";
4
+ version?: string;
5
+ source: string;
6
+ installedAt: string;
7
+ }
8
+ /** Read .cs-meta.json from each registered plugin dir that has one (local installs). */
9
+ export declare function listInstalledPlugins(): PluginListRow[];
@@ -0,0 +1,30 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { readInstalledPlugins } from "../installedPlugins.js";
4
+ import { CSMeta } from "./types.js";
5
+ /** Read .cs-meta.json from each registered plugin dir that has one (local installs). */
6
+ export function listInstalledPlugins() {
7
+ const rows = [];
8
+ const data = readInstalledPlugins();
9
+ for (const entries of Object.values(data.plugins)) {
10
+ for (const entry of entries) {
11
+ const metaPath = join(entry.installPath, ".cs-meta.json");
12
+ if (!existsSync(metaPath))
13
+ continue;
14
+ try {
15
+ const meta = CSMeta.parse(JSON.parse(readFileSync(metaPath, "utf-8")));
16
+ rows.push({
17
+ name: meta.name,
18
+ format: meta.format,
19
+ version: meta.version,
20
+ source: meta.source,
21
+ installedAt: meta.installedAt,
22
+ });
23
+ }
24
+ catch {
25
+ // not a local cs-managed install; skip
26
+ }
27
+ }
28
+ }
29
+ return rows;
30
+ }
@@ -0,0 +1,3 @@
1
+ import type { AgentSourceDir } from "../../agent/agent-definition-registry.js";
2
+ /** Agent source dirs contributed by installed plugins (each <installPath>/agents). */
3
+ export declare function pluginAgentDirs(disabledPlugins?: string[]): AgentSourceDir[];
@@ -0,0 +1,27 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { readInstalledPlugins } from "../installedPlugins.js";
4
+ function pluginNameFromKey(key) {
5
+ const at = key.lastIndexOf("@");
6
+ return at > 0 ? key.slice(0, at) : key;
7
+ }
8
+ /** Agent source dirs contributed by installed plugins (each <installPath>/agents). */
9
+ export function pluginAgentDirs(disabledPlugins = []) {
10
+ const disabled = new Set(disabledPlugins);
11
+ const out = [];
12
+ const data = readInstalledPlugins();
13
+ for (const [key, entries] of Object.entries(data.plugins)) {
14
+ const pluginName = pluginNameFromKey(key);
15
+ if (disabled.has(pluginName))
16
+ continue;
17
+ for (const entry of entries) {
18
+ const dir = join(entry.installPath, "agents");
19
+ // Carry pluginName so a plugin agent's bare skill allowlist
20
+ // (`director-skill`) can be namespaced to `<pluginName>:director-skill`
21
+ // at spawn time — see resolveAgentTypeOverrides.
22
+ if (existsSync(dir))
23
+ out.push({ dir, source: "plugin", pluginName });
24
+ }
25
+ }
26
+ return out;
27
+ }
@@ -0,0 +1,14 @@
1
+ import type { MCPServerConfig, MCPServerOverride } from "../../types.js";
2
+ /**
3
+ * Merge each registered plugin's MCP servers into a copy of `base`.
4
+ * Plugin keys are `<plugin>:<server>`. A key already present in `base`
5
+ * (user-configured) is NOT overwritten. Disabled plugins are skipped.
6
+ *
7
+ * `overrides` lets the user *supplement* a plugin server's env/credential
8
+ * fields without editing the plugin's manifest: for a plugin-sourced server,
9
+ * the override's {@link OVERRIDE_FIELDS} are layered on top (override wins),
10
+ * while command/args/url/transport stay from the plugin. Overrides do NOT
11
+ * apply to user-added (base) servers — those are edited via `mcpServers`
12
+ * directly — and an override for an unknown/disabled server has no effect.
13
+ */
14
+ export declare function mergePluginMcpServers(base: Record<string, MCPServerConfig>, disabledPlugins?: string[], overrides?: Record<string, MCPServerOverride>): Record<string, MCPServerConfig>;
@@ -0,0 +1,107 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { readInstalledPlugins } from "../installedPlugins.js";
4
+ function pluginNameFromKey(key) {
5
+ const at = key.lastIndexOf("@");
6
+ return at > 0 ? key.slice(0, at) : key;
7
+ }
8
+ /**
9
+ * Layer a user override's supplement fields onto a plugin server config.
10
+ *
11
+ * Only env/credential fields are picked — command/args/url/transport are
12
+ * deliberately NOT carried, because those are the plugin's identity and must
13
+ * keep coming from the plugin manifest so a plugin update can change them
14
+ * without the user being stuck on a stale shadow copy. This explicit pick is
15
+ * defense-in-depth on top of the schema's `.strict()`, so a hand-edited
16
+ * settings file can never smuggle those fields in.
17
+ */
18
+ function applyOverride(pluginConfig, override) {
19
+ if (!override)
20
+ return pluginConfig;
21
+ const supplement = {};
22
+ if (override.env !== undefined)
23
+ supplement.env = override.env;
24
+ if (override.envVars !== undefined)
25
+ supplement.envVars = override.envVars;
26
+ if (override.credentialRef !== undefined)
27
+ supplement.credentialRef = override.credentialRef;
28
+ if (override.bearerTokenEnvVar !== undefined)
29
+ supplement.bearerTokenEnvVar = override.bearerTokenEnvVar;
30
+ if (override.envHeaders !== undefined)
31
+ supplement.envHeaders = override.envHeaders;
32
+ return { ...pluginConfig, ...supplement };
33
+ }
34
+ /**
35
+ * Read a single plugin's MCP servers, already keyed `<plugin>:<server>`.
36
+ *
37
+ * Two on-disk shapes are supported:
38
+ * - `mcp-servers.json` — the Codex-install product: already keyed + named.
39
+ * - `.mcp.json` — what a CC plugin ships verbatim (Docker's mcp-toolkit etc.).
40
+ * It uses a `{ mcpServers: {...} }` wrapper with bare server names; we unwrap
41
+ * it and apply the `<plugin>:` prefix + `name` so it matches the keyed shape.
42
+ *
43
+ * `mcp-servers.json` wins if both exist. Malformed files yield {} (must not
44
+ * break startup).
45
+ */
46
+ function readPluginMcp(installPath, pluginName) {
47
+ const keyedPath = join(installPath, "mcp-servers.json");
48
+ if (existsSync(keyedPath)) {
49
+ try {
50
+ return JSON.parse(readFileSync(keyedPath, "utf-8"));
51
+ }
52
+ catch {
53
+ return {};
54
+ }
55
+ }
56
+ const rawPath = join(installPath, ".mcp.json");
57
+ if (existsSync(rawPath)) {
58
+ let parsed;
59
+ try {
60
+ parsed = JSON.parse(readFileSync(rawPath, "utf-8"));
61
+ }
62
+ catch {
63
+ return {};
64
+ }
65
+ const servers = parsed && typeof parsed === "object" && "mcpServers" in parsed
66
+ ? parsed.mcpServers ?? {}
67
+ : parsed ?? {};
68
+ const keyed = {};
69
+ for (const [serverName, cfg] of Object.entries(servers)) {
70
+ const key = `${pluginName}:${serverName}`;
71
+ keyed[key] = { ...cfg, name: key };
72
+ }
73
+ return keyed;
74
+ }
75
+ return {};
76
+ }
77
+ /**
78
+ * Merge each registered plugin's MCP servers into a copy of `base`.
79
+ * Plugin keys are `<plugin>:<server>`. A key already present in `base`
80
+ * (user-configured) is NOT overwritten. Disabled plugins are skipped.
81
+ *
82
+ * `overrides` lets the user *supplement* a plugin server's env/credential
83
+ * fields without editing the plugin's manifest: for a plugin-sourced server,
84
+ * the override's {@link OVERRIDE_FIELDS} are layered on top (override wins),
85
+ * while command/args/url/transport stay from the plugin. Overrides do NOT
86
+ * apply to user-added (base) servers — those are edited via `mcpServers`
87
+ * directly — and an override for an unknown/disabled server has no effect.
88
+ */
89
+ export function mergePluginMcpServers(base, disabledPlugins = [], overrides = {}) {
90
+ const disabled = new Set(disabledPlugins);
91
+ const merged = { ...base };
92
+ const data = readInstalledPlugins();
93
+ for (const [key, entries] of Object.entries(data.plugins)) {
94
+ const pluginName = pluginNameFromKey(key);
95
+ if (disabled.has(pluginName))
96
+ continue;
97
+ for (const entry of entries) {
98
+ const servers = readPluginMcp(entry.installPath, pluginName);
99
+ for (const [k, cfg] of Object.entries(servers)) {
100
+ if (k in merged)
101
+ continue; // user / earlier wins
102
+ merged[k] = applyOverride(cfg, overrides[k]);
103
+ }
104
+ }
105
+ }
106
+ return merged;
107
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Result of classifying a `plugin install <source>` argument. Pure parse — no
3
+ * I/O, no execution. `local` resolves to an absolute path; `remote` carries a
4
+ * git-cloneable URL plus optional ref/subdir and the original raw string
5
+ * (written back into .cs-meta.json so `plugin list`/`update` see the git
6
+ * source, not the throwaway clone path). See spec
7
+ * docs/superpowers/specs/2026-05-29-plugin-remote-install-design.md §4–§5.
8
+ */
9
+ export type ParsedSource = {
10
+ kind: "local";
11
+ path: string;
12
+ } | {
13
+ kind: "remote";
14
+ url: string;
15
+ ref?: string;
16
+ subdir?: string;
17
+ raw: string;
18
+ inferredName: string;
19
+ };
20
+ export declare function parseSource(input: string): ParsedSource;
@@ -0,0 +1,74 @@
1
+ import { resolve } from "node:path";
2
+ import { githubRepoToCloneUrl } from "../gitOps.js";
3
+ /** SSH shorthand `git@host:org/repo.git` — has a `:` after the `git@host` part. */
4
+ function isSshUrl(s) {
5
+ return /^[^/]+@[^/]+:/.test(s) && !s.includes("://");
6
+ }
7
+ function isRemote(s) {
8
+ return (s.startsWith("github:") ||
9
+ s.startsWith("https://") ||
10
+ s.startsWith("http://") ||
11
+ s.startsWith("git://") ||
12
+ s.startsWith("file://") ||
13
+ isSshUrl(s));
14
+ }
15
+ /** Last path segment of a repo url/path, with a trailing `.git` stripped. */
16
+ function repoNameFromUrl(url) {
17
+ const noGit = url.replace(/\.git$/, "");
18
+ const seg = noGit.split(/[/:]/).filter(Boolean).pop() ?? noGit;
19
+ return seg;
20
+ }
21
+ /** Last path segment of a subdir. */
22
+ function lastSegment(p) {
23
+ return p.split("/").filter(Boolean).pop() ?? p;
24
+ }
25
+ export function parseSource(input) {
26
+ if (!isRemote(input)) {
27
+ return { kind: "local", path: resolve(input) };
28
+ }
29
+ const raw = input;
30
+ // 1. Split off `#subdir` (last `#`).
31
+ let rest = input;
32
+ let subdir;
33
+ const hashIdx = rest.indexOf("#");
34
+ if (hashIdx >= 0) {
35
+ subdir = rest.slice(hashIdx + 1) || undefined;
36
+ rest = rest.slice(0, hashIdx);
37
+ }
38
+ // 2. Split off `@ref`. SSH form `git@host:...` contains its own `@`, so
39
+ // strip the leading `user@` first, then look for a ref `@` in the tail.
40
+ let ref;
41
+ let base = rest;
42
+ if (isSshUrl(rest)) {
43
+ const at = rest.indexOf("@");
44
+ const head = rest.slice(0, at + 1); // "git@"
45
+ const tail = rest.slice(at + 1); // "host:org/repo.git@ref"
46
+ const tailAt = tail.lastIndexOf("@");
47
+ if (tailAt >= 0) {
48
+ ref = tail.slice(tailAt + 1) || undefined;
49
+ base = head + tail.slice(0, tailAt);
50
+ }
51
+ }
52
+ else {
53
+ const at = rest.lastIndexOf("@");
54
+ if (at >= 0) {
55
+ ref = rest.slice(at + 1) || undefined;
56
+ base = rest.slice(0, at);
57
+ }
58
+ }
59
+ // 3. Normalize url.
60
+ let url;
61
+ if (base.startsWith("github:")) {
62
+ url = githubRepoToCloneUrl(base.slice("github:".length));
63
+ }
64
+ else {
65
+ url = base;
66
+ }
67
+ const inferredName = subdir ? lastSegment(subdir) : repoNameFromUrl(url);
68
+ const result = { kind: "remote", url, raw, inferredName };
69
+ if (ref)
70
+ result.ref = ref;
71
+ if (subdir)
72
+ result.subdir = subdir;
73
+ return result;
74
+ }
@@ -0,0 +1,5 @@
1
+ /** A plugin name must be a single safe path segment — no separators, no traversal. */
2
+ export declare function assertSafePluginName(name: string): void;
3
+ export declare function pluginsRoot(): string;
4
+ export declare function pluginInstallDir(name: string): string;
5
+ export declare function pluginMetaPath(name: string): string;