@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
@@ -5,12 +5,16 @@
5
5
  * MVP subset (single-level commands directory, no nested subcommands,
6
6
  * no inline-via-plugin.json commands).
7
7
  */
8
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
9
- import { join } from "node:path";
8
+ import { closeSync, constants, existsSync, fstatSync, openSync, readdirSync, readSync, realpathSync, statSync, } from "node:fs";
9
+ import { isAbsolute, join, relative, sep } from "node:path";
10
10
  import { homedir } from "node:os";
11
11
  import { memoize } from "../utils/memoize.js";
12
12
  import { parseFrontmatter, coerceDescription } from "../skills/frontmatter.js";
13
13
  import { installedPluginsPath, readInstalledPlugins } from "./installedPlugins.js";
14
+ /** Bounded prompt contribution limits shared by Desktop, TUI, and protocol hosts. */
15
+ export const MAX_PLUGIN_COMMAND_FILE_BYTES = 256 * 1024;
16
+ export const MAX_PLUGIN_COMMAND_ARGUMENT_CHARS = 32 * 1024;
17
+ export const MAX_PLUGIN_COMMAND_EXPANDED_CHARS = 512 * 1024;
14
18
  function isENOENT(e) {
15
19
  return (typeof e === "object" && e !== null && "code" in e && e.code === "ENOENT");
16
20
  }
@@ -18,14 +22,34 @@ function isInaccessible(e) {
18
22
  if (typeof e !== "object" || e === null || !("code" in e))
19
23
  return false;
20
24
  const code = e.code;
21
- return code === "EACCES" || code === "EPERM" || code === "EIO";
25
+ return code === "EACCES" || code === "EPERM" || code === "EIO" || code === "ELOOP";
22
26
  }
23
27
  function userHome() {
24
28
  return process.env.HOME ?? homedir();
25
29
  }
26
30
  function readCommandFile(filePath) {
31
+ let fd;
27
32
  try {
28
- return readFileSync(filePath, "utf-8");
33
+ fd = openSync(filePath, constants.O_RDONLY | constants.O_NOFOLLOW);
34
+ const stat = fstatSync(fd);
35
+ if (!stat.isFile() || stat.size > MAX_PLUGIN_COMMAND_FILE_BYTES)
36
+ return null;
37
+ const chunks = [];
38
+ let total = 0;
39
+ while (true) {
40
+ const remaining = MAX_PLUGIN_COMMAND_FILE_BYTES + 1 - total;
41
+ if (remaining <= 0)
42
+ return null;
43
+ const chunk = Buffer.allocUnsafe(Math.min(64 * 1024, remaining));
44
+ const bytesRead = readSync(fd, chunk, 0, chunk.length, null);
45
+ if (bytesRead === 0)
46
+ break;
47
+ total += bytesRead;
48
+ if (total > MAX_PLUGIN_COMMAND_FILE_BYTES)
49
+ return null;
50
+ chunks.push(chunk.subarray(0, bytesRead));
51
+ }
52
+ return Buffer.concat(chunks, total).toString("utf-8");
29
53
  }
30
54
  catch (e) {
31
55
  if (isENOENT(e))
@@ -37,6 +61,29 @@ function readCommandFile(filePath) {
37
61
  }
38
62
  throw e;
39
63
  }
64
+ finally {
65
+ if (fd !== undefined)
66
+ closeSync(fd);
67
+ }
68
+ }
69
+ /**
70
+ * Resolve a plugin contribution through symlinks and require it to remain
71
+ * inside its declared owner directory. Installed plugin trees are untrusted:
72
+ * without this check `commands -> /some/private/dir` or `command.md` symlinks
73
+ * could make the host read arbitrary local Markdown and expose it as a prompt.
74
+ */
75
+ function resolveContainedPath(root, candidate) {
76
+ try {
77
+ const realRoot = realpathSync(root);
78
+ const realCandidate = realpathSync(candidate);
79
+ const rel = relative(realRoot, realCandidate);
80
+ if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel))
81
+ return null;
82
+ return realCandidate;
83
+ }
84
+ catch {
85
+ return null;
86
+ }
40
87
  }
41
88
  function scanOnce() {
42
89
  const data = readInstalledPlugins();
@@ -51,14 +98,17 @@ function scanOnce() {
51
98
  const commandsDir = join(entry.installPath, "commands");
52
99
  if (!existsSync(commandsDir))
53
100
  continue;
101
+ const resolvedCommandsDir = resolveContainedPath(entry.installPath, commandsDir);
102
+ if (!resolvedCommandsDir)
103
+ continue;
54
104
  let dirEntries;
55
105
  try {
56
- dirEntries = readdirSync(commandsDir, { withFileTypes: true });
106
+ dirEntries = readdirSync(resolvedCommandsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
57
107
  }
58
108
  catch (e) {
59
109
  if (isInaccessible(e)) {
60
110
  // eslint-disable-next-line no-console
61
- console.warn(`[plugin-commands] cannot read ${commandsDir}: ${e.message}`);
111
+ console.warn(`[plugin-commands] cannot read ${resolvedCommandsDir}: ${e.message}`);
62
112
  continue;
63
113
  }
64
114
  throw e;
@@ -68,7 +118,17 @@ function scanOnce() {
68
118
  continue;
69
119
  if (!dirent.name.endsWith(".md"))
70
120
  continue;
71
- const filePath = join(commandsDir, dirent.name);
121
+ const filePath = resolveContainedPath(resolvedCommandsDir, join(resolvedCommandsDir, dirent.name));
122
+ if (!filePath)
123
+ continue;
124
+ try {
125
+ const fileStat = statSync(filePath);
126
+ if (!fileStat.isFile() || fileStat.size > MAX_PLUGIN_COMMAND_FILE_BYTES)
127
+ continue;
128
+ }
129
+ catch {
130
+ continue;
131
+ }
72
132
  const raw = readCommandFile(filePath);
73
133
  if (raw === null)
74
134
  continue;
@@ -112,3 +172,117 @@ export function scanPluginCommands() {
112
172
  export function invalidatePluginCommandsCache() {
113
173
  memoized.cache.clear?.();
114
174
  }
175
+ function parsePluginCommandArguments(input) {
176
+ const tokens = [];
177
+ let current = "";
178
+ let quote = null;
179
+ let escaping = false;
180
+ const push = () => {
181
+ if (current.length === 0)
182
+ return;
183
+ tokens.push(current);
184
+ current = "";
185
+ };
186
+ for (const character of input.trim()) {
187
+ if (escaping) {
188
+ current += character;
189
+ escaping = false;
190
+ continue;
191
+ }
192
+ if (character === "\\" && quote !== "'") {
193
+ escaping = true;
194
+ continue;
195
+ }
196
+ if (quote) {
197
+ if (character === quote)
198
+ quote = null;
199
+ else
200
+ current += character;
201
+ continue;
202
+ }
203
+ if (character === "'" || character === '"') {
204
+ quote = character;
205
+ continue;
206
+ }
207
+ if (/\s/u.test(character)) {
208
+ push();
209
+ continue;
210
+ }
211
+ current += character;
212
+ }
213
+ if (escaping)
214
+ current += "\\";
215
+ push();
216
+ const positional = [];
217
+ const named = new Map();
218
+ for (const token of tokens) {
219
+ const assignment = /^([A-Z][A-Z0-9_]*)=(.*)$/u.exec(token);
220
+ if (assignment)
221
+ named.set(assignment[1], assignment[2]);
222
+ else
223
+ positional.push(token);
224
+ }
225
+ return { positional, named };
226
+ }
227
+ export function describePluginCommands(commands, disabledPluginNames = new Set()) {
228
+ return commands
229
+ .filter((command) => !disabledPluginNames.has(command.pluginName))
230
+ .map((command) => ({
231
+ name: command.name,
232
+ pluginName: command.pluginName,
233
+ description: command.description,
234
+ ...(command.argumentHint ? { argumentHint: command.argumentHint } : {}),
235
+ }))
236
+ .sort((left, right) => left.name.localeCompare(right.name));
237
+ }
238
+ const PLUGIN_COMMAND_PLACEHOLDER = /\$\$|\$ARGUMENTS|\{args\}|\$([1-9])|\$([A-Z][A-Z0-9_]*)(?![A-Z0-9_])/gu;
239
+ function pluginCommandReplacement(token, positionalIndex, namedPlaceholder, rawArguments, parsed) {
240
+ if (token === "$$")
241
+ return "$";
242
+ if (token === "$ARGUMENTS" || token === "{args}")
243
+ return rawArguments;
244
+ if (positionalIndex)
245
+ return parsed.positional[Number(positionalIndex) - 1] ?? "";
246
+ if (namedPlaceholder && parsed.named.has(namedPlaceholder)) {
247
+ return parsed.named.get(namedPlaceholder);
248
+ }
249
+ return token;
250
+ }
251
+ function assertExpansionBudget(body, rawArguments, parsed) {
252
+ if (Buffer.byteLength(body, "utf-8") > MAX_PLUGIN_COMMAND_FILE_BYTES) {
253
+ throw new Error(`plugin command body exceeds ${MAX_PLUGIN_COMMAND_FILE_BYTES} bytes`);
254
+ }
255
+ if (rawArguments.length > MAX_PLUGIN_COMMAND_ARGUMENT_CHARS) {
256
+ throw new Error(`plugin command arguments exceed ${MAX_PLUGIN_COMMAND_ARGUMENT_CHARS} characters`);
257
+ }
258
+ let projected = body.length;
259
+ for (const match of body.matchAll(PLUGIN_COMMAND_PLACEHOLDER)) {
260
+ projected +=
261
+ pluginCommandReplacement(match[0], match[1], match[2], rawArguments, parsed).length -
262
+ match[0].length;
263
+ if (projected > MAX_PLUGIN_COMMAND_EXPANDED_CHARS)
264
+ break;
265
+ }
266
+ if (projected > MAX_PLUGIN_COMMAND_EXPANDED_CHARS) {
267
+ throw new Error(`expanded plugin command exceeds ${MAX_PLUGIN_COMMAND_EXPANDED_CHARS} characters`);
268
+ }
269
+ }
270
+ /**
271
+ * Expand CC/CodeShell and deprecated Codex custom-prompt placeholders.
272
+ *
273
+ * Codex plugins in the wild still ship `prompts/*.md`, so compatibility needs
274
+ * `$1`…`$9`, named `KEY=value` placeholders, `$ARGUMENTS`, and `$$` literals
275
+ * even though new upstream workflows are expected to use skills.
276
+ */
277
+ export function expandPluginCommandBody(body, rawArguments = "") {
278
+ if (rawArguments.length > MAX_PLUGIN_COMMAND_ARGUMENT_CHARS) {
279
+ throw new Error(`plugin command arguments exceed ${MAX_PLUGIN_COMMAND_ARGUMENT_CHARS} characters`);
280
+ }
281
+ const parsed = parsePluginCommandArguments(rawArguments);
282
+ assertExpansionBudget(body, rawArguments, parsed);
283
+ const expanded = body.replace(PLUGIN_COMMAND_PLACEHOLDER, (token, positionalIndex, namedPlaceholder) => pluginCommandReplacement(token, positionalIndex, namedPlaceholder, rawArguments, parsed));
284
+ if (expanded.length > MAX_PLUGIN_COMMAND_EXPANDED_CHARS) {
285
+ throw new Error(`expanded plugin command exceeds ${MAX_PLUGIN_COMMAND_EXPANDED_CHARS} characters`);
286
+ }
287
+ return expanded;
288
+ }
@@ -6,6 +6,11 @@
6
6
  * loaders use so the inventory can't drift from what actually loads.
7
7
  */
8
8
  import { type PluginHookEntry } from "./loadPluginHooks.js";
9
+ import { type PluginHookReview } from "./pluginHookApproval.js";
10
+ import { type PluginAutomationTemplate } from "./installer/types.js";
11
+ export type PluginAutomationTemplateDescriptor = PluginAutomationTemplate & {
12
+ revision: string;
13
+ };
9
14
  export interface PluginContentInventory {
10
15
  /** skills/<name>/SKILL.md — name + frontmatter description when present. */
11
16
  skills: {
@@ -18,8 +23,12 @@ export interface PluginContentInventory {
18
23
  agents: string[];
19
24
  /** hooks/hooks.json entries (event + command), owner-filtered. */
20
25
  hooks: PluginHookEntry[];
26
+ /** Current hook definition compared with the last explicitly approved snapshot. */
27
+ hookReview?: PluginHookReview;
21
28
  /** MCP server names as merged (keyed `<plugin>:<server>` — bare name here). */
22
29
  mcpServers: string[];
30
+ /** Reusable scheduled-task templates; never instantiated automatically. */
31
+ automationTemplates: PluginAutomationTemplateDescriptor[];
23
32
  }
24
33
  /**
25
34
  * Inventory one plugin's contributions. `pluginName` is the bare name (no
@@ -27,4 +36,4 @@ export interface PluginContentInventory {
27
36
  * scanners the runtime loaders use (filtered to this plugin) so naming —
28
37
  * e.g. MCP's `<plugin>:<server>` record keys — matches what users see live.
29
38
  */
30
- export declare function describePluginContent(pluginName: string, installPath: string): PluginContentInventory;
39
+ export declare function describePluginContent(pluginName: string, installPath: string, installKey?: string): PluginContentInventory;
@@ -5,17 +5,46 @@
5
5
  * actually installs (feedback#15). Read-only; reuses the same parsers the
6
6
  * loaders use so the inventory can't drift from what actually loads.
7
7
  */
8
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
9
- import { join } from "node:path";
8
+ import { readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
9
+ import { isAbsolute, join, relative, sep } from "node:path";
10
10
  import { parseFrontmatter } from "../skills/frontmatter.js";
11
11
  import { listPluginHooks } from "./loadPluginHooks.js";
12
- import { mergePluginMcpServers } from "./installer/loadPluginMcp.js";
13
- function listMdNames(dir) {
14
- if (!existsSync(dir))
12
+ import { reviewPluginHooks } from "./pluginHookApproval.js";
13
+ import { readPluginMcp } from "./installer/loadPluginMcp.js";
14
+ import { CANONICAL_PLUGIN_MANIFEST_FILE, CanonicalPluginManifest, } from "./installer/types.js";
15
+ import { pluginAutomationTemplateRevision } from "./pluginCatalog.js";
16
+ function resolveContainedPath(root, candidate) {
17
+ try {
18
+ const realRoot = realpathSync(root);
19
+ const realCandidate = realpathSync(candidate);
20
+ const rel = relative(realRoot, realCandidate);
21
+ if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel))
22
+ return null;
23
+ return realCandidate;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ function listMdNames(installPath, dirName) {
30
+ const dir = resolveContainedPath(installPath, join(installPath, dirName));
31
+ if (!dir)
15
32
  return [];
16
33
  try {
17
34
  return readdirSync(dir)
18
- .filter((f) => f.endsWith(".md"))
35
+ .filter((file) => {
36
+ if (!file.endsWith(".md"))
37
+ return false;
38
+ const target = resolveContainedPath(dir, join(dir, file));
39
+ if (!target)
40
+ return false;
41
+ try {
42
+ return statSync(target).isFile();
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ })
19
48
  .map((f) => f.replace(/\.md$/, ""))
20
49
  .sort();
21
50
  }
@@ -24,15 +53,18 @@ function listMdNames(dir) {
24
53
  }
25
54
  }
26
55
  function listSkills(installPath) {
27
- const dir = join(installPath, "skills");
28
- if (!existsSync(dir))
56
+ const dir = resolveContainedPath(installPath, join(installPath, "skills"));
57
+ if (!dir)
29
58
  return [];
30
59
  const out = [];
31
60
  try {
32
61
  for (const entry of readdirSync(dir).sort()) {
33
- const skillMd = join(dir, entry, "SKILL.md");
34
62
  try {
35
- if (!statSync(join(dir, entry)).isDirectory() || !existsSync(skillMd))
63
+ const skillDir = resolveContainedPath(dir, join(dir, entry));
64
+ if (!skillDir || !statSync(skillDir).isDirectory())
65
+ continue;
66
+ const skillMd = resolveContainedPath(skillDir, join(skillDir, "SKILL.md"));
67
+ if (!skillMd || !statSync(skillMd).isFile())
36
68
  continue;
37
69
  const { frontmatter } = parseFrontmatter(readFileSync(skillMd, "utf-8"));
38
70
  const desc = typeof frontmatter.description === "string" ? frontmatter.description : undefined;
@@ -54,30 +86,55 @@ function listSkills(installPath) {
54
86
  * scanners the runtime loaders use (filtered to this plugin) so naming —
55
87
  * e.g. MCP's `<plugin>:<server>` record keys — matches what users see live.
56
88
  */
57
- export function describePluginContent(pluginName, installPath) {
89
+ export function describePluginContent(pluginName, installPath, installKey) {
58
90
  const mcpPrefix = `${pluginName}:`;
59
- let mcpServers = [];
60
- try {
61
- mcpServers = Object.keys(mergePluginMcpServers({}))
62
- .filter((k) => k.startsWith(mcpPrefix))
63
- .map((k) => k.slice(mcpPrefix.length))
64
- .sort();
65
- }
66
- catch {
67
- mcpServers = [];
68
- }
69
- let hooks = [];
70
- try {
71
- hooks = listPluginHooks().filter((h) => h.plugin === pluginName);
72
- }
73
- catch {
74
- hooks = [];
75
- }
91
+ const mcpServers = (() => {
92
+ try {
93
+ return Object.keys(readPluginMcp(installPath, pluginName))
94
+ .filter((k) => k.startsWith(mcpPrefix))
95
+ .map((k) => k.slice(mcpPrefix.length))
96
+ .sort();
97
+ }
98
+ catch {
99
+ return [];
100
+ }
101
+ })();
102
+ const hooks = (() => {
103
+ try {
104
+ return listPluginHooks().filter((h) => h.plugin === pluginName && (installKey === undefined || h.installKey === installKey));
105
+ }
106
+ catch {
107
+ return [];
108
+ }
109
+ })();
110
+ const hookReview = (() => {
111
+ if (!installKey)
112
+ return undefined;
113
+ try {
114
+ return reviewPluginHooks(installKey)[0];
115
+ }
116
+ catch {
117
+ return undefined;
118
+ }
119
+ })();
120
+ const manifest = (() => {
121
+ try {
122
+ return CanonicalPluginManifest.parse(JSON.parse(readFileSync(join(installPath, CANONICAL_PLUGIN_MANIFEST_FILE), "utf-8")));
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ })();
76
128
  return {
77
129
  skills: listSkills(installPath),
78
- commands: listMdNames(join(installPath, "commands")),
79
- agents: listMdNames(join(installPath, "agents")),
130
+ commands: listMdNames(installPath, "commands"),
131
+ agents: listMdNames(installPath, "agents"),
80
132
  hooks,
133
+ ...(hookReview ? { hookReview } : {}),
81
134
  mcpServers,
135
+ automationTemplates: (manifest?.automations?.templates ?? []).map((template) => ({
136
+ ...template,
137
+ revision: pluginAutomationTemplateRevision(installKey ?? pluginName, template),
138
+ })),
82
139
  };
83
140
  }
@@ -0,0 +1,30 @@
1
+ import { type PluginHookApprovalState } from "./pluginHookIntegrity.js";
2
+ import type { StoredPluginHookReview } from "./types.js";
3
+ export interface PluginHookApprovalResult {
4
+ installKey: string;
5
+ plugin: string;
6
+ status: PluginHookApprovalState;
7
+ changed: boolean;
8
+ }
9
+ export interface PluginHookReviewDiffItem {
10
+ change: "added" | "removed" | "changed" | "unchanged";
11
+ current?: StoredPluginHookReview;
12
+ previous?: StoredPluginHookReview;
13
+ }
14
+ export interface PluginHookReview {
15
+ installKey: string;
16
+ plugin: string;
17
+ status: PluginHookApprovalState;
18
+ baselineAvailable: boolean;
19
+ items: PluginHookReviewDiffItem[];
20
+ error?: string;
21
+ }
22
+ /** Review current hooks against the last explicitly approved per-command snapshot. */
23
+ export declare function reviewPluginHooks(target: string): PluginHookReview[];
24
+ /** Approve the exact install-time digest; changed-on-disk hooks cannot be blessed. */
25
+ export declare function approvePluginHooks(target: string): PluginHookApprovalResult[];
26
+ /**
27
+ * Revoke hook execution. Legacy entries are first migrated to a recorded
28
+ * digest so revocation fails closed instead of falling back to legacy trust.
29
+ */
30
+ export declare function revokePluginHooks(target: string): PluginHookApprovalResult[];
@@ -0,0 +1,160 @@
1
+ import { readInstalledPlugins, writeInstalledPlugins } from "./installedPlugins.js";
2
+ import { inspectPluginHooks, pluginHookReviewSnapshot, pluginHookApprovalState, } from "./pluginHookIntegrity.js";
3
+ function pluginNameFromKey(key) {
4
+ const at = key.lastIndexOf("@");
5
+ return at > 0 ? key.slice(0, at) : key;
6
+ }
7
+ function matchingInstallKeys(data, target) {
8
+ if (!target.trim())
9
+ throw new Error("plugin hook approval requires a plugin name or install key");
10
+ if (data.plugins[target])
11
+ return [target];
12
+ const matches = Object.keys(data.plugins).filter((key) => pluginNameFromKey(key) === target);
13
+ if (matches.length === 0)
14
+ throw new Error(`plugin "${target}" is not installed`);
15
+ if (matches.length > 1) {
16
+ throw new Error(`plugin "${target}" has multiple installs; use one of: ${matches.join(", ")}`);
17
+ }
18
+ return matches;
19
+ }
20
+ function result(installKey, entry, changed, snapshot) {
21
+ return {
22
+ installKey,
23
+ plugin: pluginNameFromKey(installKey),
24
+ status: pluginHookApprovalState(entry, snapshot),
25
+ changed,
26
+ };
27
+ }
28
+ function sameReviewHook(a, b) {
29
+ return (a.rawEvent === b.rawEvent &&
30
+ a.matcher === b.matcher &&
31
+ a.commandDigest === b.commandDigest &&
32
+ a.async === b.async &&
33
+ a.timeoutMs === b.timeoutMs);
34
+ }
35
+ function diffHookReview(current, previous) {
36
+ if (previous === undefined)
37
+ return current.map((hook) => ({ change: "added", current: hook }));
38
+ const unused = new Set(previous.map((_, index) => index));
39
+ const items = [];
40
+ for (const hook of current) {
41
+ const exact = [...unused].find((index) => sameReviewHook(hook, previous[index]));
42
+ if (exact !== undefined) {
43
+ unused.delete(exact);
44
+ items.push({ change: "unchanged", current: hook, previous: previous[exact] });
45
+ continue;
46
+ }
47
+ let changed = [...unused].find((index) => {
48
+ const old = previous[index];
49
+ return (old.rawEvent === hook.rawEvent &&
50
+ (old.commandDigest === hook.commandDigest || old.matcher === hook.matcher));
51
+ });
52
+ // If both command and matcher changed, pair the remaining command at the
53
+ // same event when that match is unambiguous instead of presenting a noisy
54
+ // remove+add pair.
55
+ if (changed === undefined) {
56
+ const sameEvent = [...unused].filter((index) => previous[index].rawEvent === hook.rawEvent);
57
+ if (sameEvent.length === 1)
58
+ changed = sameEvent[0];
59
+ }
60
+ if (changed !== undefined) {
61
+ unused.delete(changed);
62
+ items.push({ change: "changed", current: hook, previous: previous[changed] });
63
+ continue;
64
+ }
65
+ items.push({ change: "added", current: hook });
66
+ }
67
+ for (const index of unused)
68
+ items.push({ change: "removed", previous: previous[index] });
69
+ return items;
70
+ }
71
+ function review(installKey, entry) {
72
+ const snapshot = inspectPluginHooks(entry.installPath);
73
+ return {
74
+ installKey,
75
+ plugin: pluginNameFromKey(installKey),
76
+ status: pluginHookApprovalState(entry, snapshot),
77
+ baselineAvailable: entry.approvedHookSnapshot !== undefined,
78
+ items: diffHookReview(pluginHookReviewSnapshot(snapshot), entry.approvedHookSnapshot),
79
+ ...(snapshot.error ? { error: snapshot.error } : {}),
80
+ };
81
+ }
82
+ /** Review current hooks against the last explicitly approved per-command snapshot. */
83
+ export function reviewPluginHooks(target) {
84
+ const data = readInstalledPlugins();
85
+ return matchingInstallKeys(data, target).flatMap((installKey) => (data.plugins[installKey] ?? []).map((entry) => review(installKey, entry)));
86
+ }
87
+ /** Approve the exact install-time digest; changed-on-disk hooks cannot be blessed. */
88
+ export function approvePluginHooks(target) {
89
+ const data = readInstalledPlugins();
90
+ const keys = matchingInstallKeys(data, target);
91
+ const out = [];
92
+ let writeNeeded = false;
93
+ for (const installKey of keys) {
94
+ for (const entry of data.plugins[installKey] ?? []) {
95
+ let entryChanged = false;
96
+ const snapshot = inspectPluginHooks(entry.installPath);
97
+ if (snapshot.state === "invalid") {
98
+ throw new Error(`plugin "${installKey}" hooks definition is invalid and cannot be approved: ${snapshot.error ?? "unknown error"}`);
99
+ }
100
+ if (entry.hookDigest && snapshot.digest !== entry.hookDigest) {
101
+ throw new Error(`plugin "${installKey}" hooks changed after install; reinstall or update before approving`);
102
+ }
103
+ if (!entry.hookDigest) {
104
+ entry.hookDigest = snapshot.digest;
105
+ entryChanged = true;
106
+ writeNeeded = true;
107
+ }
108
+ if (entry.approvedHookDigest !== entry.hookDigest) {
109
+ entry.approvedHookDigest = entry.hookDigest;
110
+ entryChanged = true;
111
+ writeNeeded = true;
112
+ }
113
+ const nextReview = pluginHookReviewSnapshot(snapshot);
114
+ if (JSON.stringify(entry.approvedHookSnapshot) !== JSON.stringify(nextReview)) {
115
+ entry.approvedHookSnapshot = nextReview;
116
+ entryChanged = true;
117
+ writeNeeded = true;
118
+ }
119
+ out.push(result(installKey, entry, entryChanged, snapshot));
120
+ }
121
+ }
122
+ if (writeNeeded)
123
+ writeInstalledPlugins(data);
124
+ return out;
125
+ }
126
+ /**
127
+ * Revoke hook execution. Legacy entries are first migrated to a recorded
128
+ * digest so revocation fails closed instead of falling back to legacy trust.
129
+ */
130
+ export function revokePluginHooks(target) {
131
+ const data = readInstalledPlugins();
132
+ const keys = matchingInstallKeys(data, target);
133
+ const out = [];
134
+ let writeNeeded = false;
135
+ for (const installKey of keys) {
136
+ for (const entry of data.plugins[installKey] ?? []) {
137
+ let entryChanged = false;
138
+ const snapshot = inspectPluginHooks(entry.installPath);
139
+ if (!entry.hookDigest) {
140
+ entry.hookDigest = snapshot.digest;
141
+ entryChanged = true;
142
+ }
143
+ if (snapshot.hasExecutableHooks || snapshot.state === "invalid") {
144
+ if (entry.approvedHookDigest !== undefined) {
145
+ delete entry.approvedHookDigest;
146
+ entryChanged = true;
147
+ }
148
+ }
149
+ else if (entry.approvedHookDigest !== entry.hookDigest) {
150
+ entry.approvedHookDigest = entry.hookDigest;
151
+ entryChanged = true;
152
+ }
153
+ writeNeeded ||= entryChanged;
154
+ out.push(result(installKey, entry, entryChanged, snapshot));
155
+ }
156
+ }
157
+ if (writeNeeded)
158
+ writeInstalledPlugins(data);
159
+ return out;
160
+ }