chainlesschain 0.162.182 → 0.162.183

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 (176) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-DzZ5_xoj.js → AIOps-BapS7lz4.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-DeLXddIg.js → ActionButton-CXYdXEUI.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-rvDCmet1.js → Analytics-CKR5Lexn.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-Yt6QVDnp.js → AppLayout-DATVUOXB.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BS112K5L.js → Artifacts-vb_0ZlV1.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-0wJuQrNu.js → Audit-BI1l9GWt.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-B90PMgbn.js → BackgroundAgents-BFXbaUEf.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-TkgMglQQ.js → Backup-DEYBJJ6H.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CQVS9p1l.js → BaseInput-COdzeO0M.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-YTjQHoC7.js → Chat-oSN6sfM5.js} +6 -6
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-CI_jT0ru.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-5bwaOabq.js → Checkbox-BezEa4tm.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-BFmNQ_Xe.js → Codegen-CNEL0Ife.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-BT_u4Dzp.js → Col-Bf2Y2Bn1.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CJP52u5b.js → Community-BfUlu4Hc.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BpzhJE9i.js → Compact-BN4xWP9e.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-Cg7rfslp.js → Compliance-Bt6BKmEP.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-JisxL6Yy.js → Cowork-DKLp8YxO.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-Bu7Ug_MC.js → Cron-o7Hhw6ky.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-CvuqoLdj.js → Crosschain-DaNXWJIw.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-C2u9G8Pu.js → DID-B-Qa2mha.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-BFt5Yv3d.js → Dashboard-CMX0Qnxw.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DIaT9Wxq.js → Dropdown-BLuLyRu_.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-D_A601Y4.js → EmailListRenderer-CFBAeMij.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard--IyQ8I8w.js → FamilyGuardDashboard-DWzXQ67V.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BihWHxuY.js → Federation-DB1QSLgr.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-BB8dOXc_.js → FormItemContext-C-OKCToP.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-DQYhj1HH.js → GenericCardRenderer-DMJFtFZf.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-B-2QZxGf.js → Git-DsGSujOV.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CusSb-nG.js → Governance-B0iS9NEW.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-BAjmvPPL.js → Inference-CH004H7c.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DoNYWKYq.js → KnowledgeGraph-Q9MTQ83c.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-B8fKWD-n.js → Logs-B_fyjZK9.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-BlJm1J7E.js → MarkdownRenderer-C0o4FtpD.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-CyOscbSL.js → Marketplace-BIStF9d1.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Ex6Om5da.js → McpTools-pGfal768.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-CDcD8l8r.js → Memory-xbNqpIqB.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-xfBqoFDg.js → MobileBridge-B5EQGrIK.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-VTc3gT1y.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-CIWd36OV.js → Mtc-a_rmfxJH.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-CPX0ouuA.js → MtcAudit-BmKuofUr.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-BDJsIUuW.js → Multisig-BQbJ-CAN.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-DEkbuD3N.js → NLProgramming-JtPJKX25.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-DJpHRhH1.js → Notes-ZFKznTSG.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-C1UZ-Qd5.js → NotificationSettings-B6aHRBBR.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-GlJtqLjT.js → OrderTableRenderer-DdcsOqEz.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Bbhj0fac.js → Organization-BFDTAUgS.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-1H04x3kx.js → Overflow-0FoTfbWH.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-CDpPe3et.js → P2P-CWd90etw.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-MUX0Bpvw.js → PdhVaultBrowser-DtCGC-W-.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-A07-0Ci1.js → Permissions-CvQ7nr7T.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-DhhDWxAZ.js → PersonalDataHub-rdNPcR-Z.js} +5 -5
  54. package/src/assets/web-panel/assets/{Pipeline-CyfbJfe-.js → Pipeline-CmrfiNOs.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-CNFps3ED.js → Privacy-D7ep1h_t.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit--T-u3Dr5.js → ProjectInit-C0xKINHS.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-DJmrK2fC.js → ProjectSettings-AOmZFp-F.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-BWHSkXZP.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-DLzzbOZd.js → Providers-Cb7JCTPL.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-CexOomKS.js → QrScannerModal-BDMehcXC.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-QklGi19_.js → QuickAsk-BF6_1nvx.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Bb9kwSw8.js → Recommend-BHfT-A28.js} +1 -1
  63. package/src/assets/web-panel/assets/RemoteSession-B6EEf8hh.js +5 -0
  64. package/src/assets/web-panel/assets/{Reputation-Dr5cLP0N.js → Reputation-CsWHLEcj.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-oCQHYv5t.js → Row-D6srnWhm.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-IFDEykIR.js → RssFeed-Xhr-KyVd.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-CspVIxDc.js → Search-vIbIJvwL.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-Bm66o_DH.js → Security-Bzi5Aiko.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-DvanNqXl.js → Services-BHtVX52P.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-CHjEe9_O.js → Skeleton-C0R8B2jf.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-Cb8jWjMX.js → Skills-DtT6rWOX.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-DxZm1491.js → Sla-0B37mxVU.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-DWxEEclC.js → SpeechSettings-0V2jE1Bs.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-FIvOFw5p.js → SyncSettings-CYedRzaj.js} +2 -2
  75. package/src/assets/web-panel/assets/Tasks-D-R1x8vm.js +1 -0
  76. package/src/assets/web-panel/assets/{Templates-CaNjzV_t.js → Templates-BKoHztGT.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DjlP6TmH.js → Tenant--17nwVNZ.js} +1 -1
  78. package/src/assets/web-panel/assets/Terminal-Dnkos7vW.js +3 -0
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DoZ8y7y8.js → TimelineRenderer-C5jx4AE3.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-390cg2TC.js → Tokens-DYJKYa9t.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-CLrtCj5_.js → Trigger-DChpWiQ9.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-DpESfSPn.js → Trust-DfWG52EA.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-CN6279O0.js → UkeySign-CMugYcyA.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DPtAUlSe.js → VideoEditing-BOSmrHAd.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-nKOMV_1n.js → Wallet-D5g3k3Sa.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-HuXlSOc4.js → WebAuthn-D-7u4Mkc.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-CUfFjARi.js → WorkflowEditor-CFzZMSUJ.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-6Eq0PcZJ.js → chat-VbR6l6mc.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BP_Sf6Iy.js → colors-BSZn8EDS.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-BufMKIh5.js → compact-item-y74obMEq.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BBMXxWSW.js → createContext-C326bjex.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-D3Bho_6u.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-fUK_tRO2.js → hasIn-D_INJQT_.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-LvCBfTLo.js → index-4PIeTM--.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CgiECHu2.js → index-4eyH-eC2.js} +1 -1
  96. package/src/assets/web-panel/assets/index-5iAFwYx1.js +1 -0
  97. package/src/assets/web-panel/assets/{index-DLpIs_P_.js → index-9PIVuXqo.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-cpEli44X.js → index-B7SrC-On.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-6GmBa4Kg.js → index-BJi3UqBt.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-D9vU25ij.js → index-BY8-nCgs.js} +1 -1
  101. package/src/assets/web-panel/assets/index-BfnB7LPx.js +1 -0
  102. package/src/assets/web-panel/assets/{index-B2vS66eI.js → index-Bfw2hf2s.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DVsqvI4M.js → index-BjcWKg1S.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-C44atv4k.js → index-BnSfnSMP.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BWKoBU8R.js → index-Bnua8IX3.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-GwdRUZ-x.js → index-C-ZCaUJc.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-pum7HYBA.js → index-C2NyllnW.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B9WYSn4m.js → index-C327pLbw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bkg4ZePE.js → index-CMHqs3Jb.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DmkMXwnR.js → index-CfLJ42kv.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Dyngbd29.js → index-Cr3uuz0C.js} +19 -19
  112. package/src/assets/web-panel/assets/{index-t8N1tSeX.js → index-CsovTpx9.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DocdRcbd.js → index-CzE53HiB.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-fzaMtSJ8.js → index-DBkzrpiL.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CE2DdTP2.js → index-DNMxIsDg.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-wKTLbKyc.js → index-DUU2606o.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-uCbEN7cY.js → index-DdyjrCAu.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CZ6Yt17L.js → index-DkH1JvEt.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CwSf5pnf.js → index-Dlxh9D8D.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-3FuwBewR.js → index-DuIkfnTF.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CW_G-MXw.js → index-DwHSZLXg.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BHy6yNiF.js → index-E_v1ZCTP.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-wV6iGdpY.js → index-FQBsuExX.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DASluSqY.js → index-GA80ir_u.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BMLHv389.js → index-IZAWt0H8.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-B7Etk0Te.js → index-Iw0FfqUz.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-D4_MuGkd.js → index-KF9Zmqln.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Cp8vhyZy.js → index-abmn_8Yz.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-2A5ph8b2.js → index-gINyI1rh.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CeASi4fr.js → index-jYaogFE8.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CGjmILDm.js → index-nSn2-C4N.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DPdUNk1i.js → index-qMA4GYdQ.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-V5Fo95FM.js → initDefaultProps-DI0Zaf8-.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BYWU0hUT.js → motion-BZDKSy3Z.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-Cr1M-J2h.js → move-DsIW01Vp.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BysQKi2N.js → mtc-parser-CohkDhsf.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-D1zHU8GC.js → omit-DpiN5rzg.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-CUArxtfi.js → pickAttrs-qbuqni3y.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-ChoYEys0.js → placementArrow-mBky6714.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-BQRs3Mo7.js → responsiveObserve-Bas3eQ2K.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-B8zbsCkg.js → slide-CBx_SKoK.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-C2U8Gs6h.js → statusUtils-BlYguJSV.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-Dd8MgL_V.js → styleChecker-BCYQmRGv.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-hknqY5NH.js → useFlexGapSupport-Dp5dybLM.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-CLTAmcfw.js → useFs-DHAMBgA2.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-ByegHbiB.js → usePersonalDataHub-W6jsSw76.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-DqlAy5DP.js → vnode-BkI6aayc.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-DiXiztQn.js → zoom-C_IMGueq.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/agent.js +9 -0
  151. package/src/commands/background-session.js +49 -0
  152. package/src/commands/plugin.js +235 -23
  153. package/src/commands/session.js +13 -0
  154. package/src/data/changelog.json +13 -0
  155. package/src/harness/jsonl-session-store.js +6 -4
  156. package/src/lib/agent-team/team-runner.js +19 -1
  157. package/src/lib/background-agent-supervisor.js +49 -0
  158. package/src/lib/plugin-runtime/install.js +226 -7
  159. package/src/lib/plugin-runtime/scopes.js +13 -2
  160. package/src/lib/plugin-usage-attribution.js +44 -0
  161. package/src/lib/process-execution-broker/index.js +252 -1
  162. package/src/lib/process-execution-broker/platform-sandbox.js +1251 -101
  163. package/src/lib/session-usage.js +77 -0
  164. package/src/repl/agent-repl.js +6 -6
  165. package/src/runtime/headless-runner.js +9 -1
  166. package/src/runtime/headless-stream.js +20 -1
  167. package/src/runtime/mcp-config.js +15 -5
  168. package/src/assets/web-panel/assets/ChatBubbleRenderer-PR074hUN.js +0 -1
  169. package/src/assets/web-panel/assets/MobileProjects-BwObMMA2.js +0 -1
  170. package/src/assets/web-panel/assets/Projects-Qx_MdX9k.js +0 -1
  171. package/src/assets/web-panel/assets/RemoteSession-DZuVNNN5.js +0 -5
  172. package/src/assets/web-panel/assets/Tasks-CyuLnDFR.js +0 -1
  173. package/src/assets/web-panel/assets/Terminal-DwzGMniO.js +0 -3
  174. package/src/assets/web-panel/assets/devWarning-DgVKduH2.js +0 -1
  175. package/src/assets/web-panel/assets/index-DOZTSoS7.js +0 -1
  176. package/src/assets/web-panel/assets/index-DhpvjpqI.js +0 -1
@@ -20,10 +20,8 @@ import {
20
20
  removePlugin,
21
21
  updatePlugin,
22
22
  getPluginSettings,
23
- setPluginSetting,
24
23
  searchRegistry,
25
24
  listRegistry,
26
- registerInMarketplace,
27
25
  getPluginSummary,
28
26
  installPluginSkills,
29
27
  removePluginSkills,
@@ -404,8 +402,28 @@ export function registerPluginCommand(program) {
404
402
  .command("enable")
405
403
  .description("Enable a plugin")
406
404
  .argument("<name>", "Plugin name")
407
- .action(async (name) => {
405
+ .option(
406
+ "--scope <scope>",
407
+ "Enable the unified-runtime install at this scope (user|project|local)",
408
+ )
409
+ .option("--json", "Output unified-runtime result as JSON")
410
+ .action(async (name, options) => {
408
411
  try {
412
+ if (options.scope) {
413
+ const { setPluginEnabled } =
414
+ await import("../lib/plugin-runtime/install.js");
415
+ const result = setPluginEnabled(name, true, {
416
+ scope: options.scope,
417
+ cwd: process.cwd(),
418
+ });
419
+ if (options.json) console.log(JSON.stringify(result, null, 2));
420
+ else {
421
+ logger.success(
422
+ `Enabled ${name} (${options.scope} scope). Reload active plugin sessions to apply the change.`,
423
+ );
424
+ }
425
+ return;
426
+ }
409
427
  enforcePluginPolicy(
410
428
  { name, action: "enable" },
411
429
  loadPluginManagedPolicy(),
@@ -436,8 +454,28 @@ export function registerPluginCommand(program) {
436
454
  .command("disable")
437
455
  .description("Disable a plugin")
438
456
  .argument("<name>", "Plugin name")
439
- .action(async (name) => {
457
+ .option(
458
+ "--scope <scope>",
459
+ "Disable the unified-runtime install at this scope (user|project|local)",
460
+ )
461
+ .option("--json", "Output unified-runtime result as JSON")
462
+ .action(async (name, options) => {
440
463
  try {
464
+ if (options.scope) {
465
+ const { setPluginEnabled } =
466
+ await import("../lib/plugin-runtime/install.js");
467
+ const result = setPluginEnabled(name, false, {
468
+ scope: options.scope,
469
+ cwd: process.cwd(),
470
+ });
471
+ if (options.json) console.log(JSON.stringify(result, null, 2));
472
+ else {
473
+ logger.success(
474
+ `Disabled ${name} (${options.scope} scope). Reload active plugin sessions to apply the change.`,
475
+ );
476
+ }
477
+ return;
478
+ }
441
479
  const ctx = await bootstrap({ verbose: program.opts().verbose });
442
480
  if (!ctx.db) {
443
481
  logger.error("Database not available");
@@ -860,6 +898,7 @@ export function registerPluginCommand(program) {
860
898
  // plugin name) resolves to a git source the installer already handles.
861
899
  let installSource = source;
862
900
  let integritySha = null;
901
+ let sourceMetadata = null;
863
902
  const { isRemoteSource, resolveRemoteSource } =
864
903
  await import("../lib/plugin-runtime/remote-source.js");
865
904
  if (options.registry || isRemoteSource(source)) {
@@ -883,6 +922,19 @@ export function registerPluginCommand(program) {
883
922
  });
884
923
  installSource = resolved.source;
885
924
  integritySha = resolved.sha256;
925
+ sourceMetadata = {
926
+ type: "registry",
927
+ source: url,
928
+ registry: url,
929
+ package: name || source,
930
+ resolvedSource: resolved.source,
931
+ ref:
932
+ (typeof resolved.source === "string" &&
933
+ resolved.source.includes("#") &&
934
+ resolved.source.slice(resolved.source.indexOf("#") + 1)) ||
935
+ null,
936
+ offline: resolved.fromCache === true,
937
+ };
886
938
  if (resolved.fromCache) {
887
939
  logger.warn(
888
940
  chalk.yellow(
@@ -897,13 +949,31 @@ export function registerPluginCommand(program) {
897
949
  }
898
950
  }
899
951
 
952
+ let managed = null;
953
+ try {
954
+ managed = loadPluginManagedPolicy();
955
+ } catch (err) {
956
+ logger.error(`Managed plugin policy is invalid: ${err.message}`);
957
+ process.exitCode = 1;
958
+ return;
959
+ }
960
+ const requiresManagedSignature =
961
+ managed?.requireSignedPlugins === true ||
962
+ managed?.requireSignedPlugins === "require";
900
963
  const signature =
901
- options.sha256 || options.signature || options.publicKey || integritySha
964
+ options.sha256 ||
965
+ options.signature ||
966
+ options.publicKey ||
967
+ integritySha ||
968
+ requiresManagedSignature
902
969
  ? {
903
970
  sha256: options.sha256 || integritySha,
904
971
  signatureFile: options.signature,
905
972
  publicKeyFile: options.publicKey,
906
- requireSignature: Boolean(options.signature),
973
+ requireSignature:
974
+ Boolean(options.signature) || requiresManagedSignature,
975
+ trustedKeySha256: managed?.trustedPluginKeySha256 || null,
976
+ requireTrustedKey: requiresManagedSignature,
907
977
  }
908
978
  : null;
909
979
  try {
@@ -912,6 +982,9 @@ export function registerPluginCommand(program) {
912
982
  cwd: process.cwd(),
913
983
  force: options.force === true,
914
984
  signature,
985
+ sourceMetadata,
986
+ managedPolicy: managed,
987
+ policySource: options.registry || source,
915
988
  });
916
989
  const capNotice = await resolvePluginCapabilityNotice(
917
990
  res.name,
@@ -1060,8 +1133,21 @@ export function registerPluginCommand(program) {
1060
1133
  const trust = isPluginTrusted(r)
1061
1134
  ? chalk.green("trusted")
1062
1135
  : chalk.yellow("untrusted");
1136
+ const state =
1137
+ r.enabled === false
1138
+ ? chalk.yellow("disabled")
1139
+ : chalk.green("enabled");
1140
+ const signed = r.integrity?.signature?.verified
1141
+ ? chalk.green("signed")
1142
+ : chalk.gray("unsigned");
1143
+ const policy =
1144
+ r.policy?.allowed === false
1145
+ ? chalk.red("policy-blocked")
1146
+ : r.policy?.managed
1147
+ ? chalk.cyan("managed")
1148
+ : "";
1063
1149
  logger.log(
1064
- ` ${ok} ${chalk.cyan(r.name)} v${r.version} ${chalk.gray(`[${r.scope}]`)} ${trust}`,
1150
+ ` ${ok} ${chalk.cyan(r.name)} v${r.version} ${chalk.gray(`[${r.scope}]`)} ${state} ${trust} ${signed}${policy ? ` ${policy}` : ""}`,
1065
1151
  );
1066
1152
  }
1067
1153
  });
@@ -1456,22 +1542,162 @@ export function registerPluginCommand(program) {
1456
1542
  plugin
1457
1543
  .command("upgrade <source>")
1458
1544
  .description(
1459
- "Update a runtime plugin from its source (local dir or git); repoints .active",
1545
+ "Update a runtime plugin from its pinned local, git, or registry source; repoints .active",
1460
1546
  )
1461
1547
  .option("--scope <scope>", `Scope to update in (${SCOPES})`, "user")
1462
1548
  .option("--force", "Reinstall even if the version is unchanged")
1549
+ .option("--sha256 <hex>", "Expected SHA-256 of the manifest file")
1550
+ .option("--signature <path>", "Detached Ed25519 signature of the manifest")
1551
+ .option("--public-key <path>", "Public key for signature verification")
1552
+ .option(
1553
+ "--registry <url>",
1554
+ "Resolve <source> as a plugin NAME in this registry URL",
1555
+ )
1556
+ .option(
1557
+ "--name <plugin>",
1558
+ "Plugin name to select from a multi-plugin registry",
1559
+ )
1560
+ .option("--token <token>", "Bearer token for a private registry")
1561
+ .option(
1562
+ "--allow-insecure-registry",
1563
+ "Allow a plain-HTTP registry URL (MITM risk — trusted networks only)",
1564
+ )
1463
1565
  .option(
1464
1566
  "--grant-capabilities",
1465
1567
  "Grant any newly declared capabilities during the upgrade (no separate consent step)",
1466
1568
  )
1569
+ .option("--json", "Output as JSON")
1467
1570
  .action(async (source, options) => {
1468
1571
  const { updatePlugin } = await import("../lib/plugin-runtime/install.js");
1572
+ let installSource = source;
1573
+ let integritySha = null;
1574
+ let sourceMetadata = null;
1575
+ const { isRemoteSource, resolveRemoteSource } =
1576
+ await import("../lib/plugin-runtime/remote-source.js");
1577
+ if (options.registry || isRemoteSource(source)) {
1578
+ const url = options.registry || source;
1579
+ const name = options.registry ? source : options.name;
1580
+ let config = null;
1581
+ try {
1582
+ const cm = await import("../lib/config-manager.js");
1583
+ config = cm.loadConfig();
1584
+ } catch {
1585
+ config = null;
1586
+ }
1587
+ try {
1588
+ const resolved = await resolveRemoteSource(url, {
1589
+ name,
1590
+ token: options.token,
1591
+ config,
1592
+ allowInsecure: options.allowInsecureRegistry === true,
1593
+ });
1594
+ installSource = resolved.source;
1595
+ integritySha = resolved.sha256;
1596
+ sourceMetadata = {
1597
+ type: "registry",
1598
+ source: url,
1599
+ registry: url,
1600
+ package: name || source,
1601
+ resolvedSource: resolved.source,
1602
+ ref:
1603
+ (typeof resolved.source === "string" &&
1604
+ resolved.source.includes("#") &&
1605
+ resolved.source.slice(resolved.source.indexOf("#") + 1)) ||
1606
+ null,
1607
+ offline: resolved.fromCache === true,
1608
+ };
1609
+ if (resolved.fromCache && !options.json) {
1610
+ logger.warn(
1611
+ chalk.yellow(
1612
+ " ⚠ registry unreachable — using cached copy (offline)",
1613
+ ),
1614
+ );
1615
+ }
1616
+ } catch (err) {
1617
+ logger.error(`Registry resolution failed: ${err.message}`);
1618
+ process.exitCode = 1;
1619
+ return;
1620
+ }
1621
+ }
1622
+
1623
+ let managed = null;
1469
1624
  try {
1470
- const res = updatePlugin(source, {
1625
+ managed = loadPluginManagedPolicy();
1626
+ } catch (err) {
1627
+ logger.error(`Managed plugin policy is invalid: ${err.message}`);
1628
+ process.exitCode = 1;
1629
+ return;
1630
+ }
1631
+ const requiresManagedSignature =
1632
+ managed?.requireSignedPlugins === true ||
1633
+ managed?.requireSignedPlugins === "require";
1634
+ const signature =
1635
+ options.sha256 ||
1636
+ options.signature ||
1637
+ options.publicKey ||
1638
+ integritySha ||
1639
+ requiresManagedSignature
1640
+ ? {
1641
+ sha256: options.sha256 || integritySha,
1642
+ signatureFile: options.signature,
1643
+ publicKeyFile: options.publicKey,
1644
+ requireSignature:
1645
+ Boolean(options.signature) || requiresManagedSignature,
1646
+ trustedKeySha256: managed?.trustedPluginKeySha256 || null,
1647
+ requireTrustedKey: requiresManagedSignature,
1648
+ }
1649
+ : null;
1650
+ try {
1651
+ const res = updatePlugin(installSource, {
1471
1652
  scope: options.scope,
1472
1653
  cwd: process.cwd(),
1473
1654
  force: options.force,
1655
+ signature,
1656
+ sourceMetadata,
1657
+ managedPolicy: managed,
1658
+ policySource: options.registry || source,
1474
1659
  });
1660
+ const upgradeNotice = await resolvePluginCapabilityNotice(
1661
+ res.name,
1662
+ options.scope,
1663
+ process.cwd(),
1664
+ );
1665
+ if (res.updated || res.reinstalled)
1666
+ await auditPluginInstall(
1667
+ "upgrade",
1668
+ { ...res, scope: options.scope },
1669
+ installSource,
1670
+ upgradeNotice,
1671
+ );
1672
+
1673
+ if (options.json) {
1674
+ let capabilitiesGranted = false;
1675
+ if (
1676
+ options.grantCapabilities &&
1677
+ upgradeNotice &&
1678
+ !upgradeNotice.consented
1679
+ ) {
1680
+ capabilitiesGranted = await grantInstalledPluginCapabilities(
1681
+ res.name,
1682
+ options.scope,
1683
+ process.cwd(),
1684
+ );
1685
+ }
1686
+ console.log(
1687
+ JSON.stringify(
1688
+ {
1689
+ ...res,
1690
+ scope: options.scope,
1691
+ capabilities: upgradeNotice,
1692
+ capabilitiesGranted,
1693
+ },
1694
+ null,
1695
+ 2,
1696
+ ),
1697
+ );
1698
+ return;
1699
+ }
1700
+
1475
1701
  if (res.updated) {
1476
1702
  logger.success(
1477
1703
  `Updated ${res.name}: ${res.previousVersion ? `v${res.previousVersion} → ` : ""}v${res.version} (${options.scope} scope)`,
@@ -1489,20 +1715,6 @@ export function registerPluginCommand(program) {
1489
1715
  // upgrade that adds a capability shows a `⚠ capability consent required`
1490
1716
  // notice diffed against the prior consent, then either auto-grants
1491
1717
  // (--grant-capabilities) or blocks interactively to re-consent now.
1492
- const upgradeNotice = await resolvePluginCapabilityNotice(
1493
- res.name,
1494
- options.scope,
1495
- process.cwd(),
1496
- );
1497
- // Only a version that actually landed on disk is an install; an
1498
- // already-up-to-date no-op fetched nothing new to run.
1499
- if (res.updated || res.reinstalled)
1500
- await auditPluginInstall(
1501
- "upgrade",
1502
- { ...res, scope: options.scope },
1503
- source,
1504
- upgradeNotice,
1505
- );
1506
1718
  await applyCapabilityConsentGate(
1507
1719
  res.name,
1508
1720
  options.scope,
@@ -1333,6 +1333,7 @@ export function registerSessionCommand(program) {
1333
1333
  "subagent",
1334
1334
  "tool",
1335
1335
  "mcp",
1336
+ "plugin",
1336
1337
  "model",
1337
1338
  ];
1338
1339
 
@@ -1403,6 +1404,18 @@ export function registerSessionCommand(program) {
1403
1404
  );
1404
1405
  return;
1405
1406
  }
1407
+ case "plugin": {
1408
+ const rows = a.tools?.byPlugin || [];
1409
+ if (rows.length === 0) return empty("plugin-attributed tool calls");
1410
+ for (const r of rows)
1411
+ toolRow(`${r.plugin}${r.version ? `@${r.version}` : ""}`, r);
1412
+ logger.log(
1413
+ chalk.gray(
1414
+ " turnTokens = tokens of turns that used the plugin (approximation; do not sum across rows)",
1415
+ ),
1416
+ );
1417
+ return;
1418
+ }
1406
1419
  default:
1407
1420
  break;
1408
1421
  }
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.162.183",
7
+ "cliVersions": ["0.4.74", "0.37.35", "0.162.182", "0.162.183"],
8
+ "date": "2026-07-27",
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Added — cc CLI 0.162.183 + IDE quality, plugin, and worktree governance",
13
+ "body": "> `chainlesschain` **0.162.182 → 0.162.183**, VS Code\n> **0.37.34 → 0.37.35**, and JetBrains **0.4.73 → 0.4.74** (2026-07-27).\n> `@chainlesschain/personal-data-hub` remains **0.4.57** and\n> `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **IDE-native quality context**: both IDE bridges negotiate bounded\n `cc-ide-quality/v1` test-result, coverage, and debugger snapshots with\n Context v2 freshness metadata; VS Code notebook execution now carries its\n real notebook context.\n- **Installation Doctor depth**: VS Code and JetBrains report Node/Java\n availability plus managed-CLI and plugin-registry offline recovery state,\n without probing executables from an untrusted workspace directory.\n- **Plugin lifecycle and supply-chain UI**: scoped enable/disable, source-aware\n upgrades, live-session reload, signature/SBOM summaries, managed-policy\n provenance, and sanitized registry/Git/local source metadata stay governed\n by the CLI runtime.\n- **Plugin usage attribution**: compact transcripts and usage reports now\n attribute plugin-bin and plugin-provided MCP calls by plugin/version without\n persisting tool arguments.\n- **Supervised worktree tasks**: IDE-created isolated tasks run as background\n worktree agents and display canonical lifecycle, owner/session, permission\n mode, resource budget, and bounded side-effect counts. Team and batch rows\n remain explicitly unmanaged until they expose equivalent durable state.\n- **Release validation**: publication remains gated on the exact release\n commit passing CLI CI, CLI Strict Sandbox, background reconnect E2E, packaged\n VSIX Extension Host gates, JetBrains unit/build/Remote Robot gates, and\n public marketplace readback."
14
+ }
15
+ ]
16
+ },
4
17
  {
5
18
  "productVersion": null,
6
19
  "cliVersion": "0.162.182",
@@ -164,20 +164,22 @@ export function appendToolCall(sessionId, toolName, args) {
164
164
 
165
165
  /**
166
166
  * Compact tool-call record for usage attribution (用量归因): tool name +
167
- * error flag (+ an optional skill hint for `run_skill`) — deliberately NOT
167
+ * error flag (+ optional skill and plugin/version hints) — deliberately NOT
168
168
  * the args, which can carry whole file bodies (write_file content) and would
169
169
  * bloat the transcript. Written at tool-result time by the agent drivers so
170
- * `cc session usage --by tool|mcp` and `cc insights` can aggregate tool use
171
- * for any persisted session.
170
+ * `cc session usage --by tool|mcp|plugin` and `cc insights` can aggregate tool
171
+ * use for any persisted session.
172
172
  */
173
173
  export function appendToolCallCompact(
174
174
  sessionId,
175
- { tool, isError, skill } = {},
175
+ { tool, isError, skill, plugin, pluginVersion } = {},
176
176
  ) {
177
177
  appendEvent(sessionId, "tool_call", {
178
178
  tool: tool || "?",
179
179
  is_error: Boolean(isError),
180
180
  ...(skill ? { skill: String(skill) } : {}),
181
+ ...(plugin ? { plugin: String(plugin) } : {}),
182
+ ...(pluginVersion ? { plugin_version: String(pluginVersion) } : {}),
181
183
  });
182
184
  }
183
185
 
@@ -51,6 +51,10 @@ export class TeamRunner {
51
51
  this._executions = 0;
52
52
  this._inFlight = 0;
53
53
  this._maxInFlight = 0;
54
+ // Keys executing in this runner process. An event-loop stall may let a
55
+ // short lease expire before its heartbeat callback runs; peer loops in the
56
+ // same process must not steal and double-run that still-active task.
57
+ this._activeKeys = new Set();
54
58
  this._members = new Map(); // holder → lifecycle record
55
59
  this._budgetStopped = false;
56
60
  }
@@ -208,6 +212,7 @@ export class TeamRunner {
208
212
  let best = null;
209
213
  let bestScore = Infinity;
210
214
  for (const key of claimable) {
215
+ if (this._activeKeys.has(key)) continue;
211
216
  const t = this.registry.getTask(key);
212
217
  const score = rank[t?.priority] ?? 1;
213
218
  if (score < bestScore) {
@@ -222,10 +227,22 @@ export class TeamRunner {
222
227
  const task = this.registry.getTask(key);
223
228
  this._executions++;
224
229
  this._inFlight++;
230
+ this._activeKeys.add(key);
225
231
  this._maxInFlight = Math.max(this._maxInFlight, this._inFlight);
226
232
  this._setState(holder, "running", { key });
227
233
  this._emit("task:claimed", { key, holder, attempts: task.attempts });
228
- const renew = () => this.registry.renew(key, { holder, ttlMs: this.ttlMs });
234
+ const renew = () => {
235
+ const result = this.registry.renew(key, {
236
+ holder,
237
+ ttlMs: this.ttlMs,
238
+ });
239
+ // A delayed timer may wake just after expiry. Reacquire is safe and
240
+ // optimistic: it succeeds only if no external runner has taken the
241
+ // lease; a real takeover remains authoritative and stops the heartbeat.
242
+ return !result?.ok && result?.reason === "not_holder_or_expired"
243
+ ? this.registry.acquire(key, { holder, ttlMs: this.ttlMs })
244
+ : result;
245
+ };
229
246
  // Heartbeat: the built-in executors (shell / agent / worktree) never call
230
247
  // `renew` themselves, so before this ANY task outliving the lease TTL was
231
248
  // indistinguishable from a crash — a peer could steal it and the SAME task
@@ -338,6 +355,7 @@ export class TeamRunner {
338
355
  });
339
356
  } finally {
340
357
  clearInterval(heartbeat);
358
+ this._activeKeys.delete(key);
341
359
  this._inFlight--;
342
360
  }
343
361
  }
@@ -762,6 +762,47 @@ export function normalizeBackgroundWorktree(worktree, cwd) {
762
762
  return normalized;
763
763
  }
764
764
 
765
+ /**
766
+ * Persist only the bounded, secret-free governance envelope needed by IDE task
767
+ * rows. The supervisor owns `owner`; callers cannot forge it. Prompt text,
768
+ * argv, credentials and tool arguments are deliberately excluded.
769
+ */
770
+ export function normalizeBackgroundGovernance(
771
+ governance,
772
+ { id, sessionId } = {},
773
+ ) {
774
+ const source = governance && typeof governance === "object" ? governance : {};
775
+ const budget =
776
+ source.resourceBudget && typeof source.resourceBudget === "object"
777
+ ? source.resourceBudget
778
+ : {};
779
+ const positive = (value) => {
780
+ const n = Number(value);
781
+ return Number.isFinite(n) && n > 0 ? n : null;
782
+ };
783
+ const permissionMode = new Set([
784
+ "manual",
785
+ "auto",
786
+ "dontAsk",
787
+ "default",
788
+ "plan",
789
+ "acceptEdits",
790
+ "bypassPermissions",
791
+ ]).has(source.permissionMode)
792
+ ? source.permissionMode
793
+ : "default";
794
+ return {
795
+ version: 1,
796
+ owner: `background:${String(id || "").slice(0, 160)}`,
797
+ sessionId: sessionId ? String(sessionId).slice(0, 256) : null,
798
+ permissionMode,
799
+ resourceBudget: {
800
+ maxTurns: positive(budget.maxTurns),
801
+ maxCostUsd: positive(budget.maxCostUsd),
802
+ },
803
+ };
804
+ }
805
+
765
806
  function persistedWorktree(state) {
766
807
  if (!state?.worktreePath) return null;
767
808
  return {
@@ -817,6 +858,7 @@ export function resumeBackgroundAgent(id, prompt, options = {}) {
817
858
  cliEntry: options.cliEntry,
818
859
  followUpArgv: ["agent", "--session", state.sessionId],
819
860
  worktree,
861
+ governance: state.governance,
820
862
  });
821
863
  }
822
864
 
@@ -855,10 +897,15 @@ export function launchBackgroundAgent({
855
897
  cliEntry,
856
898
  followUpArgv,
857
899
  worktree,
900
+ governance,
858
901
  }) {
859
902
  assertUsableCwd(cwd);
860
903
  const worktreeState = normalizeBackgroundWorktree(worktree, cwd);
861
904
  const id = createBackgroundAgentId();
905
+ const governanceState = normalizeBackgroundGovernance(governance, {
906
+ id,
907
+ sessionId,
908
+ });
862
909
  const dir = backgroundAgentsDir();
863
910
  const jobFile = join(dir, `${id}.job.${process.pid}.json`);
864
911
  const worker = fileURLToPath(
@@ -873,6 +920,7 @@ export function launchBackgroundAgent({
873
920
  cliEntry: cliEntry || process.argv[1],
874
921
  logFile: logPath(id),
875
922
  ...(worktreeState || {}),
923
+ governance: governanceState,
876
924
  // Present = interactive attach can start follow-up turns; absent = the
877
925
  // transport rejects prompts (log-only session).
878
926
  ...(Array.isArray(followUpArgv) ? { followUpArgv } : {}),
@@ -897,6 +945,7 @@ export function launchBackgroundAgent({
897
945
  exitCode: null,
898
946
  logFile: job.logFile,
899
947
  ...(worktreeState || {}),
948
+ governance: governanceState,
900
949
  };
901
950
  writeBackgroundAgentState(state);
902
951
  let child;