@cjhyy/code-shell-core 0.7.1 → 0.8.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 (595) hide show
  1. package/README.md +36 -23
  2. package/dist/agent/agent-definition-registry.d.ts +2 -2
  3. package/dist/agent/agent-definition-registry.js +47 -10
  4. package/dist/agent/agent-definition.d.ts +5 -0
  5. package/dist/agent/agent-definition.js +14 -0
  6. package/dist/automation/index.d.ts +7 -4
  7. package/dist/automation/index.js +4 -2
  8. package/dist/automation/runner.js +3 -1
  9. package/dist/automation/scheduler.d.ts +57 -1
  10. package/dist/automation/scheduler.js +123 -23
  11. package/dist/automation/store.d.ts +6 -2
  12. package/dist/automation/store.js +7 -3
  13. package/dist/capabilities/index.d.ts +109 -0
  14. package/dist/capabilities/index.js +80 -0
  15. package/dist/capability-control/disabled-lists.d.ts +2 -1
  16. package/dist/capability-control/disabled-lists.js +3 -5
  17. package/dist/capability-control/overlay.d.ts +14 -1
  18. package/dist/capability-control/overlay.js +40 -0
  19. package/dist/capability-control/service.js +6 -4
  20. package/dist/cli/agent-server-stdio.d.ts +1 -1
  21. package/dist/cli/agent-server-stdio.js +66 -6
  22. package/dist/cli/agent-server-tcp.js +7 -3
  23. package/dist/context/compaction.d.ts +39 -3
  24. package/dist/context/compaction.js +151 -39
  25. package/dist/context/manager.d.ts +17 -1
  26. package/dist/context/manager.js +36 -1
  27. package/dist/credentials/access.d.ts +3 -1
  28. package/dist/credentials/access.js +24 -3
  29. package/dist/credentials/index.d.ts +1 -1
  30. package/dist/credentials/index.js +1 -1
  31. package/dist/credentials/oauth.d.ts +4 -1
  32. package/dist/credentials/oauth.js +14 -0
  33. package/dist/credentials/store.d.ts +15 -1
  34. package/dist/credentials/store.js +17 -4
  35. package/dist/credentials/types.d.ts +24 -0
  36. package/dist/credentials/use-credential-tool.js +15 -1
  37. package/dist/engine/auxiliary-pipeline.d.ts +40 -0
  38. package/dist/engine/auxiliary-pipeline.js +181 -0
  39. package/dist/{settings → engine}/disk-defaults.d.ts +2 -2
  40. package/dist/{settings → engine}/disk-defaults.js +5 -2
  41. package/dist/engine/dynamic-tool-defs.d.ts +4 -0
  42. package/dist/engine/dynamic-tool-defs.js +4 -0
  43. package/dist/engine/engine.d.ts +254 -195
  44. package/dist/engine/engine.js +1812 -2041
  45. package/dist/engine/file-history-hook.d.ts +11 -0
  46. package/dist/engine/file-history-hook.js +31 -0
  47. package/dist/engine/goal-judge-context.d.ts +9 -0
  48. package/dist/engine/goal-judge-context.js +234 -0
  49. package/dist/engine/injected-context-cache.d.ts +6 -0
  50. package/dist/engine/injected-context-cache.js +13 -0
  51. package/dist/engine/input-attachments.d.ts +1 -1
  52. package/dist/engine/model-facade.d.ts +3 -3
  53. package/dist/engine/model-facade.js +15 -14
  54. package/dist/engine/permission-controller.d.ts +55 -0
  55. package/dist/engine/permission-controller.js +148 -0
  56. package/dist/engine/prompt-cache-diagnostics.d.ts +58 -0
  57. package/dist/engine/prompt-cache-diagnostics.js +178 -0
  58. package/dist/engine/run-accounting.d.ts +41 -0
  59. package/dist/engine/run-accounting.js +126 -0
  60. package/dist/engine/run-context.d.ts +44 -0
  61. package/dist/engine/run-context.js +88 -0
  62. package/dist/engine/run-environment.d.ts +30 -0
  63. package/dist/engine/run-environment.js +77 -0
  64. package/dist/engine/run-finalize.d.ts +58 -0
  65. package/dist/engine/run-finalize.js +245 -0
  66. package/dist/engine/run-goal.d.ts +58 -0
  67. package/dist/engine/run-goal.js +188 -0
  68. package/dist/engine/run-image-input.d.ts +1 -1
  69. package/dist/engine/run-image-input.js +5 -3
  70. package/dist/engine/run-session-open.d.ts +41 -0
  71. package/dist/engine/run-session-open.js +186 -0
  72. package/dist/engine/run-setup.d.ts +42 -0
  73. package/dist/engine/run-setup.js +58 -0
  74. package/dist/engine/run-tooling.d.ts +125 -0
  75. package/dist/engine/run-tooling.js +283 -0
  76. package/dist/engine/run-types.d.ts +139 -0
  77. package/dist/engine/run-types.js +12 -0
  78. package/dist/engine/run-workspace.d.ts +50 -0
  79. package/dist/engine/run-workspace.js +114 -0
  80. package/dist/engine/steer-queue.d.ts +1 -1
  81. package/dist/engine/subagent-spawner.d.ts +32 -0
  82. package/dist/engine/subagent-spawner.js +287 -0
  83. package/dist/engine/tool-summary.d.ts +2 -2
  84. package/dist/engine/tool-summary.js +2 -2
  85. package/dist/engine/turn-loop.d.ts +49 -10
  86. package/dist/engine/turn-loop.js +370 -104
  87. package/dist/engine/types.d.ts +30 -3
  88. package/dist/engine/types.js +1 -1
  89. package/dist/{engine/goal.d.ts → goal/lifecycle.d.ts} +76 -4
  90. package/dist/goal/lifecycle.js +482 -0
  91. package/dist/hooks/events.d.ts +24 -10
  92. package/dist/hooks/goal-stop-hook.d.ts +17 -28
  93. package/dist/hooks/goal-stop-hook.js +110 -465
  94. package/dist/hooks/registry.js +1 -1
  95. package/dist/index.d.ts +48 -108
  96. package/dist/index.extension.d.ts +51 -0
  97. package/dist/index.extension.js +39 -0
  98. package/dist/index.internal.d.ts +86 -0
  99. package/dist/index.internal.js +92 -0
  100. package/dist/index.js +34 -123
  101. package/dist/links/cli.d.ts +48 -0
  102. package/dist/links/cli.js +617 -0
  103. package/dist/links/http.d.ts +40 -0
  104. package/dist/links/http.js +166 -0
  105. package/dist/links/index.d.ts +4 -0
  106. package/dist/links/index.js +3 -0
  107. package/dist/links/link-action-tool.d.ts +5 -0
  108. package/dist/links/link-action-tool.js +241 -0
  109. package/dist/links/providers.d.ts +8 -0
  110. package/dist/links/providers.js +665 -0
  111. package/dist/links/types.d.ts +44 -0
  112. package/dist/llm/client-base.d.ts +7 -0
  113. package/dist/llm/client-base.js +60 -0
  114. package/dist/llm/model-pool.d.ts +1 -1
  115. package/dist/llm/model-pool.js +1 -1
  116. package/dist/llm/providers/anthropic.d.ts +1 -0
  117. package/dist/llm/providers/anthropic.js +9 -0
  118. package/dist/llm/providers/openai.d.ts +1 -0
  119. package/dist/llm/providers/openai.js +17 -0
  120. package/dist/model-catalog/index.js +15 -2
  121. package/dist/model-catalog/resolve.d.ts +13 -1
  122. package/dist/model-catalog/resolve.js +37 -2
  123. package/dist/model-catalog/types.d.ts +74 -48
  124. package/dist/model-catalog/types.js +16 -5
  125. package/dist/model-catalog/upsert.d.ts +3 -1
  126. package/dist/model-catalog/upsert.js +9 -0
  127. package/dist/onboarding.d.ts +0 -1
  128. package/dist/onboarding.js +1 -22
  129. package/dist/panel-apps/bindings.d.ts +24 -0
  130. package/dist/panel-apps/bindings.js +69 -0
  131. package/dist/panel-apps/github-archive.d.ts +21 -0
  132. package/dist/panel-apps/github-archive.js +98 -0
  133. package/dist/panel-apps/index.d.ts +4 -0
  134. package/dist/panel-apps/index.js +4 -0
  135. package/dist/panel-apps/installer.d.ts +68 -0
  136. package/dist/panel-apps/installer.js +622 -0
  137. package/dist/panel-apps/manifest.d.ts +364 -0
  138. package/dist/panel-apps/manifest.js +189 -0
  139. package/dist/panel-apps/paths.d.ts +13 -0
  140. package/dist/panel-apps/paths.js +38 -0
  141. package/dist/panel-apps/registry.d.ts +51 -0
  142. package/dist/panel-apps/registry.js +99 -0
  143. package/dist/panel-apps/runtime.d.ts +80 -0
  144. package/dist/panel-apps/runtime.js +154 -0
  145. package/dist/plugins/gitOps.js +8 -1
  146. package/dist/plugins/installedPlugins.d.ts +2 -1
  147. package/dist/plugins/installedPlugins.js +146 -8
  148. package/dist/plugins/installer/codex/convertAgents.d.ts +4 -1
  149. package/dist/plugins/installer/codex/convertAgents.js +62 -8
  150. package/dist/plugins/installer/codex/convertCommands.d.ts +5 -5
  151. package/dist/plugins/installer/codex/convertCommands.js +35 -12
  152. package/dist/plugins/installer/codex/convertHooks.d.ts +10 -0
  153. package/dist/plugins/installer/codex/convertHooks.js +82 -0
  154. package/dist/plugins/installer/codex/convertSkills.js +41 -6
  155. package/dist/plugins/installer/install.d.ts +7 -1
  156. package/dist/plugins/installer/install.js +21 -87
  157. package/dist/plugins/installer/installFromArchive.d.ts +26 -4
  158. package/dist/plugins/installer/installFromArchive.js +44 -27
  159. package/dist/plugins/installer/installFromNpm.d.ts +31 -0
  160. package/dist/plugins/installer/installFromNpm.js +273 -0
  161. package/dist/plugins/installer/loadPluginAgents.js +17 -4
  162. package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
  163. package/dist/plugins/installer/loadPluginMcp.js +245 -35
  164. package/dist/plugins/installer/normalizeManifest.d.ts +13 -0
  165. package/dist/plugins/installer/normalizeManifest.js +306 -0
  166. package/dist/plugins/installer/npmTar.d.ts +13 -0
  167. package/dist/plugins/installer/npmTar.js +321 -0
  168. package/dist/plugins/installer/parseSource.d.ts +11 -0
  169. package/dist/plugins/installer/parseSource.js +48 -0
  170. package/dist/plugins/installer/preview.d.ts +101 -0
  171. package/dist/plugins/installer/preview.js +336 -0
  172. package/dist/plugins/installer/projectPluginSource.d.ts +14 -0
  173. package/dist/plugins/installer/projectPluginSource.js +140 -0
  174. package/dist/plugins/installer/types.d.ts +775 -0
  175. package/dist/plugins/installer/types.js +100 -0
  176. package/dist/plugins/installer/unzip.d.ts +11 -0
  177. package/dist/plugins/installer/unzip.js +123 -9
  178. package/dist/plugins/installer/update.d.ts +2 -2
  179. package/dist/plugins/installer/update.js +43 -4
  180. package/dist/plugins/loadPluginHooks.d.ts +19 -2
  181. package/dist/plugins/loadPluginHooks.js +97 -86
  182. package/dist/plugins/pluginAutomationTemplates.d.ts +18 -0
  183. package/dist/plugins/pluginAutomationTemplates.js +50 -0
  184. package/dist/plugins/pluginCatalog.d.ts +45 -0
  185. package/dist/plugins/pluginCatalog.js +87 -0
  186. package/dist/plugins/pluginCommandHook.d.ts +6 -0
  187. package/dist/plugins/pluginCommandHook.js +25 -8
  188. package/dist/plugins/pluginCommandsLoader.d.ts +19 -0
  189. package/dist/plugins/pluginCommandsLoader.js +181 -7
  190. package/dist/plugins/pluginContent.d.ts +10 -1
  191. package/dist/plugins/pluginContent.js +87 -30
  192. package/dist/plugins/pluginHookApproval.d.ts +30 -0
  193. package/dist/plugins/pluginHookApproval.js +160 -0
  194. package/dist/plugins/pluginHookIntegrity.d.ts +69 -0
  195. package/dist/plugins/pluginHookIntegrity.js +361 -0
  196. package/dist/plugins/pluginInstaller.js +71 -12
  197. package/dist/plugins/pluginMcpApproval.d.ts +19 -0
  198. package/dist/plugins/pluginMcpApproval.js +110 -0
  199. package/dist/plugins/pluginMcpIntegrity.d.ts +21 -0
  200. package/dist/plugins/pluginMcpIntegrity.js +74 -0
  201. package/dist/plugins/types.d.ts +30 -0
  202. package/dist/plugins/varRewrite.d.ts +9 -5
  203. package/dist/plugins/varRewrite.js +26 -17
  204. package/dist/preset/index.d.ts +11 -8
  205. package/dist/preset/index.js +62 -203
  206. package/dist/product/define.js +9 -3
  207. package/dist/product/types.d.ts +0 -2
  208. package/dist/profile/activation.d.ts +36 -0
  209. package/dist/profile/activation.js +57 -0
  210. package/dist/profile/catalog-store.d.ts +77 -0
  211. package/dist/profile/catalog-store.js +346 -0
  212. package/dist/profile/catalog.d.ts +54 -0
  213. package/dist/profile/catalog.js +152 -0
  214. package/dist/profile/index.d.ts +7 -0
  215. package/dist/profile/index.js +7 -0
  216. package/dist/profile/requirements.d.ts +76 -0
  217. package/dist/profile/requirements.js +117 -0
  218. package/dist/profile/resolve.d.ts +11 -0
  219. package/dist/profile/resolve.js +41 -0
  220. package/dist/profile/store.d.ts +17 -0
  221. package/dist/profile/store.js +167 -0
  222. package/dist/profile/types.d.ts +321 -0
  223. package/dist/profile/types.js +104 -0
  224. package/dist/prompt/composer.d.ts +46 -7
  225. package/dist/prompt/composer.js +78 -48
  226. package/dist/prompt/instruction-scanner.d.ts +6 -5
  227. package/dist/prompt/instruction-scanner.js +8 -23
  228. package/dist/prompt/section-loader.d.ts +2 -2
  229. package/dist/prompt/section-loader.js +7 -4
  230. package/dist/prompt/sections/browser.md +10 -9
  231. package/dist/prompt/sections/harness-base.md +9 -0
  232. package/dist/protocol/chat-session-manager.d.ts +64 -1
  233. package/dist/protocol/chat-session-manager.js +104 -0
  234. package/dist/protocol/chat-session.d.ts +61 -10
  235. package/dist/protocol/chat-session.js +135 -25
  236. package/dist/protocol/client.d.ts +33 -3
  237. package/dist/protocol/client.js +96 -5
  238. package/dist/protocol/index.d.ts +2 -2
  239. package/dist/protocol/index.js +2 -2
  240. package/dist/protocol/mobile-remote-types.d.ts +406 -0
  241. package/dist/protocol/mobile-remote-types.js +1 -0
  242. package/dist/protocol/server.d.ts +127 -3
  243. package/dist/protocol/server.js +1309 -182
  244. package/dist/protocol/types.d.ts +152 -34
  245. package/dist/protocol/types.js +16 -0
  246. package/dist/run/ArtifactTracker.d.ts +6 -1
  247. package/dist/run/ArtifactTracker.js +29 -21
  248. package/dist/run/EngineRunner.d.ts +2 -0
  249. package/dist/run/EngineRunner.js +1 -0
  250. package/dist/run/RunManager.d.ts +26 -0
  251. package/dist/run/RunManager.js +82 -11
  252. package/dist/run/factory.d.ts +3 -0
  253. package/dist/run/factory.js +2 -0
  254. package/dist/runtime/safe-spawn.d.ts +6 -0
  255. package/dist/runtime/safe-spawn.js +8 -13
  256. package/dist/services/auto-dream.d.ts +13 -1
  257. package/dist/services/auto-dream.js +56 -8
  258. package/dist/services/dream-consolidation.js +10 -1
  259. package/dist/services/memory-orchestrator.js +6 -2
  260. package/dist/services/oauth.js +4 -1
  261. package/dist/services/session-memory.d.ts +4 -4
  262. package/dist/services/session-memory.js +13 -10
  263. package/dist/session/memory.d.ts +26 -7
  264. package/dist/session/memory.js +79 -21
  265. package/dist/session/session-manager.d.ts +182 -28
  266. package/dist/session/session-manager.js +910 -130
  267. package/dist/session/session-message.d.ts +22 -0
  268. package/dist/session/session-message.js +1 -0
  269. package/dist/session/transcript.d.ts +46 -5
  270. package/dist/session/transcript.js +159 -3
  271. package/dist/settings/feature-flags.d.ts +40 -0
  272. package/dist/settings/feature-flags.js +40 -0
  273. package/dist/settings/manager.d.ts +39 -1
  274. package/dist/settings/manager.js +102 -41
  275. package/dist/settings/migrate-config.js +4 -2
  276. package/dist/settings/schema.d.ts +511 -177
  277. package/dist/settings/schema.js +98 -25
  278. package/dist/skills/scanner.d.ts +6 -2
  279. package/dist/skills/scanner.js +160 -9
  280. package/dist/sources/adapter.d.ts +14 -0
  281. package/dist/sources/adapter.js +7 -0
  282. package/dist/sources/adapters/local-files.d.ts +10 -0
  283. package/dist/sources/adapters/local-files.js +127 -0
  284. package/dist/sources/adapters/mcp-resource.d.ts +17 -0
  285. package/dist/sources/adapters/mcp-resource.js +41 -0
  286. package/dist/sources/adapters/mock.d.ts +3 -0
  287. package/dist/sources/adapters/mock.js +29 -0
  288. package/dist/sources/binding.d.ts +6 -0
  289. package/dist/sources/binding.js +24 -0
  290. package/dist/sources/catalog.d.ts +6 -0
  291. package/dist/sources/catalog.js +64 -0
  292. package/dist/sources/context-summary.d.ts +8 -0
  293. package/dist/sources/context-summary.js +13 -0
  294. package/dist/sources/credential-status.d.ts +2 -0
  295. package/dist/sources/credential-status.js +13 -0
  296. package/dist/sources/index.d.ts +10 -0
  297. package/dist/sources/index.js +10 -0
  298. package/dist/sources/resolve.d.ts +28 -0
  299. package/dist/sources/resolve.js +47 -0
  300. package/dist/sources/truncate-utf8.d.ts +7 -0
  301. package/dist/sources/truncate-utf8.js +18 -0
  302. package/dist/sources/types.d.ts +71 -0
  303. package/dist/sources/types.js +26 -0
  304. package/dist/testing/fetch-stub.d.ts +32 -0
  305. package/dist/testing/fetch-stub.js +24 -0
  306. package/dist/themes/image.d.ts +18 -0
  307. package/dist/themes/image.js +117 -0
  308. package/dist/themes/index.d.ts +4 -0
  309. package/dist/themes/index.js +4 -0
  310. package/dist/themes/installer.d.ts +50 -0
  311. package/dist/themes/installer.js +290 -0
  312. package/dist/themes/manifest.d.ts +102 -0
  313. package/dist/themes/manifest.js +86 -0
  314. package/dist/themes/paths.d.ts +14 -0
  315. package/dist/themes/paths.js +33 -0
  316. package/dist/tool-system/browser-bridge.d.ts +53 -11
  317. package/dist/tool-system/browser-bridge.js +8 -9
  318. package/dist/tool-system/builtin/agent-heartbeat.d.ts +2 -2
  319. package/dist/tool-system/builtin/agent-heartbeat.js +20 -6
  320. package/dist/tool-system/builtin/agent-notifications.d.ts +127 -72
  321. package/dist/tool-system/builtin/agent-notifications.js +291 -101
  322. package/dist/tool-system/builtin/agent-output-file.js +1 -3
  323. package/dist/tool-system/builtin/agent-progress.d.ts +6 -0
  324. package/dist/tool-system/builtin/agent-progress.js +83 -0
  325. package/dist/tool-system/builtin/agent-registry.d.ts +38 -2
  326. package/dist/tool-system/builtin/agent-registry.js +178 -9
  327. package/dist/tool-system/builtin/agent-transcript-translator.js +1 -1
  328. package/dist/tool-system/builtin/agent.d.ts +2 -0
  329. package/dist/tool-system/builtin/agent.js +274 -33
  330. package/dist/tool-system/builtin/background-jobs.d.ts +55 -2
  331. package/dist/tool-system/builtin/background-jobs.js +96 -4
  332. package/dist/tool-system/builtin/background-work.d.ts +6 -0
  333. package/dist/tool-system/builtin/background-work.js +8 -1
  334. package/dist/tool-system/builtin/bash.js +5 -2
  335. package/dist/tool-system/builtin/browser-tools.d.ts +6 -3
  336. package/dist/tool-system/builtin/browser-tools.js +89 -23
  337. package/dist/tool-system/builtin/edit-model-catalog.d.ts +6 -0
  338. package/dist/tool-system/builtin/edit-model-catalog.js +172 -12
  339. package/dist/tool-system/builtin/edit.js +2 -6
  340. package/dist/tool-system/builtin/file-cache.d.ts +2 -0
  341. package/dist/tool-system/builtin/file-cache.js +4 -0
  342. package/dist/tool-system/builtin/generate-image.js +17 -10
  343. package/dist/tool-system/builtin/generate-video.js +26 -7
  344. package/dist/tool-system/builtin/grep.js +2 -2
  345. package/dist/tool-system/builtin/image-uploader.js +7 -1
  346. package/dist/tool-system/builtin/index.d.ts +32 -7
  347. package/dist/tool-system/builtin/index.js +237 -167
  348. package/dist/tool-system/builtin/memory.d.ts +6 -0
  349. package/dist/tool-system/builtin/memory.js +36 -15
  350. package/dist/tool-system/builtin/panel.d.ts +9 -0
  351. package/dist/tool-system/builtin/panel.js +314 -0
  352. package/dist/tool-system/builtin/read.js +5 -1
  353. package/dist/tool-system/builtin/send-message-to-session.d.ts +6 -0
  354. package/dist/tool-system/builtin/send-message-to-session.js +67 -0
  355. package/dist/tool-system/builtin/sources.d.ts +8 -0
  356. package/dist/tool-system/builtin/sources.js +137 -0
  357. package/dist/tool-system/builtin/tool-search.js +7 -2
  358. package/dist/tool-system/builtin/update-automation-memory.js +2 -0
  359. package/dist/tool-system/builtin/web-fetch.js +17 -13
  360. package/dist/tool-system/builtin/web-search.js +1 -3
  361. package/dist/tool-system/capability-module.d.ts +93 -0
  362. package/dist/tool-system/capability-module.js +53 -0
  363. package/dist/tool-system/context.d.ts +77 -19
  364. package/dist/tool-system/executor.js +75 -50
  365. package/dist/tool-system/external-tool-exposure.d.ts +60 -0
  366. package/dist/tool-system/external-tool-exposure.js +304 -0
  367. package/dist/tool-system/mcp-manager.d.ts +11 -1
  368. package/dist/tool-system/mcp-manager.js +19 -4
  369. package/dist/tool-system/mcp-tool-policy.d.ts +9 -0
  370. package/dist/tool-system/mcp-tool-policy.js +34 -0
  371. package/dist/tool-system/panel-bridge.d.ts +53 -0
  372. package/dist/tool-system/panel-bridge.js +1 -0
  373. package/dist/tool-system/path-policy.js +99 -2
  374. package/dist/tool-system/permission.d.ts +26 -0
  375. package/dist/tool-system/permission.js +46 -0
  376. package/dist/tool-system/registry.d.ts +12 -1
  377. package/dist/tool-system/registry.js +31 -7
  378. package/dist/tool-system/sandbox/index.js +3 -8
  379. package/dist/tool-system/sandbox/seatbelt.js +2 -6
  380. package/dist/tool-system/session-tool-host.d.ts +139 -0
  381. package/dist/tool-system/session-tool-host.js +167 -0
  382. package/dist/tool-system/testing/tool-registry-harness.d.ts +31 -0
  383. package/dist/tool-system/testing/tool-registry-harness.js +51 -0
  384. package/dist/tool-system/validation.d.ts +14 -7
  385. package/dist/tool-system/validation.js +701 -7
  386. package/dist/types.d.ts +186 -20
  387. package/dist/{cc-orchestrator → utils}/cwd-normalize.d.ts +1 -0
  388. package/dist/{cc-orchestrator → utils}/cwd-normalize.js +1 -0
  389. package/dist/utils/file-mutex.d.ts +65 -0
  390. package/dist/utils/file-mutex.js +145 -0
  391. package/dist/utils/json.d.ts +2 -4
  392. package/dist/utils/json.js +2 -4
  393. package/dist/utils/lockfile.d.ts +30 -1
  394. package/dist/utils/lockfile.js +2 -2
  395. package/dist/utils/secret-scrubber.d.ts +8 -0
  396. package/dist/utils/secret-scrubber.js +227 -0
  397. package/dist/utils/toolDisplay.js +1 -1
  398. package/package.json +20 -5
  399. package/THIRD_PARTY_NOTICES.md +0 -206
  400. package/dist/arena/arena.d.ts +0 -45
  401. package/dist/arena/arena.js +0 -362
  402. package/dist/arena/context/context-tools.d.ts +0 -16
  403. package/dist/arena/context/context-tools.js +0 -272
  404. package/dist/arena/context/within-root.d.ts +0 -7
  405. package/dist/arena/context/within-root.js +0 -15
  406. package/dist/arena/detect-mode.d.ts +0 -20
  407. package/dist/arena/detect-mode.js +0 -78
  408. package/dist/arena/digest-builder.d.ts +0 -25
  409. package/dist/arena/digest-builder.js +0 -120
  410. package/dist/arena/index.d.ts +0 -29
  411. package/dist/arena/index.js +0 -29
  412. package/dist/arena/iterate/convergence.d.ts +0 -25
  413. package/dist/arena/iterate/convergence.js +0 -103
  414. package/dist/arena/iterate/formats/index.d.ts +0 -22
  415. package/dist/arena/iterate/formats/index.js +0 -283
  416. package/dist/arena/iterate/index.d.ts +0 -11
  417. package/dist/arena/iterate/index.js +0 -9
  418. package/dist/arena/iterate/iterative-arena.d.ts +0 -23
  419. package/dist/arena/iterate/iterative-arena.js +0 -237
  420. package/dist/arena/iterate/parse.d.ts +0 -42
  421. package/dist/arena/iterate/parse.js +0 -123
  422. package/dist/arena/iterate/phases/argue.d.ts +0 -22
  423. package/dist/arena/iterate/phases/argue.js +0 -165
  424. package/dist/arena/iterate/phases/revise.d.ts +0 -16
  425. package/dist/arena/iterate/phases/revise.js +0 -62
  426. package/dist/arena/iterate/phases/tournament.d.ts +0 -34
  427. package/dist/arena/iterate/phases/tournament.js +0 -113
  428. package/dist/arena/iterate/tools/web-tools.d.ts +0 -13
  429. package/dist/arena/iterate/tools/web-tools.js +0 -54
  430. package/dist/arena/iterate/types.d.ts +0 -152
  431. package/dist/arena/iterate/types.js +0 -8
  432. package/dist/arena/ledger.d.ts +0 -47
  433. package/dist/arena/ledger.js +0 -159
  434. package/dist/arena/lenses/architecture.d.ts +0 -5
  435. package/dist/arena/lenses/architecture.js +0 -22
  436. package/dist/arena/lenses/engineering.d.ts +0 -5
  437. package/dist/arena/lenses/engineering.js +0 -22
  438. package/dist/arena/lenses/general.d.ts +0 -5
  439. package/dist/arena/lenses/general.js +0 -20
  440. package/dist/arena/lenses/index.d.ts +0 -16
  441. package/dist/arena/lenses/index.js +0 -47
  442. package/dist/arena/lenses/product.d.ts +0 -5
  443. package/dist/arena/lenses/product.js +0 -22
  444. package/dist/arena/model-presets.d.ts +0 -23
  445. package/dist/arena/model-presets.js +0 -44
  446. package/dist/arena/phases/adjudication.d.ts +0 -25
  447. package/dist/arena/phases/adjudication.js +0 -142
  448. package/dist/arena/phases/build-consensus.d.ts +0 -30
  449. package/dist/arena/phases/build-consensus.js +0 -85
  450. package/dist/arena/phases/claim-registry.d.ts +0 -26
  451. package/dist/arena/phases/claim-registry.js +0 -60
  452. package/dist/arena/phases/cross-review.d.ts +0 -47
  453. package/dist/arena/phases/cross-review.js +0 -224
  454. package/dist/arena/phases/debate-rounds.d.ts +0 -28
  455. package/dist/arena/phases/debate-rounds.js +0 -161
  456. package/dist/arena/phases/participant-research.d.ts +0 -39
  457. package/dist/arena/phases/participant-research.js +0 -316
  458. package/dist/arena/phases/planning-detail-expansion.d.ts +0 -39
  459. package/dist/arena/phases/planning-detail-expansion.js +0 -120
  460. package/dist/arena/planner.d.ts +0 -28
  461. package/dist/arena/planner.js +0 -312
  462. package/dist/arena/providers/docs.d.ts +0 -7
  463. package/dist/arena/providers/docs.js +0 -111
  464. package/dist/arena/providers/git.d.ts +0 -8
  465. package/dist/arena/providers/git.js +0 -174
  466. package/dist/arena/providers/index.d.ts +0 -32
  467. package/dist/arena/providers/index.js +0 -132
  468. package/dist/arena/providers/none.d.ts +0 -7
  469. package/dist/arena/providers/none.js +0 -11
  470. package/dist/arena/providers/repo.d.ts +0 -7
  471. package/dist/arena/providers/repo.js +0 -258
  472. package/dist/arena/render/session.d.ts +0 -17
  473. package/dist/arena/render/session.js +0 -190
  474. package/dist/arena/render/terminal.d.ts +0 -34
  475. package/dist/arena/render/terminal.js +0 -286
  476. package/dist/arena/strategies/discussion.d.ts +0 -25
  477. package/dist/arena/strategies/discussion.js +0 -143
  478. package/dist/arena/strategies/index.d.ts +0 -15
  479. package/dist/arena/strategies/index.js +0 -28
  480. package/dist/arena/strategies/language-wrapper.d.ts +0 -17
  481. package/dist/arena/strategies/language-wrapper.js +0 -102
  482. package/dist/arena/strategies/lens-wrapper.d.ts +0 -16
  483. package/dist/arena/strategies/lens-wrapper.js +0 -236
  484. package/dist/arena/strategies/planning.d.ts +0 -30
  485. package/dist/arena/strategies/planning.js +0 -225
  486. package/dist/arena/strategies/review.d.ts +0 -26
  487. package/dist/arena/strategies/review.js +0 -168
  488. package/dist/arena/strategies/utils.d.ts +0 -36
  489. package/dist/arena/strategies/utils.js +0 -603
  490. package/dist/arena/tools/selector.d.ts +0 -17
  491. package/dist/arena/tools/selector.js +0 -61
  492. package/dist/arena/transitions.d.ts +0 -53
  493. package/dist/arena/transitions.js +0 -97
  494. package/dist/arena/types.d.ts +0 -518
  495. package/dist/arena/types.js +0 -27
  496. package/dist/cc-orchestrator/agent-adapter.d.ts +0 -54
  497. package/dist/cc-orchestrator/agent-adapter.js +0 -143
  498. package/dist/cc-orchestrator/cc-capability.d.ts +0 -19
  499. package/dist/cc-orchestrator/cc-capability.js +0 -53
  500. package/dist/cc-orchestrator/codex-session-discovery.d.ts +0 -24
  501. package/dist/cc-orchestrator/codex-session-discovery.js +0 -191
  502. package/dist/cc-orchestrator/codex-session-history.d.ts +0 -38
  503. package/dist/cc-orchestrator/codex-session-history.js +0 -247
  504. package/dist/cc-orchestrator/external-agent-bindings.d.ts +0 -27
  505. package/dist/cc-orchestrator/external-agent-bindings.js +0 -150
  506. package/dist/cc-orchestrator/external-agent-changes.d.ts +0 -19
  507. package/dist/cc-orchestrator/external-agent-changes.js +0 -231
  508. package/dist/cc-orchestrator/external-agent-driver.d.ts +0 -19
  509. package/dist/cc-orchestrator/external-agent-driver.js +0 -284
  510. package/dist/cc-orchestrator/external-agent-session-store.d.ts +0 -23
  511. package/dist/cc-orchestrator/external-agent-session-store.js +0 -146
  512. package/dist/cc-orchestrator/index.d.ts +0 -8
  513. package/dist/cc-orchestrator/index.js +0 -8
  514. package/dist/cc-orchestrator/relevance-judge.d.ts +0 -15
  515. package/dist/cc-orchestrator/relevance-judge.js +0 -29
  516. package/dist/cc-orchestrator/session-discovery.d.ts +0 -46
  517. package/dist/cc-orchestrator/session-discovery.js +0 -125
  518. package/dist/cc-orchestrator/session-history.d.ts +0 -54
  519. package/dist/cc-orchestrator/session-history.js +0 -150
  520. package/dist/cron/cron-runtime.d.ts +0 -2
  521. package/dist/cron/cron-runtime.js +0 -2
  522. package/dist/cron/cron-store.d.ts +0 -2
  523. package/dist/cron/cron-store.js +0 -2
  524. package/dist/cron/scheduler.d.ts +0 -7
  525. package/dist/cron/scheduler.js +0 -7
  526. package/dist/engine/goal.js +0 -206
  527. package/dist/external-agents/config.d.ts +0 -2
  528. package/dist/external-agents/config.js +0 -15
  529. package/dist/external-agents/types.d.ts +0 -31
  530. package/dist/git/parse-log.d.ts +0 -13
  531. package/dist/git/parse-log.js +0 -21
  532. package/dist/git/utils.d.ts +0 -49
  533. package/dist/git/utils.js +0 -161
  534. package/dist/git/worktree/crud.d.ts +0 -72
  535. package/dist/git/worktree/crud.js +0 -235
  536. package/dist/git/worktree/diff.d.ts +0 -14
  537. package/dist/git/worktree/diff.js +0 -82
  538. package/dist/git/worktree/git-exec.d.ts +0 -7
  539. package/dist/git/worktree/git-exec.js +0 -87
  540. package/dist/git/worktree/index.d.ts +0 -5
  541. package/dist/git/worktree/index.js +0 -5
  542. package/dist/git/worktree/query.d.ts +0 -43
  543. package/dist/git/worktree/query.js +0 -128
  544. package/dist/git/worktree/slug.d.ts +0 -11
  545. package/dist/git/worktree/slug.js +0 -58
  546. package/dist/git/worktree.d.ts +0 -1
  547. package/dist/git/worktree.js +0 -5
  548. package/dist/lsp/client.d.ts +0 -41
  549. package/dist/lsp/client.js +0 -186
  550. package/dist/lsp/manager.d.ts +0 -40
  551. package/dist/lsp/manager.js +0 -155
  552. package/dist/lsp/root-path.d.ts +0 -9
  553. package/dist/lsp/root-path.js +0 -12
  554. package/dist/lsp/servers.d.ts +0 -16
  555. package/dist/lsp/servers.js +0 -60
  556. package/dist/prompt/sections/coding.md +0 -35
  557. package/dist/quota/credentials.d.ts +0 -3
  558. package/dist/quota/credentials.js +0 -80
  559. package/dist/quota/index.d.ts +0 -36
  560. package/dist/quota/index.js +0 -155
  561. package/dist/quota/types.d.ts +0 -48
  562. package/dist/quota/types.js +0 -13
  563. package/dist/review/review-prompt.d.ts +0 -28
  564. package/dist/review/review-prompt.js +0 -81
  565. package/dist/state.d.ts +0 -160
  566. package/dist/state.js +0 -267
  567. package/dist/tool-system/builtin/apply-patch/applier.d.ts +0 -26
  568. package/dist/tool-system/builtin/apply-patch/applier.js +0 -308
  569. package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +0 -10
  570. package/dist/tool-system/builtin/apply-patch/backup-targets.js +0 -30
  571. package/dist/tool-system/builtin/apply-patch/index.d.ts +0 -20
  572. package/dist/tool-system/builtin/apply-patch/index.js +0 -105
  573. package/dist/tool-system/builtin/apply-patch/parser.d.ts +0 -17
  574. package/dist/tool-system/builtin/apply-patch/parser.js +0 -212
  575. package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +0 -18
  576. package/dist/tool-system/builtin/apply-patch/seek-sequence.js +0 -123
  577. package/dist/tool-system/builtin/apply-patch/types.d.ts +0 -49
  578. package/dist/tool-system/builtin/apply-patch/types.js +0 -13
  579. package/dist/tool-system/builtin/arena.d.ts +0 -31
  580. package/dist/tool-system/builtin/arena.js +0 -416
  581. package/dist/tool-system/builtin/brief.d.ts +0 -6
  582. package/dist/tool-system/builtin/brief.js +0 -41
  583. package/dist/tool-system/builtin/check-quota.d.ts +0 -15
  584. package/dist/tool-system/builtin/check-quota.js +0 -34
  585. package/dist/tool-system/builtin/drive-claude-code.d.ts +0 -51
  586. package/dist/tool-system/builtin/drive-claude-code.js +0 -698
  587. package/dist/tool-system/builtin/lsp.d.ts +0 -7
  588. package/dist/tool-system/builtin/lsp.js +0 -144
  589. package/dist/tool-system/builtin/notebook-edit.d.ts +0 -7
  590. package/dist/tool-system/builtin/notebook-edit.js +0 -127
  591. package/dist/tool-system/builtin/worktree.d.ts +0 -11
  592. package/dist/tool-system/builtin/worktree.js +0 -363
  593. /package/dist/{external-agents → links}/types.js +0 -0
  594. /package/dist/{engine/session-usage.d.ts → session/usage.d.ts} +0 -0
  595. /package/dist/{engine/session-usage.js → session/usage.js} +0 -0
@@ -1,4 +1,5 @@
1
1
  import { resolve } from "node:path";
2
+ import { valid as validSemver, validRange as validSemverRange } from "semver";
2
3
  import { githubRepoToCloneUrl } from "../gitOps.js";
3
4
  import { PluginInstallError } from "./types.js";
4
5
  /** SSH shorthand `git@host:org/repo.git` — has a `:` after the `git@host` part. */
@@ -9,6 +10,51 @@ function isRemote(s) {
9
10
  const lower = s.toLowerCase();
10
11
  return lower.startsWith("github:") || /^[a-z][a-z0-9+.-]*:\/\//i.test(s) || isSshUrl(s);
11
12
  }
13
+ const MAX_NPM_PACKAGE_NAME = 214;
14
+ const MAX_NPM_SELECTOR = 128;
15
+ const NPM_PACKAGE_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
16
+ const NPM_DIST_TAG = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
17
+ /** Parse the intentionally small npm Phase-A source grammar. */
18
+ export function parseNpmPluginSource(input) {
19
+ if (!input.startsWith("npm:")) {
20
+ throw new PluginInstallError("npm plugin source must start with npm:");
21
+ }
22
+ const spec = input.slice("npm:".length);
23
+ let packageName = spec;
24
+ let selector = "latest";
25
+ // Scoped names contain their own leading '@'. A selector separator is only
26
+ // an '@' after the slash; unscoped names use their last '@'.
27
+ const selectorAt = spec.startsWith("@")
28
+ ? (() => {
29
+ const slash = spec.indexOf("/");
30
+ return slash < 0 ? -1 : spec.lastIndexOf("@") > slash ? spec.lastIndexOf("@") : -1;
31
+ })()
32
+ : spec.lastIndexOf("@");
33
+ if (selectorAt >= 0) {
34
+ packageName = spec.slice(0, selectorAt);
35
+ selector = spec.slice(selectorAt + 1);
36
+ }
37
+ if (packageName.length === 0 ||
38
+ packageName.length > MAX_NPM_PACKAGE_NAME ||
39
+ !NPM_PACKAGE_NAME.test(packageName)) {
40
+ throw new PluginInstallError(`invalid public npm package name: ${packageName || "(empty)"}`);
41
+ }
42
+ const exact = validSemver(selector);
43
+ if (selector.length === 0 ||
44
+ selector.length > MAX_NPM_SELECTOR ||
45
+ (!exact && (!NPM_DIST_TAG.test(selector) || validSemverRange(selector) !== null))) {
46
+ throw new PluginInstallError(`npm selector must be an exact version or dist-tag (ranges are not supported): ${selector || "(empty)"}`);
47
+ }
48
+ const inferredName = packageName.split("/").pop() ?? packageName;
49
+ return {
50
+ kind: "npm",
51
+ packageName,
52
+ selector: exact ?? selector,
53
+ selectorKind: exact ? "exact" : "tag",
54
+ raw: input,
55
+ inferredName,
56
+ };
57
+ }
12
58
  function unsafeTransport(input) {
13
59
  const scheme = input.match(/^([a-z][a-z0-9+.-]*):\/\//i)?.[1]?.toLowerCase();
14
60
  if (!scheme)
@@ -37,6 +83,8 @@ function lastSegment(p) {
37
83
  return p.split("/").filter(Boolean).pop() ?? p;
38
84
  }
39
85
  export function parseSource(input, options = {}) {
86
+ if (input.startsWith("npm:"))
87
+ return parseNpmPluginSource(input);
40
88
  if (!isRemote(input)) {
41
89
  return { kind: "local", path: resolve(input) };
42
90
  }
@@ -0,0 +1,101 @@
1
+ import { type InstallLocalOptions, type LocalPluginSourceInput } from "./installFromArchive.js";
2
+ import { PluginInstallError } from "./types.js";
3
+ export type LocalPluginPreviewWarningKind = "executable-hooks" | "stdio-mcp" | "network-mcp" | "automation-templates" | "external-links" | "media";
4
+ export interface LocalPluginPreviewWarning {
5
+ count: number;
6
+ kind: LocalPluginPreviewWarningKind;
7
+ severity: "warning" | "info";
8
+ }
9
+ export interface LocalPluginHookPreview {
10
+ command: string;
11
+ commandTruncated: boolean;
12
+ event: string;
13
+ matcher?: string;
14
+ matcherTruncated?: boolean;
15
+ }
16
+ export interface LocalPluginMcpPreview {
17
+ command?: string;
18
+ commandTruncated?: boolean;
19
+ name: string;
20
+ transport: "stdio" | "sse" | "streamable-http";
21
+ url?: string;
22
+ urlTruncated?: boolean;
23
+ }
24
+ export interface LocalPluginAutomationTemplatePreview {
25
+ description?: string;
26
+ id: string;
27
+ permissionLevel: "read-only" | "workspace-write" | "full";
28
+ prompt: string;
29
+ promptTruncated: boolean;
30
+ schedule: string;
31
+ timezone?: string;
32
+ title: {
33
+ default: string;
34
+ en?: string;
35
+ "zh-CN"?: string;
36
+ };
37
+ workspace: "current" | "none";
38
+ }
39
+ export interface LocalPluginMediaPreview {
40
+ composerIcon?: string;
41
+ logo?: string;
42
+ logoDark?: string;
43
+ screenshots: string[];
44
+ }
45
+ export interface LocalPluginInterfacePreview {
46
+ brandColor?: string;
47
+ capabilities: string[];
48
+ category?: string;
49
+ defaultPrompt: string[];
50
+ developerName?: string;
51
+ displayName?: string;
52
+ externalLinks: Array<{
53
+ kind: "website" | "privacy" | "terms";
54
+ url: string;
55
+ }>;
56
+ longDescription?: string;
57
+ media: LocalPluginMediaPreview;
58
+ shortDescription?: string;
59
+ }
60
+ export interface LocalPluginPreview {
61
+ agents: string[];
62
+ alreadyInstalled: boolean;
63
+ commands: string[];
64
+ format: "cc" | "codex";
65
+ hooks: LocalPluginHookPreview[];
66
+ installedVersion?: string;
67
+ interface: LocalPluginInterfacePreview;
68
+ mcpServers: LocalPluginMcpPreview[];
69
+ name: string;
70
+ automationTemplates: LocalPluginAutomationTemplatePreview[];
71
+ reviewToken: string;
72
+ skills: Array<{
73
+ description?: string;
74
+ name: string;
75
+ }>;
76
+ source: {
77
+ kind: "dir" | "zip";
78
+ label: string;
79
+ };
80
+ version?: string;
81
+ warnings: LocalPluginPreviewWarning[];
82
+ }
83
+ export declare class LocalPluginReviewChangedError extends PluginInstallError {
84
+ constructor();
85
+ }
86
+ /**
87
+ * Inspect a local directory/zip through the exact runtime projection used by
88
+ * install. No plugin root or installed registry is mutated.
89
+ */
90
+ export declare function previewLocalPlugin(input: LocalPluginSourceInput): Promise<LocalPluginPreview>;
91
+ /**
92
+ * Install exactly the source tree represented by a review token.
93
+ *
94
+ * A private, symlink-free snapshot closes the gap between re-review and
95
+ * installation: after its projection matches the token, the installer reads
96
+ * only that snapshot, never the caller-owned directory or archive again.
97
+ */
98
+ export declare function installReviewedLocalPlugin(input: LocalPluginSourceInput, expectedReviewToken: string, installedAt: string, options?: InstallLocalOptions): Promise<{
99
+ dir: string;
100
+ name: string;
101
+ }>;
@@ -0,0 +1,336 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { cp, lstat, mkdtemp, readFile, readdir, readlink, realpath, rm, stat, } from "node:fs/promises";
4
+ import { basename, join, relative, sep } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+ import { parseFrontmatter } from "../../skills/frontmatter.js";
7
+ import { readInstalledPlugins } from "../installedPlugins.js";
8
+ import { inspectPluginHooks } from "../pluginHookIntegrity.js";
9
+ import { deriveName, installLocalPlugin, normalizePluginName, withLocalPluginSourceRoot, } from "./installFromArchive.js";
10
+ import { readPluginMcp } from "./loadPluginMcp.js";
11
+ import { pluginInstallDir } from "./paths.js";
12
+ import { assertBoundedPluginSource, projectPluginSource } from "./projectPluginSource.js";
13
+ import { PluginInstallError } from "./types.js";
14
+ const MAX_PREVIEW_ITEMS = 256;
15
+ const MAX_PREVIEW_SKILL_BYTES = 512 * 1024;
16
+ const MAX_PREVIEW_TEXT = 240;
17
+ const MAX_PREVIEW_DESCRIPTION = 300;
18
+ const MAX_PREVIEW_MCP_BYTES = 1024 * 1024;
19
+ export class LocalPluginReviewChangedError extends PluginInstallError {
20
+ constructor() {
21
+ super("Plugin source changed after review. Review it again before installing.");
22
+ this.name = "LocalPluginReviewChangedError";
23
+ }
24
+ }
25
+ function truncated(value, max = MAX_PREVIEW_TEXT) {
26
+ if (value.length <= max)
27
+ return { text: value, truncated: false };
28
+ return { text: `${value.slice(0, Math.max(0, max - 1))}…`, truncated: true };
29
+ }
30
+ function ensureItemBound(kind, count) {
31
+ if (count > MAX_PREVIEW_ITEMS) {
32
+ throw new PluginInstallError(`plugin declares more than ${MAX_PREVIEW_ITEMS} ${kind}; preview refused`);
33
+ }
34
+ }
35
+ async function listMarkdownNames(root, recursive) {
36
+ if (!existsSync(root))
37
+ return [];
38
+ const names = [];
39
+ const walk = async (directory) => {
40
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
41
+ const path = join(directory, entry.name);
42
+ if (entry.isDirectory() && recursive) {
43
+ await walk(path);
44
+ continue;
45
+ }
46
+ if (!entry.isFile() || !entry.name.endsWith(".md"))
47
+ continue;
48
+ names.push(relative(root, path).replaceAll(sep, "/").replace(/\.md$/, ""));
49
+ ensureItemBound("entries", names.length);
50
+ }
51
+ };
52
+ await walk(root);
53
+ return names.sort();
54
+ }
55
+ async function listSkills(root) {
56
+ if (!existsSync(root))
57
+ return [];
58
+ const output = [];
59
+ for (const entry of (await readdir(root, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
60
+ if (!entry.isDirectory())
61
+ continue;
62
+ const skillFile = join(root, entry.name, "SKILL.md");
63
+ if (!existsSync(skillFile) || !(await stat(skillFile)).isFile())
64
+ continue;
65
+ const info = await stat(skillFile);
66
+ if (info.size > MAX_PREVIEW_SKILL_BYTES) {
67
+ throw new PluginInstallError(`skills/${entry.name}/SKILL.md exceeds ${MAX_PREVIEW_SKILL_BYTES} bytes`);
68
+ }
69
+ const { frontmatter } = parseFrontmatter(await readFile(skillFile, "utf-8"));
70
+ const description = typeof frontmatter.description === "string"
71
+ ? truncated(frontmatter.description, MAX_PREVIEW_DESCRIPTION).text
72
+ : undefined;
73
+ output.push({ name: entry.name, ...(description ? { description } : {}) });
74
+ ensureItemBound("skills", output.length);
75
+ }
76
+ return output;
77
+ }
78
+ function listHooks(projectionRoot) {
79
+ const snapshot = inspectPluginHooks(projectionRoot);
80
+ if (snapshot.state === "invalid") {
81
+ throw new PluginInstallError(`invalid plugin hooks: ${snapshot.error ?? "unknown error"}`);
82
+ }
83
+ const hooks = [];
84
+ for (const [event, groups] of Object.entries(snapshot.definition?.hooks ?? {})) {
85
+ for (const group of groups ?? []) {
86
+ const matcher = group.matcher ? truncated(group.matcher) : null;
87
+ for (const hook of group.hooks) {
88
+ const command = truncated(hook.command);
89
+ hooks.push({
90
+ event,
91
+ command: command.text,
92
+ commandTruncated: command.truncated,
93
+ ...(matcher
94
+ ? {
95
+ matcher: matcher.text,
96
+ matcherTruncated: matcher.truncated,
97
+ }
98
+ : {}),
99
+ });
100
+ ensureItemBound("hooks", hooks.length);
101
+ }
102
+ }
103
+ }
104
+ return hooks;
105
+ }
106
+ async function assertCcMcpPreviewComplete(projectionRoot, normalizedCount) {
107
+ const path = join(projectionRoot, ".mcp.json");
108
+ if (!existsSync(path))
109
+ return;
110
+ const info = await lstat(path);
111
+ if (info.isSymbolicLink() || !info.isFile() || info.size > MAX_PREVIEW_MCP_BYTES) {
112
+ throw new PluginInstallError("plugin .mcp.json is not a bounded regular file");
113
+ }
114
+ let parsed;
115
+ try {
116
+ parsed = JSON.parse(await readFile(path, "utf-8"));
117
+ }
118
+ catch (error) {
119
+ throw new PluginInstallError(`invalid plugin .mcp.json: ${error instanceof Error ? error.message : String(error)}`);
120
+ }
121
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
122
+ throw new PluginInstallError("plugin .mcp.json root must be an object");
123
+ }
124
+ const raw = "mcpServers" in parsed ? parsed.mcpServers : parsed;
125
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
126
+ throw new PluginInstallError("plugin .mcp.json mcpServers must be an object");
127
+ }
128
+ if (Object.keys(raw).length !== normalizedCount) {
129
+ throw new PluginInstallError("plugin .mcp.json contains invalid MCP server declarations");
130
+ }
131
+ }
132
+ async function listMcp(projectionRoot, pluginName, format) {
133
+ const configs = readPluginMcp(projectionRoot, pluginName);
134
+ if (format === "cc") {
135
+ await assertCcMcpPreviewComplete(projectionRoot, Object.keys(configs).length);
136
+ }
137
+ const output = Object.entries(configs)
138
+ .map(([key, config]) => {
139
+ const transport = config.transport ??
140
+ (config.url && !config.command ? "streamable-http" : "stdio");
141
+ const command = config.command ? truncated(config.command) : null;
142
+ const url = config.url ? truncated(config.url) : null;
143
+ return {
144
+ name: key.startsWith(`${pluginName}:`) ? key.slice(pluginName.length + 1) : key,
145
+ transport: transport === "sse" || transport === "streamable-http" ? transport : "stdio",
146
+ ...(command ? { command: command.text, commandTruncated: command.truncated } : {}),
147
+ ...(url ? { url: url.text, urlTruncated: url.truncated } : {}),
148
+ };
149
+ })
150
+ .sort((a, b) => a.name.localeCompare(b.name));
151
+ ensureItemBound("MCP servers", output.length);
152
+ return output;
153
+ }
154
+ function interfacePreview(value) {
155
+ const externalLinks = [];
156
+ if (value?.websiteURL)
157
+ externalLinks.push({ kind: "website", url: value.websiteURL });
158
+ if (value?.privacyPolicyURL) {
159
+ externalLinks.push({ kind: "privacy", url: value.privacyPolicyURL });
160
+ }
161
+ if (value?.termsOfServiceURL) {
162
+ externalLinks.push({ kind: "terms", url: value.termsOfServiceURL });
163
+ }
164
+ return {
165
+ capabilities: [...(value?.capabilities ?? [])],
166
+ defaultPrompt: [...(value?.defaultPrompt ?? [])],
167
+ externalLinks,
168
+ media: {
169
+ ...(value?.composerIcon ? { composerIcon: value.composerIcon } : {}),
170
+ ...(value?.logo ? { logo: value.logo } : {}),
171
+ ...(value?.logoDark ? { logoDark: value.logoDark } : {}),
172
+ screenshots: [...(value?.screenshots ?? [])],
173
+ },
174
+ ...(value?.displayName ? { displayName: value.displayName } : {}),
175
+ ...(value?.shortDescription ? { shortDescription: value.shortDescription } : {}),
176
+ ...(value?.longDescription ? { longDescription: value.longDescription } : {}),
177
+ ...(value?.developerName ? { developerName: value.developerName } : {}),
178
+ ...(value?.category ? { category: value.category } : {}),
179
+ ...(value?.brandColor ? { brandColor: value.brandColor } : {}),
180
+ };
181
+ }
182
+ function warningsFor(hooks, mcpServers, automationTemplates, metadata) {
183
+ const warnings = [];
184
+ if (hooks.length > 0) {
185
+ warnings.push({ kind: "executable-hooks", severity: "warning", count: hooks.length });
186
+ }
187
+ const stdio = mcpServers.filter((server) => server.transport === "stdio").length;
188
+ const network = mcpServers.length - stdio;
189
+ if (stdio > 0)
190
+ warnings.push({ kind: "stdio-mcp", severity: "warning", count: stdio });
191
+ if (network > 0)
192
+ warnings.push({ kind: "network-mcp", severity: "warning", count: network });
193
+ if (automationTemplates.length > 0) {
194
+ warnings.push({
195
+ kind: "automation-templates",
196
+ severity: "warning",
197
+ count: automationTemplates.length,
198
+ });
199
+ }
200
+ if (metadata.externalLinks.length > 0) {
201
+ warnings.push({
202
+ kind: "external-links",
203
+ severity: "info",
204
+ count: metadata.externalLinks.length,
205
+ });
206
+ }
207
+ const mediaCount = Number(Boolean(metadata.media.composerIcon)) +
208
+ Number(Boolean(metadata.media.logo)) +
209
+ Number(Boolean(metadata.media.logoDark)) +
210
+ metadata.media.screenshots.length;
211
+ if (mediaCount > 0) {
212
+ warnings.push({ kind: "media", severity: "info", count: mediaCount });
213
+ }
214
+ return warnings;
215
+ }
216
+ async function digestProjection(root) {
217
+ const hash = createHash("sha256").update("codeshell-local-plugin-review-v1").update("\0");
218
+ const canonicalRoot = await realpath(root);
219
+ const walk = async (directory) => {
220
+ for (const entry of (await readdir(directory, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
221
+ const path = join(directory, entry.name);
222
+ const rel = relative(canonicalRoot, path).replaceAll(sep, "/");
223
+ // rewritePluginVars intentionally stamps this explanatory breadcrumb
224
+ // with the current time. It does not affect runtime capabilities and
225
+ // must not make two reviews of unchanged source produce different tokens.
226
+ if (rel === ".code-shell-installed.json")
227
+ continue;
228
+ hash.update(rel).update("\0");
229
+ const info = await lstat(path);
230
+ if (info.isDirectory()) {
231
+ hash.update("dir\0");
232
+ await walk(path);
233
+ }
234
+ else if (info.isSymbolicLink()) {
235
+ const target = await readlink(path);
236
+ hash.update("link\0").update(target).update("\0");
237
+ }
238
+ else if (info.isFile()) {
239
+ hash
240
+ .update("file\0")
241
+ .update(await readFile(path))
242
+ .update("\0");
243
+ }
244
+ }
245
+ };
246
+ await walk(canonicalRoot);
247
+ return hash.digest("hex");
248
+ }
249
+ function installedVersion(name) {
250
+ const entries = readInstalledPlugins().plugins[`${name}@local`] ?? [];
251
+ return entries.at(-1)?.version;
252
+ }
253
+ /**
254
+ * Inspect a local directory/zip through the exact runtime projection used by
255
+ * install. No plugin root or installed registry is mutated.
256
+ */
257
+ export async function previewLocalPlugin(input) {
258
+ return withLocalPluginSourceRoot(input, async (sourceRoot) => {
259
+ const name = normalizePluginName(await deriveName(sourceRoot));
260
+ const projectionRoot = await mkdtemp(join(tmpdir(), "cs-plugin-preview-"));
261
+ try {
262
+ const projected = await projectPluginSource(sourceRoot, projectionRoot, name);
263
+ const skills = await listSkills(join(projectionRoot, "skills"));
264
+ const commands = await listMarkdownNames(join(projectionRoot, "commands"), false);
265
+ const agents = await listMarkdownNames(join(projectionRoot, "agents"), true);
266
+ const hooks = listHooks(projectionRoot);
267
+ const mcpServers = await listMcp(projectionRoot, name, projected.format);
268
+ const automationTemplates = (projected.canonicalManifest.automations?.templates ?? []).map((template) => {
269
+ const prompt = truncated(template.prompt, 500);
270
+ return {
271
+ id: template.id,
272
+ title: template.title,
273
+ ...(template.description ? { description: template.description } : {}),
274
+ schedule: template.schedule,
275
+ prompt: prompt.text,
276
+ promptTruncated: prompt.truncated,
277
+ ...(template.timezone ? { timezone: template.timezone } : {}),
278
+ permissionLevel: template.permissionLevel,
279
+ workspace: template.workspace,
280
+ };
281
+ });
282
+ const metadata = interfacePreview(projected.canonicalManifest.interface);
283
+ const reviewToken = await digestProjection(projectionRoot);
284
+ const exists = existsSync(pluginInstallDir(name));
285
+ const currentInstalledVersion = exists ? installedVersion(name) : undefined;
286
+ return {
287
+ name,
288
+ format: projected.format,
289
+ ...(projected.version ? { version: projected.version } : {}),
290
+ source: { kind: input.kind, label: basename(input.path) },
291
+ alreadyInstalled: exists,
292
+ ...(currentInstalledVersion ? { installedVersion: currentInstalledVersion } : {}),
293
+ reviewToken,
294
+ skills,
295
+ commands,
296
+ agents,
297
+ hooks,
298
+ mcpServers,
299
+ automationTemplates,
300
+ interface: metadata,
301
+ warnings: warningsFor(hooks, mcpServers, automationTemplates, metadata),
302
+ };
303
+ }
304
+ finally {
305
+ await rm(projectionRoot, { recursive: true, force: true });
306
+ }
307
+ });
308
+ }
309
+ /**
310
+ * Install exactly the source tree represented by a review token.
311
+ *
312
+ * A private, symlink-free snapshot closes the gap between re-review and
313
+ * installation: after its projection matches the token, the installer reads
314
+ * only that snapshot, never the caller-owned directory or archive again.
315
+ */
316
+ export async function installReviewedLocalPlugin(input, expectedReviewToken, installedAt, options) {
317
+ if (!/^[a-f0-9]{64}$/.test(expectedReviewToken)) {
318
+ throw new PluginInstallError("local plugin review token is invalid");
319
+ }
320
+ return withLocalPluginSourceRoot(input, async (sourceRoot) => {
321
+ const snapshotContainer = await mkdtemp(join(tmpdir(), "cs-plugin-reviewed-"));
322
+ const snapshotRoot = join(snapshotContainer, "source");
323
+ try {
324
+ await assertBoundedPluginSource(sourceRoot);
325
+ await cp(sourceRoot, snapshotRoot, { recursive: true, errorOnExist: true });
326
+ const snapshotPreview = await previewLocalPlugin({ kind: "dir", path: snapshotRoot });
327
+ if (snapshotPreview.reviewToken !== expectedReviewToken) {
328
+ throw new LocalPluginReviewChangedError();
329
+ }
330
+ return await installLocalPlugin({ kind: "dir", path: snapshotRoot }, installedAt, snapshotPreview.name, options);
331
+ }
332
+ finally {
333
+ await rm(snapshotContainer, { recursive: true, force: true });
334
+ }
335
+ });
336
+ }
@@ -0,0 +1,14 @@
1
+ import { type CanonicalPluginManifest as CanonicalPluginManifestData } from "./types.js";
2
+ export interface ProjectedPluginSource {
3
+ canonicalManifest: CanonicalPluginManifestData;
4
+ format: "cc" | "codex";
5
+ version?: string;
6
+ }
7
+ /** Bound local directory input before copying or parsing author-controlled files. */
8
+ export declare function assertBoundedPluginSource(sourceDir: string): Promise<void>;
9
+ /**
10
+ * Build the same CodeShell-native projection used by installation, without
11
+ * touching the plugin root or installed registry. The destination must be a
12
+ * private temporary/staging directory owned by the caller.
13
+ */
14
+ export declare function projectPluginSource(sourceDir: string, destinationRoot: string, name: string): Promise<ProjectedPluginSource>;
@@ -0,0 +1,140 @@
1
+ import { existsSync } from "node:fs";
2
+ import { cp, lstat, readFile, readdir, realpath, stat, writeFile } from "node:fs/promises";
3
+ import { join, relative } from "node:path";
4
+ import { rewritePluginVars } from "../varRewrite.js";
5
+ import { convertCodexAgentsDirectory } from "./codex/convertAgents.js";
6
+ import { copyCodexCommands } from "./codex/convertCommands.js";
7
+ import { copyCodexHooks } from "./codex/convertHooks.js";
8
+ import { resolveCodexMcpServers } from "./codex/convertMcp.js";
9
+ import { copyCodexSkills } from "./codex/convertSkills.js";
10
+ import { detectPluginFormat } from "./detectFormat.js";
11
+ import { normalizePluginMcpMap } from "./loadPluginMcp.js";
12
+ import { normalizePluginManifest } from "./normalizeManifest.js";
13
+ import { CodexPluginManifest, PluginInstallError, } from "./types.js";
14
+ import { PANEL_APP_MANIFEST_FILE } from "../../panel-apps/manifest.js";
15
+ const MAX_PLUGIN_SOURCE_ENTRIES = 10_000;
16
+ const MAX_PLUGIN_SOURCE_BYTES = 256 * 1024 * 1024;
17
+ const MAX_PLUGIN_SOURCE_FILE_BYTES = 64 * 1024 * 1024;
18
+ const MAX_PLUGIN_SOURCE_DEPTH = 32;
19
+ const MAX_PLUGIN_SOURCE_RELATIVE_PATH = 1_024;
20
+ const MAX_PLUGIN_MANIFEST_BYTES = 1024 * 1024;
21
+ async function assertBoundedTreeEntry(root, directory, depth, budget) {
22
+ if (depth > MAX_PLUGIN_SOURCE_DEPTH) {
23
+ throw new PluginInstallError(`plugin source exceeds the maximum directory depth ${MAX_PLUGIN_SOURCE_DEPTH}`);
24
+ }
25
+ const entries = await readdir(directory, { withFileTypes: true });
26
+ for (const entry of entries) {
27
+ budget.entries += 1;
28
+ if (budget.entries > MAX_PLUGIN_SOURCE_ENTRIES) {
29
+ throw new PluginInstallError(`plugin source contains more than ${MAX_PLUGIN_SOURCE_ENTRIES} entries`);
30
+ }
31
+ const path = join(directory, entry.name);
32
+ const rel = relative(root, path);
33
+ if (rel.length > MAX_PLUGIN_SOURCE_RELATIVE_PATH) {
34
+ throw new PluginInstallError(`plugin source path exceeds ${MAX_PLUGIN_SOURCE_RELATIVE_PATH} characters`);
35
+ }
36
+ const info = await lstat(path);
37
+ if (info.isSymbolicLink()) {
38
+ throw new PluginInstallError(`plugin source must not contain symbolic links; link escapes the stable review boundary: ${rel}`);
39
+ }
40
+ if (info.isDirectory()) {
41
+ await assertBoundedTreeEntry(root, path, depth + 1, budget);
42
+ continue;
43
+ }
44
+ if (!info.isFile()) {
45
+ throw new PluginInstallError(`plugin source contains an unsupported file type: ${rel}`);
46
+ }
47
+ if (info.size > MAX_PLUGIN_SOURCE_FILE_BYTES) {
48
+ throw new PluginInstallError(`plugin source file exceeds ${MAX_PLUGIN_SOURCE_FILE_BYTES} bytes: ${rel}`);
49
+ }
50
+ budget.bytes += info.size;
51
+ if (budget.bytes > MAX_PLUGIN_SOURCE_BYTES) {
52
+ throw new PluginInstallError(`plugin source exceeds the ${MAX_PLUGIN_SOURCE_BYTES} byte size limit`);
53
+ }
54
+ }
55
+ }
56
+ /** Bound local directory input before copying or parsing author-controlled files. */
57
+ export async function assertBoundedPluginSource(sourceDir) {
58
+ let root;
59
+ try {
60
+ root = await realpath(sourceDir);
61
+ }
62
+ catch {
63
+ throw new PluginInstallError(`source is not a readable directory: ${sourceDir}`);
64
+ }
65
+ if (!(await stat(root)).isDirectory()) {
66
+ throw new PluginInstallError(`source is not a directory: ${sourceDir}`);
67
+ }
68
+ await assertBoundedTreeEntry(root, root, 0, { bytes: 0, entries: 0 });
69
+ }
70
+ async function readBoundedJson(path) {
71
+ const info = await stat(path);
72
+ if (!info.isFile() || info.size > MAX_PLUGIN_MANIFEST_BYTES) {
73
+ throw new PluginInstallError(`plugin manifest must be a regular file no larger than ${MAX_PLUGIN_MANIFEST_BYTES} bytes`);
74
+ }
75
+ try {
76
+ const parsed = JSON.parse(await readFile(path, "utf-8"));
77
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
78
+ throw new Error("manifest root must be an object");
79
+ }
80
+ return parsed;
81
+ }
82
+ catch (error) {
83
+ if (error instanceof PluginInstallError)
84
+ throw error;
85
+ throw new PluginInstallError(`invalid plugin manifest: ${error instanceof Error ? error.message : String(error)}`);
86
+ }
87
+ }
88
+ /**
89
+ * Build the same CodeShell-native projection used by installation, without
90
+ * touching the plugin root or installed registry. The destination must be a
91
+ * private temporary/staging directory owned by the caller.
92
+ */
93
+ export async function projectPluginSource(sourceDir, destinationRoot, name) {
94
+ if (existsSync(join(sourceDir, PANEL_APP_MANIFEST_FILE))) {
95
+ throw new PluginInstallError(`Panel App packages use a separate installer; remove ${PANEL_APP_MANIFEST_FILE} from the agent plugin source`);
96
+ }
97
+ await assertBoundedPluginSource(sourceDir);
98
+ const format = detectPluginFormat(sourceDir);
99
+ let version;
100
+ await cp(sourceDir, destinationRoot, { recursive: true });
101
+ if (format === "codex") {
102
+ const manifest = CodexPluginManifest.parse(await readBoundedJson(join(sourceDir, ".codex-plugin", "plugin.json")));
103
+ version = manifest.version;
104
+ await copyCodexSkills(sourceDir, destinationRoot);
105
+ await convertCodexAgentsDirectory(sourceDir, destinationRoot, name);
106
+ await copyCodexCommands(sourceDir, destinationRoot);
107
+ await copyCodexHooks(sourceDir, destinationRoot, manifest.hooks);
108
+ const servers = resolveCodexMcpServers(sourceDir, manifest.mcpServers);
109
+ const keyed = {};
110
+ for (const [serverName, config] of Object.entries(servers)) {
111
+ const key = `${name}:${serverName}`;
112
+ keyed[key] = { ...config, name: key };
113
+ }
114
+ if (Object.keys(keyed).length > 0) {
115
+ const normalized = normalizePluginMcpMap(keyed, name, true);
116
+ if (Object.keys(normalized).length !== Object.keys(keyed).length) {
117
+ throw new PluginInstallError("invalid plugin MCP server declaration");
118
+ }
119
+ await writeFile(join(destinationRoot, "mcp-servers.json"), JSON.stringify(normalized, null, 2));
120
+ }
121
+ }
122
+ else {
123
+ const manifestPath = join(sourceDir, ".claude-plugin", "plugin.json");
124
+ if (existsSync(manifestPath)) {
125
+ const manifest = await readBoundedJson(manifestPath);
126
+ version =
127
+ typeof manifest.version === "string" && manifest.version.length > 0
128
+ ? manifest.version
129
+ : undefined;
130
+ }
131
+ }
132
+ const canonicalManifest = await normalizePluginManifest(sourceDir, {
133
+ name,
134
+ version,
135
+ format,
136
+ destinationRoot,
137
+ });
138
+ rewritePluginVars(destinationRoot);
139
+ return { canonicalManifest, format, version };
140
+ }