chainlesschain 0.162.183 → 0.162.185

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 (205) 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-BapS7lz4.js → AIOps-Co4ipAKx.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CXYdXEUI.js → ActionButton-BpsoDrDq.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CKR5Lexn.js → Analytics-DMUqeBik.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DATVUOXB.js → AppLayout-C6fD_dXr.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-vb_0ZlV1.js → Artifacts-DW0YlQlV.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-BI1l9GWt.js → Audit-DXtHiiFK.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-BFXbaUEf.js → BackgroundAgents-BgmF62U-.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-DEYBJJ6H.js → Backup-D8vhVLQC.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-COdzeO0M.js → BaseInput-D7nCtY2X.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-oSN6sfM5.js → Chat-CBZLEV2G.js} +6 -6
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CI_jT0ru.js → ChatBubbleRenderer-CtDb-2Qu.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-BezEa4tm.js → Checkbox-DJLkeD4M.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CNEL0Ife.js → Codegen-Cs6xO8Fd.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-Bf2Y2Bn1.js → Col-Dtx9wxfT.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-BfUlu4Hc.js → Community-DiigJg4n.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BN4xWP9e.js → Compact-B67oMDDL.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-Bt6BKmEP.js → Compliance-BBDl-Jos.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-DKLp8YxO.js → Cowork-Ba98hSsa.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-o7Hhw6ky.js → Cron-DBWQZIz7.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-DaNXWJIw.js → Crosschain-OcrKzxAt.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-B-Qa2mha.js → DID-mW2eSbjM.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-CMX0Qnxw.js → Dashboard-BmsDPmKJ.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BLuLyRu_.js → Dropdown-CVzmCyRx.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-CFBAeMij.js → EmailListRenderer-vVgqKzhh.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DWzXQ67V.js → FamilyGuardDashboard-CWY5t_ZJ.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-DB1QSLgr.js → Federation-ZGomhjxr.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-C-OKCToP.js → FormItemContext-DyaknbLr.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-DMJFtFZf.js → GenericCardRenderer-CmIvN1qr.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-DsGSujOV.js → Git-DQOJIYkG.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-B0iS9NEW.js → Governance-CMiY-EEp.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-CH004H7c.js → Inference-D6IXuucf.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-Q9MTQ83c.js → KnowledgeGraph-6jkTL0hV.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-B_fyjZK9.js → Logs-N0jD-349.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-BL1IVXm-.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-BIStF9d1.js → Marketplace-WhYuhBxm.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-pGfal768.js → McpTools-DTeO28xy.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-xbNqpIqB.js → Memory-MSHzPSE-.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-B5EQGrIK.js → MobileBridge-Cyqs3J3W.js} +1 -1
  41. package/src/assets/web-panel/assets/MobileProjects-7IN2hWHg.js +1 -0
  42. package/src/assets/web-panel/assets/{Mtc-a_rmfxJH.js → Mtc-MWBnezNM.js} +5 -5
  43. package/src/assets/web-panel/assets/{MtcAudit-BmKuofUr.js → MtcAudit-DQu35Nu-.js} +4 -4
  44. package/src/assets/web-panel/assets/{Multisig-BQbJ-CAN.js → Multisig-CQS_M-DP.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-JtPJKX25.js → NLProgramming-WD16vQvY.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-ZFKznTSG.js → Notes-DqsiSwOq.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-B6aHRBBR.js → NotificationSettings-D3LoxO-P.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-DdcsOqEz.js → OrderTableRenderer-C5jPoTd6.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-BFDTAUgS.js → Organization-48aMBJso.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-0FoTfbWH.js → Overflow-j-a2XkhR.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CWd90etw.js → P2P-BYpBNYnh.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-DtCGC-W-.js → PdhVaultBrowser-CYCsrrLg.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-CvQ7nr7T.js → Permissions-ZRXGXDFb.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-rdNPcR-Z.js → PersonalDataHub-6OWUPHyL.js} +5 -5
  55. package/src/assets/web-panel/assets/{Pipeline-CmrfiNOs.js → Pipeline-FcjlDK9E.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-D7ep1h_t.js → Privacy-vD_6Tldp.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-C0xKINHS.js → ProjectInit-B_CHOLXp.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-AOmZFp-F.js → ProjectSettings-rEiqQ2da.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-BWHSkXZP.js → Projects-Bg8obRAM.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-Cb7JCTPL.js → Providers-Dgtt97B4.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-BDMehcXC.js → QrScannerModal-DaGVylZO.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-BF6_1nvx.js → QuickAsk-DP2_2x3u.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-BHfT-A28.js → Recommend-D29yj4ki.js} +1 -1
  64. package/src/assets/web-panel/assets/RemoteSession-Ue2wnBLp.js +5 -0
  65. package/src/assets/web-panel/assets/{Reputation-CsWHLEcj.js → Reputation-CrxIHqeC.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-D6srnWhm.js → Row-BgSzJPCn.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-Xhr-KyVd.js → RssFeed-AwhYOrP9.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-vIbIJvwL.js → Search-D2shpEcm.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-Bzi5Aiko.js → Security-BtKzhTbT.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-BHtVX52P.js → Services-BY0DsUSm.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-C0R8B2jf.js → Skeleton-B3Sb0UI9.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-DtT6rWOX.js → Skills-Ne5w0bDs.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-0B37mxVU.js → Sla-C8VkaP4T.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-0V2jE1Bs.js → SpeechSettings-BQdIEYP9.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-CYedRzaj.js → SyncSettings-CwFafrUg.js} +2 -2
  76. package/src/assets/web-panel/assets/Tasks-yJuKoDlR.js +1 -0
  77. package/src/assets/web-panel/assets/{Templates-BKoHztGT.js → Templates-DYn9qCmx.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant--17nwVNZ.js → Tenant-DkKReHvn.js} +1 -1
  79. package/src/assets/web-panel/assets/Terminal-r6bd-owt.js +3 -0
  80. package/src/assets/web-panel/assets/{TimelineRenderer-C5jx4AE3.js → TimelineRenderer-Mq2juUC3.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-DYJKYa9t.js → Tokens-BnMw7MRi.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-DChpWiQ9.js → Trigger-CTzKp4o9.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-DfWG52EA.js → Trust-BBrSZm9U.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-CMugYcyA.js → UkeySign-D9fDvEMq.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-BOSmrHAd.js → VideoEditing-DUi5ve-0.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-D5g3k3Sa.js → Wallet-C8Fi1P8_.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-D-7u4Mkc.js → WebAuthn-s1LppYi2.js} +5 -5
  88. package/src/assets/web-panel/assets/{WorkflowEditor-CFzZMSUJ.js → WorkflowEditor-DJL2C4lj.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-VbR6l6mc.js → chat-D3F2ndOB.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-BSZn8EDS.js → colors-B7739-e3.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-y74obMEq.js → compact-item-CcJbFTF4.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-C326bjex.js → createContext-CuP_DEFS.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-Cj_36GHq.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-D_INJQT_.js → hasIn-6YEXfIik.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DuIkfnTF.js → index-4h3lpWJ3.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DBkzrpiL.js → index-BIID4XcP.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-B7SrC-On.js → index-BOHUo3aM.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BnSfnSMP.js → index-BYYSLEjn.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-KF9Zmqln.js → index-Bh4hcNWW.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-C327pLbw.js → index-BhIKnQAW.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-E_v1ZCTP.js → index-Bru_kpZl.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Bfw2hf2s.js → index-BsdSnHQE.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-jYaogFE8.js → index-BxSqVMGh.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Dlxh9D8D.js → index-C3ZA_h1j.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DdyjrCAu.js → index-C3pctdCb.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-abmn_8Yz.js → index-CRuoRapN.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-qMA4GYdQ.js → index-CY0zd_jc.js} +1 -1
  108. package/src/assets/web-panel/assets/index-CezFrAmD.js +1 -0
  109. package/src/assets/web-panel/assets/index-Cxgguez6.js +1 -0
  110. package/src/assets/web-panel/assets/{index-Cr3uuz0C.js → index-CxradkS6.js} +19 -19
  111. package/src/assets/web-panel/assets/{index-DwHSZLXg.js → index-D0K_rFC1.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CMHqs3Jb.js → index-D0zdPyTD.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Bnua8IX3.js → index-D3haorUt.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BY8-nCgs.js → index-D6Ij_2uw.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-FQBsuExX.js → index-DDRlBaDt.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-C-ZCaUJc.js → index-DGsE7MQz.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BjcWKg1S.js → index-DHvxXXNA.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-GA80ir_u.js → index-DV11jpeO.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CsovTpx9.js → index-DXdnfDVK.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-nSn2-C4N.js → index-D_75jYWk.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BJi3UqBt.js → index-DjI9MkId.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-gINyI1rh.js → index-DlSvpNMf.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CfLJ42kv.js → index-Dox44j29.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C2NyllnW.js → index-DpEKmjoa.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Iw0FfqUz.js → index-Dsy7_x4s.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-4eyH-eC2.js → index-Gxw09e9R.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-4PIeTM--.js → index-LfRlSmqe.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-IZAWt0H8.js → index-Nz-MUHD1.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DUU2606o.js → index-b9cuvFEv.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CzE53HiB.js → index-eR6H6NR7.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-9PIVuXqo.js → index-fWgUQZ9d.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DkH1JvEt.js → index-mfWQRSLn.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DNMxIsDg.js → index-yOZYSNmG.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-DI0Zaf8-.js → initDefaultProps-CJ1Bq2L3.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BZDKSy3Z.js → motion-rYJN_vzf.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-DsIW01Vp.js → move-DnDK2gTP.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-CohkDhsf.js → mtc-parser-CKnXy7ES.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-DpiN5rzg.js → omit-3nRc3hWT.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-qbuqni3y.js → pickAttrs-Ddjj3sLu.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-mBky6714.js → placementArrow-CbsbphQY.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-Bas3eQ2K.js → responsiveObserve-D9aZ4VDJ.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-CBx_SKoK.js → slide-D4pvdFj0.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-BlYguJSV.js → statusUtils-C2W-vY-S.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-BCYQmRGv.js → styleChecker-Cbq5150d.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-Dp5dybLM.js → useFlexGapSupport-BA2B7R82.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-DHAMBgA2.js → useFs-CLrwg3xg.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-W6jsSw76.js → usePersonalDataHub-DQeAI5qs.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-BkI6aayc.js → vnode-8BDGy-YU.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-C_IMGueq.js → zoom-B2SzFprl.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/background-session.js +11 -1
  153. package/src/commands/batch.js +160 -5
  154. package/src/commands/plugin.js +90 -27
  155. package/src/commands/session.js +31 -1
  156. package/src/commands/team.js +212 -6
  157. package/src/data/changelog.json +26 -0
  158. package/src/gateways/terminal/PtyManager.js +45 -15
  159. package/src/gateways/ws/ws-agent-handler.js +15 -1
  160. package/src/gateways/ws/ws-session-gateway.js +88 -0
  161. package/src/harness/background-task-command-runner.js +234 -0
  162. package/src/harness/background-task-manager.js +150 -20
  163. package/src/harness/background-task-worker.js +17 -11
  164. package/src/harness/jsonl-session-store.js +57 -6
  165. package/src/harness/mcp-client.js +65 -43
  166. package/src/lib/agent-batch.js +4 -1
  167. package/src/lib/agent-team/team-worktree.js +3 -0
  168. package/src/lib/async-hook-supervisor.cjs +82 -10
  169. package/src/lib/async-hook-supervisor.js +50 -4
  170. package/src/lib/background-agent-supervisor.js +46 -0
  171. package/src/lib/collaboration-run-store.js +362 -0
  172. package/src/lib/event-runtime-host.js +12 -10
  173. package/src/lib/hook-runner.cjs +105 -18
  174. package/src/lib/hook-runner.js +79 -6
  175. package/src/lib/hook-shell-command.cjs +148 -0
  176. package/src/lib/hooks-v2-runtime.js +280 -81
  177. package/src/lib/hooks-v2-workspace-context.js +258 -0
  178. package/src/lib/jsonl-session-store.js +2 -0
  179. package/src/lib/lsp/__tests__/lsp-client.test.js +15 -0
  180. package/src/lib/lsp/lsp-client.js +12 -1
  181. package/src/lib/plugin-monitor-supervisor.js +53 -16
  182. package/src/lib/plugin-runtime/bin.js +21 -5
  183. package/src/lib/plugin-runtime/install.js +249 -57
  184. package/src/lib/plugin-runtime/mcp.js +21 -2
  185. package/src/lib/plugin-runtime/monitors.js +19 -3
  186. package/src/lib/plugin-runtime/sandbox-policy.js +100 -4
  187. package/src/lib/process-execution-broker/index.js +1151 -44
  188. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +1557 -0
  189. package/src/lib/process-execution-broker/linux-generic-bwrap.js +1378 -0
  190. package/src/lib/process-execution-broker/platform-sandbox.js +586 -58
  191. package/src/lib/session-usage.js +202 -2
  192. package/src/lib/stream-retry.js +29 -0
  193. package/src/repl/agent-repl.js +40 -3
  194. package/src/runtime/agent-core.js +304 -42
  195. package/src/runtime/headless-runner.js +48 -1
  196. package/src/runtime/headless-stream.js +42 -2
  197. package/src/workers/background-agent-worker.js +5 -11
  198. package/src/assets/web-panel/assets/MarkdownRenderer-C0o4FtpD.js +0 -1
  199. package/src/assets/web-panel/assets/MobileProjects-VTc3gT1y.js +0 -1
  200. package/src/assets/web-panel/assets/RemoteSession-B6EEf8hh.js +0 -5
  201. package/src/assets/web-panel/assets/Tasks-D-R1x8vm.js +0 -1
  202. package/src/assets/web-panel/assets/Terminal-Dnkos7vW.js +0 -3
  203. package/src/assets/web-panel/assets/devWarning-D3Bho_6u.js +0 -1
  204. package/src/assets/web-panel/assets/index-5iAFwYx1.js +0 -1
  205. package/src/assets/web-panel/assets/index-BfnB7LPx.js +0 -1
@@ -37,7 +37,12 @@ import {
37
37
  * (for --json folding) or null when the plugin declares nothing / can't be
38
38
  * resolved.
39
39
  */
40
- async function resolvePluginCapabilityNotice(name, scope, cwd) {
40
+ async function resolvePluginCapabilityNotice(
41
+ name,
42
+ scope,
43
+ cwd,
44
+ { strict = false } = {},
45
+ ) {
41
46
  try {
42
47
  const { discoverPlugins } = await import("../lib/plugin-runtime/scopes.js");
43
48
  const { describeCapabilities } =
@@ -46,7 +51,12 @@ async function resolvePluginCapabilityNotice(name, scope, cwd) {
46
51
  const installed = discoverPlugins({ cwd, skipPolicy: true }).find(
47
52
  (p) => p.name === name && p.scope === scope,
48
53
  );
49
- if (!installed) return null;
54
+ if (!installed) {
55
+ if (strict) {
56
+ throw new Error(`${name} is not discoverable at ${scope} scope`);
57
+ }
58
+ return null;
59
+ }
50
60
  const declared = installed.manifest?.capabilities;
51
61
  if (!declared || consent.capabilitiesAreEmpty(declared)) return null;
52
62
  const entry = consent.loadConsentStore()[`${scope}:${name}`] || null;
@@ -57,7 +67,12 @@ async function resolvePluginCapabilityNotice(name, scope, cwd) {
57
67
  reason: status.reason,
58
68
  added: status.added,
59
69
  };
60
- } catch {
70
+ } catch (error) {
71
+ if (strict) {
72
+ throw new Error(
73
+ `installed plugin capability validation failed: ${error.message}`,
74
+ );
75
+ }
61
76
  return null; // capability rendering is advisory — never break an install
62
77
  }
63
78
  }
@@ -1568,7 +1583,8 @@ export function registerPluginCommand(program) {
1568
1583
  )
1569
1584
  .option("--json", "Output as JSON")
1570
1585
  .action(async (source, options) => {
1571
- const { updatePlugin } = await import("../lib/plugin-runtime/install.js");
1586
+ const { updatePlugin, finalizePluginUpdate, rollbackPluginUpdate } =
1587
+ await import("../lib/plugin-runtime/install.js");
1572
1588
  let installSource = source;
1573
1589
  let integritySha = null;
1574
1590
  let sourceMetadata = null;
@@ -1647,8 +1663,9 @@ export function registerPluginCommand(program) {
1647
1663
  requireTrustedKey: requiresManagedSignature,
1648
1664
  }
1649
1665
  : null;
1666
+ let res = null;
1650
1667
  try {
1651
- const res = updatePlugin(installSource, {
1668
+ res = updatePlugin(installSource, {
1652
1669
  scope: options.scope,
1653
1670
  cwd: process.cwd(),
1654
1671
  force: options.force,
@@ -1656,11 +1673,13 @@ export function registerPluginCommand(program) {
1656
1673
  sourceMetadata,
1657
1674
  managedPolicy: managed,
1658
1675
  policySource: options.registry || source,
1676
+ transactional: true,
1659
1677
  });
1660
1678
  const upgradeNotice = await resolvePluginCapabilityNotice(
1661
1679
  res.name,
1662
1680
  options.scope,
1663
1681
  process.cwd(),
1682
+ { strict: true },
1664
1683
  );
1665
1684
  if (res.updated || res.reinstalled)
1666
1685
  await auditPluginInstall(
@@ -1670,19 +1689,53 @@ export function registerPluginCommand(program) {
1670
1689
  upgradeNotice,
1671
1690
  );
1672
1691
 
1692
+ let capabilitiesGranted = false;
1673
1693
  if (options.json) {
1674
- let capabilitiesGranted = false;
1675
- if (
1676
- options.grantCapabilities &&
1677
- upgradeNotice &&
1678
- !upgradeNotice.consented
1679
- ) {
1694
+ if (options.grantCapabilities && upgradeNotice?.consented === false) {
1680
1695
  capabilitiesGranted = await grantInstalledPluginCapabilities(
1681
1696
  res.name,
1682
1697
  options.scope,
1683
1698
  process.cwd(),
1684
1699
  );
1685
1700
  }
1701
+ } else {
1702
+ capabilitiesGranted = await applyCapabilityConsentGate(
1703
+ res.name,
1704
+ options.scope,
1705
+ upgradeNotice,
1706
+ process.cwd(),
1707
+ {
1708
+ grant: options.grantCapabilities === true,
1709
+ interactive: Boolean(process.stdin.isTTY),
1710
+ },
1711
+ );
1712
+ }
1713
+
1714
+ const changed = res.updated || res.reinstalled;
1715
+ const consentBlocked =
1716
+ changed &&
1717
+ upgradeNotice?.consented === false &&
1718
+ capabilitiesGranted !== true;
1719
+ const rollbackReason = consentBlocked
1720
+ ? options.grantCapabilities
1721
+ ? "capability_consent_failed"
1722
+ : "capability_consent_required"
1723
+ : null;
1724
+ let activationStatus = changed ? "activated" : "unchanged";
1725
+ let rollbackVersion = null;
1726
+ let cleanupPending = false;
1727
+ if (rollbackReason) {
1728
+ const recovery = rollbackPluginUpdate(res);
1729
+ if (!recovery.rolledBack) {
1730
+ throw new Error("upgrade rollback transaction was unavailable");
1731
+ }
1732
+ activationStatus = "rolled_back";
1733
+ rollbackVersion = recovery.version;
1734
+ } else {
1735
+ cleanupPending = finalizePluginUpdate(res).cleanupPending === true;
1736
+ }
1737
+
1738
+ if (options.json) {
1686
1739
  console.log(
1687
1740
  JSON.stringify(
1688
1741
  {
@@ -1690,6 +1743,10 @@ export function registerPluginCommand(program) {
1690
1743
  scope: options.scope,
1691
1744
  capabilities: upgradeNotice,
1692
1745
  capabilitiesGranted,
1746
+ activationStatus,
1747
+ rollbackVersion,
1748
+ rollbackReason,
1749
+ cleanupPending,
1693
1750
  },
1694
1751
  null,
1695
1752
  2,
@@ -1698,7 +1755,14 @@ export function registerPluginCommand(program) {
1698
1755
  return;
1699
1756
  }
1700
1757
 
1701
- if (res.updated) {
1758
+ if (activationStatus === "rolled_back") {
1759
+ logger.warn(
1760
+ `Upgrade not activated: ${rollbackReason.replaceAll("_", " ")}; ` +
1761
+ (rollbackVersion
1762
+ ? `restored ${res.name} v${rollbackVersion}`
1763
+ : `removed the rejected ${res.name} v${res.version} install`),
1764
+ );
1765
+ } else if (res.updated) {
1702
1766
  logger.success(
1703
1767
  `Updated ${res.name}: ${res.previousVersion ? `v${res.previousVersion} → ` : ""}v${res.version} (${options.scope} scope)`,
1704
1768
  );
@@ -1711,22 +1775,21 @@ export function registerPluginCommand(program) {
1711
1775
  `${res.name} is already up to date at v${res.version} (use --force to reinstall)`,
1712
1776
  );
1713
1777
  }
1714
- // Surface the (possibly widened) capability set + re-consent hint. An
1715
- // upgrade that adds a capability shows a `⚠ capability consent required`
1716
- // notice diffed against the prior consent, then either auto-grants
1717
- // (--grant-capabilities) or blocks interactively to re-consent now.
1718
- await applyCapabilityConsentGate(
1719
- res.name,
1720
- options.scope,
1721
- upgradeNotice,
1722
- process.cwd(),
1723
- {
1724
- grant: options.grantCapabilities === true,
1725
- interactive: Boolean(process.stdin.isTTY),
1726
- },
1727
- );
1728
1778
  } catch (err) {
1729
- logger.error(`Upgrade failed: ${err.message}`);
1779
+ let recoveryNote = "";
1780
+ if (res) {
1781
+ try {
1782
+ const recovery = rollbackPluginUpdate(res);
1783
+ if (recovery.rolledBack) {
1784
+ recoveryNote = recovery.version
1785
+ ? `; restored v${recovery.version}`
1786
+ : "; removed the rejected install";
1787
+ }
1788
+ } catch (recoveryError) {
1789
+ recoveryNote = `; automatic recovery failed: ${recoveryError.message}`;
1790
+ }
1791
+ }
1792
+ logger.error(`Upgrade failed: ${err.message}${recoveryNote}`);
1730
1793
  process.exitCode = 1;
1731
1794
  }
1732
1795
  });
@@ -1334,6 +1334,7 @@ export function registerSessionCommand(program) {
1334
1334
  "tool",
1335
1335
  "mcp",
1336
1336
  "plugin",
1337
+ "retry",
1337
1338
  "model",
1338
1339
  ];
1339
1340
 
@@ -1347,9 +1348,19 @@ export function registerSessionCommand(program) {
1347
1348
  logger.log(
1348
1349
  ` ${chalk.gray(String(label).padEnd(28))} in=${r.inputTokens} out=${r.outputTokens} total=${chalk.cyan(r.totalTokens.toLocaleString())} calls=${r.calls}`,
1349
1350
  );
1351
+ const elapsed = (ms) => {
1352
+ const value = Math.max(0, Number(ms) || 0);
1353
+ if (value < 1000) return `${Math.round(value)}ms`;
1354
+ return `${(value / 1000).toFixed(2)}s`;
1355
+ };
1350
1356
  const toolRow = (label, r) =>
1351
1357
  logger.log(
1352
- ` ${chalk.gray(String(label).padEnd(28))} calls=${r.calls} errors=${r.errors} turnTokens≈${chalk.cyan((r.turnTokens || 0).toLocaleString())}`,
1358
+ ` ${chalk.gray(String(label).padEnd(28))} calls=${r.calls} errors=${r.errors}` +
1359
+ (r.retries != null ? ` retries=${r.retries}` : "") +
1360
+ (r.timedCalls != null
1361
+ ? ` observed=${elapsed(r.durationMs)} (${r.timedCalls} timed)`
1362
+ : "") +
1363
+ ` turnTokens≈${chalk.cyan((r.turnTokens || 0).toLocaleString())}`,
1353
1364
  );
1354
1365
  const empty = (what) => logger.log(chalk.gray(` (no ${what} recorded)`));
1355
1366
 
@@ -1416,6 +1427,25 @@ export function registerSessionCommand(program) {
1416
1427
  );
1417
1428
  return;
1418
1429
  }
1430
+ case "retry": {
1431
+ const retry = a.retries || null;
1432
+ if (!retry || !retry.totalRetries)
1433
+ return empty("automatic LLM retries");
1434
+ logger.log(
1435
+ ` ${chalk.gray("all".padEnd(28))} retries=${retry.totalRetries} failedAttemptTime=${chalk.cyan(elapsed(retry.durationMs))}`,
1436
+ );
1437
+ for (const r of retry.byReason || []) {
1438
+ logger.log(
1439
+ ` ${chalk.gray(String(r.reason || "unknown").padEnd(28))} retries=${r.retries} failedAttemptTime=${chalk.cyan(elapsed(r.durationMs))}`,
1440
+ );
1441
+ }
1442
+ for (const r of retry.byModel || []) {
1443
+ logger.log(
1444
+ ` ${chalk.gray(`${r.provider || "?"}/${r.model || "?"}`.padEnd(28))} retries=${r.retries} failedAttemptTime=${chalk.cyan(elapsed(r.durationMs))}`,
1445
+ );
1446
+ }
1447
+ return;
1448
+ }
1419
1449
  default:
1420
1450
  break;
1421
1451
  }
@@ -24,14 +24,48 @@ import { TeamWorktreeCoordinator } from "../lib/agent-team/team-worktree.js";
24
24
  import { TeamBudget } from "../lib/agent-team/team-budget.js";
25
25
  import { TeamMailbox } from "../lib/agent-team/team-mailbox.js";
26
26
  import { executionBroker } from "../lib/process-execution-broker/index.js";
27
+ import {
28
+ createCollaborationRun,
29
+ createCollaborationRunId,
30
+ createCollaborationSessionId,
31
+ finalizeCollaborationRun,
32
+ readCollaborationRun,
33
+ updateCollaborationUnit,
34
+ } from "../lib/collaboration-run-store.js";
35
+ import { loadSideEffectLedger } from "../lib/side-effect-ledger-store.js";
27
36
 
28
37
  export const _deps = {
29
38
  spawn: (...args) => executionBroker.spawn(...args),
39
+ collaborationStore: {
40
+ createRun: createCollaborationRun,
41
+ createRunId: createCollaborationRunId,
42
+ createSessionId: createCollaborationSessionId,
43
+ readRun: readCollaborationRun,
44
+ updateUnit: updateCollaborationUnit,
45
+ finalizeRun: finalizeCollaborationRun,
46
+ loadSideEffects: (sessionId) =>
47
+ loadSideEffectLedger(sessionId, { failIfUnavailable: false }),
48
+ },
30
49
  };
31
50
 
32
51
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
33
52
  const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
34
53
 
54
+ function normalizePermissionMode(value) {
55
+ const mode = String(value || "acceptEdits");
56
+ return new Set([
57
+ "manual",
58
+ "auto",
59
+ "dontAsk",
60
+ "default",
61
+ "plan",
62
+ "acceptEdits",
63
+ "bypassPermissions",
64
+ ]).has(mode)
65
+ ? mode
66
+ : "acceptEdits";
67
+ }
68
+
35
69
  /** Load + validate a task-graph file into a registry (throws on bad input). */
36
70
  export function loadRegistry(file, { ttlMs } = {}) {
37
71
  const abs = path.resolve(process.cwd(), file);
@@ -136,6 +170,13 @@ export function spawnAgent(prompt, cwd, opts = {}) {
136
170
  "text",
137
171
  ];
138
172
  if (opts.model) args.push("--model", opts.model);
173
+ if (opts.sessionId) args.push("--session", opts.sessionId);
174
+ if (Number(opts.maxTurns) > 0) {
175
+ args.push("--max-turns", String(opts.maxTurns));
176
+ }
177
+ if (Number(opts.maxBudgetUsd) > 0) {
178
+ args.push("--max-budget-usd", String(opts.maxBudgetUsd));
179
+ }
139
180
  const child = _deps.spawn(process.execPath, args, {
140
181
  cwd,
141
182
  env: { ...process.env, CLAUDECODE: "1" },
@@ -162,12 +203,15 @@ export function spawnAgent(prompt, cwd, opts = {}) {
162
203
 
163
204
  /** Real executor: hand a task's `prompt` to a headless `cc agent -p` in cwd. */
164
205
  function makeAgentRunTask(opts = {}) {
165
- return function runTask({ task }) {
206
+ return function runTask({ key, task }) {
166
207
  const prompt = task.metadata?.prompt || task?.prompt;
167
208
  if (!prompt) {
168
209
  throw new Error(`task "${task.key}" has no \`prompt\` to --agent`);
169
210
  }
170
- return spawnAgent(prompt, process.cwd(), opts);
211
+ return spawnAgent(prompt, process.cwd(), {
212
+ ...opts,
213
+ sessionId: opts.sessionIdForTask?.(key) || null,
214
+ });
171
215
  };
172
216
  }
173
217
 
@@ -220,6 +264,13 @@ export function registerTeamCommand(program, { logger } = {}) {
220
264
  "Hand each task's `prompt` to a headless cc agent (real)",
221
265
  )
222
266
  .option("--model <model>", "Model for --agent runs")
267
+ .option(
268
+ "--permission-mode <mode>",
269
+ "Permission mode for each --agent task",
270
+ "acceptEdits",
271
+ )
272
+ .option("--agent-max-turns <n>", "Per-agent task turn cap")
273
+ .option("--agent-max-budget-usd <amount>", "Per-agent task cost cap")
223
274
  .option(
224
275
  "--worktree",
225
276
  "Run each task's `command` in its own git worktree (parallel isolation)",
@@ -272,6 +323,7 @@ export function registerTeamCommand(program, { logger } = {}) {
272
323
  : null,
273
324
  });
274
325
  let priorMembers = [];
326
+ let priorCollaborationRunId = null;
275
327
  try {
276
328
  // Resume from a prior (possibly crashed) run's state: completed tasks
277
329
  // stay COMPLETED, and any lease left dangling by a crash is reclaimed so
@@ -297,6 +349,7 @@ export function registerTeamCommand(program, { logger } = {}) {
297
349
  },
298
350
  });
299
351
  priorMembers = Array.isArray(snap.members) ? snap.members : [];
352
+ priorCollaborationRunId = snap.collaborationRunId || null;
300
353
  }
301
354
  // A teammate whose lease is still dangling here crashed last run — its
302
355
  // task is about to be reclaimed, so report it LOST before the sweep.
@@ -331,6 +384,86 @@ export function registerTeamCommand(program, { logger } = {}) {
331
384
  return;
332
385
  }
333
386
 
387
+ const permissionMode = normalizePermissionMode(options.permissionMode);
388
+ let priorCollaborationRun = null;
389
+ if (priorCollaborationRunId) {
390
+ try {
391
+ priorCollaborationRun = _deps.collaborationStore.readRun(
392
+ priorCollaborationRunId,
393
+ );
394
+ } catch {
395
+ // A malformed/foreign v3 pointer must not block registry recovery.
396
+ priorCollaborationRun = null;
397
+ }
398
+ }
399
+ const priorUnits = new Map(
400
+ (priorCollaborationRun?.units || []).map((unit) => [unit.key, unit]),
401
+ );
402
+ let collaborationRun;
403
+ try {
404
+ const runId = _deps.collaborationStore.createRunId("team");
405
+ collaborationRun = _deps.collaborationStore.createRun({
406
+ id: runId,
407
+ kind: "team",
408
+ repoRoot: process.cwd(),
409
+ permissionMode: options.agent ? permissionMode : "default",
410
+ resourceBudget: {
411
+ maxTurns: options.agentMaxTurns,
412
+ maxCostUsd: options.agentMaxBudgetUsd,
413
+ maxTasks: options.maxTasks,
414
+ maxTokens: options.maxTokens,
415
+ maxWallMs: options.maxWall
416
+ ? Math.max(1, Number(options.maxWall)) * 1000
417
+ : null,
418
+ },
419
+ units: reg.list().map((task) => ({
420
+ key: task.key,
421
+ branch: options.worktree ? `team/${task.key}` : null,
422
+ sessionId: options.agent
423
+ ? priorUnits.get(task.key)?.sessionId ||
424
+ _deps.collaborationStore.createSessionId(runId, task.key)
425
+ : null,
426
+ status:
427
+ String(task.status || "").toLowerCase() === "completed"
428
+ ? "completed"
429
+ : "pending",
430
+ })),
431
+ });
432
+ } catch (err) {
433
+ (log.error || console.error)(
434
+ `Failed to persist team governance: ${err.message}`,
435
+ );
436
+ process.exitCode = 1;
437
+ return;
438
+ }
439
+ const collaborationUnits = new Map(
440
+ collaborationRun.units.map((unit) => [unit.key, unit]),
441
+ );
442
+ const settleGovernance = (key, status, extra = {}) => {
443
+ const unit = collaborationUnits.get(key);
444
+ let sideEffects = null;
445
+ if (unit?.sessionId) {
446
+ try {
447
+ sideEffects = _deps.collaborationStore.loadSideEffects(
448
+ unit.sessionId,
449
+ );
450
+ } catch {
451
+ /* side-effect summary is additive */
452
+ }
453
+ }
454
+ const updated = _deps.collaborationStore.updateUnit(
455
+ collaborationRun.id,
456
+ key,
457
+ {
458
+ status,
459
+ ...extra,
460
+ ...(sideEffects ? { sideEffects } : {}),
461
+ },
462
+ );
463
+ const next = updated.units.find((candidate) => candidate.key === key);
464
+ if (next) collaborationUnits.set(key, next);
465
+ };
466
+
334
467
  // Persist a snapshot after each task settles so a crash mid-run is
335
468
  // resumable (persist-after-run alone would lose everything on a crash).
336
469
  // v2 bundles registry + mailbox + budget + member lifecycle so a resume
@@ -347,11 +480,12 @@ export function registerTeamCommand(program, { logger } = {}) {
347
480
  tmp,
348
481
  JSON.stringify(
349
482
  {
350
- version: 2,
483
+ version: 3,
351
484
  registry: reg.snapshot(),
352
485
  mailbox: mailbox.snapshot(),
353
486
  budget: budget.snapshot(),
354
487
  members: runnerRef ? runnerRef.members() : priorMembers,
488
+ collaborationRunId: collaborationRun.id,
355
489
  },
356
490
  null,
357
491
  2,
@@ -379,8 +513,20 @@ export function registerTeamCommand(program, { logger } = {}) {
379
513
  coord = new TeamWorktreeCoordinator(process.cwd(), {
380
514
  sparsePaths: splitList(options.sparsePaths),
381
515
  symlinkDirectories: splitList(options.symlinkDirs),
516
+ onWorktree: ({ key, branch, path: worktreePath }) => {
517
+ settleGovernance(key, "running", {
518
+ branch,
519
+ worktreePath,
520
+ startedAt: Date.now(),
521
+ });
522
+ },
382
523
  });
383
524
  if (!coord.isGitRepo()) {
525
+ try {
526
+ _deps.collaborationStore.finalizeRun(collaborationRun.id, "failed");
527
+ } catch {
528
+ /* the original validation error remains primary */
529
+ }
384
530
  (log.error || console.error)(
385
531
  "--worktree requires a git repository (run inside one)",
386
532
  );
@@ -397,7 +543,13 @@ export function registerTeamCommand(program, { logger } = {}) {
397
543
  if (!prompt) {
398
544
  throw new Error(`task "${key}" has no \`prompt\` to --agent`);
399
545
  }
400
- await spawnAgent(prompt, cwd, { model: options.model });
546
+ await spawnAgent(prompt, cwd, {
547
+ model: options.model,
548
+ permissionMode,
549
+ maxTurns: options.agentMaxTurns,
550
+ maxBudgetUsd: options.agentMaxBudgetUsd,
551
+ sessionId: collaborationUnits.get(key)?.sessionId,
552
+ });
401
553
  },
402
554
  });
403
555
  } else {
@@ -412,7 +564,13 @@ export function registerTeamCommand(program, { logger } = {}) {
412
564
  );
413
565
  runTask = makeShellRunTask(log);
414
566
  } else if (options.agent)
415
- runTask = makeAgentRunTask({ model: options.model });
567
+ runTask = makeAgentRunTask({
568
+ model: options.model,
569
+ permissionMode,
570
+ maxTurns: options.agentMaxTurns,
571
+ maxBudgetUsd: options.agentMaxBudgetUsd,
572
+ sessionIdForTask: (key) => collaborationUnits.get(key)?.sessionId,
573
+ });
416
574
  else runTask = async () => ({ dryRun: true });
417
575
 
418
576
  // Optional workflow tracing (Claude-Code 2.1.202 parity): every task
@@ -439,6 +597,19 @@ export function registerTeamCommand(program, { logger } = {}) {
439
597
  mailbox,
440
598
  recorder,
441
599
  onEvent: (e) => {
600
+ if (e.type === "task:claimed") {
601
+ settleGovernance(e.key, "running", {
602
+ startedAt: Date.now(),
603
+ });
604
+ } else if (e.type === "task:completed") {
605
+ settleGovernance(e.key, "completed", {
606
+ endedAt: Date.now(),
607
+ });
608
+ } else if (e.type === "task:failed") {
609
+ settleGovernance(e.key, e.retry ? "pending" : "failed", {
610
+ endedAt: e.retry ? null : Date.now(),
611
+ });
612
+ }
442
613
  if (options.json) console.log(JSON.stringify(e));
443
614
  else if (e.type === "task:claimed")
444
615
  (log.info || console.log)(` → ${e.key} [${e.holder}]`);
@@ -459,8 +630,43 @@ export function registerTeamCommand(program, { logger } = {}) {
459
630
  runner.seedMembers(priorMembers);
460
631
  runnerRef = runner;
461
632
 
462
- const summary = await runner.run();
633
+ let summary;
634
+ try {
635
+ summary = await runner.run();
636
+ } catch (err) {
637
+ try {
638
+ _deps.collaborationStore.finalizeRun(collaborationRun.id, "failed");
639
+ } catch {
640
+ /* retain the original runner failure */
641
+ }
642
+ throw err;
643
+ }
463
644
  persist();
645
+ try {
646
+ // Reconcile from the authoritative registry after all event callbacks.
647
+ // This closes any best-effort onEvent write that failed mid-run.
648
+ for (const task of reg.list()) {
649
+ const state = String(task.status || "").toLowerCase();
650
+ const status =
651
+ state === "completed"
652
+ ? "completed"
653
+ : state === "cancelled" || state === "pending"
654
+ ? "cancelled"
655
+ : "failed";
656
+ settleGovernance(task.key, status, {
657
+ endedAt: Date.now(),
658
+ });
659
+ }
660
+ _deps.collaborationStore.finalizeRun(
661
+ collaborationRun.id,
662
+ summary.done ? "completed" : "failed",
663
+ );
664
+ } catch (err) {
665
+ (log.error || console.error)(
666
+ `Failed to finalize team governance: ${err.message}`,
667
+ );
668
+ process.exitCode = 1;
669
+ }
464
670
 
465
671
  if (recorder && options.otlp) {
466
672
  try {
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.162.185",
7
+ "cliVersions": ["0.162.184", "0.162.185"],
8
+ "date": "2026-07-29",
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Fixed — cc CLI 0.162.185: sandbox authority and Hook runtime hardening",
13
+ "body": "> `chainlesschain` **0.162.184 → 0.162.185** (2026-07-29).\n> CLI-only release; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Complete strong execution routes**: policy-bearing Plugin bins now retain\n pinned identity through async/background launches, while generic background,\n CLI PTY, and Desktop project PTY enter the same fail-closed Linux\n filesystem/network boundary.\n- **Authority and teardown integrity**: every actual bind source requires\n private mount propagation, parent-side pinned descriptors close after spawn,\n raw PTY masters invalidate on close/error, and attached sessions terminate\n their POSIX process group or Windows process tree.\n- **Trusted project and Hook roots**: Desktop V8 migrations quarantine\n unattested project roots and prevent remote metadata from acquiring local PTY\n authority. Hooks v2 binds canonical host roots to generation-aware opaque\n durable identities across headless, stream, REPL, and WebSocket turns.\n- **Hook process reliability**: completed Hook subprocesses preserve their\n status-0 output and status-2 block protocol when Node reports a late stdin\n `EPIPE`; missing exit status and unrelated spawn errors still fail closed.\n- **Single Broker runtime graph**: Hooks v2 now registers its default runtime\n as the Broker event sink without a reverse ESM load, preventing a duplicate\n CredentialTransport Worker, Unix listener, and steady-state file descriptors.\n- **Release validation gate**: publication requires this exact release commit\n to pass `CLI CI` and `CLI Strict Sandbox` on their configured Ubuntu,\n Windows, and macOS runners; local tests remain supplementary."
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "productVersion": null,
19
+ "cliVersion": "0.162.184",
20
+ "cliVersions": ["0.4.75", "0.37.36", "0.162.183", "0.162.184"],
21
+ "date": "2026-07-28",
22
+ "title": "",
23
+ "sections": [
24
+ {
25
+ "heading": "Added — cc CLI 0.162.184 + IDE retry, collaboration, and recovery governance",
26
+ "body": "> `chainlesschain` **0.162.183 → 0.162.184**, VS Code\n> **0.37.35 → 0.37.36**, and JetBrains **0.4.74 → 0.4.75** (2026-07-28).\n> `@chainlesschain/personal-data-hub` remains **0.4.57** and\n> `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Measured retry and tool attribution**: compact transcripts now record\n bounded tool durations, observed same-turn retries, and secret-free streaming\n LLM retry reasons with actual provider/model identity. CLI and both IDE usage\n reports consume the same authoritative aggregates.\n- **Durable team/batch governance**: collaboration runs persist bounded\n owner/session, permission mode, resource budget, lifecycle, and side-effect\n counts without prompts, argv, tool arguments, output, or credentials. IDE\n worktree views project these records as managed tasks without exposing\n background attach/stop controls.\n- **Transactional plugin upgrades**: staged installs revalidate manifests and\n signed SBOMs before atomic activation. Failed copies, load checks,\n post-install handling, or declined capability widening restore the prior\n active version; forced same-version reinstalls restore the exact old bytes.\n- **IDE activation feedback**: VS Code and JetBrains parse controlled\n `activated / rolled_back / unchanged` results, reload live sessions only\n after activation, and require explicit user approval before retrying with a\n widened capability grant.\n- **Process-boundary hardening**: plugin hooks, MCP/LSP servers, monitors, and\n native bins retain sandbox policy through the centralized execution broker;\n Linux bubblewrap setup fails closed with bounded diagnostics.\n- **Release validation**: publication requires this exact release commit to\n pass CLI CI and CLI Strict Sandbox on Linux, Windows, and macOS plus the\n packaged VSIX and JetBrains unit/build/Remote Robot gates."
27
+ }
28
+ ]
29
+ },
4
30
  {
5
31
  "productVersion": null,
6
32
  "cliVersion": "0.162.183",