chainlesschain 0.164.0 → 0.165.2

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 (228) hide show
  1. package/README.md +248 -2
  2. package/package.json +7 -4
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-D2MEn7fI.js → AIOps-lS1R0Cza.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-lCW_4Gf0.js → ActionButton-BmlgBPsj.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-Bs7i-nsS.js → Analytics-CNKczv1S.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CK7B6S_j.js → AppLayout-BuZGJARQ.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-C8ILjpyo.js → Artifacts-Dm73Sl-O.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-Bb9cNaWc.js → Audit-BGMW7A5e.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-sC9ooXIf.js → BackgroundAgents-BQ6M54JR.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-D-DrsplT.js → Backup-DBzGP0bR.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-uCNZpwSK.js → BaseInput-D1mLCoOV.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-CsDK1uE9.js → Chat-BUfcN7p8.js} +6 -6
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-OqSDt50w.js → ChatBubbleRenderer-CY5m8ZHg.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-JhTXM1-K.js → Checkbox-Du0Yg5Pi.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-BbzZLnyD.js → Codegen-B2RXziHW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-D4VW4m4j.js → Col-DWhekOrR.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-BXrYawxV.js → Community-HQhrkon4.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-DCihGy1u.js → Compact-izHNb4uz.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-DlyZ-lk8.js → Compliance-BDwLy41-.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-DvGZrhbO.js → Cowork-DFJhLa7K.js} +3 -3
  22. package/src/assets/web-panel/assets/{Cron-DUncZi8h.js → Cron-DYY9RG7-.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-C_hLuUcm.js → Crosschain-rr7tJTtv.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-b6YSUqxr.js → DID-D2sfHRLi.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-uvM15Cfb.js → Dashboard-q_eGdhha.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-D1-Nd4qY.js → Dropdown-Cufrh2Bz.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-8ApvL6Zc.js → EmailListRenderer-B-kdv10f.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-LYJt8811.js → FamilyGuardDashboard-D21XjgfG.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-BbI3HGpv.js → Federation-CAwRTLZH.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-DSoEKuFu.js → FormItemContext-vx3daNDF.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-B0S9OWd5.js → GenericCardRenderer-CRWY2wU4.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-DIs9Zhf3.js → Git-Q6SwauyD.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-jzZXrxcl.js → Governance-BJ1q4IQZ.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-JUPjf2ZI.js → Inference-CSWjROgD.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-DxnfJvlP.js → KnowledgeGraph-fzuQsWuY.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-iXiz8BEE.js → Logs-DVF8Mnns.js} +2 -2
  37. package/src/assets/web-panel/assets/MarkdownRenderer-BLif4QSg.js +1 -0
  38. package/src/assets/web-panel/assets/{Marketplace-Y3Xch312.js → Marketplace-BQP7LOA4.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-D7kGGbO7.js → McpTools-BNlJCmNc.js} +4 -4
  40. package/src/assets/web-panel/assets/{Memory-Do_hVxzh.js → Memory-DLLg5WQ4.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-CtrR0Tas.js → MobileBridge-CR2skNAF.js} +1 -1
  42. package/src/assets/web-panel/assets/MobileProjects-BxVavObl.js +1 -0
  43. package/src/assets/web-panel/assets/{Mtc-qo5QCTGd.js → Mtc-B17pgqMI.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-cq5mnjYj.js → MtcAudit-4UmV5cIL.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-Bq0MAQHw.js → Multisig-DoMEXEcU.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-DdWE6Vi2.js → NLProgramming-h9DMXFX4.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-BxMBFcIp.js → Notes-Cihn-xX8.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-RTrAcbUe.js → NotificationSettings-BE6ZGa3R.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-DJbpGqzT.js → OrderTableRenderer-CnwojoSI.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-SQzIPdqC.js → Organization-B2vpwmjb.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-02yECh22.js → Overflow-C4z28R0-.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-BNg4pNCM.js → P2P-BVlFkwhW.js} +2 -2
  53. package/src/assets/web-panel/assets/{PdhVaultBrowser-BxPJZsD3.js → PdhVaultBrowser-BXbEdL5B.js} +3 -3
  54. package/src/assets/web-panel/assets/{Permissions-CLnDnPAz.js → Permissions-C28xs4lp.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-C5m0AjGf.js → PersonalDataHub-Dgl_rBjM.js} +4 -4
  56. package/src/assets/web-panel/assets/{Pipeline-VwOf5Dhv.js → Pipeline-3QUIhrKI.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-CC0W2hZd.js → Privacy-8Gh33OZ5.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-Dz893Bob.js → ProjectInit-BNmg4tZi.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-CxQkvl0k.js → ProjectSettings-vgMfeCf9.js} +2 -2
  60. package/src/assets/web-panel/assets/Projects-BhtAVilc.js +1 -0
  61. package/src/assets/web-panel/assets/{Providers-DeB9IkxK.js → Providers-CXoOa8eX.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-OCeoaswn.js → QrScannerModal-BhfTF0oS.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-DenotaAj.js → QuickAsk-C746HEAj.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-Cies_jjI.js → Recommend-BSej8Eo0.js} +1 -1
  65. package/src/assets/web-panel/assets/RemoteSession-f3gmnlG3.js +5 -0
  66. package/src/assets/web-panel/assets/{Reputation-CW0mvxgZ.js → Reputation-CyvybpkN.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-SEd32qZU.js → Row-DwV2PeYn.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-BSwnJ3Lm.js → RssFeed-11GrzjZy.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-xe2m8bkC.js → Search-BjKXkrAY.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-Mq2F9Nro.js → Security-eWiFb9Yk.js} +4 -4
  71. package/src/assets/web-panel/assets/{Services-BKGw2V3P.js → Services-CdCsMAtt.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-DW95-Rxf.js → Skeleton-4Q2UTKQ5.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-CHgChCv_.js → Skills-v4rtYrRj.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-tKh6k3R7.js → Sla-CRhsFvd_.js} +1 -1
  75. package/src/assets/web-panel/assets/SpeechSettings-DLjKsDVu.js +1 -0
  76. package/src/assets/web-panel/assets/{SyncSettings-D0Fw8fVL.js → SyncSettings-D16zonl7.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-20x1GB3D.js → Tasks-Xxozz0i_.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-DJ-lts-a.js → Templates-CXJpPtCT.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-BFdGpbs7.js → Tenant-XRV0L1ZF.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-Xpx61vHL.js → Terminal-CYuO1i_w.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-C6UIvyZQ.js → TimelineRenderer-BXqitWsu.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-Dellq08f.js → Tokens-BvPrDHIy.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-VKw8d0J-.js → Trigger-DhCrSTf5.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-DNftdKT5.js → Trust-DmsuZD6K.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-DX9VAKJI.js → UkeySign-D_yrts5C.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-B2h3jO8q.js → VideoEditing-B01ihPrm.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-CjGkof7f.js → Wallet-DpUjKa-N.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-2Zfcu55P.js → WebAuthn-CL07yON6.js} +4 -4
  89. package/src/assets/web-panel/assets/{WorkflowEditor-B9eZ8UxZ.js → WorkflowEditor-CLMflnRr.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-CQNfD-YO.js → chat-DtUqe8h_.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-D4usyFT2.js → colors-DPKrgVfy.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-s4TpjvjX.js → compact-item-BTt2GtOm.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-BRCSvYxj.js → createContext-D_VeUc1J.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-Bj5nUW2v.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-AdkUbkV-.js → hasIn-1kndiylj.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BIoG5yYf.js → index-2eyAXE3d.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-nXyk8GZ9.js → index-4bna2_SR.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B2V-eKfK.js → index-8nz_fmlj.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-D_XBHopw.js → index-B9KvcS7R.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-s_buFMEG.js → index-BAXfRKfG.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DZT36ZYq.js → index-BHpBMWCh.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BMcimU-2.js → index-BaZAbw9A.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DzRjHxEv.js → index-BepLZwgB.js} +1 -1
  104. package/src/assets/web-panel/assets/{index--00U6vXZ.js → index-Bhudc_Ez.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C7Y8Aluc.js → index-BlDNVgBt.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BtobShro.js → index-By5n8up9.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Cvyt-zhm.js → index-CHG-KcS4.js} +1 -1
  108. package/src/assets/web-panel/assets/index-CPcM-eqo.js +1 -0
  109. package/src/assets/web-panel/assets/{index-MMN9V6JF.js → index-CX81qSM4.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Bad4VNvz.js → index-CauoBQkH.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CCsM_Ybx.js → index-CcO04eDn.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DARsAyUp.js → index-CtF7EN49.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-C5KAQFPQ.js → index-CzjkKUmR.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-RfMr79MW.js → index-D95OFht7.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DdCB70SS.js → index-DFIZ_1Sf.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CYdoQsa1.js → index-DG2MZQ3f.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BPhkFZ1I.js → index-DJ8vXGOa.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-_IRVsV9X.js → index-Dbbymxpj.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DVKfQ0Ux.js → index-DdkplL9R.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CkwiSLhU.js → index-DfGl8CqG.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CJVEOa4i.js → index-DfKBRdSS.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-C1mJtE6q.js → index-DsJCDUJG.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BgiXR_-_.js → index-Dwqmtk65.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CJCFe2Qf.js → index-DxdTdBix.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-C484EJiS.js → index-FzdwcSy2.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-B4JJCfQ2.js → index-GsoUQ2M7.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CQhAVU5t.js → index-brCInrzq.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CKC1t3Ic.js → index-dVc-CXY4.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BQ3DXBtD.js → index-fk2Rjacw.js} +3 -3
  130. package/src/assets/web-panel/assets/{index-Cduu2Hhr.js → index-l1BETrDb.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Bw2MEnUk.js → index-m31Ka8hZ.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D2GjI2oe.js → index-ocf06EVQ.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CJdQrZth.js → index-sDoMHTNA.js} +1 -1
  134. package/src/assets/web-panel/assets/index-xeSyVoRe.js +1 -0
  135. package/src/assets/web-panel/assets/{initDefaultProps-Blmpk7HL.js → initDefaultProps-CvyYJd7z.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-DPBJMv1n.js → motion-DYZkhUdz.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-ButdzCM7.js → move-slnJRVT1.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-cyRC_QCe.js → mtc-parser-DVc0CKmy.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-1epSV7hz.js → omit-BCXAtHCq.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-DuPY8xJs.js → pickAttrs-DBsemz_K.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-6XZqarhe.js → placementArrow-BRtkJ-nv.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-B40pXBWM.js → responsiveObserve-Cebq7EZn.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-jbZ9Wu4n.js → slide-DT7qvId2.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-BKQQcVy4.js → statusUtils-pQiITLkG.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-NiKfWjUT.js → styleChecker-c-19BVKQ.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-bQUCvPeb.js → useFlexGapSupport-DsS5-0bE.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-CUGji7ph.js → useFs-CxGiMe5n.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-4veyN2N2.js → usePersonalDataHub-D9btVID5.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-1-nLug-Z.js → vnode-CUYFsFEN.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-dhCeRDMo.js → zoom-CXmn_35j.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +1 -1
  153. package/src/commands/cowork.js +559 -62
  154. package/src/commands/plugin.js +819 -64
  155. package/src/commands/session-location.js +318 -7
  156. package/src/constants.js +2 -2
  157. package/src/data/changelog.json +28 -2
  158. package/src/gateways/ws/action-protocol.js +293 -19
  159. package/src/gateways/ws/message-dispatcher.js +30 -0
  160. package/src/gateways/ws/remote-session-protocol.js +542 -35
  161. package/src/gateways/ws/ws-approval-gate.js +5 -0
  162. package/src/gateways/ws/ws-server.js +462 -38
  163. package/src/harness/jsonl-session-store.js +638 -2
  164. package/src/harness/prompt-compressor.js +4 -0
  165. package/src/harness/remote-session-audit.js +1 -0
  166. package/src/harness/remote-session-crypto.js +750 -50
  167. package/src/harness/remote-session-registry.js +795 -27
  168. package/src/lib/auto-mode-config.js +98 -3
  169. package/src/lib/background-agent-keeper-client.js +29 -0
  170. package/src/lib/background-agent-keeper-protocol.js +158 -10
  171. package/src/lib/background-agent-supervisor.js +870 -48
  172. package/src/lib/background-session-transport.js +23 -6
  173. package/src/lib/background-turn-bootstrap-protocol.js +64 -0
  174. package/src/lib/cowork-task-runner.js +70 -0
  175. package/src/lib/cowork-workflow.js +887 -62
  176. package/src/lib/delivery-production-adapter.js +38 -2
  177. package/src/lib/doctor-checkup.js +34 -10
  178. package/src/lib/dynamic-workflow-draft.js +535 -0
  179. package/src/lib/dynamic-workflow-facade.js +1105 -17
  180. package/src/lib/dynamic-workflow-runtime.js +2974 -0
  181. package/src/lib/execution-location-contract.js +111 -7
  182. package/src/lib/execution-location-runtime.js +3 -1
  183. package/src/lib/execution-location-target.js +910 -0
  184. package/src/lib/llm-providers.js +1 -0
  185. package/src/lib/mcp-call-ledger-store.js +35 -0
  186. package/src/lib/mcp-call-ledger.js +30 -0
  187. package/src/lib/mcp-stdio-package-materialization.js +1 -1
  188. package/src/lib/plugin-runtime/__tests__/remote-source.test.js +34 -16
  189. package/src/lib/plugin-runtime/install.js +4956 -657
  190. package/src/lib/plugin-runtime/manifest.js +3 -1
  191. package/src/lib/plugin-runtime/marketplace-artifact-readback.js +671 -31
  192. package/src/lib/plugin-runtime/marketplace-catalog.js +68 -2
  193. package/src/lib/plugin-runtime/marketplace-impact.js +208 -15
  194. package/src/lib/plugin-runtime/marketplace-network.js +317 -0
  195. package/src/lib/plugin-runtime/marketplace-pac-worker.js +15 -0
  196. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +25 -2
  197. package/src/lib/plugin-runtime/marketplace-source-cache.js +359 -0
  198. package/src/lib/plugin-runtime/policy.js +21 -6
  199. package/src/lib/plugin-runtime/publisher-trust.js +332 -0
  200. package/src/lib/plugin-runtime/remote-source.js +323 -27
  201. package/src/lib/plugin-runtime/scopes.js +317 -41
  202. package/src/lib/plugin-runtime/transaction-journal.js +806 -0
  203. package/src/lib/public-ide-capability-manifest.js +1 -1
  204. package/src/lib/remote-approval-bridge.js +745 -108
  205. package/src/lib/remote-control.js +2 -0
  206. package/src/lib/remote-membership-coordinator.js +612 -46
  207. package/src/lib/remote-membership-host-store.js +59 -10
  208. package/src/lib/runtime-provenance-ledger.js +171 -46
  209. package/src/lib/shell-approval.js +169 -6
  210. package/src/lib/sub-agent-context.js +268 -2
  211. package/src/lib/task-model-selector.js +1 -1
  212. package/src/lib/with-file-lock.js +167 -42
  213. package/src/repl/agent-repl.js +70 -29
  214. package/src/repl/remote-approval.js +29 -7
  215. package/src/runtime/agent-core.js +1695 -194
  216. package/src/runtime/headless-runner.js +22 -5
  217. package/src/runtime/headless-stream.js +19 -3
  218. package/src/workers/background-agent-keeper.js +279 -58
  219. package/src/workers/background-agent-worker.js +7 -0
  220. package/src/workers/background-turn-bootstrap.js +29 -2
  221. package/src/assets/web-panel/assets/MarkdownRenderer-GmB6DOr6.js +0 -1
  222. package/src/assets/web-panel/assets/MobileProjects-BL0Czcoj.js +0 -1
  223. package/src/assets/web-panel/assets/Projects-DDAjkUkT.js +0 -1
  224. package/src/assets/web-panel/assets/RemoteSession-Dxzl5n2T.js +0 -5
  225. package/src/assets/web-panel/assets/SpeechSettings-D6UL3dA5.js +0 -1
  226. package/src/assets/web-panel/assets/devWarning-DKJjSWRn.js +0 -1
  227. package/src/assets/web-panel/assets/index-C61cnl3K.js +0 -1
  228. package/src/assets/web-panel/assets/index-D4XFHxBr.js +0 -1
@@ -16,7 +16,9 @@
16
16
  *
17
17
  * so an in-flight session keeps running its version even while another is
18
18
  * installed. The active version per (scope,name) is the one named by a
19
- * `.active` file, or the highest semver present if none is set.
19
+ * `.active` file. Missing, unreadable, or dangling pointers fail closed instead
20
+ * of silently selecting another payload; legacy directories must be repaired
21
+ * by a reviewed install/use flow.
20
22
  */
21
23
 
22
24
  import fs from "fs";
@@ -38,15 +40,25 @@ export const _deps = {
38
40
  readdirSync: fs.readdirSync,
39
41
  readFileSync: fs.readFileSync,
40
42
  statSync: fs.statSync,
43
+ lstatSync: fs.lstatSync,
41
44
  };
42
45
 
46
+ const MAX_ACTIVE_POINTER_BYTES = 256;
47
+
43
48
  // Lowest → highest precedence.
44
49
  export const SCOPES = ["user", "project", "local"];
45
50
  export const DISABLED_FILENAME = ".disabled";
51
+ export const PLUGIN_LIFECYCLE_COORDINATOR_DIRNAME =
52
+ "plugin-lifecycle-transactions";
53
+ const PLUGIN_TRANSACTION_LOCK_DIRNAME = ".plugin-transaction-lock";
46
54
 
47
55
  /** Filesystem-safe encoding of a (possibly scoped, e.g. @org/name) plugin name. */
48
56
  export function encodeName(name) {
49
- return String(name || "").replace(/[^a-zA-Z0-9._-]/g, "__");
57
+ const encoded = String(name || "").replace(/[^a-zA-Z0-9._-]/g, "__");
58
+ if (!encoded || encoded === "." || encoded === "..") {
59
+ throw new Error(`invalid plugin name: ${String(name || "")}`);
60
+ }
61
+ return encoded;
50
62
  }
51
63
 
52
64
  /**
@@ -73,15 +85,56 @@ export function pluginNameDir(scope, name, opts = {}) {
73
85
  return path.join(scopeRoot(scope, opts), encodeName(name));
74
86
  }
75
87
 
88
+ /** Global same-user coordinator shared by every scope for one plugin name. */
89
+ export function pluginLifecycleCoordinatorDir(name, opts = {}) {
90
+ return path.join(pluginLifecycleCoordinatorRoot(opts), encodeName(name));
91
+ }
92
+
93
+ /** Fixed global lock path used by runtime discovery to fence review state. */
94
+ export function pluginLifecycleCoordinatorLock(name, opts = {}) {
95
+ return path.join(
96
+ pluginLifecycleCoordinatorDir(name, opts),
97
+ PLUGIN_TRANSACTION_LOCK_DIRNAME,
98
+ );
99
+ }
100
+
101
+ function pluginLifecycleCoordinatorRoot(opts = {}) {
102
+ const configured = String(
103
+ (opts.env || process.env).CC_PLUGIN_TRANSACTION_HOME || "",
104
+ ).trim();
105
+ if (!configured) {
106
+ return path.join(
107
+ getElectronUserDataDir(),
108
+ PLUGIN_LIFECYCLE_COORDINATOR_DIRNAME,
109
+ );
110
+ }
111
+ if (!path.isAbsolute(configured)) {
112
+ throw new Error("CC_PLUGIN_TRANSACTION_HOME must be an absolute path");
113
+ }
114
+ const resolved = path.resolve(configured);
115
+ if (resolved === path.parse(resolved).root) {
116
+ throw new Error("CC_PLUGIN_TRANSACTION_HOME must not be a filesystem root");
117
+ }
118
+ return resolved;
119
+ }
120
+
76
121
  /** Immutable install dir for a specific plugin version. */
77
122
  export function pluginVersionDir(scope, name, version, opts = {}) {
78
- return path.join(pluginNameDir(scope, name, opts), String(version));
123
+ const value = String(version || "");
124
+ if (!semver.valid(value)) {
125
+ throw new Error(`invalid plugin version: ${value}`);
126
+ }
127
+ return path.join(pluginNameDir(scope, name, opts), value);
79
128
  }
80
129
 
81
130
  /** Versions present on disk for a plugin, newest semver first. */
82
131
  export function listInstalledVersions(scope, name, opts = {}) {
83
132
  const dir = pluginNameDir(scope, name, opts);
84
133
  if (!dirExists(dir)) return [];
134
+ return listVersionsForDir(dir);
135
+ }
136
+
137
+ function listVersionsForDir(dir) {
85
138
  return _deps
86
139
  .readdirSync(dir, { withFileTypes: true })
87
140
  .filter((e) => e.isDirectory())
@@ -90,20 +143,53 @@ export function listInstalledVersions(scope, name, opts = {}) {
90
143
  .sort(semver.rcompare);
91
144
  }
92
145
 
93
- /** The active version for a plugin: `.active` file if valid, else highest semver. */
94
- export function activeVersion(scope, name, opts = {}) {
95
- const versions = listInstalledVersions(scope, name, opts);
96
- if (versions.length === 0) return null;
97
- const activeFile = path.join(pluginNameDir(scope, name, opts), ".active");
98
- if (_deps.existsSync(activeFile)) {
99
- try {
100
- const pinned = _deps.readFileSync(activeFile, "utf8").trim();
101
- if (versions.includes(pinned)) return pinned;
102
- } catch {
103
- /* fall through to highest */
146
+ /** Inspect pointer authority without silently selecting another payload. */
147
+ export function inspectActivePointer(scope, name, opts = {}) {
148
+ return inspectActivePointerForDir(pluginNameDir(scope, name, opts), {
149
+ strictIo: opts.strictIo === true,
150
+ });
151
+ }
152
+
153
+ function inspectActivePointerForDir(nameDir, { strictIo = false } = {}) {
154
+ if (!dirExists(nameDir, strictIo)) {
155
+ return { status: "absent", version: null, versions: [] };
156
+ }
157
+ const versions = listVersionsForDir(nameDir);
158
+ if (versions.length === 0) {
159
+ return { status: "absent", version: null, versions };
160
+ }
161
+ const activeFile = path.join(nameDir, ".active");
162
+ if (!_deps.existsSync(activeFile)) {
163
+ return { status: "missing", version: null, versions };
164
+ }
165
+ let pinned;
166
+ try {
167
+ const stat = _deps.lstatSync(activeFile);
168
+ if (!stat.isFile() || stat.size > MAX_ACTIVE_POINTER_BYTES) {
169
+ return { status: "unsafe", version: null, versions };
104
170
  }
171
+ pinned = _deps.readFileSync(activeFile, "utf8").trim();
172
+ } catch (error) {
173
+ if (strictIo) throw error;
174
+ return {
175
+ status: "unreadable",
176
+ version: null,
177
+ versions,
178
+ errorCode: error?.code || null,
179
+ };
180
+ }
181
+ if (!semver.valid(pinned)) {
182
+ return { status: "corrupt", version: null, versions };
105
183
  }
106
- return versions[0];
184
+ if (!versions.includes(pinned)) {
185
+ return { status: "dangling", version: null, versions, pinned };
186
+ }
187
+ return { status: "valid", version: pinned, versions };
188
+ }
189
+
190
+ /** The active version for a plugin; invalid/missing authority fails closed. */
191
+ export function activeVersion(scope, name, opts = {}) {
192
+ return inspectActivePointer(scope, name, opts).version;
107
193
  }
108
194
 
109
195
  /** Whether one scoped plugin install is eligible for runtime discovery. */
@@ -140,17 +226,78 @@ export function discoverPlugins(opts = {}) {
140
226
  ) {
141
227
  return [];
142
228
  }
143
- const scopes = opts.scopes || SCOPES;
229
+ const requestedScopes = new Set(opts.scopes || SCOPES);
230
+ for (const requested of requestedScopes) {
231
+ if (!SCOPES.includes(requested)) {
232
+ throw new Error(`unknown plugin scope: ${requested}`);
233
+ }
234
+ }
235
+ // A caller may select a subset, but cannot reverse canonical precedence.
236
+ const scopes = SCOPES.filter((scope) => requestedScopes.has(scope));
144
237
  const byName = new Map(); // name → record (later scope overrides earlier)
238
+ const nameByEncoded = new Map();
145
239
  for (const scope of scopes) {
146
240
  const root = scopeRoot(scope, opts);
147
241
  if (!dirExists(root, opts.strictIo === true)) continue;
148
242
  for (const encoded of listDirs(root, opts.strictIo === true)) {
149
243
  const nameDir = path.join(root, encoded);
244
+ const lifecycleRecovery = findLifecycleCoordinatorRecovery(encoded, opts);
150
245
  const enabled = !_deps.existsSync(path.join(nameDir, DISABLED_FILENAME));
151
246
  if (!enabled && opts.includeDisabled !== true) continue;
152
- const version = activeVersionForDir(nameDir, opts.strictIo === true);
153
- if (!version) continue;
247
+ const pointer = inspectActivePointerForDir(nameDir, {
248
+ strictIo: opts.strictIo === true,
249
+ });
250
+ const version = pointer.version;
251
+ if (!version) {
252
+ const recovery =
253
+ findRecoveryInspection(nameDir, encoded) || lifecycleRecovery;
254
+ const pointerStatus = recovery ? "recovery-required" : pointer.status;
255
+ const reservesIdentity =
256
+ pointer.versions.length > 0 || Boolean(recovery);
257
+ if (!reservesIdentity) continue;
258
+ // A broken higher-precedence install reserves its encoded identity.
259
+ // Falling through would silently activate lower-scope bytes. Remove
260
+ // only that name; unrelated plugins remain discoverable.
261
+ const shadowedName = nameByEncoded.get(encoded);
262
+ if (shadowedName) byName.delete(shadowedName);
263
+ nameByEncoded.delete(encoded);
264
+ opts.onBlocked?.({
265
+ scope,
266
+ encodedName: encoded,
267
+ pointerStatus,
268
+ versions: [...pointer.versions],
269
+ });
270
+ if (opts.includeBlocked === true && reservesIdentity) {
271
+ const inspectionVersion = recovery?.version || pointer.versions[0];
272
+ const inspectionRoot =
273
+ recovery?.root ||
274
+ (inspectionVersion
275
+ ? path.join(nameDir, inspectionVersion)
276
+ : recovery?.transactionRoot);
277
+ const inspectionManifest =
278
+ recovery?.manifest || parsePluginManifest(inspectionRoot);
279
+ inspectionManifest.scope = scope;
280
+ const inspectedName =
281
+ inspectionManifest.ok === true &&
282
+ encodeName(inspectionManifest.metadata?.name) === encoded
283
+ ? inspectionManifest.metadata.name
284
+ : shadowedName || encoded;
285
+ nameByEncoded.set(encoded, inspectedName);
286
+ byName.set(inspectedName, {
287
+ scope,
288
+ name: inspectedName,
289
+ version: null,
290
+ inspectionVersion,
291
+ root: inspectionRoot,
292
+ manifest: inspectionManifest,
293
+ enabled,
294
+ runtimeBlocked: true,
295
+ pointerStatus,
296
+ recoveryRoot: recovery?.root || recovery?.transactionRoot || null,
297
+ });
298
+ }
299
+ continue;
300
+ }
154
301
  const versionDir = path.join(nameDir, version);
155
302
  const manifest = parsePluginManifest(versionDir);
156
303
  if (opts.strictIo === true && manifest.ok !== true) {
@@ -160,8 +307,70 @@ export function discoverPlugins(opts = {}) {
160
307
  }`,
161
308
  );
162
309
  }
310
+ const manifestName = manifest.metadata?.name || null;
311
+ if (manifest.ok !== true || encodeName(manifestName) !== encoded) {
312
+ const shadowedName = nameByEncoded.get(encoded);
313
+ if (shadowedName) byName.delete(shadowedName);
314
+ nameByEncoded.delete(encoded);
315
+ const pointerStatus =
316
+ manifest.ok === true ? "identity-mismatch" : "manifest-invalid";
317
+ opts.onBlocked?.({
318
+ scope,
319
+ encodedName: encoded,
320
+ pointerStatus,
321
+ versions: [...pointer.versions],
322
+ });
323
+ if (opts.includeBlocked === true) {
324
+ const inspectedName = shadowedName || encoded;
325
+ nameByEncoded.set(encoded, inspectedName);
326
+ byName.set(inspectedName, {
327
+ scope,
328
+ name: inspectedName,
329
+ version: null,
330
+ inspectionVersion: version,
331
+ root: versionDir,
332
+ manifest,
333
+ enabled,
334
+ runtimeBlocked: true,
335
+ pointerStatus,
336
+ });
337
+ }
338
+ continue;
339
+ }
163
340
  manifest.scope = scope;
164
- const name = manifest.metadata?.name || encoded;
341
+ const name = manifestName;
342
+ const retainedRecovery =
343
+ findRecoveryInspection(nameDir, encoded) || lifecycleRecovery;
344
+ const priorForEncoded = nameByEncoded.get(encoded);
345
+ if (priorForEncoded && priorForEncoded !== name) {
346
+ byName.delete(priorForEncoded);
347
+ }
348
+ nameByEncoded.set(encoded, name);
349
+ if (retainedRecovery && opts.allowRetainedInstall !== true) {
350
+ if (priorForEncoded) byName.delete(priorForEncoded);
351
+ opts.onBlocked?.({
352
+ scope,
353
+ encodedName: encoded,
354
+ pointerStatus: "recovery-required",
355
+ versions: [...pointer.versions],
356
+ });
357
+ if (opts.includeBlocked === true) {
358
+ byName.set(name, {
359
+ scope,
360
+ name,
361
+ version: null,
362
+ inspectionVersion: version,
363
+ root: versionDir,
364
+ manifest,
365
+ enabled,
366
+ runtimeBlocked: true,
367
+ pointerStatus: "recovery-required",
368
+ recoveryRoot:
369
+ retainedRecovery.root || retainedRecovery.transactionRoot,
370
+ });
371
+ }
372
+ continue;
373
+ }
165
374
  byName.set(name, {
166
375
  scope,
167
376
  name,
@@ -169,6 +378,10 @@ export function discoverPlugins(opts = {}) {
169
378
  root: versionDir,
170
379
  manifest,
171
380
  enabled,
381
+ runtimeBlocked: false,
382
+ pointerStatus: "valid",
383
+ recoveryRoot:
384
+ retainedRecovery?.root || retainedRecovery?.transactionRoot || null,
172
385
  });
173
386
  }
174
387
  }
@@ -206,28 +419,6 @@ export function discoverPlugins(opts = {}) {
206
419
 
207
420
  // ── internals ────────────────────────────────────────────────────────────
208
421
 
209
- function activeVersionForDir(nameDir, strictIo = false) {
210
- if (!dirExists(nameDir, strictIo)) return null;
211
- const versions = _deps
212
- .readdirSync(nameDir, { withFileTypes: true })
213
- .filter((e) => e.isDirectory())
214
- .map((e) => e.name)
215
- .filter((v) => semver.valid(v))
216
- .sort(semver.rcompare);
217
- if (versions.length === 0) return null;
218
- const activeFile = path.join(nameDir, ".active");
219
- if (_deps.existsSync(activeFile)) {
220
- try {
221
- const pinned = _deps.readFileSync(activeFile, "utf8").trim();
222
- if (versions.includes(pinned)) return pinned;
223
- } catch (error) {
224
- if (strictIo) throw error;
225
- /* fall through */
226
- }
227
- }
228
- return versions[0];
229
- }
230
-
231
422
  function dirExists(dir, strictIo = false) {
232
423
  try {
233
424
  return _deps.existsSync(dir) && _deps.statSync(dir).isDirectory();
@@ -237,6 +428,91 @@ function dirExists(dir, strictIo = false) {
237
428
  }
238
429
  }
239
430
 
431
+ function findRecoveryInspection(nameDir, encodedName) {
432
+ let entries;
433
+ try {
434
+ entries = _deps
435
+ .readdirSync(nameDir, { withFileTypes: true })
436
+ .filter(
437
+ (entry) =>
438
+ entry.isDirectory() &&
439
+ (entry.name.startsWith(".install-") ||
440
+ entry.name.startsWith(".uninstall-") ||
441
+ entry.name === ".plugin-transaction-lock"),
442
+ )
443
+ .sort((left, right) => {
444
+ if (left.name === ".plugin-transaction-lock") return 1;
445
+ if (right.name === ".plugin-transaction-lock") return -1;
446
+ return right.name.localeCompare(left.name);
447
+ });
448
+ } catch {
449
+ return null;
450
+ }
451
+
452
+ let fallback = null;
453
+ for (const entry of entries.slice(0, 64)) {
454
+ const transactionRoot = path.join(nameDir, entry.name);
455
+ try {
456
+ const transactionStat = _deps.lstatSync(transactionRoot);
457
+ if (transactionStat.isSymbolicLink() || !transactionStat.isDirectory()) {
458
+ continue;
459
+ }
460
+ } catch {
461
+ continue;
462
+ }
463
+ if (!fallback) {
464
+ fallback = {
465
+ root: null,
466
+ version: null,
467
+ manifest: null,
468
+ transactionRoot,
469
+ };
470
+ }
471
+ let recoveryChildren = ["previous", "rejected", "staged"];
472
+ if (entry.name.startsWith(".uninstall-")) {
473
+ try {
474
+ recoveryChildren = _deps
475
+ .readdirSync(transactionRoot, { withFileTypes: true })
476
+ .filter((child) => child.isDirectory() && semver.valid(child.name))
477
+ .map((child) => child.name)
478
+ .sort(semver.rcompare);
479
+ } catch {
480
+ recoveryChildren = [];
481
+ }
482
+ }
483
+ for (const child of recoveryChildren) {
484
+ const root = path.join(transactionRoot, child);
485
+ let stat;
486
+ try {
487
+ stat = _deps.lstatSync(root);
488
+ } catch {
489
+ continue;
490
+ }
491
+ if (stat.isSymbolicLink() || !stat.isDirectory()) continue;
492
+ const manifest = parsePluginManifest(root);
493
+ const version = semver.valid(manifest.metadata?.version)
494
+ ? manifest.metadata.version
495
+ : null;
496
+ const candidate = { root, version, manifest, transactionRoot };
497
+ if (!fallback?.root) fallback = candidate;
498
+ if (
499
+ manifest.ok === true &&
500
+ encodeName(manifest.metadata?.name) === encodedName
501
+ ) {
502
+ return candidate;
503
+ }
504
+ }
505
+ }
506
+ return fallback;
507
+ }
508
+
509
+ function findLifecycleCoordinatorRecovery(encodedName, opts) {
510
+ const lockDir = pluginLifecycleCoordinatorLock(encodedName, opts);
511
+ return _deps.existsSync(lockDir)
512
+ ? { transactionRoot: lockDir, global: true }
513
+ : null;
514
+ }
515
+
240
516
  function listDirs(dir, strictIo = false) {
241
517
  try {
242
518
  return _deps