chainlesschain 0.163.7 → 0.164.0

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 (252) hide show
  1. package/package.json +5 -1
  2. package/scripts/macos-mcp-launcher-build.mjs +317 -0
  3. package/scripts/macos-mcp-launcher-postinstall.sh +54 -0
  4. package/scripts/macos-mcp-launcher-preinstall.sh +61 -0
  5. package/src/assets/web-panel/assets/{AIOps-axqQfwv8.js → AIOps-D2MEn7fI.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-DV-Ro0By.js → ActionButton-lCW_4Gf0.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-Bt72WEVu.js → Analytics-Bs7i-nsS.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-BtepG55E.js → AppLayout-CK7B6S_j.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-B7KaJ7S_.js → Artifacts-C8ILjpyo.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-FNFaUg7A.js → Audit-Bb9cNaWc.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-DFb6J2wQ.js → BackgroundAgents-sC9ooXIf.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-CC7YBhyj.js → Backup-D-DrsplT.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-RkgTNVtj.js → BaseInput-uCNZpwSK.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-hHEmGZy-.js → Chat-CsDK1uE9.js} +6 -6
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CAP9YhHv.js → ChatBubbleRenderer-OqSDt50w.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-z5wXOQP1.js → Checkbox-JhTXM1-K.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-DVaDJnxy.js → Codegen-BbzZLnyD.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-CJmaRDR5.js → Col-D4VW4m4j.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-DF29_2bI.js → Community-BXrYawxV.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-DtkQkBzn.js → Compact-DCihGy1u.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-xoHDxp7I.js → Compliance-DlyZ-lk8.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-BUm-R7ht.js → Cowork-DvGZrhbO.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-Cgl14ZkB.js → Cron-DUncZi8h.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-BNcbmoqh.js → Crosschain-C_hLuUcm.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-Bwja0Zo9.js → DID-b6YSUqxr.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-Bk5XjEdJ.js → Dashboard-uvM15Cfb.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-Ci36Oitq.js → Dropdown-D1-Nd4qY.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer--U04ZN4q.js → EmailListRenderer-8ApvL6Zc.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2gNPR2s.js → FamilyGuardDashboard-LYJt8811.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-C4KghYn7.js → Federation-BbI3HGpv.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-QL7x_Q_0.js → FormItemContext-DSoEKuFu.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-F3Ryltwm.js → GenericCardRenderer-B0S9OWd5.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-2HassK5k.js → Git-DIs9Zhf3.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-DoBIp7oe.js → Governance-jzZXrxcl.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference--W01QhZ-.js → Inference-JUPjf2ZI.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-DmvwqGpT.js → KnowledgeGraph-DxnfJvlP.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-BBJ4yAel.js → Logs-iXiz8BEE.js} +2 -2
  38. package/src/assets/web-panel/assets/{MarkdownRenderer-BLCZMzhJ.js → MarkdownRenderer-GmB6DOr6.js} +1 -1
  39. package/src/assets/web-panel/assets/{Marketplace-D5lNngSI.js → Marketplace-Y3Xch312.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-CkEVOMKH.js → McpTools-D7kGGbO7.js} +4 -4
  41. package/src/assets/web-panel/assets/{Memory-B1Ow1xVE.js → Memory-Do_hVxzh.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-SgYbUfb6.js → MobileBridge-CtrR0Tas.js} +1 -1
  43. package/src/assets/web-panel/assets/MobileProjects-BL0Czcoj.js +1 -0
  44. package/src/assets/web-panel/assets/{Mtc-DcTXSSma.js → Mtc-qo5QCTGd.js} +2 -2
  45. package/src/assets/web-panel/assets/{MtcAudit-Dt3WG4oj.js → MtcAudit-cq5mnjYj.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-B9B38UZx.js → Multisig-Bq0MAQHw.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-B0S4GGvG.js → NLProgramming-DdWE6Vi2.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-DZ5U58Ng.js → Notes-BxMBFcIp.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-PjL5ZW34.js → NotificationSettings-RTrAcbUe.js} +1 -1
  50. package/src/assets/web-panel/assets/{OrderTableRenderer-DrAX2ESt.js → OrderTableRenderer-DJbpGqzT.js} +1 -1
  51. package/src/assets/web-panel/assets/{Organization-Cv1GYs-c.js → Organization-SQzIPdqC.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-Bbkp_PL3.js → Overflow-02yECh22.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-BD8QUgoZ.js → P2P-BNg4pNCM.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-BO-2PeaB.js → PdhVaultBrowser-BxPJZsD3.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-D_OPVa02.js → Permissions-CLnDnPAz.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-mh-pEmaB.js → PersonalDataHub-C5m0AjGf.js} +4 -4
  57. package/src/assets/web-panel/assets/{Pipeline-6JC2EDdb.js → Pipeline-VwOf5Dhv.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-CUshzUAG.js → Privacy-CC0W2hZd.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-Cs2Aalri.js → ProjectInit-Dz893Bob.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-1ak49tcj.js → ProjectSettings-CxQkvl0k.js} +2 -2
  61. package/src/assets/web-panel/assets/Projects-DDAjkUkT.js +1 -0
  62. package/src/assets/web-panel/assets/{Providers-CXXxvafH.js → Providers-DeB9IkxK.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-PTcDsF58.js → QrScannerModal-OCeoaswn.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-CDwucrJw.js → QuickAsk-DenotaAj.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-CJlLVRXR.js → Recommend-Cies_jjI.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-DlN-ETsO.js → RemoteSession-Dxzl5n2T.js} +3 -3
  67. package/src/assets/web-panel/assets/{Reputation-DI23LR6m.js → Reputation-CW0mvxgZ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-Cl7UQMrM.js → Row-SEd32qZU.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-CexHNfh8.js → RssFeed-BSwnJ3Lm.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-BneBWvRN.js → Search-xe2m8bkC.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-DX7Phgrp.js → Security-Mq2F9Nro.js} +4 -4
  72. package/src/assets/web-panel/assets/{Services-BWXO8Mte.js → Services-BKGw2V3P.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-DCyOjKPJ.js → Skeleton-DW95-Rxf.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-CXqERsTB.js → Skills-CHgChCv_.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-bhbrbz8E.js → Sla-tKh6k3R7.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-3IPU0HBZ.js → SpeechSettings-D6UL3dA5.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-DBNTQLbM.js → SyncSettings-D0Fw8fVL.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-quP0bkN-.js → Tasks-20x1GB3D.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-BouWmgho.js → Templates-DJ-lts-a.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-qv0D9s7z.js → Tenant-BFdGpbs7.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-BxvbE8BB.js → Terminal-Xpx61vHL.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-D-IeLnJ2.js → TimelineRenderer-C6UIvyZQ.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-CFMKKyVG.js → Tokens-Dellq08f.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-L8as3UuJ.js → Trigger-VKw8d0J-.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-MxmA4VZG.js → Trust-DNftdKT5.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-C0VvJYRi.js → UkeySign-DX9VAKJI.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-Bf5QZj8N.js → VideoEditing-B2h3jO8q.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-BIJ9riRz.js → Wallet-CjGkof7f.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-B8p9Mhkw.js → WebAuthn-2Zfcu55P.js} +4 -4
  90. package/src/assets/web-panel/assets/{WorkflowEditor-BVsuaPen.js → WorkflowEditor-B9eZ8UxZ.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-BfkjoKpV.js → chat-CQNfD-YO.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-DeAlsWK8.js → colors-D4usyFT2.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-Cs97bz5j.js → compact-item-s4TpjvjX.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-BqbG60LH.js → createContext-BRCSvYxj.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-DKJjSWRn.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-i_RY0b1X.js → hasIn-AdkUbkV-.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BOVkf1K3.js → index--00U6vXZ.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B-3tEpTc.js → index-B2V-eKfK.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-D2B4VPyP.js → index-B4JJCfQ2.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BkBi5TmC.js → index-BIoG5yYf.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-79V_zv1s.js → index-BMcimU-2.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-U4f5izHz.js → index-BPhkFZ1I.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DiSkx4UB.js → index-BQ3DXBtD.js} +3 -3
  104. package/src/assets/web-panel/assets/{index-dIHr4B_u.js → index-Bad4VNvz.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CIG8fQ2_.js → index-BgiXR_-_.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DqBgBpgp.js → index-BtobShro.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-ZxO_-E8a.js → index-Bw2MEnUk.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DUUrv141.js → index-C1mJtE6q.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bm7lLR4c.js → index-C484EJiS.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-COdGA-8n.js → index-C5KAQFPQ.js} +1 -1
  111. package/src/assets/web-panel/assets/index-C61cnl3K.js +1 -0
  112. package/src/assets/web-panel/assets/{index-CED2PL_y.js → index-C7Y8Aluc.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-YXgLng0K.js → index-CCsM_Ybx.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-0-agYlWL.js → index-CJCFe2Qf.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-B5UkyA3c.js → index-CJVEOa4i.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B1CbOH1i.js → index-CJdQrZth.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-s1opAL-M.js → index-CKC1t3Ic.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-yObj1O4n.js → index-CQhAVU5t.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CgsqdnRV.js → index-CYdoQsa1.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Dk7-v4hP.js → index-Cduu2Hhr.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-B-JVTrpr.js → index-CkwiSLhU.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CeWoNHau.js → index-Cvyt-zhm.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CE2VtTlp.js → index-D2GjI2oe.js} +1 -1
  124. package/src/assets/web-panel/assets/index-D4XFHxBr.js +1 -0
  125. package/src/assets/web-panel/assets/{index-DmbfhJUP.js → index-DARsAyUp.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BESLFt4q.js → index-DVKfQ0Ux.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-PT_5sBMA.js → index-DZT36ZYq.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-gyFpvL7l.js → index-D_XBHopw.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BYUVuwKt.js → index-DdCB70SS.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BcUXAB2s.js → index-DzRjHxEv.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Dk2qouAz.js → index-MMN9V6JF.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D9evtvg2.js → index-RfMr79MW.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BuLQobzW.js → index-_IRVsV9X.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Cf3WCLmy.js → index-nXyk8GZ9.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CG3PRyAL.js → index-s_buFMEG.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-C9h9yKL3.js → initDefaultProps-Blmpk7HL.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-BvmLsPdu.js → motion-DPBJMv1n.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-CoL4ekU1.js → move-ButdzCM7.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-C4pMy6xV.js → mtc-parser-cyRC_QCe.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-DPuJfNxx.js → omit-1epSV7hz.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-D0KEeaK2.js → pickAttrs-DuPY8xJs.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-BpkyINxt.js → placementArrow-6XZqarhe.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-DQI_wOq8.js → responsiveObserve-B40pXBWM.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-DYfdDiRg.js → slide-jbZ9Wu4n.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-B5dtvb0D.js → statusUtils-BKQQcVy4.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-CF310mSj.js → styleChecker-NiKfWjUT.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-D1Qp4BLp.js → useFlexGapSupport-bQUCvPeb.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-C7_iyvJK.js → useFs-CUGji7ph.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-DZUt_fIm.js → usePersonalDataHub-4veyN2N2.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-D3dsi0lZ.js → vnode-1-nLug-Z.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-WdbOlvdQ.js → zoom-dhCeRDMo.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/command-help-index.json +6 -6
  154. package/src/commands/automation.js +103 -1
  155. package/src/commands/cowork.js +174 -19
  156. package/src/commands/permissions.js +240 -16
  157. package/src/commands/plugin.js +1293 -56
  158. package/src/commands/session-location.js +276 -0
  159. package/src/commands/session.js +2 -0
  160. package/src/commands/team-merge-review.js +937 -0
  161. package/src/commands/team.js +2 -0
  162. package/src/data/changelog.json +27 -1
  163. package/src/gateways/ws/action-protocol.js +35 -10
  164. package/src/gateways/ws/remote-session-protocol.js +24 -1
  165. package/src/gateways/ws/ws-agent-handler.js +12 -0
  166. package/src/gateways/ws/ws-server.js +48 -12
  167. package/src/harness/jsonl-session-store.js +341 -24
  168. package/src/harness/mcp-client.js +8 -1
  169. package/src/harness/remote-session-audit.js +1 -0
  170. package/src/harness/remote-session-crypto.js +210 -2
  171. package/src/harness/remote-session-registry.js +159 -6
  172. package/src/harness/session-list-index.js +233 -14
  173. package/src/lib/agent-authority.js +6 -0
  174. package/src/lib/agent-schedule-store.js +139 -28
  175. package/src/lib/agent-team/team-merge-review-store.js +765 -0
  176. package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
  177. package/src/lib/agent-team/team-merge-review.js +1847 -0
  178. package/src/lib/automation-center-incidents.js +314 -0
  179. package/src/lib/automation-center-runtime.js +448 -0
  180. package/src/lib/automation-center.js +182 -38
  181. package/src/lib/automation-engine.js +41 -0
  182. package/src/lib/automation-execution-authority.js +241 -12
  183. package/src/lib/automation-execution-incident.js +737 -0
  184. package/src/lib/background-agent-keeper-client.js +248 -0
  185. package/src/lib/background-agent-keeper-protocol.js +147 -0
  186. package/src/lib/background-agent-supervisor.js +520 -40
  187. package/src/lib/background-interaction-resolver.js +12 -0
  188. package/src/lib/background-turn-bootstrap-protocol.js +126 -0
  189. package/src/lib/cowork-cron.js +85 -14
  190. package/src/lib/cowork-workflow.js +336 -16
  191. package/src/lib/dynamic-workflow-facade.js +648 -0
  192. package/src/lib/execution-location-contract.js +551 -0
  193. package/src/lib/execution-location-runtime.js +130 -0
  194. package/src/lib/ide-context.js +94 -6
  195. package/src/lib/mcp-stdio-package-materialization.js +166 -14
  196. package/src/lib/packer/pkg-config-generator.js +2 -0
  197. package/src/lib/permission-authority.js +77 -0
  198. package/src/lib/permission-side-effect-center.js +495 -0
  199. package/src/lib/plugin-runtime/install.js +514 -13
  200. package/src/lib/plugin-runtime/marketplace-artifact-readback.js +900 -0
  201. package/src/lib/plugin-runtime/marketplace-catalog.js +1181 -0
  202. package/src/lib/plugin-runtime/marketplace-impact.js +408 -0
  203. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1567 -0
  204. package/src/lib/plugin-security.js +60 -3
  205. package/src/lib/process-execution-broker/index.js +1095 -57
  206. package/src/lib/process-execution-broker/linux-bwrap-descriptor-launch.js +375 -0
  207. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +90 -16
  208. package/src/lib/process-execution-broker/linux-generic-bwrap.js +159 -18
  209. package/src/lib/process-execution-broker/macos-mcp-launcher-contract.js +278 -0
  210. package/src/lib/process-execution-broker/macos-mcp-launcher-protocol.json +23 -0
  211. package/src/lib/process-execution-broker/macos-mcp-launcher.c +1497 -0
  212. package/src/lib/process-execution-broker/mcp-fd-entry-bootstrap.js +37 -0
  213. package/src/lib/process-execution-broker/platform-sandbox.js +2330 -279
  214. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  215. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  216. package/src/lib/process-execution-broker/windows-sandbox.cs +50 -4
  217. package/src/lib/public-ide-capability-manifest.js +3 -0
  218. package/src/lib/remote-approval-bridge.js +123 -17
  219. package/src/lib/remote-membership-authority.js +632 -0
  220. package/src/lib/remote-membership-coordinator.js +2409 -0
  221. package/src/lib/remote-membership-host-store.js +1750 -0
  222. package/src/lib/scheduler-kernel/agenda-adapter.js +17 -7
  223. package/src/lib/scheduler-kernel/automation-adapter.js +105 -11
  224. package/src/lib/scheduler-kernel/automation-event-adapter.js +87 -11
  225. package/src/lib/scheduler-kernel/contract.js +91 -0
  226. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +12 -1
  227. package/src/lib/scheduler-kernel/loop-adapter.js +7 -1
  228. package/src/lib/scheduler-kernel/routine-adapter.js +7 -1
  229. package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
  230. package/src/lib/scheduler-kernel/runtime.js +176 -3
  231. package/src/lib/scheduler-kernel/store.js +1253 -45
  232. package/src/lib/scoped-permission-store.js +369 -0
  233. package/src/lib/session-anti-rollback-anchor.js +262 -5
  234. package/src/lib/sub-agent-context.js +4 -0
  235. package/src/lib/workflow-definition-contract.js +149 -0
  236. package/src/repl/agent-repl.js +41 -7
  237. package/src/repl/chat-repl.js +2 -0
  238. package/src/repl/clipboard-image.js +735 -16
  239. package/src/repl/ide-status.js +1 -1
  240. package/src/repl/prompt-interactions.js +59 -6
  241. package/src/runtime/agent-core.js +93 -3
  242. package/src/runtime/headless-runner.js +30 -25
  243. package/src/runtime/headless-stream.js +32 -25
  244. package/src/runtime/mcp-config.js +81 -10
  245. package/src/workers/background-agent-keeper.js +498 -0
  246. package/src/workers/background-agent-worker.js +358 -13
  247. package/src/workers/background-turn-bootstrap.js +143 -0
  248. package/src/assets/web-panel/assets/MobileProjects-BWdOvQAj.js +0 -1
  249. package/src/assets/web-panel/assets/Projects-BV4oApsm.js +0 -1
  250. package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +0 -1
  251. package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +0 -1
  252. package/src/assets/web-panel/assets/index-ChVT0p9u.js +0 -1
@@ -11,9 +11,10 @@
11
11
  * 3. substitutes placeholders in `message` from completed step outputs
12
12
  * 4. halts on first failure unless `continueOnError` is set
13
13
  *
14
- * Persistence mirrors the cron scheduler: one JSON file per workflow under
15
- * `.chainlesschain/cowork/workflows/<id>.json`, plus a `run-history.jsonl`
16
- * capturing each execution.
14
+ * Persistence keeps a versioned current envelope under
15
+ * `.chainlesschain/cowork/workflows/<id>.json`, immutable content-addressed
16
+ * definitions under `workflow-versions/<id>/<digest>.json`, plus a
17
+ * `run-history.jsonl` capturing each execution.
17
18
  *
18
19
  * The runner itself is injected via `_deps.runTask` to avoid a circular import
19
20
  * with `cowork-task-runner.js`.
@@ -21,7 +22,7 @@
21
22
  * @module cowork-workflow
22
23
  */
23
24
 
24
- import {
25
+ import fs, {
25
26
  existsSync,
26
27
  mkdirSync,
27
28
  readFileSync,
@@ -30,15 +31,34 @@ import {
30
31
  unlinkSync,
31
32
  appendFileSync,
32
33
  renameSync,
34
+ lstatSync,
35
+ openSync,
36
+ fstatSync,
37
+ closeSync,
38
+ realpathSync,
39
+ constants as fsConstants,
33
40
  } from "node:fs";
34
- import { join } from "node:path";
41
+ import { isAbsolute, join, relative } from "node:path";
42
+ import {
43
+ sameFileStatIdentity,
44
+ samePathHandleFileIdentity,
45
+ withTrustedFileParentSync,
46
+ } from "./secure-file-identity.js";
35
47
  import { evaluate as evalExpr, resolveReference } from "./workflow-expr.js";
48
+ import {
49
+ MAX_WORKFLOW_DEFINITION_BYTES,
50
+ createCoworkWorkflowRecord,
51
+ createWorkflowDefinitionAuthority,
52
+ normalizeWorkflowDefinitionDigest,
53
+ verifyCoworkWorkflowRecord,
54
+ } from "./workflow-definition-contract.js";
36
55
 
37
56
  /** Maximum number of items a single forEach step can expand into. */
38
57
  export const MAX_FAN_OUT = 500;
39
58
 
40
59
  /** Absolute ceiling on a single loop step's iterations (infinite-loop guard). */
41
60
  export const MAX_LOOP_ITERATIONS = 100;
61
+ export const COWORK_WORKFLOW_RUN_RECORD_SCHEMA = "cc-cowork-workflow-run/v1";
42
62
 
43
63
  export const _deps = {
44
64
  existsSync,
@@ -49,6 +69,12 @@ export const _deps = {
49
69
  unlinkSync,
50
70
  appendFileSync,
51
71
  renameSync,
72
+ lstatSync,
73
+ openSync,
74
+ fstatSync,
75
+ closeSync,
76
+ realpathSync,
77
+ fsConstants,
52
78
  now: () => Date.now(),
53
79
  runTask: null, // injected by CLI
54
80
  // Timer seams (injectable for deterministic retry/timeout tests).
@@ -83,14 +109,174 @@ function _atomicWriteJson(file, data) {
83
109
  }
84
110
  }
85
111
 
112
+ function _parseBoundedWorkflowJson(raw) {
113
+ const text =
114
+ typeof raw === "string" ? raw : Buffer.from(raw).toString("utf8");
115
+ const bytes = Buffer.byteLength(text, "utf8");
116
+ if (bytes <= 0 || bytes > MAX_WORKFLOW_DEFINITION_BYTES) {
117
+ throw new Error(
118
+ `workflow record must be 1..${MAX_WORKFLOW_DEFINITION_BYTES} bytes`,
119
+ );
120
+ }
121
+ return JSON.parse(text);
122
+ }
123
+
124
+ function _pathIsInside(root, candidate) {
125
+ const offset = relative(root, candidate);
126
+ return offset === "" || (!offset.startsWith("..") && !isAbsolute(offset));
127
+ }
128
+
129
+ function _canonicalWorkflowStoragePath(candidate, runtimeRealpath) {
130
+ const nativeRealpath = runtimeRealpath?.native;
131
+ return typeof nativeRealpath === "function"
132
+ ? nativeRealpath(candidate)
133
+ : runtimeRealpath(candidate);
134
+ }
135
+
136
+ export function workflowStoragePathIsContained(
137
+ cwd,
138
+ candidate,
139
+ runtimeRealpath = realpathSync,
140
+ ) {
141
+ const realRoot = _canonicalWorkflowStoragePath(cwd, runtimeRealpath);
142
+ const realCandidate = _canonicalWorkflowStoragePath(
143
+ candidate,
144
+ runtimeRealpath,
145
+ );
146
+ return _pathIsInside(realRoot, realCandidate);
147
+ }
148
+
149
+ function _assertWorkflowStoragePath(cwd, candidate) {
150
+ const usingRuntimeFs =
151
+ _deps.readFileSync === readFileSync &&
152
+ _deps.realpathSync === realpathSync &&
153
+ _deps.lstatSync === lstatSync;
154
+ if (!usingRuntimeFs) return;
155
+ // Canonicalize both sides through the same native API. Windows hosted
156
+ // runners can expose cwd through an 8.3 alias while a trusted-parent read
157
+ // returns the expanded path; mixing legacy/native realpath projections can
158
+ // otherwise misclassify the same directory as an escape.
159
+ if (!workflowStoragePathIsContained(cwd, candidate, _deps.realpathSync)) {
160
+ throw new Error("workflow storage path escapes the working directory");
161
+ }
162
+ }
163
+
164
+ function _assertWorkflowStorageDirectory(cwd, directory) {
165
+ _assertWorkflowStoragePath(cwd, directory);
166
+ if (
167
+ _deps.readFileSync === readFileSync &&
168
+ _deps.lstatSync === lstatSync &&
169
+ _deps.realpathSync === realpathSync
170
+ ) {
171
+ const stat = _deps.lstatSync(directory);
172
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
173
+ throw new Error("workflow storage directory must not be a symlink");
174
+ }
175
+ }
176
+ }
177
+
178
+ function _readBoundedWorkflowJson(cwd, file) {
179
+ const usingRuntimeFs =
180
+ _deps.readFileSync === readFileSync &&
181
+ _deps.lstatSync === lstatSync &&
182
+ _deps.openSync === openSync &&
183
+ _deps.fstatSync === fstatSync &&
184
+ _deps.closeSync === closeSync &&
185
+ _deps.realpathSync === realpathSync;
186
+ if (!usingRuntimeFs) {
187
+ return _parseBoundedWorkflowJson(_deps.readFileSync(file, "utf8"));
188
+ }
189
+
190
+ _assertWorkflowStoragePath(cwd, file);
191
+ return withTrustedFileParentSync(
192
+ fs,
193
+ file,
194
+ ({ canonicalPath, parentDevice }) => {
195
+ _assertWorkflowStoragePath(cwd, canonicalPath);
196
+ const before = _deps.lstatSync(canonicalPath, { bigint: true });
197
+ if (
198
+ !before.isFile() ||
199
+ before.isSymbolicLink() ||
200
+ Number(before.nlink) !== 1
201
+ ) {
202
+ throw new Error("workflow record must be a regular, single-link file");
203
+ }
204
+ if (
205
+ Number(before.size) <= 0 ||
206
+ Number(before.size) > MAX_WORKFLOW_DEFINITION_BYTES
207
+ ) {
208
+ throw new Error(
209
+ `workflow record must be 1..${MAX_WORKFLOW_DEFINITION_BYTES} bytes`,
210
+ );
211
+ }
212
+
213
+ let descriptor;
214
+ try {
215
+ let flags = Number(_deps.fsConstants.O_RDONLY || 0);
216
+ if (typeof _deps.fsConstants.O_NOFOLLOW === "number") {
217
+ flags |= _deps.fsConstants.O_NOFOLLOW;
218
+ }
219
+ descriptor = _deps.openSync(canonicalPath, flags);
220
+ const opened = _deps.fstatSync(descriptor, { bigint: true });
221
+ if (
222
+ !opened.isFile() ||
223
+ Number(opened.nlink) !== 1 ||
224
+ !samePathHandleFileIdentity(before, opened, parentDevice)
225
+ ) {
226
+ throw new Error("workflow record identity changed while opening");
227
+ }
228
+ const value = _parseBoundedWorkflowJson(
229
+ _deps.readFileSync(descriptor, "utf8"),
230
+ );
231
+ const after = _deps.fstatSync(descriptor, { bigint: true });
232
+ if (!sameFileStatIdentity(opened, after)) {
233
+ throw new Error("workflow record changed while being read");
234
+ }
235
+ return value;
236
+ } finally {
237
+ if (descriptor !== undefined) _deps.closeSync(descriptor);
238
+ }
239
+ },
240
+ );
241
+ }
242
+
86
243
  // ─── Paths ───────────────────────────────────────────────────────────────────
87
244
 
88
245
  function workflowsDir(cwd) {
89
246
  return join(cwd, ".chainlesschain", "cowork", "workflows");
90
247
  }
91
248
 
249
+ function assertWorkflowId(id) {
250
+ if (
251
+ typeof id !== "string" ||
252
+ !/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(id) ||
253
+ id.includes("..")
254
+ ) {
255
+ throw new TypeError(
256
+ "workflow id must be 1..128 safe filename characters without '..'",
257
+ );
258
+ }
259
+ return id;
260
+ }
261
+
92
262
  function workflowFile(cwd, id) {
93
- return join(workflowsDir(cwd), `${id}.json`);
263
+ return join(workflowsDir(cwd), `${assertWorkflowId(id)}.json`);
264
+ }
265
+
266
+ function workflowVersionsDir(cwd, id) {
267
+ return join(
268
+ cwd,
269
+ ".chainlesschain",
270
+ "cowork",
271
+ "workflow-versions",
272
+ assertWorkflowId(id),
273
+ );
274
+ }
275
+
276
+ function workflowVersionFile(cwd, id, definitionDigest) {
277
+ const digest = normalizeWorkflowDefinitionDigest(definitionDigest);
278
+ if (!digest) throw new TypeError("workflow definition digest is invalid");
279
+ return join(workflowVersionsDir(cwd, id), `${digest.slice(7)}.json`);
94
280
  }
95
281
 
96
282
  function historyFile(cwd) {
@@ -107,7 +293,15 @@ export function validateWorkflow(wf) {
107
293
  if (!wf || typeof wf !== "object") {
108
294
  return { valid: false, errors: ["workflow must be an object"] };
109
295
  }
110
- if (!wf.id || typeof wf.id !== "string") errors.push("id required");
296
+ if (!wf.id || typeof wf.id !== "string") {
297
+ errors.push("id required");
298
+ } else {
299
+ try {
300
+ assertWorkflowId(wf.id);
301
+ } catch (error) {
302
+ errors.push(error.message);
303
+ }
304
+ }
111
305
  if (!wf.name || typeof wf.name !== "string") errors.push("name required");
112
306
  if (!Array.isArray(wf.steps) || wf.steps.length === 0) {
113
307
  errors.push("steps must be a non-empty array");
@@ -375,6 +569,40 @@ export function substitutePlaceholders(template, resultsById) {
375
569
 
376
570
  // ─── Persistence ─────────────────────────────────────────────────────────────
377
571
 
572
+ function _storedWorkflowError(message) {
573
+ const error = new Error(message);
574
+ error.code = "WORKFLOW_DEFINITION_INTEGRITY";
575
+ return error;
576
+ }
577
+
578
+ function _readStoredWorkflowRecord(
579
+ cwd,
580
+ file,
581
+ { allowLegacy = true, expectedId, expectedDigest } = {},
582
+ ) {
583
+ const record = verifyCoworkWorkflowRecord(
584
+ _readBoundedWorkflowJson(cwd, file),
585
+ {
586
+ allowLegacy,
587
+ },
588
+ );
589
+ const validation = validateWorkflow(record.definition);
590
+ if (!validation.valid) {
591
+ throw _storedWorkflowError(
592
+ `stored workflow is invalid: ${validation.errors.join("; ")}`,
593
+ );
594
+ }
595
+ if (expectedId && record.definition.id !== expectedId) {
596
+ throw _storedWorkflowError("stored workflow id does not match its path");
597
+ }
598
+ if (expectedDigest && record.definitionDigest !== expectedDigest) {
599
+ throw _storedWorkflowError(
600
+ "stored workflow digest does not match its version path",
601
+ );
602
+ }
603
+ return record;
604
+ }
605
+
378
606
  export function listWorkflows(cwd) {
379
607
  const dir = workflowsDir(cwd);
380
608
  if (!_deps.existsSync(dir)) return [];
@@ -383,21 +611,28 @@ export function listWorkflows(cwd) {
383
611
  for (const name of entries) {
384
612
  if (!name.endsWith(".json")) continue;
385
613
  try {
386
- const body = _deps.readFileSync(join(dir, name), "utf-8");
387
- out.push(JSON.parse(body));
388
- } catch (_e) {
614
+ const id = name.slice(0, -5);
615
+ const record = _readStoredWorkflowRecord(cwd, join(dir, name), {
616
+ expectedId: id,
617
+ });
618
+ out.push(record.definition);
619
+ } catch {
389
620
  // skip malformed files
390
621
  }
391
622
  }
392
623
  return out;
393
624
  }
394
625
 
395
- export function getWorkflow(cwd, id) {
626
+ export function getWorkflowRecord(cwd, id) {
396
627
  const file = workflowFile(cwd, id);
397
628
  if (!_deps.existsSync(file)) return null;
629
+ return _readStoredWorkflowRecord(cwd, file, { expectedId: id });
630
+ }
631
+
632
+ export function getWorkflow(cwd, id) {
398
633
  try {
399
- return JSON.parse(_deps.readFileSync(file, "utf-8"));
400
- } catch (_e) {
634
+ return getWorkflowRecord(cwd, id)?.definition || null;
635
+ } catch {
401
636
  return null;
402
637
  }
403
638
  }
@@ -405,14 +640,82 @@ export function getWorkflow(cwd, id) {
405
640
  export function saveWorkflow(cwd, wf) {
406
641
  const { valid, errors } = validateWorkflow(wf);
407
642
  if (!valid) throw new Error(`Invalid workflow: ${errors.join("; ")}`);
643
+ const record = createCoworkWorkflowRecord(wf);
644
+ const serialized = JSON.stringify(record, null, 2);
408
645
  const dir = workflowsDir(cwd);
409
646
  _deps.mkdirSync(dir, { recursive: true });
410
- _atomicWriteJson(workflowFile(cwd, wf.id), JSON.stringify(wf, null, 2));
647
+ _assertWorkflowStorageDirectory(cwd, dir);
648
+ const versionDir = workflowVersionsDir(cwd, wf.id);
649
+ _deps.mkdirSync(versionDir, { recursive: true });
650
+ _assertWorkflowStorageDirectory(cwd, versionDir);
651
+ const versionFile = workflowVersionFile(cwd, wf.id, record.definitionDigest);
652
+ if (_deps.existsSync(versionFile)) {
653
+ _readStoredWorkflowRecord(cwd, versionFile, {
654
+ allowLegacy: false,
655
+ expectedId: wf.id,
656
+ expectedDigest: record.definitionDigest,
657
+ });
658
+ } else {
659
+ _atomicWriteJson(versionFile, serialized);
660
+ }
661
+ const currentFile = workflowFile(cwd, wf.id);
662
+ if (_deps.existsSync(currentFile)) {
663
+ _readStoredWorkflowRecord(cwd, currentFile, {
664
+ expectedId: wf.id,
665
+ });
666
+ }
667
+ _atomicWriteJson(currentFile, serialized);
411
668
  return wf;
412
669
  }
413
670
 
671
+ export function getWorkflowVersion(cwd, id, definitionDigest) {
672
+ const digest = normalizeWorkflowDefinitionDigest(definitionDigest);
673
+ if (!digest) throw new TypeError("workflow definition digest is invalid");
674
+ const file = workflowVersionFile(cwd, id, digest);
675
+ if (!_deps.existsSync(file)) return null;
676
+ return _readStoredWorkflowRecord(cwd, file, {
677
+ allowLegacy: false,
678
+ expectedId: id,
679
+ expectedDigest: digest,
680
+ });
681
+ }
682
+
683
+ export function listWorkflowVersions(cwd, id) {
684
+ const dir = workflowVersionsDir(cwd, id);
685
+ if (!_deps.existsSync(dir)) return [];
686
+ const versions = [];
687
+ for (const name of _deps.readdirSync(dir) || []) {
688
+ const match = /^([a-f0-9]{64})\.json$/u.exec(name);
689
+ if (!match) continue;
690
+ const digest = `sha256:${match[1]}`;
691
+ const record = _readStoredWorkflowRecord(cwd, join(dir, name), {
692
+ allowLegacy: false,
693
+ expectedId: id,
694
+ expectedDigest: digest,
695
+ });
696
+ versions.push(
697
+ Object.freeze({
698
+ status: record.status,
699
+ recordSchema: record.recordSchema,
700
+ definitionSchema: record.definitionSchema,
701
+ definitionDigest: record.definitionDigest,
702
+ id: record.definition.id,
703
+ name: record.definition.name,
704
+ }),
705
+ );
706
+ }
707
+ return versions.sort((left, right) =>
708
+ left.definitionDigest.localeCompare(right.definitionDigest),
709
+ );
710
+ }
711
+
414
712
  export function removeWorkflow(cwd, id) {
415
- const file = workflowFile(cwd, id);
713
+ let file;
714
+ try {
715
+ file = workflowFile(cwd, id);
716
+ } catch {
717
+ return false;
718
+ }
416
719
  if (!_deps.existsSync(file)) return false;
417
720
  _deps.unlinkSync(file);
418
721
  return true;
@@ -872,6 +1175,7 @@ export async function runPipeline({
872
1175
  *
873
1176
  * @param {object} options
874
1177
  * @param {object} options.workflow - Workflow definition
1178
+ * @param {string} [options.definitionDigest] - Exact definition digest to bind
875
1179
  * @param {string} [options.cwd] - Working directory for history
876
1180
  * @param {number} [options.maxParallel] - Max parallel steps (per batch, or
877
1181
  * concurrent step nodes in pipeline mode)
@@ -893,6 +1197,7 @@ export async function runPipeline({
893
1197
  export async function executeWorkflow(options = {}) {
894
1198
  const {
895
1199
  workflow,
1200
+ definitionDigest: requestedDefinitionDigest,
896
1201
  cwd = process.cwd(),
897
1202
  maxParallel = 4,
898
1203
  continueOnError = false,
@@ -904,6 +1209,18 @@ export async function executeWorkflow(options = {}) {
904
1209
 
905
1210
  const { valid, errors } = validateWorkflow(workflow);
906
1211
  if (!valid) throw new Error(`Invalid workflow: ${errors.join("; ")}`);
1212
+ const definitionAuthority = createWorkflowDefinitionAuthority(workflow);
1213
+ if (requestedDefinitionDigest != null) {
1214
+ const normalizedDigest = normalizeWorkflowDefinitionDigest(
1215
+ requestedDefinitionDigest,
1216
+ );
1217
+ if (!normalizedDigest) {
1218
+ throw new Error("workflow definition digest is invalid");
1219
+ }
1220
+ if (normalizedDigest !== definitionAuthority.definitionDigest) {
1221
+ throw new Error("workflow definition digest mismatch");
1222
+ }
1223
+ }
907
1224
  if (typeof _deps.runTask !== "function") {
908
1225
  throw new Error(
909
1226
  "cowork-workflow: _deps.runTask is not injected (wire runCoworkTask in CLI before executing)",
@@ -1107,8 +1424,11 @@ export async function executeWorkflow(options = {}) {
1107
1424
  : "failed";
1108
1425
 
1109
1426
  const record = {
1427
+ schema: COWORK_WORKFLOW_RUN_RECORD_SCHEMA,
1110
1428
  workflowId: workflow.id,
1111
1429
  workflowName: workflow.name,
1430
+ definitionSchema: definitionAuthority.schema,
1431
+ definitionDigest: definitionAuthority.definitionDigest,
1112
1432
  status,
1113
1433
  steps: stepOutcomes,
1114
1434
  startedAt,
@@ -1127,7 +1447,7 @@ function _appendHistory(cwd, record) {
1127
1447
  JSON.stringify(record) + "\n",
1128
1448
  "utf-8",
1129
1449
  );
1130
- } catch (_e) {
1450
+ } catch {
1131
1451
  // best-effort
1132
1452
  }
1133
1453
  }