@cjhyy/code-shell-core 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (594) 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/permission.d.ts +26 -0
  374. package/dist/tool-system/permission.js +46 -0
  375. package/dist/tool-system/registry.d.ts +12 -1
  376. package/dist/tool-system/registry.js +31 -7
  377. package/dist/tool-system/sandbox/index.js +3 -8
  378. package/dist/tool-system/sandbox/seatbelt.js +2 -6
  379. package/dist/tool-system/session-tool-host.d.ts +139 -0
  380. package/dist/tool-system/session-tool-host.js +167 -0
  381. package/dist/tool-system/testing/tool-registry-harness.d.ts +31 -0
  382. package/dist/tool-system/testing/tool-registry-harness.js +51 -0
  383. package/dist/tool-system/validation.d.ts +14 -7
  384. package/dist/tool-system/validation.js +701 -7
  385. package/dist/types.d.ts +186 -20
  386. package/dist/{cc-orchestrator → utils}/cwd-normalize.d.ts +1 -0
  387. package/dist/{cc-orchestrator → utils}/cwd-normalize.js +1 -0
  388. package/dist/utils/file-mutex.d.ts +65 -0
  389. package/dist/utils/file-mutex.js +145 -0
  390. package/dist/utils/json.d.ts +2 -4
  391. package/dist/utils/json.js +2 -4
  392. package/dist/utils/lockfile.d.ts +30 -1
  393. package/dist/utils/lockfile.js +2 -2
  394. package/dist/utils/secret-scrubber.d.ts +8 -0
  395. package/dist/utils/secret-scrubber.js +227 -0
  396. package/dist/utils/toolDisplay.js +1 -1
  397. package/package.json +20 -5
  398. package/THIRD_PARTY_NOTICES.md +0 -206
  399. package/dist/arena/arena.d.ts +0 -45
  400. package/dist/arena/arena.js +0 -362
  401. package/dist/arena/context/context-tools.d.ts +0 -16
  402. package/dist/arena/context/context-tools.js +0 -272
  403. package/dist/arena/context/within-root.d.ts +0 -7
  404. package/dist/arena/context/within-root.js +0 -15
  405. package/dist/arena/detect-mode.d.ts +0 -20
  406. package/dist/arena/detect-mode.js +0 -78
  407. package/dist/arena/digest-builder.d.ts +0 -25
  408. package/dist/arena/digest-builder.js +0 -120
  409. package/dist/arena/index.d.ts +0 -29
  410. package/dist/arena/index.js +0 -29
  411. package/dist/arena/iterate/convergence.d.ts +0 -25
  412. package/dist/arena/iterate/convergence.js +0 -103
  413. package/dist/arena/iterate/formats/index.d.ts +0 -22
  414. package/dist/arena/iterate/formats/index.js +0 -283
  415. package/dist/arena/iterate/index.d.ts +0 -11
  416. package/dist/arena/iterate/index.js +0 -9
  417. package/dist/arena/iterate/iterative-arena.d.ts +0 -23
  418. package/dist/arena/iterate/iterative-arena.js +0 -237
  419. package/dist/arena/iterate/parse.d.ts +0 -42
  420. package/dist/arena/iterate/parse.js +0 -123
  421. package/dist/arena/iterate/phases/argue.d.ts +0 -22
  422. package/dist/arena/iterate/phases/argue.js +0 -165
  423. package/dist/arena/iterate/phases/revise.d.ts +0 -16
  424. package/dist/arena/iterate/phases/revise.js +0 -62
  425. package/dist/arena/iterate/phases/tournament.d.ts +0 -34
  426. package/dist/arena/iterate/phases/tournament.js +0 -113
  427. package/dist/arena/iterate/tools/web-tools.d.ts +0 -13
  428. package/dist/arena/iterate/tools/web-tools.js +0 -54
  429. package/dist/arena/iterate/types.d.ts +0 -152
  430. package/dist/arena/iterate/types.js +0 -8
  431. package/dist/arena/ledger.d.ts +0 -47
  432. package/dist/arena/ledger.js +0 -159
  433. package/dist/arena/lenses/architecture.d.ts +0 -5
  434. package/dist/arena/lenses/architecture.js +0 -22
  435. package/dist/arena/lenses/engineering.d.ts +0 -5
  436. package/dist/arena/lenses/engineering.js +0 -22
  437. package/dist/arena/lenses/general.d.ts +0 -5
  438. package/dist/arena/lenses/general.js +0 -20
  439. package/dist/arena/lenses/index.d.ts +0 -16
  440. package/dist/arena/lenses/index.js +0 -47
  441. package/dist/arena/lenses/product.d.ts +0 -5
  442. package/dist/arena/lenses/product.js +0 -22
  443. package/dist/arena/model-presets.d.ts +0 -23
  444. package/dist/arena/model-presets.js +0 -44
  445. package/dist/arena/phases/adjudication.d.ts +0 -25
  446. package/dist/arena/phases/adjudication.js +0 -142
  447. package/dist/arena/phases/build-consensus.d.ts +0 -30
  448. package/dist/arena/phases/build-consensus.js +0 -85
  449. package/dist/arena/phases/claim-registry.d.ts +0 -26
  450. package/dist/arena/phases/claim-registry.js +0 -60
  451. package/dist/arena/phases/cross-review.d.ts +0 -47
  452. package/dist/arena/phases/cross-review.js +0 -224
  453. package/dist/arena/phases/debate-rounds.d.ts +0 -28
  454. package/dist/arena/phases/debate-rounds.js +0 -161
  455. package/dist/arena/phases/participant-research.d.ts +0 -39
  456. package/dist/arena/phases/participant-research.js +0 -316
  457. package/dist/arena/phases/planning-detail-expansion.d.ts +0 -39
  458. package/dist/arena/phases/planning-detail-expansion.js +0 -120
  459. package/dist/arena/planner.d.ts +0 -28
  460. package/dist/arena/planner.js +0 -312
  461. package/dist/arena/providers/docs.d.ts +0 -7
  462. package/dist/arena/providers/docs.js +0 -111
  463. package/dist/arena/providers/git.d.ts +0 -8
  464. package/dist/arena/providers/git.js +0 -174
  465. package/dist/arena/providers/index.d.ts +0 -32
  466. package/dist/arena/providers/index.js +0 -132
  467. package/dist/arena/providers/none.d.ts +0 -7
  468. package/dist/arena/providers/none.js +0 -11
  469. package/dist/arena/providers/repo.d.ts +0 -7
  470. package/dist/arena/providers/repo.js +0 -258
  471. package/dist/arena/render/session.d.ts +0 -17
  472. package/dist/arena/render/session.js +0 -190
  473. package/dist/arena/render/terminal.d.ts +0 -34
  474. package/dist/arena/render/terminal.js +0 -286
  475. package/dist/arena/strategies/discussion.d.ts +0 -25
  476. package/dist/arena/strategies/discussion.js +0 -143
  477. package/dist/arena/strategies/index.d.ts +0 -15
  478. package/dist/arena/strategies/index.js +0 -28
  479. package/dist/arena/strategies/language-wrapper.d.ts +0 -17
  480. package/dist/arena/strategies/language-wrapper.js +0 -102
  481. package/dist/arena/strategies/lens-wrapper.d.ts +0 -16
  482. package/dist/arena/strategies/lens-wrapper.js +0 -236
  483. package/dist/arena/strategies/planning.d.ts +0 -30
  484. package/dist/arena/strategies/planning.js +0 -225
  485. package/dist/arena/strategies/review.d.ts +0 -26
  486. package/dist/arena/strategies/review.js +0 -168
  487. package/dist/arena/strategies/utils.d.ts +0 -36
  488. package/dist/arena/strategies/utils.js +0 -603
  489. package/dist/arena/tools/selector.d.ts +0 -17
  490. package/dist/arena/tools/selector.js +0 -61
  491. package/dist/arena/transitions.d.ts +0 -53
  492. package/dist/arena/transitions.js +0 -97
  493. package/dist/arena/types.d.ts +0 -518
  494. package/dist/arena/types.js +0 -27
  495. package/dist/cc-orchestrator/agent-adapter.d.ts +0 -54
  496. package/dist/cc-orchestrator/agent-adapter.js +0 -143
  497. package/dist/cc-orchestrator/cc-capability.d.ts +0 -19
  498. package/dist/cc-orchestrator/cc-capability.js +0 -53
  499. package/dist/cc-orchestrator/codex-session-discovery.d.ts +0 -24
  500. package/dist/cc-orchestrator/codex-session-discovery.js +0 -191
  501. package/dist/cc-orchestrator/codex-session-history.d.ts +0 -38
  502. package/dist/cc-orchestrator/codex-session-history.js +0 -247
  503. package/dist/cc-orchestrator/external-agent-bindings.d.ts +0 -27
  504. package/dist/cc-orchestrator/external-agent-bindings.js +0 -150
  505. package/dist/cc-orchestrator/external-agent-changes.d.ts +0 -19
  506. package/dist/cc-orchestrator/external-agent-changes.js +0 -231
  507. package/dist/cc-orchestrator/external-agent-driver.d.ts +0 -19
  508. package/dist/cc-orchestrator/external-agent-driver.js +0 -284
  509. package/dist/cc-orchestrator/external-agent-session-store.d.ts +0 -23
  510. package/dist/cc-orchestrator/external-agent-session-store.js +0 -146
  511. package/dist/cc-orchestrator/index.d.ts +0 -8
  512. package/dist/cc-orchestrator/index.js +0 -8
  513. package/dist/cc-orchestrator/relevance-judge.d.ts +0 -15
  514. package/dist/cc-orchestrator/relevance-judge.js +0 -29
  515. package/dist/cc-orchestrator/session-discovery.d.ts +0 -46
  516. package/dist/cc-orchestrator/session-discovery.js +0 -125
  517. package/dist/cc-orchestrator/session-history.d.ts +0 -54
  518. package/dist/cc-orchestrator/session-history.js +0 -150
  519. package/dist/cron/cron-runtime.d.ts +0 -2
  520. package/dist/cron/cron-runtime.js +0 -2
  521. package/dist/cron/cron-store.d.ts +0 -2
  522. package/dist/cron/cron-store.js +0 -2
  523. package/dist/cron/scheduler.d.ts +0 -7
  524. package/dist/cron/scheduler.js +0 -7
  525. package/dist/engine/goal.js +0 -206
  526. package/dist/external-agents/config.d.ts +0 -2
  527. package/dist/external-agents/config.js +0 -15
  528. package/dist/external-agents/types.d.ts +0 -31
  529. package/dist/git/parse-log.d.ts +0 -13
  530. package/dist/git/parse-log.js +0 -21
  531. package/dist/git/utils.d.ts +0 -49
  532. package/dist/git/utils.js +0 -161
  533. package/dist/git/worktree/crud.d.ts +0 -72
  534. package/dist/git/worktree/crud.js +0 -235
  535. package/dist/git/worktree/diff.d.ts +0 -14
  536. package/dist/git/worktree/diff.js +0 -82
  537. package/dist/git/worktree/git-exec.d.ts +0 -7
  538. package/dist/git/worktree/git-exec.js +0 -87
  539. package/dist/git/worktree/index.d.ts +0 -5
  540. package/dist/git/worktree/index.js +0 -5
  541. package/dist/git/worktree/query.d.ts +0 -43
  542. package/dist/git/worktree/query.js +0 -128
  543. package/dist/git/worktree/slug.d.ts +0 -11
  544. package/dist/git/worktree/slug.js +0 -58
  545. package/dist/git/worktree.d.ts +0 -1
  546. package/dist/git/worktree.js +0 -5
  547. package/dist/lsp/client.d.ts +0 -41
  548. package/dist/lsp/client.js +0 -186
  549. package/dist/lsp/manager.d.ts +0 -40
  550. package/dist/lsp/manager.js +0 -155
  551. package/dist/lsp/root-path.d.ts +0 -9
  552. package/dist/lsp/root-path.js +0 -12
  553. package/dist/lsp/servers.d.ts +0 -16
  554. package/dist/lsp/servers.js +0 -60
  555. package/dist/prompt/sections/coding.md +0 -35
  556. package/dist/quota/credentials.d.ts +0 -3
  557. package/dist/quota/credentials.js +0 -80
  558. package/dist/quota/index.d.ts +0 -36
  559. package/dist/quota/index.js +0 -155
  560. package/dist/quota/types.d.ts +0 -48
  561. package/dist/quota/types.js +0 -13
  562. package/dist/review/review-prompt.d.ts +0 -28
  563. package/dist/review/review-prompt.js +0 -81
  564. package/dist/state.d.ts +0 -160
  565. package/dist/state.js +0 -267
  566. package/dist/tool-system/builtin/apply-patch/applier.d.ts +0 -26
  567. package/dist/tool-system/builtin/apply-patch/applier.js +0 -308
  568. package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +0 -10
  569. package/dist/tool-system/builtin/apply-patch/backup-targets.js +0 -30
  570. package/dist/tool-system/builtin/apply-patch/index.d.ts +0 -20
  571. package/dist/tool-system/builtin/apply-patch/index.js +0 -105
  572. package/dist/tool-system/builtin/apply-patch/parser.d.ts +0 -17
  573. package/dist/tool-system/builtin/apply-patch/parser.js +0 -212
  574. package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +0 -18
  575. package/dist/tool-system/builtin/apply-patch/seek-sequence.js +0 -123
  576. package/dist/tool-system/builtin/apply-patch/types.d.ts +0 -49
  577. package/dist/tool-system/builtin/apply-patch/types.js +0 -13
  578. package/dist/tool-system/builtin/arena.d.ts +0 -31
  579. package/dist/tool-system/builtin/arena.js +0 -416
  580. package/dist/tool-system/builtin/brief.d.ts +0 -6
  581. package/dist/tool-system/builtin/brief.js +0 -41
  582. package/dist/tool-system/builtin/check-quota.d.ts +0 -15
  583. package/dist/tool-system/builtin/check-quota.js +0 -34
  584. package/dist/tool-system/builtin/drive-claude-code.d.ts +0 -51
  585. package/dist/tool-system/builtin/drive-claude-code.js +0 -698
  586. package/dist/tool-system/builtin/lsp.d.ts +0 -7
  587. package/dist/tool-system/builtin/lsp.js +0 -144
  588. package/dist/tool-system/builtin/notebook-edit.d.ts +0 -7
  589. package/dist/tool-system/builtin/notebook-edit.js +0 -127
  590. package/dist/tool-system/builtin/worktree.d.ts +0 -11
  591. package/dist/tool-system/builtin/worktree.js +0 -363
  592. /package/dist/{external-agents → links}/types.js +0 -0
  593. /package/dist/{engine/session-usage.d.ts → session/usage.d.ts} +0 -0
  594. /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
+ }