chainlesschain 0.162.182 → 0.162.184

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 (202) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-DzZ5_xoj.js → AIOps-DzAl5fGx.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-DeLXddIg.js → ActionButton-DAHtMGeC.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-rvDCmet1.js → Analytics-BHQaexv5.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-Yt6QVDnp.js → AppLayout-Phz_pD0n.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-BS112K5L.js → Artifacts-DHt47kCA.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-0wJuQrNu.js → Audit--Y_8FULl.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-B90PMgbn.js → BackgroundAgents-N1zchH7D.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-TkgMglQQ.js → Backup-B_BoyN30.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-CQVS9p1l.js → BaseInput-Gl4uQHcT.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-YTjQHoC7.js → Chat-Cg-eIyAZ.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-BzeUi3JH.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-5bwaOabq.js → Checkbox-D0MGR2wA.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-BFmNQ_Xe.js → Codegen-BdObJEFn.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-BT_u4Dzp.js → Col--ghxXT3z.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-CJP52u5b.js → Community-BUFeXOqz.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BpzhJE9i.js → Compact-DhQO2_Mr.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-Cg7rfslp.js → Compliance-3HoTqKYd.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-JisxL6Yy.js → Cowork-B3zmO4VW.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-Bu7Ug_MC.js → Cron-CJDrZOcc.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CvuqoLdj.js → Crosschain-SMl15obd.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-C2u9G8Pu.js → DID-CgTrTWrl.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-BFt5Yv3d.js → Dashboard-dXFKaKol.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-DIaT9Wxq.js → Dropdown-qQHEhCvI.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-D_A601Y4.js → EmailListRenderer-C_ej0MWH.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard--IyQ8I8w.js → FamilyGuardDashboard-D6ajoE7I.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-BihWHxuY.js → Federation-Cio2y49h.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-BB8dOXc_.js → FormItemContext-ClJz1cYp.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-DQYhj1HH.js → GenericCardRenderer-Dr_8Maca.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-B-2QZxGf.js → Git-CevLwp5u.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CusSb-nG.js → Governance-CW9YyQUY.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-BAjmvPPL.js → Inference-CQqeAyER.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-DoNYWKYq.js → KnowledgeGraph-cuGVxHrw.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-B8fKWD-n.js → Logs-DIuHri5d.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-BlJm1J7E.js → MarkdownRenderer-R91Qw5JA.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-CyOscbSL.js → Marketplace-CY1VhFGx.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-Ex6Om5da.js → McpTools-BBAbi1vt.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-CDcD8l8r.js → Memory-BWYGHxJA.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-xfBqoFDg.js → MobileBridge-CPIFkW7A.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-BwObMMA2.js → MobileProjects-DQyWxCho.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-CIWd36OV.js → Mtc-Bo3GnQbx.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-CPX0ouuA.js → MtcAudit-C8-c4rSW.js} +4 -4
  44. package/src/assets/web-panel/assets/{Multisig-BDJsIUuW.js → Multisig-ChqMTtoq.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-DEkbuD3N.js → NLProgramming-C48TyhvI.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-DJpHRhH1.js → Notes-zogUFWxp.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-C1UZ-Qd5.js → NotificationSettings-v-K9XpSB.js} +1 -1
  48. package/src/assets/web-panel/assets/OrderTableRenderer-P94JGGNz.js +1 -0
  49. package/src/assets/web-panel/assets/{Organization-Bbhj0fac.js → Organization-Boi1dQfR.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-1H04x3kx.js → Overflow-DM5YWwgA.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CDpPe3et.js → P2P-C57LKpKK.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-MUX0Bpvw.js → PdhVaultBrowser-BFkPqu6Q.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-A07-0Ci1.js → Permissions-D6fB9YSp.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-DhhDWxAZ.js → PersonalDataHub-Bp7EefEo.js} +5 -5
  55. package/src/assets/web-panel/assets/{Pipeline-CyfbJfe-.js → Pipeline-BVln3hZf.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-CNFps3ED.js → Privacy-Bf8P3nF6.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit--T-u3Dr5.js → ProjectInit-DM6wA2E2.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-DJmrK2fC.js → ProjectSettings-CGbc5Iho.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-D0p9EOxm.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-DLzzbOZd.js → Providers-B2kJcxS6.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-CexOomKS.js → QrScannerModal-Cxu7dXYy.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-QklGi19_.js → QuickAsk-DTlrTPms.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-Bb9kwSw8.js → Recommend-Cm3X-cCj.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-DZuVNNN5.js → RemoteSession-DNb2kjvt.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-Dr5cLP0N.js → Reputation-CZUFFjc1.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-oCQHYv5t.js → Row-DAPgloxA.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-IFDEykIR.js → RssFeed-dsx9S793.js} +2 -2
  68. package/src/assets/web-panel/assets/{Search-CspVIxDc.js → Search-DnnC8kz-.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-Bm66o_DH.js → Security-VuZknRMK.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-DvanNqXl.js → Services-B3XNX8Vx.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-CHjEe9_O.js → Skeleton-Dl1nVtCj.js} +1 -1
  72. package/src/assets/web-panel/assets/Skills-CY09CZ_W.js +1 -0
  73. package/src/assets/web-panel/assets/{Sla-DxZm1491.js → Sla-HzU56n1z.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-DWxEEclC.js → SpeechSettings-CRle7Jl2.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-FIvOFw5p.js → SyncSettings-DWadz7Sl.js} +2 -2
  76. package/src/assets/web-panel/assets/Tasks-CNVTDGg8.js +1 -0
  77. package/src/assets/web-panel/assets/{Templates-CaNjzV_t.js → Templates-BBAgvrlM.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-DjlP6TmH.js → Tenant-BsbbvGN8.js} +1 -1
  79. package/src/assets/web-panel/assets/Terminal-uscpZI4q.js +3 -0
  80. package/src/assets/web-panel/assets/{TimelineRenderer-DoZ8y7y8.js → TimelineRenderer-mTyjNE6r.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-390cg2TC.js → Tokens-Bz97oBgs.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-CLrtCj5_.js → Trigger-BTRKC140.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-DpESfSPn.js → Trust-B4A_KuyX.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-CN6279O0.js → UkeySign-DES9TmLU.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-DPtAUlSe.js → VideoEditing-ClXs7Qxp.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-nKOMV_1n.js → Wallet-IzZqFz-7.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-HuXlSOc4.js → WebAuthn-BtOP04g_.js} +5 -5
  88. package/src/assets/web-panel/assets/{WorkflowEditor-CUfFjARi.js → WorkflowEditor-_0cqnopY.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-6Eq0PcZJ.js → chat-ax7193uU.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-BP_Sf6Iy.js → colors-Bu4WGJah.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-BufMKIh5.js → compact-item-BX1dlTW0.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-BBMXxWSW.js → createContext-CktA_Dj7.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-x877iKKS.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-fUK_tRO2.js → hasIn-D5wd817l.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-t8N1tSeX.js → index-5PYYkr8S.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DLpIs_P_.js → index-A4uBPQCz.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DVsqvI4M.js → index-BAtBNfkr.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Bkg4ZePE.js → index-BLLsUNDc.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-cpEli44X.js → index-BQtoRyTO.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-wKTLbKyc.js → index-BRfXoRuh.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-B7Etk0Te.js → index-Bad2CYeH.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CwSf5pnf.js → index-BcGdL3sG.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-3FuwBewR.js → index-C3HmzCLt.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BHy6yNiF.js → index-C8DkWyNr.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CgiECHu2.js → index-C8tLR2TG.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-C44atv4k.js → index-CP8ELJBc.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CW_G-MXw.js → index-CUForzsG.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-pum7HYBA.js → index-CYRE0NJA.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BWKoBU8R.js → index-CeVZaJSC.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-D4_MuGkd.js → index-CfzxR61U.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Dyngbd29.js → index-Ci3y1ZAv.js} +19 -19
  112. package/src/assets/web-panel/assets/{index-fzaMtSJ8.js → index-CjEJjl5C.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Cp8vhyZy.js → index-Cv7bVWJ5.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DPdUNk1i.js → index-D-o4Rwjk.js} +1 -1
  115. package/src/assets/web-panel/assets/index-D7pfPouB.js +1 -0
  116. package/src/assets/web-panel/assets/{index-CeASi4fr.js → index-D9op8poE.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DASluSqY.js → index-DF1TysIF.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DocdRcbd.js → index-DYo9S5OT.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-2A5ph8b2.js → index-D_cycOET.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-wV6iGdpY.js → index-Db3CpWTr.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BMLHv389.js → index-DkD1K-fF.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B9WYSn4m.js → index-DmPJ6T6F.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-uCbEN7cY.js → index-DmVUeWUk.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DmkMXwnR.js → index-Dzdr0zDf.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CZ6Yt17L.js → index-PBLzwYnu.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CE2DdTP2.js → index-bFCaM7Eq.js} +1 -1
  127. package/src/assets/web-panel/assets/index-e4i-VLBd.js +1 -0
  128. package/src/assets/web-panel/assets/{index-GwdRUZ-x.js → index-h3KJZr95.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-B2vS66eI.js → index-iHcPtQ2e.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-6GmBa4Kg.js → index-jzlzm4VK.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-D9vU25ij.js → index-o14NNnxw.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CGjmILDm.js → index-tYPSfGbd.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-LvCBfTLo.js → index-ytp2H5Zx.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-V5Fo95FM.js → initDefaultProps-D2Iut83B.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BYWU0hUT.js → motion-BuaJVdK9.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-Cr1M-J2h.js → move-CaEuM92y.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-BysQKi2N.js → mtc-parser-wuKNBwys.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-D1zHU8GC.js → omit-7a3eklaq.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-CUArxtfi.js → pickAttrs-Dn4z7KvJ.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-ChoYEys0.js → placementArrow-DVn_qT4-.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-BQRs3Mo7.js → responsiveObserve-Dodz1OMQ.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-B8zbsCkg.js → slide-CxoGskbp.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-C2U8Gs6h.js → statusUtils-DBh_epQH.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-Dd8MgL_V.js → styleChecker-RXQ4gG5P.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-hknqY5NH.js → useFlexGapSupport-1Wxm0HEG.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-CLTAmcfw.js → useFs-CI_ySNxJ.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-ByegHbiB.js → usePersonalDataHub-C6973rZP.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-DqlAy5DP.js → vnode-CalynwKr.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-DiXiztQn.js → zoom-CM1cd-Q0.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/agenda.js +74 -1
  152. package/src/commands/agent.js +9 -0
  153. package/src/commands/background-session.js +60 -1
  154. package/src/commands/batch.js +160 -5
  155. package/src/commands/plugin.js +318 -43
  156. package/src/commands/session.js +44 -1
  157. package/src/commands/team.js +212 -6
  158. package/src/data/changelog.json +26 -0
  159. package/src/harness/jsonl-session-store.js +59 -6
  160. package/src/harness/mcp-client.js +65 -43
  161. package/src/lib/agent-batch.js +4 -1
  162. package/src/lib/agent-team/team-runner.js +19 -1
  163. package/src/lib/agent-team/team-worktree.js +3 -0
  164. package/src/lib/async-hook-supervisor.cjs +82 -10
  165. package/src/lib/async-hook-supervisor.js +50 -4
  166. package/src/lib/background-agent-supervisor.js +49 -0
  167. package/src/lib/collaboration-run-store.js +362 -0
  168. package/src/lib/hook-runner.cjs +98 -17
  169. package/src/lib/hook-runner.js +77 -6
  170. package/src/lib/hook-shell-command.cjs +148 -0
  171. package/src/lib/hooks-v2-runtime.js +188 -77
  172. package/src/lib/jsonl-session-store.js +2 -0
  173. package/src/lib/lsp/__tests__/lsp-client.test.js +18 -0
  174. package/src/lib/lsp/lsp-client.js +12 -1
  175. package/src/lib/plugin-monitor-supervisor.js +53 -16
  176. package/src/lib/plugin-runtime/bin.js +1 -1
  177. package/src/lib/plugin-runtime/install.js +465 -54
  178. package/src/lib/plugin-runtime/mcp.js +21 -2
  179. package/src/lib/plugin-runtime/monitors.js +19 -3
  180. package/src/lib/plugin-runtime/sandbox-policy.js +99 -0
  181. package/src/lib/plugin-runtime/scopes.js +13 -2
  182. package/src/lib/plugin-usage-attribution.js +44 -0
  183. package/src/lib/process-execution-broker/index.js +705 -13
  184. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +1347 -0
  185. package/src/lib/process-execution-broker/linux-generic-bwrap.js +1260 -0
  186. package/src/lib/process-execution-broker/platform-sandbox.js +1831 -157
  187. package/src/lib/session-usage.js +278 -1
  188. package/src/lib/stream-retry.js +29 -0
  189. package/src/repl/agent-repl.js +38 -9
  190. package/src/runtime/agent-core.js +32 -4
  191. package/src/runtime/headless-runner.js +46 -1
  192. package/src/runtime/headless-stream.js +54 -3
  193. package/src/runtime/mcp-config.js +15 -5
  194. package/src/assets/web-panel/assets/ChatBubbleRenderer-PR074hUN.js +0 -1
  195. package/src/assets/web-panel/assets/OrderTableRenderer-GlJtqLjT.js +0 -1
  196. package/src/assets/web-panel/assets/Projects-Qx_MdX9k.js +0 -1
  197. package/src/assets/web-panel/assets/Skills-Cb8jWjMX.js +0 -1
  198. package/src/assets/web-panel/assets/Tasks-CyuLnDFR.js +0 -1
  199. package/src/assets/web-panel/assets/Terminal-DwzGMniO.js +0 -3
  200. package/src/assets/web-panel/assets/devWarning-DgVKduH2.js +0 -1
  201. package/src/assets/web-panel/assets/index-DOZTSoS7.js +0 -1
  202. package/src/assets/web-panel/assets/index-DhpvjpqI.js +0 -1
@@ -22,7 +22,10 @@ import fs from "fs";
22
22
  import { discoverPlugins } from "./scopes.js";
23
23
  import { partitionByTrust, warnUntrustedOnce } from "./trust.js";
24
24
  import { componentCapabilityDenial } from "./capabilities.js";
25
- import { mergePluginSandboxPolicies } from "./sandbox-policy.js";
25
+ import {
26
+ issuePluginWorkspaceAuthority,
27
+ mergePluginSandboxPolicies,
28
+ } from "./sandbox-policy.js";
26
29
 
27
30
  export const _deps = { readFileSync: fs.readFileSync };
28
31
 
@@ -55,7 +58,7 @@ export function _resetMonitorWarnings() {
55
58
  }
56
59
 
57
60
  /** Normalize one raw monitor entry into a validated descriptor, or null. */
58
- function normalizeMonitor(plugin, raw) {
61
+ function normalizeMonitor(plugin, raw, pluginWorkspaceAuthority) {
59
62
  if (!raw || typeof raw !== "object") return null;
60
63
  if (typeof raw.name !== "string" || raw.name === "") return null;
61
64
  if (typeof raw.command !== "string" || raw.command === "") return null;
@@ -91,6 +94,7 @@ function normalizeMonitor(plugin, raw) {
91
94
  intervalMs,
92
95
  env,
93
96
  cwd: plugin.root,
97
+ pluginWorkspaceAuthority,
94
98
  origin: "plugin:monitor",
95
99
  pluginId: plugin.name,
96
100
  pluginVersion: plugin.version,
@@ -131,6 +135,18 @@ export function collectPluginMonitors(opts = {}) {
131
135
  denied.push({ name: p.name, reason: denial.reason });
132
136
  continue;
133
137
  }
138
+ let pluginWorkspaceAuthority;
139
+ try {
140
+ pluginWorkspaceAuthority = issuePluginWorkspaceAuthority({
141
+ root: p.root,
142
+ origin: "plugin:monitor",
143
+ pluginId: p.name,
144
+ pluginVersion: p.version,
145
+ pluginSource: p.manifest?.manifestPath || "",
146
+ });
147
+ } catch {
148
+ continue;
149
+ }
134
150
  let parsed;
135
151
  if (m.absPath) {
136
152
  try {
@@ -159,7 +175,7 @@ export function collectPluginMonitors(opts = {}) {
159
175
  ? parsed
160
176
  : [];
161
177
  for (const raw of list) {
162
- const desc = normalizeMonitor(p, raw);
178
+ const desc = normalizeMonitor(p, raw, pluginWorkspaceAuthority);
163
179
  if (desc) out.push(desc);
164
180
  }
165
181
  }
@@ -1,3 +1,6 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
1
4
  /**
2
5
  * Normalize the small, declarative sandbox contract exposed to plugins.
3
6
  *
@@ -14,6 +17,8 @@ export const PLUGIN_SANDBOX_BOUNDARIES = Object.freeze([
14
17
  ]);
15
18
 
16
19
  const SUPPORTED_BOUNDARIES = new Set(PLUGIN_SANDBOX_BOUNDARIES);
20
+ const PLUGIN_WORKSPACE_AUTHORITY_KIND = "trusted-plugin-workspace";
21
+ const pluginWorkspaceAuthorities = new WeakMap();
17
22
 
18
23
  function invalidPolicy(message) {
19
24
  const error = new Error(message);
@@ -21,6 +26,100 @@ function invalidPolicy(message) {
21
26
  return error;
22
27
  }
23
28
 
29
+ function normalizedProvenance(value = {}) {
30
+ return Object.freeze({
31
+ origin: typeof value.origin === "string" ? value.origin : "",
32
+ pluginId: typeof value.pluginId === "string" ? value.pluginId : "",
33
+ pluginVersion:
34
+ typeof value.pluginVersion === "string" ? value.pluginVersion : "",
35
+ pluginSource:
36
+ typeof value.pluginSource === "string" ? value.pluginSource : "",
37
+ });
38
+ }
39
+
40
+ function sameProvenance(left, right) {
41
+ return (
42
+ left.origin === right.origin &&
43
+ left.pluginId === right.pluginId &&
44
+ left.pluginVersion === right.pluginVersion &&
45
+ left.pluginSource === right.pluginSource
46
+ );
47
+ }
48
+
49
+ /**
50
+ * Mint an opaque, reusable authority from a plugin root produced by trusted
51
+ * installed-plugin discovery. Manifest/server/monitor data receives only the
52
+ * token: the canonical writable root stays in this module's WeakMap.
53
+ *
54
+ * A token is reusable because MCP reconnects and interval monitors can launch
55
+ * more than once. The process broker still mints a separate one-shot execution
56
+ * contract for every child.
57
+ */
58
+ export function issuePluginWorkspaceAuthority(value = {}) {
59
+ if (
60
+ typeof value.root !== "string" ||
61
+ value.root.length === 0 ||
62
+ value.root.includes("\0")
63
+ ) {
64
+ throw invalidPolicy("trusted plugin workspace root must be a path");
65
+ }
66
+ const requestedRoot = path.resolve(value.root);
67
+ let canonicalRoot;
68
+ let stat;
69
+ try {
70
+ const implementation = fs.realpathSync.native || fs.realpathSync;
71
+ canonicalRoot = implementation.call(fs.realpathSync, requestedRoot);
72
+ stat = fs.statSync(canonicalRoot);
73
+ } catch {
74
+ throw invalidPolicy("trusted plugin workspace root is unavailable");
75
+ }
76
+ if (!stat.isDirectory()) {
77
+ throw invalidPolicy("trusted plugin workspace root must be a directory");
78
+ }
79
+
80
+ const provenance = normalizedProvenance(value);
81
+ if (
82
+ !provenance.origin.startsWith("plugin:") ||
83
+ !provenance.pluginId ||
84
+ !provenance.pluginVersion
85
+ ) {
86
+ throw invalidPolicy("trusted plugin workspace provenance is incomplete");
87
+ }
88
+
89
+ const authority = Object.freeze({
90
+ contractVersion: 1,
91
+ kind: PLUGIN_WORKSPACE_AUTHORITY_KIND,
92
+ });
93
+ pluginWorkspaceAuthorities.set(
94
+ authority,
95
+ Object.freeze({ root: canonicalRoot, provenance }),
96
+ );
97
+ return authority;
98
+ }
99
+
100
+ /**
101
+ * Resolve an authority only for the exact plugin/component provenance to which
102
+ * the loader bound it. Structurally similar manifest objects are not accepted.
103
+ */
104
+ export function resolvePluginWorkspaceAuthority(authority, provenance = {}) {
105
+ if (
106
+ !authority ||
107
+ typeof authority !== "object" ||
108
+ authority.contractVersion !== 1 ||
109
+ authority.kind !== PLUGIN_WORKSPACE_AUTHORITY_KIND
110
+ ) {
111
+ return null;
112
+ }
113
+ const binding = pluginWorkspaceAuthorities.get(authority);
114
+ if (
115
+ !binding ||
116
+ !sameProvenance(binding.provenance, normalizedProvenance(provenance))
117
+ ) {
118
+ return null;
119
+ }
120
+ return binding.root;
121
+ }
122
+
24
123
  /**
25
124
  * @param {unknown} raw
26
125
  * @param {{ label?: string }} [opts]
@@ -42,6 +42,7 @@ export const _deps = {
42
42
 
43
43
  // Lowest → highest precedence.
44
44
  export const SCOPES = ["user", "project", "local"];
45
+ export const DISABLED_FILENAME = ".disabled";
45
46
 
46
47
  /** Filesystem-safe encoding of a (possibly scoped, e.g. @org/name) plugin name. */
47
48
  export function encodeName(name) {
@@ -105,6 +106,13 @@ export function activeVersion(scope, name, opts = {}) {
105
106
  return versions[0];
106
107
  }
107
108
 
109
+ /** Whether one scoped plugin install is eligible for runtime discovery. */
110
+ export function isPluginEnabled(scope, name, opts = {}) {
111
+ return !_deps.existsSync(
112
+ path.join(pluginNameDir(scope, name, opts), DISABLED_FILENAME),
113
+ );
114
+ }
115
+
108
116
  /**
109
117
  * Discover every installed plugin's ACTIVE version across all scopes, applying
110
118
  * scope precedence (local > project > user) so a name installed at multiple
@@ -116,8 +124,8 @@ export function activeVersion(scope, name, opts = {}) {
116
124
  * for tooling that must see even blocked plugins (e.g. `cc plugin installed`
117
125
  * showing why something is blocked). No managed settings file → no filtering.
118
126
  *
119
- * @param {object} [opts] { cwd, scopes?, skipPolicy?, env?, managedSettingsFile? }
120
- * @returns {Array<{scope, name, version, root, manifest}>}
127
+ * @param {object} [opts] { cwd, scopes?, skipPolicy?, includeDisabled?, env?, managedSettingsFile? }
128
+ * @returns {Array<{scope, name, version, root, manifest, enabled}>}
121
129
  */
122
130
  export function discoverPlugins(opts = {}) {
123
131
  // `cc agent --bare` (CC_PLUGINS=0): the plugin runtime is fully off. Every
@@ -139,6 +147,8 @@ export function discoverPlugins(opts = {}) {
139
147
  if (!dirExists(root, opts.strictIo === true)) continue;
140
148
  for (const encoded of listDirs(root, opts.strictIo === true)) {
141
149
  const nameDir = path.join(root, encoded);
150
+ const enabled = !_deps.existsSync(path.join(nameDir, DISABLED_FILENAME));
151
+ if (!enabled && opts.includeDisabled !== true) continue;
142
152
  const version = activeVersionForDir(nameDir, opts.strictIo === true);
143
153
  if (!version) continue;
144
154
  const versionDir = path.join(nameDir, version);
@@ -158,6 +168,7 @@ export function discoverPlugins(opts = {}) {
158
168
  version: manifest.metadata?.version || version,
159
169
  root: versionDir,
160
170
  manifest,
171
+ enabled,
161
172
  });
162
173
  }
163
174
  }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Extract a secret-free plugin identity from a tool result. Plugin bins expose
3
+ * an explicit `plugin_bin` record; extension-tier tools may expose a
4
+ * `toolAttribution.source` in the stable `plugin:<id>` / `plugin/<id>` form.
5
+ */
6
+ export function extractPluginUsageAttribution(result) {
7
+ const pluginBin =
8
+ result?.plugin_bin && typeof result.plugin_bin === "object"
9
+ ? result.plugin_bin
10
+ : null;
11
+ if (pluginBin?.plugin) {
12
+ const plugin = boundedIdentity(pluginBin.plugin, 256);
13
+ if (!plugin) return {};
14
+ return {
15
+ plugin,
16
+ pluginVersion: pluginBin.version
17
+ ? boundedIdentity(pluginBin.version, 128) || undefined
18
+ : undefined,
19
+ };
20
+ }
21
+ const attribution =
22
+ result?.toolAttribution && typeof result.toolAttribution === "object"
23
+ ? result.toolAttribution
24
+ : null;
25
+ const source =
26
+ typeof attribution?.source === "string" ? attribution.source : "";
27
+ const match = source.match(/^plugin(?::|\/)(.+)$/i);
28
+ const plugin = match ? boundedIdentity(match[1], 256) : null;
29
+ return plugin
30
+ ? {
31
+ plugin,
32
+ pluginVersion: attribution.version
33
+ ? boundedIdentity(attribution.version, 128) || undefined
34
+ : undefined,
35
+ }
36
+ : {};
37
+ }
38
+
39
+ function boundedIdentity(value, max) {
40
+ const clean = String(value ?? "")
41
+ .replace(/\p{Cc}/gu, "")
42
+ .trim();
43
+ return clean ? clean.slice(0, max) : null;
44
+ }