chainlesschain 0.163.8 → 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 (228) hide show
  1. package/package.json +4 -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-CavM7W3k.js → AIOps-D2MEn7fI.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-CUvZGabQ.js → ActionButton-lCW_4Gf0.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DeBnWnbe.js → Analytics-Bs7i-nsS.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-DbI5kxvd.js → AppLayout-CK7B6S_j.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-D93bigKm.js → Artifacts-C8ILjpyo.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-CBNvfUZa.js → Audit-Bb9cNaWc.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-CJLyh_YU.js → BackgroundAgents-sC9ooXIf.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-D_0yoehD.js → Backup-D-DrsplT.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-TJxmbObW.js → BaseInput-uCNZpwSK.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-CE0dto1q.js → Chat-CsDK1uE9.js} +6 -6
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZ5-yYiD.js → ChatBubbleRenderer-OqSDt50w.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-Ck1RVIVo.js → Checkbox-JhTXM1-K.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-qpoyf6DK.js → Codegen-BbzZLnyD.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-DUyPWjIE.js → Col-D4VW4m4j.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-D_S1BemS.js → Community-BXrYawxV.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BjxeK-Gc.js → Compact-DCihGy1u.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-Dd3CEJsu.js → Compliance-DlyZ-lk8.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-B4QG7-ad.js → Cowork-DvGZrhbO.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-BtZnids5.js → Cron-DUncZi8h.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-CHPfCBFD.js → Crosschain-C_hLuUcm.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-DT8DCEOK.js → DID-b6YSUqxr.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-COQab5_U.js → Dashboard-uvM15Cfb.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BY1PsQuU.js → Dropdown-D1-Nd4qY.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-CsuAuaq3.js → EmailListRenderer-8ApvL6Zc.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BqpinD-j.js → FamilyGuardDashboard-LYJt8811.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-D0gkfQFv.js → Federation-BbI3HGpv.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-BqgE-axK.js → FormItemContext-DSoEKuFu.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-D0hJ2KvC.js → GenericCardRenderer-B0S9OWd5.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-CmMB0uPY.js → Git-DIs9Zhf3.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-BnVEI0Dk.js → Governance-jzZXrxcl.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-YTAMihRP.js → Inference-JUPjf2ZI.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-0ax7VHop.js → KnowledgeGraph-DxnfJvlP.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-B9TRcokL.js → Logs-iXiz8BEE.js} +2 -2
  38. package/src/assets/web-panel/assets/MarkdownRenderer-GmB6DOr6.js +1 -0
  39. package/src/assets/web-panel/assets/{Marketplace-B6CSuD_H.js → Marketplace-Y3Xch312.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-CjMXvOVU.js → McpTools-D7kGGbO7.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-CXRF71U3.js → Memory-Do_hVxzh.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-DQgNp_oS.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-6hDTRPe1.js → Mtc-qo5QCTGd.js} +2 -2
  45. package/src/assets/web-panel/assets/{MtcAudit-BlVHU1DS.js → MtcAudit-cq5mnjYj.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-DP9pzEbV.js → Multisig-Bq0MAQHw.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-Djorh8EV.js → NLProgramming-DdWE6Vi2.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-oLZ-JkUg.js → Notes-BxMBFcIp.js} +4 -4
  49. package/src/assets/web-panel/assets/{NotificationSettings-Cg288VH3.js → NotificationSettings-RTrAcbUe.js} +1 -1
  50. package/src/assets/web-panel/assets/{OrderTableRenderer-Bb1O3Ofr.js → OrderTableRenderer-DJbpGqzT.js} +1 -1
  51. package/src/assets/web-panel/assets/{Organization-CBdo-bHs.js → Organization-SQzIPdqC.js} +2 -2
  52. package/src/assets/web-panel/assets/{Overflow-qZdnVumx.js → Overflow-02yECh22.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-D4kNfGNQ.js → P2P-BNg4pNCM.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-DnlMemM7.js → PdhVaultBrowser-BxPJZsD3.js} +5 -5
  55. package/src/assets/web-panel/assets/{Permissions-DHucHFBJ.js → Permissions-CLnDnPAz.js} +3 -3
  56. package/src/assets/web-panel/assets/{PersonalDataHub-BovlOIPR.js → PersonalDataHub-C5m0AjGf.js} +4 -4
  57. package/src/assets/web-panel/assets/{Pipeline-Deru3CQY.js → Pipeline-VwOf5Dhv.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-Bq5oTTbU.js → Privacy-CC0W2hZd.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-BfzxVWAz.js → ProjectInit-Dz893Bob.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-CKC6XBtH.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-C_jx4TWX.js → Providers-DeB9IkxK.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-BdIHeVGC.js → QrScannerModal-OCeoaswn.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-BwZwAcPD.js → QuickAsk-DenotaAj.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-BNTt0L-m.js → Recommend-Cies_jjI.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-Biyn2-Ro.js → RemoteSession-Dxzl5n2T.js} +3 -3
  67. package/src/assets/web-panel/assets/{Reputation-D6VpG32B.js → Reputation-CW0mvxgZ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-D_74OvQQ.js → Row-SEd32qZU.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-BTr0a-BQ.js → RssFeed-BSwnJ3Lm.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-C3MCFoNU.js → Search-xe2m8bkC.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-CqW9aJ6s.js → Security-Mq2F9Nro.js} +3 -3
  72. package/src/assets/web-panel/assets/{Services-Cw5GNaHF.js → Services-BKGw2V3P.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-DZps5qeY.js → Skeleton-DW95-Rxf.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-C6NQ1znT.js → Skills-CHgChCv_.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-DFP8G2Sh.js → Sla-tKh6k3R7.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-ESt6MB6v.js → SpeechSettings-D6UL3dA5.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-BHnN98aM.js → SyncSettings-D0Fw8fVL.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-NiSCaOf-.js → Tasks-20x1GB3D.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-DsKFhW2C.js → Templates-DJ-lts-a.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-CQ0E0ze5.js → Tenant-BFdGpbs7.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-D_rBu_by.js → Terminal-Xpx61vHL.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-D3Vm4Po4.js → TimelineRenderer-C6UIvyZQ.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-DNTxRH6q.js → Tokens-Dellq08f.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-Dgprz1ms.js → Trigger-VKw8d0J-.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-B2rUnVBD.js → Trust-DNftdKT5.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-DEGQNc6_.js → UkeySign-DX9VAKJI.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-jlsAx3Eh.js → VideoEditing-B2h3jO8q.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-8jQih1ij.js → Wallet-CjGkof7f.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-XLeO6xIB.js → WebAuthn-2Zfcu55P.js} +4 -4
  90. package/src/assets/web-panel/assets/{WorkflowEditor-De_dgDAG.js → WorkflowEditor-B9eZ8UxZ.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-CI19R_Sk.js → chat-CQNfD-YO.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-DsYTOYN3.js → colors-D4usyFT2.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-CM3-t_Qr.js → compact-item-s4TpjvjX.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-BjxlBRZv.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-RDaWX_4i.js → hasIn-AdkUbkV-.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BN6UPD2E.js → index--00U6vXZ.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CiECJi-Q.js → index-B2V-eKfK.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CnHH7bnD.js → index-B4JJCfQ2.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CjTrRt13.js → index-BIoG5yYf.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-Dxge-xWl.js → index-BMcimU-2.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-9R6BxAr0.js → index-BPhkFZ1I.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BHNYPO0b.js → index-BQ3DXBtD.js} +3 -3
  104. package/src/assets/web-panel/assets/{index-Cpqm1qfU.js → index-Bad4VNvz.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-B9O9YyWE.js → index-BgiXR_-_.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-B5REnKt8.js → index-BtobShro.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-D6sm5-Xq.js → index-Bw2MEnUk.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DcPFB8qJ.js → index-C1mJtE6q.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BKJr-TZp.js → index-C484EJiS.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Drlnwr8F.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-Dsij_KsN.js → index-C7Y8Aluc.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-IeiL9RKc.js → index-CCsM_Ybx.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-B-Z8eFUJ.js → index-CJCFe2Qf.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CyOGN6a5.js → index-CJVEOa4i.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B0PMlbMs.js → index-CJdQrZth.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-nAH87mQP.js → index-CKC1t3Ic.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BGqqJfL0.js → index-CQhAVU5t.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Cd9OJhHG.js → index-CYdoQsa1.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D0zcy54x.js → index-Cduu2Hhr.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DIUnNOjG.js → index-CkwiSLhU.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CVQMeiwH.js → index-Cvyt-zhm.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BlT2VAEK.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-C0yx-jtQ.js → index-DARsAyUp.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-Bi46Xu4u.js → index-DVKfQ0Ux.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Cd3euP_4.js → index-DZT36ZYq.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BCnZyIMA.js → index-D_XBHopw.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-C4gkzxkw.js → index-DdCB70SS.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-B7WBt_4T.js → index-DzRjHxEv.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DX7tuWVJ.js → index-MMN9V6JF.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DoQA0-52.js → index-RfMr79MW.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DXXtGMUJ.js → index-_IRVsV9X.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-pPL66J85.js → index-nXyk8GZ9.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DyIWssPC.js → index-s_buFMEG.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-BTL88of4.js → initDefaultProps-Blmpk7HL.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-BUB2pXwB.js → motion-DPBJMv1n.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-egCkkOMm.js → move-ButdzCM7.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-DAWhZC8c.js → mtc-parser-cyRC_QCe.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-CvOxe_6d.js → omit-1epSV7hz.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-DZUSLZ5Z.js → pickAttrs-DuPY8xJs.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-BERxGNMY.js → placementArrow-6XZqarhe.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-DZuDfZ9n.js → responsiveObserve-B40pXBWM.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-DO756sgI.js → slide-jbZ9Wu4n.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-BRQlIz28.js → statusUtils-BKQQcVy4.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-DCSfdybl.js → styleChecker-NiKfWjUT.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-LD8dWVve.js → useFlexGapSupport-bQUCvPeb.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-BX9uW2LK.js → useFs-CUGji7ph.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-BPSlPuHU.js → usePersonalDataHub-4veyN2N2.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-BmOILC9V.js → vnode-1-nLug-Z.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-1iKowKGg.js → zoom-dhCeRDMo.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/command-help-index.json +3 -3
  154. package/src/commands/cowork.js +174 -19
  155. package/src/commands/permissions.js +240 -16
  156. package/src/commands/plugin.js +1293 -56
  157. package/src/commands/session-location.js +276 -0
  158. package/src/commands/session.js +2 -0
  159. package/src/data/changelog.json +15 -2
  160. package/src/gateways/ws/action-protocol.js +35 -10
  161. package/src/gateways/ws/remote-session-protocol.js +24 -1
  162. package/src/gateways/ws/ws-agent-handler.js +12 -0
  163. package/src/gateways/ws/ws-server.js +48 -12
  164. package/src/harness/jsonl-session-store.js +341 -24
  165. package/src/harness/mcp-client.js +8 -1
  166. package/src/harness/remote-session-audit.js +1 -0
  167. package/src/harness/remote-session-crypto.js +210 -2
  168. package/src/harness/remote-session-registry.js +159 -6
  169. package/src/harness/session-list-index.js +233 -14
  170. package/src/lib/agent-authority.js +6 -0
  171. package/src/lib/background-agent-keeper-client.js +248 -0
  172. package/src/lib/background-agent-keeper-protocol.js +147 -0
  173. package/src/lib/background-agent-supervisor.js +520 -40
  174. package/src/lib/background-interaction-resolver.js +12 -0
  175. package/src/lib/background-turn-bootstrap-protocol.js +126 -0
  176. package/src/lib/cowork-workflow.js +336 -16
  177. package/src/lib/dynamic-workflow-facade.js +648 -0
  178. package/src/lib/execution-location-contract.js +551 -0
  179. package/src/lib/execution-location-runtime.js +130 -0
  180. package/src/lib/ide-context.js +94 -6
  181. package/src/lib/mcp-stdio-package-materialization.js +166 -14
  182. package/src/lib/packer/pkg-config-generator.js +2 -0
  183. package/src/lib/permission-authority.js +77 -0
  184. package/src/lib/permission-side-effect-center.js +495 -0
  185. package/src/lib/plugin-runtime/install.js +514 -13
  186. package/src/lib/plugin-runtime/marketplace-artifact-readback.js +900 -0
  187. package/src/lib/plugin-runtime/marketplace-catalog.js +1181 -0
  188. package/src/lib/plugin-runtime/marketplace-impact.js +408 -0
  189. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1567 -0
  190. package/src/lib/plugin-security.js +60 -3
  191. package/src/lib/process-execution-broker/index.js +1095 -57
  192. package/src/lib/process-execution-broker/linux-bwrap-descriptor-launch.js +375 -0
  193. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +90 -16
  194. package/src/lib/process-execution-broker/linux-generic-bwrap.js +159 -18
  195. package/src/lib/process-execution-broker/macos-mcp-launcher-contract.js +278 -0
  196. package/src/lib/process-execution-broker/macos-mcp-launcher-protocol.json +23 -0
  197. package/src/lib/process-execution-broker/macos-mcp-launcher.c +1497 -0
  198. package/src/lib/process-execution-broker/mcp-fd-entry-bootstrap.js +37 -0
  199. package/src/lib/process-execution-broker/platform-sandbox.js +2330 -279
  200. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  201. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  202. package/src/lib/process-execution-broker/windows-sandbox.cs +50 -4
  203. package/src/lib/public-ide-capability-manifest.js +3 -0
  204. package/src/lib/remote-approval-bridge.js +123 -17
  205. package/src/lib/remote-membership-authority.js +632 -0
  206. package/src/lib/remote-membership-coordinator.js +2409 -0
  207. package/src/lib/remote-membership-host-store.js +1750 -0
  208. package/src/lib/scoped-permission-store.js +369 -0
  209. package/src/lib/session-anti-rollback-anchor.js +262 -5
  210. package/src/lib/sub-agent-context.js +4 -0
  211. package/src/lib/workflow-definition-contract.js +149 -0
  212. package/src/repl/agent-repl.js +41 -7
  213. package/src/repl/chat-repl.js +2 -0
  214. package/src/repl/clipboard-image.js +735 -16
  215. package/src/repl/ide-status.js +1 -1
  216. package/src/repl/prompt-interactions.js +59 -6
  217. package/src/runtime/agent-core.js +83 -3
  218. package/src/runtime/headless-runner.js +30 -25
  219. package/src/runtime/headless-stream.js +32 -25
  220. package/src/workers/background-agent-keeper.js +498 -0
  221. package/src/workers/background-agent-worker.js +358 -13
  222. package/src/workers/background-turn-bootstrap.js +143 -0
  223. package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +0 -1
  224. package/src/assets/web-panel/assets/MobileProjects-DlPwcCbq.js +0 -1
  225. package/src/assets/web-panel/assets/Projects-CMolGhae.js +0 -1
  226. package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +0 -1
  227. package/src/assets/web-panel/assets/index-Drz6yq0m.js +0 -1
  228. package/src/assets/web-panel/assets/index-uWiUs7S_.js +0 -1
@@ -0,0 +1,648 @@
1
+ import {
2
+ MAX_FAN_OUT,
3
+ loopIterationCap,
4
+ planBatches,
5
+ validateWorkflow,
6
+ } from "./cowork-workflow.js";
7
+ import {
8
+ EXECUTION_LOCATION,
9
+ normalizeExecutionLocation,
10
+ redactCredentialRefs,
11
+ } from "./execution-location.js";
12
+ import { normalizeExecutionLocationBinding } from "./execution-location-contract.js";
13
+ import {
14
+ COWORK_WORKFLOW_RECORD_SCHEMA,
15
+ WORKFLOW_DEFINITION_SCHEMA,
16
+ createWorkflowDefinitionAuthority,
17
+ normalizeWorkflowDefinitionDigest,
18
+ } from "./workflow-definition-contract.js";
19
+
20
+ export const DYNAMIC_WORKFLOW_DEFINITION_SCHEMA = WORKFLOW_DEFINITION_SCHEMA;
21
+ export const DYNAMIC_WORKFLOW_PREFLIGHT_SCHEMA =
22
+ "cc-dynamic-workflow-preflight/v1";
23
+
24
+ export const DYNAMIC_WORKFLOW_ENGINE_CAPABILITIES = Object.freeze([
25
+ "condition",
26
+ "cowork-task",
27
+ "dag",
28
+ "for-each",
29
+ "loop",
30
+ "parallel",
31
+ "pipeline",
32
+ "retry",
33
+ "timeout",
34
+ "variables",
35
+ ]);
36
+
37
+ const CAPABILITY_SET = new Set(DYNAMIC_WORKFLOW_ENGINE_CAPABILITIES);
38
+ const FORBIDDEN_CREDENTIAL_KEYS = new Set([
39
+ "accesstoken",
40
+ "apikey",
41
+ "authorization",
42
+ "bearer",
43
+ "clientsecret",
44
+ "credentialvalue",
45
+ "key",
46
+ "password",
47
+ "privatekey",
48
+ "secret",
49
+ "token",
50
+ "value",
51
+ ]);
52
+ const CREDENTIAL_SOURCES = new Set([
53
+ "config",
54
+ "env",
55
+ "environment",
56
+ "keychain",
57
+ "local-provider",
58
+ "managed-secret",
59
+ "none",
60
+ "not-observed",
61
+ "unknown",
62
+ ]);
63
+ const DATA_BOUNDARY_KINDS = new Set([
64
+ "declared",
65
+ "repository",
66
+ "working-directory",
67
+ ]);
68
+ const SANDBOX_RANK = Object.freeze({ none: 0, partial: 1, strong: 2 });
69
+ const DEFAULT_SOFT_TASK_GUIDELINE = 16;
70
+ const DEFAULT_HARD_TASK_LIMIT = 64;
71
+
72
+ function safeString(value, max = 256) {
73
+ if (typeof value !== "string") return null;
74
+ const output = value.trim();
75
+ // eslint-disable-next-line no-control-regex -- rejecting ASCII controls is the validation boundary
76
+ if (!output || output.length > max || /[\u0000-\u001f\u007f]/u.test(output)) {
77
+ return null;
78
+ }
79
+ return output;
80
+ }
81
+
82
+ function finiteNumber(value, { integer = false, min = 0 } = {}) {
83
+ const output = Number(value);
84
+ if (!Number.isFinite(output) || output < min) return null;
85
+ if (integer && !Number.isSafeInteger(output)) return null;
86
+ return output;
87
+ }
88
+
89
+ function uniqueNames(values) {
90
+ const output = [];
91
+ for (const value of Array.isArray(values) ? values : []) {
92
+ const name = safeString(value, 64)?.toLowerCase();
93
+ if (name && /^[a-z0-9_.:-]+$/u.test(name) && !output.includes(name)) {
94
+ output.push(name);
95
+ }
96
+ }
97
+ return output.sort();
98
+ }
99
+
100
+ function usedCapabilities(workflow, batches) {
101
+ const capabilities = new Set(["cowork-task", "dag", "variables"]);
102
+ if (batches.some((batch) => batch.steps.length > 1)) {
103
+ capabilities.add("parallel");
104
+ }
105
+ if (workflow.pipeline === true) capabilities.add("pipeline");
106
+ for (const step of workflow.steps) {
107
+ if (step.when != null) capabilities.add("condition");
108
+ if (step.forEach != null) capabilities.add("for-each");
109
+ if (step.loopWhile != null || step.loopUntil != null)
110
+ capabilities.add("loop");
111
+ if (Number(step.retries) > 0) capabilities.add("retry");
112
+ if (Number(step.timeoutMs) > 0) capabilities.add("timeout");
113
+ }
114
+ return [...capabilities].sort();
115
+ }
116
+
117
+ function stepProjection(step) {
118
+ const retries =
119
+ step.retries == null
120
+ ? 0
121
+ : finiteNumber(step.retries, { integer: true, min: 0 });
122
+ if (retries == null || retries >= Number.MAX_SAFE_INTEGER) {
123
+ throw new TypeError(
124
+ `workflow step '${step.id}' retries exceed safe projection limits`,
125
+ );
126
+ }
127
+ const attempts = retries + 1;
128
+ let expansion = 1;
129
+ let expansionKnown = true;
130
+ let expansionSource = "single";
131
+ if (Array.isArray(step.forEach)) {
132
+ if (step.forEach.length > MAX_FAN_OUT) {
133
+ throw new TypeError(
134
+ `workflow step '${step.id}' exceeds MAX_FAN_OUT=${MAX_FAN_OUT}`,
135
+ );
136
+ }
137
+ expansion = step.forEach.length;
138
+ expansionSource = "literal-for-each";
139
+ } else if (typeof step.forEach === "string") {
140
+ expansion = null;
141
+ expansionKnown = false;
142
+ expansionSource = "runtime-for-each";
143
+ } else if (step.loopWhile != null || step.loopUntil != null) {
144
+ expansion = loopIterationCap(step);
145
+ expansionSource = "loop-cap";
146
+ }
147
+ return Object.freeze({
148
+ id: step.id,
149
+ dependencies: Object.freeze([...(step.dependsOn || [])].sort()),
150
+ attemptsPerTask: attempts,
151
+ expansion,
152
+ expansionKnown,
153
+ expansionSource,
154
+ worstCaseTaskCalls: expansionKnown ? expansion * attempts : null,
155
+ worstCaseDurationSlots: expansionKnown
156
+ ? expansionSource === "literal-for-each"
157
+ ? expansion === 0
158
+ ? 0
159
+ : attempts
160
+ : expansion * attempts
161
+ : null,
162
+ });
163
+ }
164
+
165
+ function containsCredentialValue(value, seen = new Set()) {
166
+ if (!value || typeof value !== "object") return false;
167
+ if (seen.has(value)) return true;
168
+ seen.add(value);
169
+ for (const [key, child] of Object.entries(value)) {
170
+ const normalizedKey = key.toLowerCase().replace(/[^a-z0-9]/gu, "");
171
+ if (FORBIDDEN_CREDENTIAL_KEYS.has(normalizedKey) && child != null) {
172
+ return true;
173
+ }
174
+ if (containsCredentialValue(child, seen)) return true;
175
+ }
176
+ return false;
177
+ }
178
+
179
+ function normalizeGovernance(workflow) {
180
+ const facade =
181
+ workflow.facade && typeof workflow.facade === "object"
182
+ ? workflow.facade
183
+ : {};
184
+ const requirements =
185
+ facade.requirements && typeof facade.requirements === "object"
186
+ ? facade.requirements
187
+ : {};
188
+ const rawCredentials = Array.isArray(requirements.credentials)
189
+ ? requirements.credentials
190
+ : [];
191
+ const credentialValuePresent = containsCredentialValue(rawCredentials);
192
+ const redactedCredentials = credentialValuePresent
193
+ ? []
194
+ : redactCredentialRefs(rawCredentials).map((credential) => {
195
+ const source = safeString(credential.source)?.toLowerCase();
196
+ return Object.freeze({
197
+ name: safeString(credential.name),
198
+ source: CREDENTIAL_SOURCES.has(source) ? source : "unknown",
199
+ scope: safeString(credential.scope),
200
+ });
201
+ });
202
+ const credentialKeys = redactedCredentials.map(
203
+ (credential) =>
204
+ `${credential.name || ""}\u0000${credential.source}\u0000${credential.scope || ""}`,
205
+ );
206
+ const credentialDeclarationInvalid =
207
+ !credentialValuePresent &&
208
+ (redactedCredentials.length !== rawCredentials.length ||
209
+ redactedCredentials.some(
210
+ (credential) =>
211
+ !credential.name ||
212
+ ["none", "not-observed", "unknown"].includes(credential.source),
213
+ ) ||
214
+ new Set(credentialKeys).size !== credentialKeys.length);
215
+ const credentials = credentialDeclarationInvalid ? [] : redactedCredentials;
216
+ const rawCapabilities = Array.isArray(requirements.capabilities)
217
+ ? requirements.capabilities
218
+ : [];
219
+ const capabilities = uniqueNames(rawCapabilities);
220
+ const rawLocations = Array.isArray(requirements.executionLocations)
221
+ ? requirements.executionLocations
222
+ : [];
223
+ const executionLocations = [
224
+ ...new Set(
225
+ uniqueNames(rawLocations)
226
+ .map(normalizeExecutionLocation)
227
+ .filter((location) => location !== EXECUTION_LOCATION.UNKNOWN),
228
+ ),
229
+ ].sort();
230
+ const permissionInput =
231
+ requirements.permissions && typeof requirements.permissions === "object"
232
+ ? requirements.permissions
233
+ : null;
234
+ const permissionDeclarationInvalid =
235
+ permissionInput != null &&
236
+ (!Object.hasOwn(permissionInput, "file") ||
237
+ !["none", "read", "write"].includes(permissionInput.file) ||
238
+ ["shell", "network", "mcp", "externalSystems"].some(
239
+ (key) =>
240
+ Object.hasOwn(permissionInput, key) &&
241
+ typeof permissionInput[key] !== "boolean",
242
+ ));
243
+ const permissions = permissionInput
244
+ ? Object.freeze({
245
+ file: ["none", "read", "write"].includes(permissionInput.file)
246
+ ? permissionInput.file
247
+ : null,
248
+ shell: permissionInput.shell === true,
249
+ network: permissionInput.network === true,
250
+ mcp: permissionInput.mcp === true,
251
+ externalSystems: permissionInput.externalSystems === true,
252
+ })
253
+ : null;
254
+ const sandbox = ["none", "partial", "strong"].includes(requirements.sandbox)
255
+ ? requirements.sandbox
256
+ : null;
257
+ const estimatesInput =
258
+ facade.estimates && typeof facade.estimates === "object"
259
+ ? facade.estimates
260
+ : {};
261
+ const budgetInput =
262
+ facade.budget && typeof facade.budget === "object" ? facade.budget : {};
263
+ return Object.freeze({
264
+ requirements: Object.freeze({
265
+ capabilities: Object.freeze(capabilities),
266
+ capabilityDeclarationInvalid:
267
+ rawCapabilities.length !== capabilities.length,
268
+ executionLocations: Object.freeze(executionLocations),
269
+ executionLocationDeclarationInvalid:
270
+ rawLocations.length !== executionLocations.length,
271
+ permissions,
272
+ permissionDeclarationInvalid,
273
+ sandbox,
274
+ dataBoundary: DATA_BOUNDARY_KINDS.has(requirements.dataBoundary)
275
+ ? requirements.dataBoundary
276
+ : null,
277
+ credentials: Object.freeze(credentials),
278
+ credentialValuePresent,
279
+ credentialDeclarationInvalid,
280
+ }),
281
+ estimates: Object.freeze({
282
+ tokensPerTask: finiteNumber(estimatesInput.tokensPerTask, {
283
+ integer: true,
284
+ min: 1,
285
+ }),
286
+ usdPerTask: finiteNumber(estimatesInput.usdPerTask, { min: 0 }),
287
+ durationMsPerTask: finiteNumber(estimatesInput.durationMsPerTask, {
288
+ integer: true,
289
+ min: 1,
290
+ }),
291
+ }),
292
+ budget: Object.freeze({
293
+ maxExpandedTasks: finiteNumber(budgetInput.maxExpandedTasks, {
294
+ integer: true,
295
+ min: 1,
296
+ }),
297
+ maxParallel: finiteNumber(budgetInput.maxParallel, {
298
+ integer: true,
299
+ min: 1,
300
+ }),
301
+ maxTokens: finiteNumber(budgetInput.maxTokens, {
302
+ integer: true,
303
+ min: 1,
304
+ }),
305
+ maxUsd: finiteNumber(budgetInput.maxUsd, { min: 0 }),
306
+ maxDurationMs: finiteNumber(budgetInput.maxDurationMs, {
307
+ integer: true,
308
+ min: 1,
309
+ }),
310
+ }),
311
+ });
312
+ }
313
+
314
+ export function createDynamicWorkflowManifest(workflow) {
315
+ const validation = validateWorkflow(workflow);
316
+ if (!validation.valid) {
317
+ throw new TypeError(`Invalid workflow: ${validation.errors.join("; ")}`);
318
+ }
319
+ const governance = normalizeGovernance(workflow);
320
+ if (governance.requirements.credentialValuePresent) {
321
+ throw new TypeError(
322
+ "workflow credential requirements must not contain values",
323
+ );
324
+ }
325
+ const authority = createWorkflowDefinitionAuthority(workflow);
326
+ const definition = authority.definition;
327
+ const batches = planBatches(workflow.steps).map((batch, index) =>
328
+ Object.freeze({
329
+ index,
330
+ steps: Object.freeze(batch.map((step) => step.id)),
331
+ }),
332
+ );
333
+ const steps = workflow.steps.map(stepProjection);
334
+ const expansionKnown = steps.every((step) => step.expansionKnown);
335
+ const worstCaseTaskCalls = expansionKnown
336
+ ? steps.reduce((total, step) => total + step.worstCaseTaskCalls, 0)
337
+ : null;
338
+ if (worstCaseTaskCalls != null && !Number.isSafeInteger(worstCaseTaskCalls)) {
339
+ throw new TypeError("workflow task-call projection exceeds safe limits");
340
+ }
341
+ return Object.freeze({
342
+ schema: DYNAMIC_WORKFLOW_DEFINITION_SCHEMA,
343
+ adapter: "cowork-workflow",
344
+ definitionDigest: authority.definitionDigest,
345
+ definition,
346
+ engineCapabilities: DYNAMIC_WORKFLOW_ENGINE_CAPABILITIES,
347
+ usedCapabilities: Object.freeze(usedCapabilities(workflow, batches)),
348
+ plan: Object.freeze({
349
+ mode: workflow.pipeline === true ? "pipeline" : "batched-dag",
350
+ batches: Object.freeze(batches),
351
+ steps: Object.freeze(steps),
352
+ expansionKnown,
353
+ worstCaseTaskCalls,
354
+ }),
355
+ governance,
356
+ runtimeClaims: Object.freeze({
357
+ durablePauseResume: false,
358
+ exactlyOnceAfterResume: false,
359
+ historyDurability: "best-effort",
360
+ needsInputBetweenStages: false,
361
+ }),
362
+ });
363
+ }
364
+
365
+ function addUnique(output, value) {
366
+ if (!output.includes(value)) output.push(value);
367
+ }
368
+
369
+ function permissionsCover(actual, required) {
370
+ if (!actual || !required) return false;
371
+ const fileRank = { none: 0, read: 1, write: 2 };
372
+ if ((fileRank[actual.file] ?? -1) < (fileRank[required.file] ?? -1)) {
373
+ return false;
374
+ }
375
+ for (const key of ["shell", "network", "mcp", "externalSystems"]) {
376
+ if (required[key] === true && actual[key] !== true) return false;
377
+ }
378
+ return true;
379
+ }
380
+
381
+ function credentialsCover(actual, required) {
382
+ const available = Array.isArray(actual) ? actual : [];
383
+ return required.filter(
384
+ (credential) =>
385
+ !available.some(
386
+ (candidate) =>
387
+ candidate.name === credential.name &&
388
+ candidate.source === credential.source &&
389
+ (credential.scope == null || candidate.scope === credential.scope),
390
+ ),
391
+ );
392
+ }
393
+
394
+ function projectedDurationSlots(plan, requestedParallel) {
395
+ if (!plan.expansionKnown || requestedParallel == null) return null;
396
+ const byId = new Map(plan.steps.map((step) => [step.id, step]));
397
+ let total = 0;
398
+ for (const batch of plan.batches) {
399
+ for (
400
+ let index = 0;
401
+ index < batch.steps.length;
402
+ index += requestedParallel
403
+ ) {
404
+ const chunk = batch.steps.slice(index, index + requestedParallel);
405
+ const chunkDuration = Math.max(
406
+ 0,
407
+ ...chunk.map((id) => byId.get(id)?.worstCaseDurationSlots ?? 0),
408
+ );
409
+ total += chunkDuration;
410
+ if (!Number.isSafeInteger(total)) return null;
411
+ }
412
+ }
413
+ return total;
414
+ }
415
+
416
+ function multiplyProjection(...values) {
417
+ if (values.some((value) => value == null)) return null;
418
+ const product = values.reduce((total, value) => total * value, 1);
419
+ return Number.isFinite(product) && product <= Number.MAX_SAFE_INTEGER
420
+ ? product
421
+ : null;
422
+ }
423
+
424
+ export function buildDynamicWorkflowPreflight(input = {}) {
425
+ const suppliedManifest =
426
+ input.manifest?.schema === DYNAMIC_WORKFLOW_DEFINITION_SCHEMA
427
+ ? input.manifest
428
+ : null;
429
+ const manifest = createDynamicWorkflowManifest(
430
+ input.workflow || suppliedManifest?.definition,
431
+ );
432
+ const binding = normalizeExecutionLocationBinding(input.executionLocation);
433
+ const governance = manifest.governance;
434
+ const requirements = governance.requirements;
435
+ const estimates = governance.estimates;
436
+ const budget = governance.budget;
437
+ const blockers = [];
438
+ const warnings = [];
439
+ const definitionAuthority = input.definitionAuthority
440
+ ? Object.freeze({
441
+ status:
442
+ input.definitionAuthority.status === "versioned"
443
+ ? "versioned"
444
+ : "legacy-unversioned",
445
+ recordSchema: safeString(input.definitionAuthority.recordSchema),
446
+ definitionSchema: safeString(
447
+ input.definitionAuthority.definitionSchema,
448
+ ),
449
+ definitionDigest: normalizeWorkflowDefinitionDigest(
450
+ input.definitionAuthority.definitionDigest,
451
+ ),
452
+ })
453
+ : null;
454
+
455
+ if (
456
+ suppliedManifest &&
457
+ suppliedManifest.definitionDigest !== manifest.definitionDigest
458
+ ) {
459
+ addUnique(blockers, "definition-digest-mismatch");
460
+ }
461
+ if (definitionAuthority) {
462
+ if (definitionAuthority.status !== "versioned") {
463
+ addUnique(blockers, "definition-authority-unversioned");
464
+ }
465
+ if (
466
+ definitionAuthority.recordSchema !== COWORK_WORKFLOW_RECORD_SCHEMA ||
467
+ definitionAuthority.definitionSchema !== manifest.schema ||
468
+ definitionAuthority.definitionDigest !== manifest.definitionDigest
469
+ ) {
470
+ addUnique(blockers, "definition-authority-mismatch");
471
+ }
472
+ }
473
+
474
+ if (requirements.capabilities.length === 0) {
475
+ addUnique(blockers, "required-capabilities-missing");
476
+ }
477
+ if (requirements.capabilityDeclarationInvalid) {
478
+ addUnique(blockers, "capability-declaration-invalid");
479
+ }
480
+ for (const capability of requirements.capabilities) {
481
+ if (!CAPABILITY_SET.has(capability)) {
482
+ addUnique(blockers, `unsupported-capability:${capability}`);
483
+ }
484
+ }
485
+ for (const capability of manifest.usedCapabilities) {
486
+ if (!requirements.capabilities.includes(capability)) {
487
+ addUnique(blockers, `undeclared-capability:${capability}`);
488
+ }
489
+ }
490
+ if (requirements.executionLocations.length === 0) {
491
+ addUnique(blockers, "execution-locations-missing");
492
+ } else if (requirements.executionLocationDeclarationInvalid) {
493
+ addUnique(blockers, "execution-location-declaration-invalid");
494
+ } else if (!requirements.executionLocations.includes(binding.location)) {
495
+ addUnique(blockers, `execution-location-not-allowed:${binding.location}`);
496
+ }
497
+ if (!requirements.permissions) {
498
+ addUnique(blockers, "permission-requirements-missing");
499
+ } else if (requirements.permissionDeclarationInvalid) {
500
+ addUnique(blockers, "permission-requirements-invalid");
501
+ } else if (binding.permissions.status !== "declared") {
502
+ addUnique(blockers, "environment-permissions-not-observed");
503
+ } else if (!permissionsCover(binding.permissions, requirements.permissions)) {
504
+ addUnique(blockers, "environment-permissions-insufficient");
505
+ }
506
+ if (requirements.permissions?.network === true) {
507
+ if (binding.policy.network === "unknown") {
508
+ addUnique(blockers, "environment-network-policy-unknown");
509
+ } else if (binding.policy.network === "offline") {
510
+ addUnique(blockers, "environment-network-policy-insufficient");
511
+ }
512
+ }
513
+ if (!requirements.sandbox) {
514
+ addUnique(blockers, "sandbox-requirement-missing");
515
+ } else if (!(binding.policy.sandbox in SANDBOX_RANK)) {
516
+ addUnique(blockers, "environment-sandbox-unknown");
517
+ } else if (
518
+ SANDBOX_RANK[binding.policy.sandbox] < SANDBOX_RANK[requirements.sandbox]
519
+ ) {
520
+ addUnique(blockers, "environment-sandbox-insufficient");
521
+ }
522
+ if (requirements.credentialValuePresent) {
523
+ addUnique(blockers, "credential-value-present");
524
+ }
525
+ if (requirements.credentialDeclarationInvalid) {
526
+ addUnique(blockers, "credential-declaration-invalid");
527
+ } else {
528
+ for (const credential of credentialsCover(
529
+ binding.credentials,
530
+ requirements.credentials,
531
+ )) {
532
+ addUnique(blockers, `environment-credential-missing:${credential.name}`);
533
+ }
534
+ }
535
+ if (!requirements.dataBoundary) {
536
+ addUnique(blockers, "data-boundary-requirement-missing");
537
+ } else if (binding.policy.dataBoundary.kind === "unknown") {
538
+ addUnique(blockers, "environment-data-boundary-unknown");
539
+ } else if (binding.policy.dataBoundary.kind !== requirements.dataBoundary) {
540
+ addUnique(blockers, "environment-data-boundary-mismatch");
541
+ }
542
+
543
+ if (!manifest.plan.expansionKnown) {
544
+ addUnique(blockers, "runtime-expansion-unknown");
545
+ }
546
+ const taskCalls = manifest.plan.worstCaseTaskCalls;
547
+ const hardLimit = Math.min(
548
+ budget.maxExpandedTasks ?? DEFAULT_HARD_TASK_LIMIT,
549
+ DEFAULT_HARD_TASK_LIMIT,
550
+ );
551
+ if (budget.maxExpandedTasks > DEFAULT_HARD_TASK_LIMIT) {
552
+ addUnique(blockers, "expanded-task-budget-exceeds-engine-limit");
553
+ }
554
+ if (taskCalls != null && taskCalls > hardLimit) {
555
+ addUnique(blockers, "expanded-task-budget-exceeded");
556
+ } else if (taskCalls != null && taskCalls > DEFAULT_SOFT_TASK_GUIDELINE) {
557
+ warnings.push("expanded task count exceeds the soft size guideline");
558
+ }
559
+ const requestedParallel = finiteNumber(input.maxParallel ?? 4, {
560
+ integer: true,
561
+ min: 1,
562
+ });
563
+ if (requestedParallel == null) {
564
+ addUnique(blockers, "requested-parallel-invalid");
565
+ } else if (requestedParallel > DEFAULT_HARD_TASK_LIMIT) {
566
+ addUnique(blockers, "requested-parallel-exceeds-engine-limit");
567
+ }
568
+ if (budget.maxParallel == null) {
569
+ addUnique(blockers, "parallel-budget-missing");
570
+ } else if (
571
+ requestedParallel != null &&
572
+ requestedParallel > budget.maxParallel
573
+ ) {
574
+ addUnique(blockers, "parallel-budget-exceeded");
575
+ }
576
+
577
+ const durationSlots = projectedDurationSlots(
578
+ manifest.plan,
579
+ requestedParallel,
580
+ );
581
+ const projectedTokens = multiplyProjection(
582
+ taskCalls,
583
+ estimates.tokensPerTask,
584
+ );
585
+ const projectedUsd = multiplyProjection(taskCalls, estimates.usdPerTask);
586
+ const projectedDurationMs = multiplyProjection(
587
+ durationSlots,
588
+ estimates.durationMsPerTask,
589
+ );
590
+ for (const [name, projected, maximum] of [
591
+ ["token", projectedTokens, budget.maxTokens],
592
+ ["usd", projectedUsd, budget.maxUsd],
593
+ ["duration", projectedDurationMs, budget.maxDurationMs],
594
+ ]) {
595
+ if (projected == null || maximum == null) {
596
+ addUnique(blockers, `${name}-budget-unevaluable`);
597
+ } else if (projected > maximum) {
598
+ addUnique(blockers, `${name}-budget-exceeded`);
599
+ }
600
+ }
601
+
602
+ return Object.freeze({
603
+ schema: DYNAMIC_WORKFLOW_PREFLIGHT_SCHEMA,
604
+ allowed: blockers.length === 0,
605
+ definition: Object.freeze({
606
+ schema: manifest.schema,
607
+ adapter: manifest.adapter,
608
+ id: manifest.definition.id,
609
+ name: manifest.definition.name,
610
+ definitionDigest: manifest.definitionDigest,
611
+ authority: definitionAuthority,
612
+ }),
613
+ executionLocation: Object.freeze({
614
+ schema: binding.schema,
615
+ location: binding.location,
616
+ source: binding.source,
617
+ permissions: binding.permissions,
618
+ policy: binding.policy,
619
+ }),
620
+ capabilities: Object.freeze({
621
+ engine: manifest.engineCapabilities,
622
+ used: manifest.usedCapabilities,
623
+ required: requirements.capabilities,
624
+ }),
625
+ permissions: Object.freeze({
626
+ required: requirements.permissions,
627
+ credentialRefs: requirements.credentials,
628
+ credentialValuesTransferred: false,
629
+ }),
630
+ scale: Object.freeze({
631
+ expansionKnown: manifest.plan.expansionKnown,
632
+ worstCaseTaskCalls: taskCalls,
633
+ softTaskGuideline: DEFAULT_SOFT_TASK_GUIDELINE,
634
+ hardTaskLimit: hardLimit,
635
+ requestedParallel,
636
+ }),
637
+ cost: Object.freeze({
638
+ projectedTokens,
639
+ projectedUsd,
640
+ projectedDurationMs,
641
+ projectedDurationSlots: durationSlots,
642
+ budget,
643
+ }),
644
+ runtimeClaims: manifest.runtimeClaims,
645
+ blockers: Object.freeze(blockers),
646
+ warnings: Object.freeze(warnings),
647
+ });
648
+ }