@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
@@ -4,23 +4,82 @@
4
4
  * source types (path / git / github / git-subdir), no dependencies, no
5
5
  * sparse-checkout, no npm/pip.
6
6
  */
7
- import { cpSync, existsSync, mkdirSync, mkdtempSync, rmSync, } from "node:fs";
8
- import { dirname, isAbsolute, join, resolve } from "node:path";
7
+ import { existsSync, realpathSync, rmSync, rmdirSync } from "node:fs";
8
+ import { cp, mkdir, mkdtemp, rm } from "node:fs/promises";
9
+ import { dirname, isAbsolute, join, resolve, sep } from "node:path";
9
10
  import { homedir, tmpdir } from "node:os";
10
- import { gitClone, gitRevParseHead, githubRepoToCloneUrl } from "./gitOps.js";
11
+ import { gitClone, gitRevParseHead, gitSparseCheckoutAdd, githubRepoToCloneUrl, } from "./gitOps.js";
11
12
  import { loadMarketplace } from "./marketplaceManager.js";
12
13
  import { readKnownMarketplaces } from "./knownMarketplaces.js";
13
14
  import { appendInstallEntry, pluginInstallKey, readInstalledPlugins, removeInstallEntries, } from "./installedPlugins.js";
14
15
  import { rewritePluginVars } from "./varRewrite.js";
16
+ import { assertSafePluginName } from "./installer/paths.js";
17
+ import { pruneDisabledSettingsForPlugin } from "./installer/pruneDisabled.js";
15
18
  function userHome() {
16
19
  return process.env.HOME ?? homedir();
17
20
  }
18
21
  function pluginCacheRoot() {
19
22
  return join(userHome(), ".code-shell", "plugins", "cache");
20
23
  }
21
- function pluginCacheDir(marketplace, plugin, version) {
24
+ /**
25
+ * Compose the on-disk cache directory for a plugin version. Every path segment
26
+ * (marketplace / plugin / version) can originate from an attacker-controlled
27
+ * marketplace manifest, so each must be validated as a single safe path
28
+ * segment before it enters `join`. Without this a manifest entry named `..`
29
+ * (or containing a separator) would let the materialized plugin tree be
30
+ * written outside the plugin cache root — a supply-chain path traversal.
31
+ *
32
+ * Reuses `assertSafePluginName` (rejects empty / "." / ".." / separators /
33
+ * NUL). Exported so the segment-validation contract can be unit-tested
34
+ * directly.
35
+ */
36
+ export function pluginCacheDir(marketplace, plugin, version) {
37
+ assertSafePluginName(marketplace);
38
+ assertSafePluginName(plugin);
39
+ assertSafePluginName(version);
22
40
  return join(pluginCacheRoot(), marketplace, plugin, version);
23
41
  }
42
+ /**
43
+ * Resolve a candidate `installPath` to a realpath and verify it lives strictly
44
+ * underneath the plugin cache root. Returns the resolved path on success, or
45
+ * null when the path is missing, escapes the cache, equals the cache root
46
+ * itself, or is otherwise unsafe to remove.
47
+ *
48
+ * Exported so tests can exercise the safety predicate directly without
49
+ * arranging a full uninstall — the contract this defends (no rmSync outside
50
+ * the plugin cache) is the entire point of T2 / Workstream A2.
51
+ */
52
+ export function resolveSafePluginPath(installPath, cacheRoot) {
53
+ if (typeof installPath !== "string" || installPath.length === 0)
54
+ return null;
55
+ // Realpath the cache root once. We require it to exist; if the cache root
56
+ // itself can't be resolved, refuse all deletions rather than fall back to
57
+ // a string-only check.
58
+ let safeCacheRoot;
59
+ try {
60
+ safeCacheRoot = realpathSync(cacheRoot);
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ // Realpath the target. A missing target (dangling symlink, already removed,
66
+ // typo in installed_plugins.json) returns null — caller will skip silently.
67
+ let resolvedTarget;
68
+ try {
69
+ resolvedTarget = realpathSync(installPath);
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ // Strict containment: must start with cacheRoot + separator. Equal-to-root
75
+ // is explicitly rejected so a tampered entry can't wipe the whole cache.
76
+ const rootWithSep = safeCacheRoot.endsWith(sep) ? safeCacheRoot : safeCacheRoot + sep;
77
+ if (resolvedTarget === safeCacheRoot)
78
+ return null;
79
+ if (!resolvedTarget.startsWith(rootWithSep))
80
+ return null;
81
+ return resolvedTarget;
82
+ }
24
83
  async function materializePath(marketplaceInstallLocation, relativePath, cacheTarget) {
25
84
  const src = isAbsolute(relativePath)
26
85
  ? relativePath
@@ -28,17 +87,17 @@ async function materializePath(marketplaceInstallLocation, relativePath, cacheTa
28
87
  if (!existsSync(src)) {
29
88
  return { ok: false, error: `plugin source path "${relativePath}" not found in marketplace` };
30
89
  }
31
- mkdirSync(dirname(cacheTarget), { recursive: true });
90
+ await mkdir(dirname(cacheTarget), { recursive: true });
32
91
  if (existsSync(cacheTarget))
33
- rmSync(cacheTarget, { recursive: true, force: true });
34
- cpSync(src, cacheTarget, { recursive: true });
92
+ await rm(cacheTarget, { recursive: true, force: true });
93
+ await cp(src, cacheTarget, { recursive: true });
35
94
  return { ok: true, sha: undefined };
36
95
  }
37
96
  async function materializeGit(url, ref, cacheTarget) {
38
- mkdirSync(dirname(cacheTarget), { recursive: true });
97
+ await mkdir(dirname(cacheTarget), { recursive: true });
39
98
  if (existsSync(cacheTarget))
40
- rmSync(cacheTarget, { recursive: true, force: true });
41
- const clone = await gitClone(url, cacheTarget, ref ? { ref } : undefined);
99
+ await rm(cacheTarget, { recursive: true, force: true });
100
+ const clone = await gitClone(url, cacheTarget, { full: true, ...(ref ? { ref } : {}) });
42
101
  if (!clone.ok)
43
102
  return { ok: false, error: clone.error };
44
103
  const head = await gitRevParseHead(cacheTarget);
@@ -48,9 +107,9 @@ async function materializeGit(url, ref, cacheTarget) {
48
107
  }
49
108
  async function materializeGitSubdir(url, subPath, ref, cacheTarget) {
50
109
  // Clone to a tempdir, then copy the subdir over.
51
- const tmp = mkdtempSync(join(tmpdir(), "plugin-clone-"));
110
+ const tmp = await mkdtemp(join(tmpdir(), "plugin-clone-"));
52
111
  try {
53
- const clone = await gitClone(url, tmp + "/repo", ref ? { ref } : undefined);
112
+ const clone = await gitClone(url, tmp + "/repo", { full: true, ...(ref ? { ref } : {}) });
54
113
  if (!clone.ok)
55
114
  return { ok: false, error: clone.error };
56
115
  const head = await gitRevParseHead(tmp + "/repo");
@@ -63,14 +122,14 @@ async function materializeGitSubdir(url, subPath, ref, cacheTarget) {
63
122
  error: `git-subdir path "${subPath}" not found in cloned repository`,
64
123
  };
65
124
  }
66
- mkdirSync(dirname(cacheTarget), { recursive: true });
125
+ await mkdir(dirname(cacheTarget), { recursive: true });
67
126
  if (existsSync(cacheTarget))
68
- rmSync(cacheTarget, { recursive: true, force: true });
69
- cpSync(src, cacheTarget, { recursive: true });
127
+ await rm(cacheTarget, { recursive: true, force: true });
128
+ await cp(src, cacheTarget, { recursive: true });
70
129
  return { ok: true, sha: head.stdout };
71
130
  }
72
131
  finally {
73
- rmSync(tmp, { recursive: true, force: true });
132
+ await rm(tmp, { recursive: true, force: true });
74
133
  }
75
134
  }
76
135
  function shortSha(sha) {
@@ -78,20 +137,53 @@ function shortSha(sha) {
78
137
  return "unknown";
79
138
  return sha.slice(0, 12);
80
139
  }
140
+ /**
141
+ * Compare a marketplace-declared SHA against the cloned HEAD. The
142
+ * declaration is allowed to be a short prefix (>= 7 chars, standard git
143
+ * abbreviation length); for stricter integrity guarantees marketplaces
144
+ * should pin the full 40-char hash. Case-insensitive.
145
+ *
146
+ * Exported so a unit test can pin the policy without spinning up a real
147
+ * clone.
148
+ */
149
+ export function shaMatches(declared, actual) {
150
+ if (typeof declared !== "string" || typeof actual !== "string")
151
+ return false;
152
+ const d = declared.trim().toLowerCase();
153
+ const a = actual.trim().toLowerCase();
154
+ if (d.length < 7)
155
+ return false; // refuse 6-or-less; too collision-prone
156
+ if (d.length > 40)
157
+ return false; // not a valid SHA
158
+ return a.startsWith(d);
159
+ }
81
160
  async function materialize(source, marketplaceInstallLocation, marketplace, plugin) {
82
161
  // First pass: install into a placeholder dir, then rename to the SHA dir
83
162
  // once we know it. For path sources there's no SHA — use "local".
84
163
  const placeholder = pluginCacheDir(marketplace, plugin, "_pending_");
85
164
  if (typeof source === "string") {
165
+ // The marketplace was cloned sparse (only the manifest dirs are on disk),
166
+ // so a local-path plugin's tree may not be checked out yet. Expand the
167
+ // sparse-checkout to include it before reading. Best-effort: on a
168
+ // non-sparse (full) clone this errors harmlessly and the files are already
169
+ // present, so we ignore the result and let materializePath report a real
170
+ // missing-path error if the subdir truly isn't there.
171
+ if (!isAbsolute(source)) {
172
+ // Strip a leading "./" — in non-cone sparse mode the literal "./" prefix
173
+ // doesn't match repo paths (which are stored without it), so the
174
+ // expand would silently no-op and the tree would stay un-materialized.
175
+ const sparseRel = source.replace(/^\.\//, "");
176
+ await gitSparseCheckoutAdd(marketplaceInstallLocation, sparseRel);
177
+ }
86
178
  const r = await materializePath(marketplaceInstallLocation, source, placeholder);
87
179
  if (!r.ok)
88
180
  return r;
89
181
  const finalDir = pluginCacheDir(marketplace, plugin, "local");
90
182
  if (existsSync(finalDir))
91
- rmSync(finalDir, { recursive: true, force: true });
92
- mkdirSync(dirname(finalDir), { recursive: true });
93
- cpSync(placeholder, finalDir, { recursive: true });
94
- rmSync(placeholder, { recursive: true, force: true });
183
+ await rm(finalDir, { recursive: true, force: true });
184
+ await mkdir(dirname(finalDir), { recursive: true });
185
+ await cp(placeholder, finalDir, { recursive: true });
186
+ await rm(placeholder, { recursive: true, force: true });
95
187
  return { ok: true, cacheDir: finalDir, version: "local", sha: undefined };
96
188
  }
97
189
  if (source.source === "git" || source.source === "github") {
@@ -99,32 +191,51 @@ async function materialize(source, marketplaceInstallLocation, marketplace, plug
99
191
  const r = await materializeGit(url, source.ref, placeholder);
100
192
  if (!r.ok) {
101
193
  if (existsSync(placeholder))
102
- rmSync(placeholder, { recursive: true, force: true });
194
+ await rm(placeholder, { recursive: true, force: true });
103
195
  return r;
104
196
  }
197
+ // Supply-chain check: when the marketplace entry pins a SHA, fail the
198
+ // install if the cloned HEAD doesn't match. Without this the `sha`
199
+ // field is decorative — present in metadata, never enforced.
200
+ if (source.sha && !shaMatches(source.sha, r.sha)) {
201
+ if (existsSync(placeholder))
202
+ await rm(placeholder, { recursive: true, force: true });
203
+ return {
204
+ ok: false,
205
+ error: `sha mismatch for ${plugin}: expected ${source.sha}, got ${r.sha}`,
206
+ };
207
+ }
105
208
  const version = shortSha(r.sha);
106
209
  const finalDir = pluginCacheDir(marketplace, plugin, version);
107
210
  if (existsSync(finalDir))
108
- rmSync(finalDir, { recursive: true, force: true });
109
- mkdirSync(dirname(finalDir), { recursive: true });
110
- cpSync(placeholder, finalDir, { recursive: true });
111
- rmSync(placeholder, { recursive: true, force: true });
211
+ await rm(finalDir, { recursive: true, force: true });
212
+ await mkdir(dirname(finalDir), { recursive: true });
213
+ await cp(placeholder, finalDir, { recursive: true });
214
+ await rm(placeholder, { recursive: true, force: true });
112
215
  return { ok: true, cacheDir: finalDir, version, sha: r.sha };
113
216
  }
114
217
  if (source.source === "git-subdir") {
115
218
  const r = await materializeGitSubdir(source.url, source.path, source.ref, placeholder);
116
219
  if (!r.ok) {
117
220
  if (existsSync(placeholder))
118
- rmSync(placeholder, { recursive: true, force: true });
221
+ await rm(placeholder, { recursive: true, force: true });
119
222
  return r;
120
223
  }
224
+ if (source.sha && !shaMatches(source.sha, r.sha)) {
225
+ if (existsSync(placeholder))
226
+ await rm(placeholder, { recursive: true, force: true });
227
+ return {
228
+ ok: false,
229
+ error: `sha mismatch for ${plugin}: expected ${source.sha}, got ${r.sha}`,
230
+ };
231
+ }
121
232
  const version = shortSha(r.sha);
122
233
  const finalDir = pluginCacheDir(marketplace, plugin, version);
123
234
  if (existsSync(finalDir))
124
- rmSync(finalDir, { recursive: true, force: true });
125
- mkdirSync(dirname(finalDir), { recursive: true });
126
- cpSync(placeholder, finalDir, { recursive: true });
127
- rmSync(placeholder, { recursive: true, force: true });
235
+ await rm(finalDir, { recursive: true, force: true });
236
+ await mkdir(dirname(finalDir), { recursive: true });
237
+ await cp(placeholder, finalDir, { recursive: true });
238
+ await rm(placeholder, { recursive: true, force: true });
128
239
  return { ok: true, cacheDir: finalDir, version, sha: r.sha };
129
240
  }
130
241
  return { ok: false, error: `unsupported source type "${source.source}"` };
@@ -154,7 +265,18 @@ export async function installPlugin(pluginName, marketplaceName) {
154
265
  if (!entry) {
155
266
  return { ok: false, error: `plugin "${pluginName}" not found in marketplace "${marketplaceName}".` };
156
267
  }
157
- const mat = await materialize(entry.source, km.installLocation, marketplaceName, pluginName);
268
+ // materialize() validates every cache path segment (marketplace / plugin /
269
+ // version) and throws a PluginInstallError on an unsafe one. Convert that to
270
+ // a clean failure result — every caller (bootstrap / marketplace-service /
271
+ // tui handler) consumes { ok, error } and must not be crashed by a hostile
272
+ // marketplace manifest.
273
+ let mat;
274
+ try {
275
+ mat = await materialize(entry.source, km.installLocation, marketplaceName, pluginName);
276
+ }
277
+ catch (e) {
278
+ return { ok: false, error: e.message };
279
+ }
158
280
  if (!mat.ok)
159
281
  return mat;
160
282
  // Rewrite ${CLAUDE_PLUGIN_ROOT} → ${CODESHELL_PLUGIN_ROOT} across every
@@ -194,10 +316,19 @@ export function uninstallPlugin(pluginName, marketplaceName) {
194
316
  const data = readInstalledPlugins();
195
317
  const entries = data.plugins[key];
196
318
  let removedFromDisk = false;
319
+ const cacheRoot = pluginCacheRoot();
197
320
  if (entries) {
198
321
  for (const e of entries) {
199
- if (e.installPath && existsSync(e.installPath)) {
200
- rmSync(e.installPath, { recursive: true, force: true });
322
+ if (!e.installPath)
323
+ continue;
324
+ // Containment check: the on-disk installed_plugins.json can be tampered
325
+ // with to point at arbitrary paths (e.g. "/", "$HOME"). Refuse to rm
326
+ // anything that doesn't realpath to a strict child of the plugin cache.
327
+ const safePath = resolveSafePluginPath(e.installPath, cacheRoot);
328
+ if (!safePath)
329
+ continue;
330
+ if (existsSync(safePath)) {
331
+ rmSync(safePath, { recursive: true, force: true });
201
332
  removedFromDisk = true;
202
333
  }
203
334
  }
@@ -205,14 +336,16 @@ export function uninstallPlugin(pluginName, marketplaceName) {
205
336
  const pluginParent = join(pluginCacheRoot(), marketplaceName, pluginName);
206
337
  try {
207
338
  // rmdir succeeds only when empty; ignore failures.
208
- const fs = require("node:fs");
209
- fs.rmdirSync(pluginParent);
339
+ rmdirSync(pluginParent);
210
340
  }
211
341
  catch {
212
342
  // not empty or doesn't exist — fine
213
343
  }
214
344
  }
215
345
  const removedFromManifest = removeInstallEntries(key);
346
+ // Clear orphaned disable flags (disabledSkills "name:skill" /
347
+ // disabledPlugins "name") so a removed plugin leaves no dangling entries.
348
+ pruneDisabledSettingsForPlugin(pluginName);
216
349
  return { ok: removedFromManifest || removedFromDisk, removedFromManifest, removedFromDisk };
217
350
  }
218
351
  export function listInstalled() {
@@ -44,6 +44,30 @@ export function validatePluginEntrySource(raw, path) {
44
44
  },
45
45
  };
46
46
  }
47
+ if (kind === "local") {
48
+ // Codex / agents-format marketplaces (e.g. awesome-codex-plugins) express
49
+ // a local plugin as { source: "local", path }. Our installer's local path
50
+ // source is a bare string, so normalize onto that.
51
+ if (typeof raw.path !== "string" || !raw.path) {
52
+ return { ok: false, error: `${path}: local source requires path` };
53
+ }
54
+ return { ok: true, value: raw.path };
55
+ }
56
+ if (kind === "url") {
57
+ // The official claude-plugins-official marketplace emits a "url" source
58
+ // type for "clone this git repo" (optionally a subdir via `path`). It is
59
+ // semantically identical to our git / git-subdir sources, so normalize it
60
+ // onto those rather than carrying a fourth code path through the installer.
61
+ if (typeof raw.url !== "string" || !raw.url) {
62
+ return { ok: false, error: `${path}: url source requires url` };
63
+ }
64
+ const ref = typeof raw.ref === "string" ? raw.ref : undefined;
65
+ const sha = typeof raw.sha === "string" ? raw.sha : undefined;
66
+ if (typeof raw.path === "string" && raw.path) {
67
+ return { ok: true, value: { source: "git-subdir", url: raw.url, path: raw.path, ref, sha } };
68
+ }
69
+ return { ok: true, value: { source: "git", url: raw.url, ref, sha } };
70
+ }
47
71
  if (kind === "git-subdir") {
48
72
  if (typeof raw.url !== "string" || !raw.url) {
49
73
  return { ok: false, error: `${path}: git-subdir source requires url` };
@@ -99,6 +123,7 @@ export function validatePluginEntry(raw, index) {
99
123
  category: typeof raw.category === "string" ? raw.category : undefined,
100
124
  source: source.value,
101
125
  homepage: typeof raw.homepage === "string" ? raw.homepage : undefined,
126
+ version: typeof raw.version === "string" ? raw.version : undefined,
102
127
  },
103
128
  };
104
129
  }
@@ -108,8 +133,21 @@ export function validateMarketplace(raw) {
108
133
  if (typeof raw.name !== "string" || !raw.name) {
109
134
  return { ok: false, error: "marketplace.json: name is required" };
110
135
  }
111
- if (!isObject(raw.owner) || typeof raw.owner.name !== "string") {
112
- return { ok: false, error: "marketplace.json: owner.name is required" };
136
+ // Claude Code marketplaces carry a top-level `owner: { name }`. Codex /
137
+ // agents-format marketplaces omit it and instead carry `interface.displayName`.
138
+ // Accept either, falling back to the marketplace name as a last resort, so a
139
+ // Codex manifest is not rejected purely for lacking an owner.
140
+ let ownerName;
141
+ let ownerEmail;
142
+ if (isObject(raw.owner) && typeof raw.owner.name === "string") {
143
+ ownerName = raw.owner.name;
144
+ ownerEmail = typeof raw.owner.email === "string" ? raw.owner.email : undefined;
145
+ }
146
+ else if (isObject(raw.interface) && typeof raw.interface.displayName === "string") {
147
+ ownerName = raw.interface.displayName;
148
+ }
149
+ else {
150
+ ownerName = raw.name;
113
151
  }
114
152
  if (!Array.isArray(raw.plugins)) {
115
153
  return { ok: false, error: "marketplace.json: plugins must be an array" };
@@ -126,10 +164,7 @@ export function validateMarketplace(raw) {
126
164
  value: {
127
165
  name: raw.name,
128
166
  description: typeof raw.description === "string" ? raw.description : undefined,
129
- owner: {
130
- name: raw.owner.name,
131
- email: typeof raw.owner.email === "string" ? raw.owner.email : undefined,
132
- },
167
+ owner: { name: ownerName, email: ownerEmail },
133
168
  plugins,
134
169
  },
135
170
  };
@@ -11,10 +11,14 @@ export type MarketplaceSource = {
11
11
  source: "git";
12
12
  url: string;
13
13
  };
14
+ /** Which plugin-manifest convention a cloned marketplace ships. */
15
+ export type MarketplaceFormat = "claude-code" | "codex" | "universal";
14
16
  export interface KnownMarketplace {
15
17
  source: MarketplaceSource;
16
18
  installLocation: string;
17
19
  lastUpdated: string;
20
+ /** Optional: absent on entries written before format detection existed. */
21
+ format?: MarketplaceFormat;
18
22
  }
19
23
  export type KnownMarketplaces = Record<string, KnownMarketplace>;
20
24
  export type PluginEntrySource = string | {
@@ -44,6 +48,12 @@ export interface PluginMarketplaceEntry {
44
48
  category?: string;
45
49
  source: PluginEntrySource;
46
50
  homepage?: string;
51
+ /**
52
+ * Declared version from the marketplace manifest, when the author wrote
53
+ * one. CC's marketplace.json has no version convention, so this is often
54
+ * absent — the UI hides it rather than showing a placeholder.
55
+ */
56
+ version?: string;
47
57
  }
48
58
  export interface PluginMarketplace {
49
59
  name: string;
@@ -51,8 +51,14 @@ export declare function listPresetNames(): string[];
51
51
  export declare function resolveAgentPreset(name?: string): AgentPreset;
52
52
  /**
53
53
  * Build the full system prompt for a preset by loading and joining its sections.
54
+ *
55
+ * `activeToolNames` (the turn's effective tool set, post capability-override
56
+ * filtering) gates tool-coupled sections: the "browser" section is dropped when
57
+ * no browser tool is active, so the browser capability is a single on/off unit
58
+ * (tools + usage instructions disappear together). Omit `activeToolNames` to
59
+ * include all sections (e.g. when assembling a generic/preview prompt).
54
60
  */
55
- export declare function buildPresetSystemPrompt(preset: AgentPreset): string;
61
+ export declare function buildPresetSystemPrompt(preset: AgentPreset, activeToolNames?: readonly string[]): string;
56
62
  export declare function resolveBuiltinToolNames(options?: {
57
63
  preset?: string;
58
64
  enabledBuiltinTools?: string[];
@@ -18,8 +18,25 @@ const GENERAL_BUILTIN_TOOLS = [
18
18
  "Glob",
19
19
  "Grep",
20
20
  "Bash",
21
+ // Bash(run_in_background=true) companions — without these in the preset
22
+ // whitelist, the registry skips them (registerBuiltins filters BUILTIN_TOOLS
23
+ // by the selected set), so a model that correctly calls BashOutput after
24
+ // launching a background shell hits "Tool not found" and the turn dies.
25
+ "BashOutput",
26
+ "KillShell",
27
+ "ListShells",
28
+ // Browser automation (drive the in-app webview) — 3 semantic tools. Same
29
+ // whitelist requirement as the BashOutput trio above: registerBuiltins filters
30
+ // BUILTIN_TOOLS by the preset set, so without these the model calling
31
+ // browser_observe/etc. hits "Tool not found". They self-degrade to a clear
32
+ // error when no browser panel is wired (headless), so listing is safe.
33
+ "browser_observe",
34
+ "browser_act",
35
+ "browser_navigate",
21
36
  "WebSearch",
22
37
  "WebFetch",
38
+ "GenerateImage",
39
+ "GenerateVideo",
23
40
  "AskUserQuestion",
24
41
  "Agent",
25
42
  // AgentStatus removed: background agents now write to ~/.code-shell/agents/
@@ -35,13 +52,57 @@ const GENERAL_BUILTIN_TOOLS = [
35
52
  "CronCreate",
36
53
  "CronDelete",
37
54
  "CronList",
55
+ // cc-orchestrator:驱动外部 claude CLI 跑一轮。同 BashOutput/UseCredential/
56
+ // EditModelCatalog 的 whitelist 要求:已在 BUILTIN_TOOLS 注册,但 registerBuiltins
57
+ // 按 preset 集过滤 → 名单里没有它,agent 就没有「指挥 Claude Code」的工具,只能幻觉
58
+ // RemoteTrigger / 兜底 Bash `claude -p`(用户实测「为什么驱动 cc 没作为工具」)。
59
+ // 定时/循环驱动统一走 CronCreate(到点跑一轮引擎,prompt 里调 DriveAgent);
60
+ // 无人值守审批由 DriveAgent 自身 bypass 解决,不需要定时层专门的 CC 调度工具。
61
+ // DriveAgent 是通用驱动(cli: claude|codex);DriveClaudeCode 保留为 cli:claude 的
62
+ // 别名(老 prompt/记忆兼容)。两个都要在白名单里,否则 registerBuiltins 滤掉。
63
+ "DriveAgent",
64
+ "DriveClaudeCode",
65
+ // 编排时读 CC/Codex 剩余额度做规划(开几个/等重置/换 provider)。
66
+ "CheckQuota",
38
67
  "Skill",
39
68
  "MCPTool",
40
69
  "ListMcpResources",
41
70
  "ReadMcpResource",
42
- "RemoteTrigger",
43
71
  "REPL",
44
72
  "PowerShell",
73
+ // Persistent cross-session memory. Including these in the default preset is
74
+ // what lets the LLM list/read/save/delete memories during a normal session,
75
+ // AND what makes the end-of-session auto-dream consolidation work — its
76
+ // tool-call loop pulls these from the registry, so without them every dream
77
+ // run bailed with "missing memory tools". Save/Delete in the user scope stay
78
+ // permission-gated (the tools declare permissionDefault: "ask"); dream-scope
79
+ // writes go through freely.
80
+ "MemoryList",
81
+ "MemoryRead",
82
+ "MemorySave",
83
+ "MemoryDelete",
84
+ // AI 取用已存凭证(cookie/token/link)给 yt-dlp/curl 等。必须在 preset 白名单里
85
+ // 否则 registerBuiltins 滤掉它 → 即使存了凭证、注册了工具,AI 列表里也没有
86
+ // UseCredential(用户实测「找不到这个工具」的真因)。它带 isUseCredentialAvailable
87
+ // guard:cwd 凭证库为空时仍自动隐藏,所以无条件列入是安全的(空库不会冒出来)。
88
+ "UseCredential",
89
+ // 同理:把 cookie 凭证注入内置浏览器(恢复登录态后用 browser_* 工具)。带
90
+ // isInjectCredentialAvailable guard(无 cookie 凭证时自动隐藏),无条件列入安全。
91
+ "InjectCredential",
92
+ // AI 增/改模型 catalog(写 ~/.code-shell/model-catalog.user.json)。同 BashOutput/
93
+ // UseCredential 一样的 whitelist 要求:registerBuiltins 按 preset 集过滤 BUILTIN_TOOLS,
94
+ // 名单里没有它 → 即使工具已注册,AI 列表里也没有 → 用户实测「找不到这个工具」。
95
+ // permissionDefault: "ask",列入只是让 AI 看得到,调用仍走审批,无条件列入安全。
96
+ "EditModelCatalog",
97
+ // Goal-mode control tools. Same whitelist requirement as the rest:
98
+ // registerBuiltins filters BUILTIN_TOOLS by the preset set, so a goal tool
99
+ // absent here is registered-but-invisible — the model never sees it and can
100
+ // neither self-declare completion (complete_goal) nor honor a user's request
101
+ // to abandon the goal (cancel_goal), stranding a persistent goal that only a
102
+ // manual disk edit could clear. cancel_goal is the "strong intent" escape
103
+ // hatch (requires confirm+reason); the turn-loop enforces the guard.
104
+ "complete_goal",
105
+ "cancel_goal",
45
106
  ];
46
107
  const TERMINAL_CODING_EXTRA_TOOLS = [
47
108
  "EnterWorktree",
@@ -68,9 +129,31 @@ const GENERAL_PERMISSION_RULES = [
68
129
  { tool: "TodoWrite", decision: "allow" },
69
130
  { tool: "Sleep", decision: "allow" },
70
131
  { tool: "CronList", decision: "allow" },
132
+ { tool: "CheckQuota", decision: "allow" },
71
133
  { tool: "Skill", decision: "allow" },
134
+ // ListMcpResources only enumerates resource names (and the executor filters
135
+ // the list to this session's enabled servers). ReadMcpResource pulls actual
136
+ // content and is intentionally NOT auto-allowed here — it falls back to its
137
+ // tool-level "ask" default so a default-mode session confirms the read.
72
138
  { tool: "ListMcpResources", decision: "allow" },
73
- { tool: "ReadMcpResource", decision: "allow" },
139
+ // Reading memory is always safe; writes (MemorySave/MemoryDelete) stay gated
140
+ // by the tools' own permissionDefault so the user confirms each change.
141
+ { tool: "MemoryList", decision: "allow" },
142
+ { tool: "MemoryRead", decision: "allow" },
143
+ // Browser automation (3 semantic tools). Rules are first-match-wins, ordered
144
+ // by specificity — so the action-gating rule for browser_act MUST come first:
145
+ // click/type/select mutate the page/form → "ask"; all other actions (hover/
146
+ // scroll/wait/press_key/list_tabs/switch_tab) fall through to browser_act's
147
+ // tool-level "allow". observe (read-only) and navigate auto-allow.
148
+ // (Main-side sensitive-action + domain-whitelist enforcement also applies.)
149
+ {
150
+ tool: "browser_act",
151
+ argsPattern: { action: "^(click|type|select)$" },
152
+ decision: "ask",
153
+ reason: "browser_act click/type/select mutate the page",
154
+ },
155
+ { tool: "browser_observe", decision: "allow" },
156
+ { tool: "browser_navigate", decision: "allow" },
74
157
  ];
75
158
  // ─── Preset definitions ──────────────────────────────────────────
76
159
  export const BUILTIN_AGENT_PRESETS = {
@@ -78,7 +161,7 @@ export const BUILTIN_AGENT_PRESETS = {
78
161
  name: "general",
79
162
  label: "General Orchestrator",
80
163
  description: "Domain-agnostic orchestration for research, operations, automation, and long-running tasks.",
81
- promptSections: ["base", "orchestration", "tone"],
164
+ promptSections: ["base", "orchestration", "browser", "tone"],
82
165
  injectGitStatus: false,
83
166
  builtinTools: [...GENERAL_BUILTIN_TOOLS],
84
167
  defaultPermissionRules: GENERAL_PERMISSION_RULES,
@@ -87,7 +170,7 @@ export const BUILTIN_AGENT_PRESETS = {
87
170
  name: "terminal-coding",
88
171
  label: "Terminal Coding Assistant",
89
172
  description: "General orchestration plus coding-focused guidance and code-navigation tools.",
90
- promptSections: ["base", "orchestration", "coding", "tone"],
173
+ promptSections: ["base", "orchestration", "coding", "browser", "tone"],
91
174
  injectGitStatus: true,
92
175
  builtinTools: [...GENERAL_BUILTIN_TOOLS, ...TERMINAL_CODING_EXTRA_TOOLS],
93
176
  defaultPermissionRules: [
@@ -140,11 +223,34 @@ export function resolveAgentPreset(name) {
140
223
  const allowed = listPresetNames().join(", ");
141
224
  throw new Error(`Unknown agent preset "${name}". Available presets: ${allowed}`);
142
225
  }
226
+ /** Tool names that gate the "browser" prompt section — if NONE of these are in
227
+ * the active tool set (browser capability turned off), the section is dropped
228
+ * so the model isn't told how to use tools it can't see. Keep in sync with the
229
+ * browser tools registered in builtin/index.ts. */
230
+ const BROWSER_SECTION_TOOLS = ["browser_observe", "browser_act", "browser_navigate"];
231
+ /** Prompt sections whose inclusion is gated by an active tool being present. */
232
+ const TOOL_GATED_SECTIONS = {
233
+ browser: BROWSER_SECTION_TOOLS,
234
+ };
143
235
  /**
144
236
  * Build the full system prompt for a preset by loading and joining its sections.
237
+ *
238
+ * `activeToolNames` (the turn's effective tool set, post capability-override
239
+ * filtering) gates tool-coupled sections: the "browser" section is dropped when
240
+ * no browser tool is active, so the browser capability is a single on/off unit
241
+ * (tools + usage instructions disappear together). Omit `activeToolNames` to
242
+ * include all sections (e.g. when assembling a generic/preview prompt).
145
243
  */
146
- export function buildPresetSystemPrompt(preset) {
147
- return loadSections(preset.promptSections);
244
+ export function buildPresetSystemPrompt(preset, activeToolNames) {
245
+ let sections = preset.promptSections;
246
+ if (activeToolNames) {
247
+ const active = new Set(activeToolNames);
248
+ sections = sections.filter((s) => {
249
+ const gate = TOOL_GATED_SECTIONS[s];
250
+ return !gate || gate.some((t) => active.has(t));
251
+ });
252
+ }
253
+ return loadSections(sections);
148
254
  }
149
255
  export function resolveBuiltinToolNames(options) {
150
256
  const preset = resolveAgentPreset(options?.preset);
@@ -21,7 +21,7 @@
21
21
  import type { PermissionRule, MCPServerConfig } from "../types.js";
22
22
  import type { Evaluator } from "../run/Evaluator.js";
23
23
  import type { RegisteredTool } from "../types.js";
24
- import type { EngineHookConfig } from "../engine/engine.js";
24
+ import type { EngineHookConfig } from "../engine/types.js";
25
25
  export interface ProductPreset {
26
26
  /** Unique name for this product's preset. */
27
27
  name: string;