@cjhyy/code-shell-core 0.7.1 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (595) hide show
  1. package/README.md +36 -23
  2. package/dist/agent/agent-definition-registry.d.ts +2 -2
  3. package/dist/agent/agent-definition-registry.js +47 -10
  4. package/dist/agent/agent-definition.d.ts +5 -0
  5. package/dist/agent/agent-definition.js +14 -0
  6. package/dist/automation/index.d.ts +7 -4
  7. package/dist/automation/index.js +4 -2
  8. package/dist/automation/runner.js +3 -1
  9. package/dist/automation/scheduler.d.ts +57 -1
  10. package/dist/automation/scheduler.js +123 -23
  11. package/dist/automation/store.d.ts +6 -2
  12. package/dist/automation/store.js +7 -3
  13. package/dist/capabilities/index.d.ts +109 -0
  14. package/dist/capabilities/index.js +80 -0
  15. package/dist/capability-control/disabled-lists.d.ts +2 -1
  16. package/dist/capability-control/disabled-lists.js +3 -5
  17. package/dist/capability-control/overlay.d.ts +14 -1
  18. package/dist/capability-control/overlay.js +40 -0
  19. package/dist/capability-control/service.js +6 -4
  20. package/dist/cli/agent-server-stdio.d.ts +1 -1
  21. package/dist/cli/agent-server-stdio.js +66 -6
  22. package/dist/cli/agent-server-tcp.js +7 -3
  23. package/dist/context/compaction.d.ts +39 -3
  24. package/dist/context/compaction.js +151 -39
  25. package/dist/context/manager.d.ts +17 -1
  26. package/dist/context/manager.js +36 -1
  27. package/dist/credentials/access.d.ts +3 -1
  28. package/dist/credentials/access.js +24 -3
  29. package/dist/credentials/index.d.ts +1 -1
  30. package/dist/credentials/index.js +1 -1
  31. package/dist/credentials/oauth.d.ts +4 -1
  32. package/dist/credentials/oauth.js +14 -0
  33. package/dist/credentials/store.d.ts +15 -1
  34. package/dist/credentials/store.js +17 -4
  35. package/dist/credentials/types.d.ts +24 -0
  36. package/dist/credentials/use-credential-tool.js +15 -1
  37. package/dist/engine/auxiliary-pipeline.d.ts +40 -0
  38. package/dist/engine/auxiliary-pipeline.js +181 -0
  39. package/dist/{settings → engine}/disk-defaults.d.ts +2 -2
  40. package/dist/{settings → engine}/disk-defaults.js +5 -2
  41. package/dist/engine/dynamic-tool-defs.d.ts +4 -0
  42. package/dist/engine/dynamic-tool-defs.js +4 -0
  43. package/dist/engine/engine.d.ts +254 -195
  44. package/dist/engine/engine.js +1812 -2041
  45. package/dist/engine/file-history-hook.d.ts +11 -0
  46. package/dist/engine/file-history-hook.js +31 -0
  47. package/dist/engine/goal-judge-context.d.ts +9 -0
  48. package/dist/engine/goal-judge-context.js +234 -0
  49. package/dist/engine/injected-context-cache.d.ts +6 -0
  50. package/dist/engine/injected-context-cache.js +13 -0
  51. package/dist/engine/input-attachments.d.ts +1 -1
  52. package/dist/engine/model-facade.d.ts +3 -3
  53. package/dist/engine/model-facade.js +15 -14
  54. package/dist/engine/permission-controller.d.ts +55 -0
  55. package/dist/engine/permission-controller.js +148 -0
  56. package/dist/engine/prompt-cache-diagnostics.d.ts +58 -0
  57. package/dist/engine/prompt-cache-diagnostics.js +178 -0
  58. package/dist/engine/run-accounting.d.ts +41 -0
  59. package/dist/engine/run-accounting.js +126 -0
  60. package/dist/engine/run-context.d.ts +44 -0
  61. package/dist/engine/run-context.js +88 -0
  62. package/dist/engine/run-environment.d.ts +30 -0
  63. package/dist/engine/run-environment.js +77 -0
  64. package/dist/engine/run-finalize.d.ts +58 -0
  65. package/dist/engine/run-finalize.js +245 -0
  66. package/dist/engine/run-goal.d.ts +58 -0
  67. package/dist/engine/run-goal.js +188 -0
  68. package/dist/engine/run-image-input.d.ts +1 -1
  69. package/dist/engine/run-image-input.js +5 -3
  70. package/dist/engine/run-session-open.d.ts +41 -0
  71. package/dist/engine/run-session-open.js +186 -0
  72. package/dist/engine/run-setup.d.ts +42 -0
  73. package/dist/engine/run-setup.js +58 -0
  74. package/dist/engine/run-tooling.d.ts +125 -0
  75. package/dist/engine/run-tooling.js +283 -0
  76. package/dist/engine/run-types.d.ts +139 -0
  77. package/dist/engine/run-types.js +12 -0
  78. package/dist/engine/run-workspace.d.ts +50 -0
  79. package/dist/engine/run-workspace.js +114 -0
  80. package/dist/engine/steer-queue.d.ts +1 -1
  81. package/dist/engine/subagent-spawner.d.ts +32 -0
  82. package/dist/engine/subagent-spawner.js +287 -0
  83. package/dist/engine/tool-summary.d.ts +2 -2
  84. package/dist/engine/tool-summary.js +2 -2
  85. package/dist/engine/turn-loop.d.ts +49 -10
  86. package/dist/engine/turn-loop.js +370 -104
  87. package/dist/engine/types.d.ts +30 -3
  88. package/dist/engine/types.js +1 -1
  89. package/dist/{engine/goal.d.ts → goal/lifecycle.d.ts} +76 -4
  90. package/dist/goal/lifecycle.js +482 -0
  91. package/dist/hooks/events.d.ts +24 -10
  92. package/dist/hooks/goal-stop-hook.d.ts +17 -28
  93. package/dist/hooks/goal-stop-hook.js +110 -465
  94. package/dist/hooks/registry.js +1 -1
  95. package/dist/index.d.ts +48 -108
  96. package/dist/index.extension.d.ts +51 -0
  97. package/dist/index.extension.js +39 -0
  98. package/dist/index.internal.d.ts +86 -0
  99. package/dist/index.internal.js +92 -0
  100. package/dist/index.js +34 -123
  101. package/dist/links/cli.d.ts +48 -0
  102. package/dist/links/cli.js +617 -0
  103. package/dist/links/http.d.ts +40 -0
  104. package/dist/links/http.js +166 -0
  105. package/dist/links/index.d.ts +4 -0
  106. package/dist/links/index.js +3 -0
  107. package/dist/links/link-action-tool.d.ts +5 -0
  108. package/dist/links/link-action-tool.js +241 -0
  109. package/dist/links/providers.d.ts +8 -0
  110. package/dist/links/providers.js +665 -0
  111. package/dist/links/types.d.ts +44 -0
  112. package/dist/llm/client-base.d.ts +7 -0
  113. package/dist/llm/client-base.js +60 -0
  114. package/dist/llm/model-pool.d.ts +1 -1
  115. package/dist/llm/model-pool.js +1 -1
  116. package/dist/llm/providers/anthropic.d.ts +1 -0
  117. package/dist/llm/providers/anthropic.js +9 -0
  118. package/dist/llm/providers/openai.d.ts +1 -0
  119. package/dist/llm/providers/openai.js +17 -0
  120. package/dist/model-catalog/index.js +15 -2
  121. package/dist/model-catalog/resolve.d.ts +13 -1
  122. package/dist/model-catalog/resolve.js +37 -2
  123. package/dist/model-catalog/types.d.ts +74 -48
  124. package/dist/model-catalog/types.js +16 -5
  125. package/dist/model-catalog/upsert.d.ts +3 -1
  126. package/dist/model-catalog/upsert.js +9 -0
  127. package/dist/onboarding.d.ts +0 -1
  128. package/dist/onboarding.js +1 -22
  129. package/dist/panel-apps/bindings.d.ts +24 -0
  130. package/dist/panel-apps/bindings.js +69 -0
  131. package/dist/panel-apps/github-archive.d.ts +21 -0
  132. package/dist/panel-apps/github-archive.js +98 -0
  133. package/dist/panel-apps/index.d.ts +4 -0
  134. package/dist/panel-apps/index.js +4 -0
  135. package/dist/panel-apps/installer.d.ts +68 -0
  136. package/dist/panel-apps/installer.js +622 -0
  137. package/dist/panel-apps/manifest.d.ts +364 -0
  138. package/dist/panel-apps/manifest.js +189 -0
  139. package/dist/panel-apps/paths.d.ts +13 -0
  140. package/dist/panel-apps/paths.js +38 -0
  141. package/dist/panel-apps/registry.d.ts +51 -0
  142. package/dist/panel-apps/registry.js +99 -0
  143. package/dist/panel-apps/runtime.d.ts +80 -0
  144. package/dist/panel-apps/runtime.js +154 -0
  145. package/dist/plugins/gitOps.js +8 -1
  146. package/dist/plugins/installedPlugins.d.ts +2 -1
  147. package/dist/plugins/installedPlugins.js +146 -8
  148. package/dist/plugins/installer/codex/convertAgents.d.ts +4 -1
  149. package/dist/plugins/installer/codex/convertAgents.js +62 -8
  150. package/dist/plugins/installer/codex/convertCommands.d.ts +5 -5
  151. package/dist/plugins/installer/codex/convertCommands.js +35 -12
  152. package/dist/plugins/installer/codex/convertHooks.d.ts +10 -0
  153. package/dist/plugins/installer/codex/convertHooks.js +82 -0
  154. package/dist/plugins/installer/codex/convertSkills.js +41 -6
  155. package/dist/plugins/installer/install.d.ts +7 -1
  156. package/dist/plugins/installer/install.js +21 -87
  157. package/dist/plugins/installer/installFromArchive.d.ts +26 -4
  158. package/dist/plugins/installer/installFromArchive.js +44 -27
  159. package/dist/plugins/installer/installFromNpm.d.ts +31 -0
  160. package/dist/plugins/installer/installFromNpm.js +273 -0
  161. package/dist/plugins/installer/loadPluginAgents.js +17 -4
  162. package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
  163. package/dist/plugins/installer/loadPluginMcp.js +245 -35
  164. package/dist/plugins/installer/normalizeManifest.d.ts +13 -0
  165. package/dist/plugins/installer/normalizeManifest.js +306 -0
  166. package/dist/plugins/installer/npmTar.d.ts +13 -0
  167. package/dist/plugins/installer/npmTar.js +321 -0
  168. package/dist/plugins/installer/parseSource.d.ts +11 -0
  169. package/dist/plugins/installer/parseSource.js +48 -0
  170. package/dist/plugins/installer/preview.d.ts +101 -0
  171. package/dist/plugins/installer/preview.js +336 -0
  172. package/dist/plugins/installer/projectPluginSource.d.ts +14 -0
  173. package/dist/plugins/installer/projectPluginSource.js +140 -0
  174. package/dist/plugins/installer/types.d.ts +775 -0
  175. package/dist/plugins/installer/types.js +100 -0
  176. package/dist/plugins/installer/unzip.d.ts +11 -0
  177. package/dist/plugins/installer/unzip.js +123 -9
  178. package/dist/plugins/installer/update.d.ts +2 -2
  179. package/dist/plugins/installer/update.js +43 -4
  180. package/dist/plugins/loadPluginHooks.d.ts +19 -2
  181. package/dist/plugins/loadPluginHooks.js +97 -86
  182. package/dist/plugins/pluginAutomationTemplates.d.ts +18 -0
  183. package/dist/plugins/pluginAutomationTemplates.js +50 -0
  184. package/dist/plugins/pluginCatalog.d.ts +45 -0
  185. package/dist/plugins/pluginCatalog.js +87 -0
  186. package/dist/plugins/pluginCommandHook.d.ts +6 -0
  187. package/dist/plugins/pluginCommandHook.js +25 -8
  188. package/dist/plugins/pluginCommandsLoader.d.ts +19 -0
  189. package/dist/plugins/pluginCommandsLoader.js +181 -7
  190. package/dist/plugins/pluginContent.d.ts +10 -1
  191. package/dist/plugins/pluginContent.js +87 -30
  192. package/dist/plugins/pluginHookApproval.d.ts +30 -0
  193. package/dist/plugins/pluginHookApproval.js +160 -0
  194. package/dist/plugins/pluginHookIntegrity.d.ts +69 -0
  195. package/dist/plugins/pluginHookIntegrity.js +361 -0
  196. package/dist/plugins/pluginInstaller.js +71 -12
  197. package/dist/plugins/pluginMcpApproval.d.ts +19 -0
  198. package/dist/plugins/pluginMcpApproval.js +110 -0
  199. package/dist/plugins/pluginMcpIntegrity.d.ts +21 -0
  200. package/dist/plugins/pluginMcpIntegrity.js +74 -0
  201. package/dist/plugins/types.d.ts +30 -0
  202. package/dist/plugins/varRewrite.d.ts +9 -5
  203. package/dist/plugins/varRewrite.js +26 -17
  204. package/dist/preset/index.d.ts +11 -8
  205. package/dist/preset/index.js +62 -203
  206. package/dist/product/define.js +9 -3
  207. package/dist/product/types.d.ts +0 -2
  208. package/dist/profile/activation.d.ts +36 -0
  209. package/dist/profile/activation.js +57 -0
  210. package/dist/profile/catalog-store.d.ts +77 -0
  211. package/dist/profile/catalog-store.js +346 -0
  212. package/dist/profile/catalog.d.ts +54 -0
  213. package/dist/profile/catalog.js +152 -0
  214. package/dist/profile/index.d.ts +7 -0
  215. package/dist/profile/index.js +7 -0
  216. package/dist/profile/requirements.d.ts +76 -0
  217. package/dist/profile/requirements.js +117 -0
  218. package/dist/profile/resolve.d.ts +11 -0
  219. package/dist/profile/resolve.js +41 -0
  220. package/dist/profile/store.d.ts +17 -0
  221. package/dist/profile/store.js +167 -0
  222. package/dist/profile/types.d.ts +321 -0
  223. package/dist/profile/types.js +104 -0
  224. package/dist/prompt/composer.d.ts +46 -7
  225. package/dist/prompt/composer.js +78 -48
  226. package/dist/prompt/instruction-scanner.d.ts +6 -5
  227. package/dist/prompt/instruction-scanner.js +8 -23
  228. package/dist/prompt/section-loader.d.ts +2 -2
  229. package/dist/prompt/section-loader.js +7 -4
  230. package/dist/prompt/sections/browser.md +10 -9
  231. package/dist/prompt/sections/harness-base.md +9 -0
  232. package/dist/protocol/chat-session-manager.d.ts +64 -1
  233. package/dist/protocol/chat-session-manager.js +104 -0
  234. package/dist/protocol/chat-session.d.ts +61 -10
  235. package/dist/protocol/chat-session.js +135 -25
  236. package/dist/protocol/client.d.ts +33 -3
  237. package/dist/protocol/client.js +96 -5
  238. package/dist/protocol/index.d.ts +2 -2
  239. package/dist/protocol/index.js +2 -2
  240. package/dist/protocol/mobile-remote-types.d.ts +406 -0
  241. package/dist/protocol/mobile-remote-types.js +1 -0
  242. package/dist/protocol/server.d.ts +127 -3
  243. package/dist/protocol/server.js +1309 -182
  244. package/dist/protocol/types.d.ts +152 -34
  245. package/dist/protocol/types.js +16 -0
  246. package/dist/run/ArtifactTracker.d.ts +6 -1
  247. package/dist/run/ArtifactTracker.js +29 -21
  248. package/dist/run/EngineRunner.d.ts +2 -0
  249. package/dist/run/EngineRunner.js +1 -0
  250. package/dist/run/RunManager.d.ts +26 -0
  251. package/dist/run/RunManager.js +82 -11
  252. package/dist/run/factory.d.ts +3 -0
  253. package/dist/run/factory.js +2 -0
  254. package/dist/runtime/safe-spawn.d.ts +6 -0
  255. package/dist/runtime/safe-spawn.js +8 -13
  256. package/dist/services/auto-dream.d.ts +13 -1
  257. package/dist/services/auto-dream.js +56 -8
  258. package/dist/services/dream-consolidation.js +10 -1
  259. package/dist/services/memory-orchestrator.js +6 -2
  260. package/dist/services/oauth.js +4 -1
  261. package/dist/services/session-memory.d.ts +4 -4
  262. package/dist/services/session-memory.js +13 -10
  263. package/dist/session/memory.d.ts +26 -7
  264. package/dist/session/memory.js +79 -21
  265. package/dist/session/session-manager.d.ts +182 -28
  266. package/dist/session/session-manager.js +910 -130
  267. package/dist/session/session-message.d.ts +22 -0
  268. package/dist/session/session-message.js +1 -0
  269. package/dist/session/transcript.d.ts +46 -5
  270. package/dist/session/transcript.js +159 -3
  271. package/dist/settings/feature-flags.d.ts +40 -0
  272. package/dist/settings/feature-flags.js +40 -0
  273. package/dist/settings/manager.d.ts +39 -1
  274. package/dist/settings/manager.js +102 -41
  275. package/dist/settings/migrate-config.js +4 -2
  276. package/dist/settings/schema.d.ts +511 -177
  277. package/dist/settings/schema.js +98 -25
  278. package/dist/skills/scanner.d.ts +6 -2
  279. package/dist/skills/scanner.js +160 -9
  280. package/dist/sources/adapter.d.ts +14 -0
  281. package/dist/sources/adapter.js +7 -0
  282. package/dist/sources/adapters/local-files.d.ts +10 -0
  283. package/dist/sources/adapters/local-files.js +127 -0
  284. package/dist/sources/adapters/mcp-resource.d.ts +17 -0
  285. package/dist/sources/adapters/mcp-resource.js +41 -0
  286. package/dist/sources/adapters/mock.d.ts +3 -0
  287. package/dist/sources/adapters/mock.js +29 -0
  288. package/dist/sources/binding.d.ts +6 -0
  289. package/dist/sources/binding.js +24 -0
  290. package/dist/sources/catalog.d.ts +6 -0
  291. package/dist/sources/catalog.js +64 -0
  292. package/dist/sources/context-summary.d.ts +8 -0
  293. package/dist/sources/context-summary.js +13 -0
  294. package/dist/sources/credential-status.d.ts +2 -0
  295. package/dist/sources/credential-status.js +13 -0
  296. package/dist/sources/index.d.ts +10 -0
  297. package/dist/sources/index.js +10 -0
  298. package/dist/sources/resolve.d.ts +28 -0
  299. package/dist/sources/resolve.js +47 -0
  300. package/dist/sources/truncate-utf8.d.ts +7 -0
  301. package/dist/sources/truncate-utf8.js +18 -0
  302. package/dist/sources/types.d.ts +71 -0
  303. package/dist/sources/types.js +26 -0
  304. package/dist/testing/fetch-stub.d.ts +32 -0
  305. package/dist/testing/fetch-stub.js +24 -0
  306. package/dist/themes/image.d.ts +18 -0
  307. package/dist/themes/image.js +117 -0
  308. package/dist/themes/index.d.ts +4 -0
  309. package/dist/themes/index.js +4 -0
  310. package/dist/themes/installer.d.ts +50 -0
  311. package/dist/themes/installer.js +290 -0
  312. package/dist/themes/manifest.d.ts +102 -0
  313. package/dist/themes/manifest.js +86 -0
  314. package/dist/themes/paths.d.ts +14 -0
  315. package/dist/themes/paths.js +33 -0
  316. package/dist/tool-system/browser-bridge.d.ts +53 -11
  317. package/dist/tool-system/browser-bridge.js +8 -9
  318. package/dist/tool-system/builtin/agent-heartbeat.d.ts +2 -2
  319. package/dist/tool-system/builtin/agent-heartbeat.js +20 -6
  320. package/dist/tool-system/builtin/agent-notifications.d.ts +127 -72
  321. package/dist/tool-system/builtin/agent-notifications.js +291 -101
  322. package/dist/tool-system/builtin/agent-output-file.js +1 -3
  323. package/dist/tool-system/builtin/agent-progress.d.ts +6 -0
  324. package/dist/tool-system/builtin/agent-progress.js +83 -0
  325. package/dist/tool-system/builtin/agent-registry.d.ts +38 -2
  326. package/dist/tool-system/builtin/agent-registry.js +178 -9
  327. package/dist/tool-system/builtin/agent-transcript-translator.js +1 -1
  328. package/dist/tool-system/builtin/agent.d.ts +2 -0
  329. package/dist/tool-system/builtin/agent.js +274 -33
  330. package/dist/tool-system/builtin/background-jobs.d.ts +55 -2
  331. package/dist/tool-system/builtin/background-jobs.js +96 -4
  332. package/dist/tool-system/builtin/background-work.d.ts +6 -0
  333. package/dist/tool-system/builtin/background-work.js +8 -1
  334. package/dist/tool-system/builtin/bash.js +5 -2
  335. package/dist/tool-system/builtin/browser-tools.d.ts +6 -3
  336. package/dist/tool-system/builtin/browser-tools.js +89 -23
  337. package/dist/tool-system/builtin/edit-model-catalog.d.ts +6 -0
  338. package/dist/tool-system/builtin/edit-model-catalog.js +172 -12
  339. package/dist/tool-system/builtin/edit.js +2 -6
  340. package/dist/tool-system/builtin/file-cache.d.ts +2 -0
  341. package/dist/tool-system/builtin/file-cache.js +4 -0
  342. package/dist/tool-system/builtin/generate-image.js +17 -10
  343. package/dist/tool-system/builtin/generate-video.js +26 -7
  344. package/dist/tool-system/builtin/grep.js +2 -2
  345. package/dist/tool-system/builtin/image-uploader.js +7 -1
  346. package/dist/tool-system/builtin/index.d.ts +32 -7
  347. package/dist/tool-system/builtin/index.js +237 -167
  348. package/dist/tool-system/builtin/memory.d.ts +6 -0
  349. package/dist/tool-system/builtin/memory.js +36 -15
  350. package/dist/tool-system/builtin/panel.d.ts +9 -0
  351. package/dist/tool-system/builtin/panel.js +314 -0
  352. package/dist/tool-system/builtin/read.js +5 -1
  353. package/dist/tool-system/builtin/send-message-to-session.d.ts +6 -0
  354. package/dist/tool-system/builtin/send-message-to-session.js +67 -0
  355. package/dist/tool-system/builtin/sources.d.ts +8 -0
  356. package/dist/tool-system/builtin/sources.js +137 -0
  357. package/dist/tool-system/builtin/tool-search.js +7 -2
  358. package/dist/tool-system/builtin/update-automation-memory.js +2 -0
  359. package/dist/tool-system/builtin/web-fetch.js +17 -13
  360. package/dist/tool-system/builtin/web-search.js +1 -3
  361. package/dist/tool-system/capability-module.d.ts +93 -0
  362. package/dist/tool-system/capability-module.js +53 -0
  363. package/dist/tool-system/context.d.ts +77 -19
  364. package/dist/tool-system/executor.js +75 -50
  365. package/dist/tool-system/external-tool-exposure.d.ts +60 -0
  366. package/dist/tool-system/external-tool-exposure.js +304 -0
  367. package/dist/tool-system/mcp-manager.d.ts +11 -1
  368. package/dist/tool-system/mcp-manager.js +19 -4
  369. package/dist/tool-system/mcp-tool-policy.d.ts +9 -0
  370. package/dist/tool-system/mcp-tool-policy.js +34 -0
  371. package/dist/tool-system/panel-bridge.d.ts +53 -0
  372. package/dist/tool-system/panel-bridge.js +1 -0
  373. package/dist/tool-system/path-policy.js +99 -2
  374. package/dist/tool-system/permission.d.ts +26 -0
  375. package/dist/tool-system/permission.js +46 -0
  376. package/dist/tool-system/registry.d.ts +12 -1
  377. package/dist/tool-system/registry.js +31 -7
  378. package/dist/tool-system/sandbox/index.js +3 -8
  379. package/dist/tool-system/sandbox/seatbelt.js +2 -6
  380. package/dist/tool-system/session-tool-host.d.ts +139 -0
  381. package/dist/tool-system/session-tool-host.js +167 -0
  382. package/dist/tool-system/testing/tool-registry-harness.d.ts +31 -0
  383. package/dist/tool-system/testing/tool-registry-harness.js +51 -0
  384. package/dist/tool-system/validation.d.ts +14 -7
  385. package/dist/tool-system/validation.js +701 -7
  386. package/dist/types.d.ts +186 -20
  387. package/dist/{cc-orchestrator → utils}/cwd-normalize.d.ts +1 -0
  388. package/dist/{cc-orchestrator → utils}/cwd-normalize.js +1 -0
  389. package/dist/utils/file-mutex.d.ts +65 -0
  390. package/dist/utils/file-mutex.js +145 -0
  391. package/dist/utils/json.d.ts +2 -4
  392. package/dist/utils/json.js +2 -4
  393. package/dist/utils/lockfile.d.ts +30 -1
  394. package/dist/utils/lockfile.js +2 -2
  395. package/dist/utils/secret-scrubber.d.ts +8 -0
  396. package/dist/utils/secret-scrubber.js +227 -0
  397. package/dist/utils/toolDisplay.js +1 -1
  398. package/package.json +20 -5
  399. package/THIRD_PARTY_NOTICES.md +0 -206
  400. package/dist/arena/arena.d.ts +0 -45
  401. package/dist/arena/arena.js +0 -362
  402. package/dist/arena/context/context-tools.d.ts +0 -16
  403. package/dist/arena/context/context-tools.js +0 -272
  404. package/dist/arena/context/within-root.d.ts +0 -7
  405. package/dist/arena/context/within-root.js +0 -15
  406. package/dist/arena/detect-mode.d.ts +0 -20
  407. package/dist/arena/detect-mode.js +0 -78
  408. package/dist/arena/digest-builder.d.ts +0 -25
  409. package/dist/arena/digest-builder.js +0 -120
  410. package/dist/arena/index.d.ts +0 -29
  411. package/dist/arena/index.js +0 -29
  412. package/dist/arena/iterate/convergence.d.ts +0 -25
  413. package/dist/arena/iterate/convergence.js +0 -103
  414. package/dist/arena/iterate/formats/index.d.ts +0 -22
  415. package/dist/arena/iterate/formats/index.js +0 -283
  416. package/dist/arena/iterate/index.d.ts +0 -11
  417. package/dist/arena/iterate/index.js +0 -9
  418. package/dist/arena/iterate/iterative-arena.d.ts +0 -23
  419. package/dist/arena/iterate/iterative-arena.js +0 -237
  420. package/dist/arena/iterate/parse.d.ts +0 -42
  421. package/dist/arena/iterate/parse.js +0 -123
  422. package/dist/arena/iterate/phases/argue.d.ts +0 -22
  423. package/dist/arena/iterate/phases/argue.js +0 -165
  424. package/dist/arena/iterate/phases/revise.d.ts +0 -16
  425. package/dist/arena/iterate/phases/revise.js +0 -62
  426. package/dist/arena/iterate/phases/tournament.d.ts +0 -34
  427. package/dist/arena/iterate/phases/tournament.js +0 -113
  428. package/dist/arena/iterate/tools/web-tools.d.ts +0 -13
  429. package/dist/arena/iterate/tools/web-tools.js +0 -54
  430. package/dist/arena/iterate/types.d.ts +0 -152
  431. package/dist/arena/iterate/types.js +0 -8
  432. package/dist/arena/ledger.d.ts +0 -47
  433. package/dist/arena/ledger.js +0 -159
  434. package/dist/arena/lenses/architecture.d.ts +0 -5
  435. package/dist/arena/lenses/architecture.js +0 -22
  436. package/dist/arena/lenses/engineering.d.ts +0 -5
  437. package/dist/arena/lenses/engineering.js +0 -22
  438. package/dist/arena/lenses/general.d.ts +0 -5
  439. package/dist/arena/lenses/general.js +0 -20
  440. package/dist/arena/lenses/index.d.ts +0 -16
  441. package/dist/arena/lenses/index.js +0 -47
  442. package/dist/arena/lenses/product.d.ts +0 -5
  443. package/dist/arena/lenses/product.js +0 -22
  444. package/dist/arena/model-presets.d.ts +0 -23
  445. package/dist/arena/model-presets.js +0 -44
  446. package/dist/arena/phases/adjudication.d.ts +0 -25
  447. package/dist/arena/phases/adjudication.js +0 -142
  448. package/dist/arena/phases/build-consensus.d.ts +0 -30
  449. package/dist/arena/phases/build-consensus.js +0 -85
  450. package/dist/arena/phases/claim-registry.d.ts +0 -26
  451. package/dist/arena/phases/claim-registry.js +0 -60
  452. package/dist/arena/phases/cross-review.d.ts +0 -47
  453. package/dist/arena/phases/cross-review.js +0 -224
  454. package/dist/arena/phases/debate-rounds.d.ts +0 -28
  455. package/dist/arena/phases/debate-rounds.js +0 -161
  456. package/dist/arena/phases/participant-research.d.ts +0 -39
  457. package/dist/arena/phases/participant-research.js +0 -316
  458. package/dist/arena/phases/planning-detail-expansion.d.ts +0 -39
  459. package/dist/arena/phases/planning-detail-expansion.js +0 -120
  460. package/dist/arena/planner.d.ts +0 -28
  461. package/dist/arena/planner.js +0 -312
  462. package/dist/arena/providers/docs.d.ts +0 -7
  463. package/dist/arena/providers/docs.js +0 -111
  464. package/dist/arena/providers/git.d.ts +0 -8
  465. package/dist/arena/providers/git.js +0 -174
  466. package/dist/arena/providers/index.d.ts +0 -32
  467. package/dist/arena/providers/index.js +0 -132
  468. package/dist/arena/providers/none.d.ts +0 -7
  469. package/dist/arena/providers/none.js +0 -11
  470. package/dist/arena/providers/repo.d.ts +0 -7
  471. package/dist/arena/providers/repo.js +0 -258
  472. package/dist/arena/render/session.d.ts +0 -17
  473. package/dist/arena/render/session.js +0 -190
  474. package/dist/arena/render/terminal.d.ts +0 -34
  475. package/dist/arena/render/terminal.js +0 -286
  476. package/dist/arena/strategies/discussion.d.ts +0 -25
  477. package/dist/arena/strategies/discussion.js +0 -143
  478. package/dist/arena/strategies/index.d.ts +0 -15
  479. package/dist/arena/strategies/index.js +0 -28
  480. package/dist/arena/strategies/language-wrapper.d.ts +0 -17
  481. package/dist/arena/strategies/language-wrapper.js +0 -102
  482. package/dist/arena/strategies/lens-wrapper.d.ts +0 -16
  483. package/dist/arena/strategies/lens-wrapper.js +0 -236
  484. package/dist/arena/strategies/planning.d.ts +0 -30
  485. package/dist/arena/strategies/planning.js +0 -225
  486. package/dist/arena/strategies/review.d.ts +0 -26
  487. package/dist/arena/strategies/review.js +0 -168
  488. package/dist/arena/strategies/utils.d.ts +0 -36
  489. package/dist/arena/strategies/utils.js +0 -603
  490. package/dist/arena/tools/selector.d.ts +0 -17
  491. package/dist/arena/tools/selector.js +0 -61
  492. package/dist/arena/transitions.d.ts +0 -53
  493. package/dist/arena/transitions.js +0 -97
  494. package/dist/arena/types.d.ts +0 -518
  495. package/dist/arena/types.js +0 -27
  496. package/dist/cc-orchestrator/agent-adapter.d.ts +0 -54
  497. package/dist/cc-orchestrator/agent-adapter.js +0 -143
  498. package/dist/cc-orchestrator/cc-capability.d.ts +0 -19
  499. package/dist/cc-orchestrator/cc-capability.js +0 -53
  500. package/dist/cc-orchestrator/codex-session-discovery.d.ts +0 -24
  501. package/dist/cc-orchestrator/codex-session-discovery.js +0 -191
  502. package/dist/cc-orchestrator/codex-session-history.d.ts +0 -38
  503. package/dist/cc-orchestrator/codex-session-history.js +0 -247
  504. package/dist/cc-orchestrator/external-agent-bindings.d.ts +0 -27
  505. package/dist/cc-orchestrator/external-agent-bindings.js +0 -150
  506. package/dist/cc-orchestrator/external-agent-changes.d.ts +0 -19
  507. package/dist/cc-orchestrator/external-agent-changes.js +0 -231
  508. package/dist/cc-orchestrator/external-agent-driver.d.ts +0 -19
  509. package/dist/cc-orchestrator/external-agent-driver.js +0 -284
  510. package/dist/cc-orchestrator/external-agent-session-store.d.ts +0 -23
  511. package/dist/cc-orchestrator/external-agent-session-store.js +0 -146
  512. package/dist/cc-orchestrator/index.d.ts +0 -8
  513. package/dist/cc-orchestrator/index.js +0 -8
  514. package/dist/cc-orchestrator/relevance-judge.d.ts +0 -15
  515. package/dist/cc-orchestrator/relevance-judge.js +0 -29
  516. package/dist/cc-orchestrator/session-discovery.d.ts +0 -46
  517. package/dist/cc-orchestrator/session-discovery.js +0 -125
  518. package/dist/cc-orchestrator/session-history.d.ts +0 -54
  519. package/dist/cc-orchestrator/session-history.js +0 -150
  520. package/dist/cron/cron-runtime.d.ts +0 -2
  521. package/dist/cron/cron-runtime.js +0 -2
  522. package/dist/cron/cron-store.d.ts +0 -2
  523. package/dist/cron/cron-store.js +0 -2
  524. package/dist/cron/scheduler.d.ts +0 -7
  525. package/dist/cron/scheduler.js +0 -7
  526. package/dist/engine/goal.js +0 -206
  527. package/dist/external-agents/config.d.ts +0 -2
  528. package/dist/external-agents/config.js +0 -15
  529. package/dist/external-agents/types.d.ts +0 -31
  530. package/dist/git/parse-log.d.ts +0 -13
  531. package/dist/git/parse-log.js +0 -21
  532. package/dist/git/utils.d.ts +0 -49
  533. package/dist/git/utils.js +0 -161
  534. package/dist/git/worktree/crud.d.ts +0 -72
  535. package/dist/git/worktree/crud.js +0 -235
  536. package/dist/git/worktree/diff.d.ts +0 -14
  537. package/dist/git/worktree/diff.js +0 -82
  538. package/dist/git/worktree/git-exec.d.ts +0 -7
  539. package/dist/git/worktree/git-exec.js +0 -87
  540. package/dist/git/worktree/index.d.ts +0 -5
  541. package/dist/git/worktree/index.js +0 -5
  542. package/dist/git/worktree/query.d.ts +0 -43
  543. package/dist/git/worktree/query.js +0 -128
  544. package/dist/git/worktree/slug.d.ts +0 -11
  545. package/dist/git/worktree/slug.js +0 -58
  546. package/dist/git/worktree.d.ts +0 -1
  547. package/dist/git/worktree.js +0 -5
  548. package/dist/lsp/client.d.ts +0 -41
  549. package/dist/lsp/client.js +0 -186
  550. package/dist/lsp/manager.d.ts +0 -40
  551. package/dist/lsp/manager.js +0 -155
  552. package/dist/lsp/root-path.d.ts +0 -9
  553. package/dist/lsp/root-path.js +0 -12
  554. package/dist/lsp/servers.d.ts +0 -16
  555. package/dist/lsp/servers.js +0 -60
  556. package/dist/prompt/sections/coding.md +0 -35
  557. package/dist/quota/credentials.d.ts +0 -3
  558. package/dist/quota/credentials.js +0 -80
  559. package/dist/quota/index.d.ts +0 -36
  560. package/dist/quota/index.js +0 -155
  561. package/dist/quota/types.d.ts +0 -48
  562. package/dist/quota/types.js +0 -13
  563. package/dist/review/review-prompt.d.ts +0 -28
  564. package/dist/review/review-prompt.js +0 -81
  565. package/dist/state.d.ts +0 -160
  566. package/dist/state.js +0 -267
  567. package/dist/tool-system/builtin/apply-patch/applier.d.ts +0 -26
  568. package/dist/tool-system/builtin/apply-patch/applier.js +0 -308
  569. package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +0 -10
  570. package/dist/tool-system/builtin/apply-patch/backup-targets.js +0 -30
  571. package/dist/tool-system/builtin/apply-patch/index.d.ts +0 -20
  572. package/dist/tool-system/builtin/apply-patch/index.js +0 -105
  573. package/dist/tool-system/builtin/apply-patch/parser.d.ts +0 -17
  574. package/dist/tool-system/builtin/apply-patch/parser.js +0 -212
  575. package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +0 -18
  576. package/dist/tool-system/builtin/apply-patch/seek-sequence.js +0 -123
  577. package/dist/tool-system/builtin/apply-patch/types.d.ts +0 -49
  578. package/dist/tool-system/builtin/apply-patch/types.js +0 -13
  579. package/dist/tool-system/builtin/arena.d.ts +0 -31
  580. package/dist/tool-system/builtin/arena.js +0 -416
  581. package/dist/tool-system/builtin/brief.d.ts +0 -6
  582. package/dist/tool-system/builtin/brief.js +0 -41
  583. package/dist/tool-system/builtin/check-quota.d.ts +0 -15
  584. package/dist/tool-system/builtin/check-quota.js +0 -34
  585. package/dist/tool-system/builtin/drive-claude-code.d.ts +0 -51
  586. package/dist/tool-system/builtin/drive-claude-code.js +0 -698
  587. package/dist/tool-system/builtin/lsp.d.ts +0 -7
  588. package/dist/tool-system/builtin/lsp.js +0 -144
  589. package/dist/tool-system/builtin/notebook-edit.d.ts +0 -7
  590. package/dist/tool-system/builtin/notebook-edit.js +0 -127
  591. package/dist/tool-system/builtin/worktree.d.ts +0 -11
  592. package/dist/tool-system/builtin/worktree.js +0 -363
  593. /package/dist/{external-agents → links}/types.js +0 -0
  594. /package/dist/{engine/session-usage.d.ts → session/usage.d.ts} +0 -0
  595. /package/dist/{engine/session-usage.js → session/usage.js} +0 -0
@@ -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
+ }