chainlesschain 0.165.1 → 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 (202) hide show
  1. package/README.md +248 -2
  2. package/package.json +4 -1
  3. package/src/assets/web-panel/assets/{AIOps-CYxFDrcm.js → AIOps-lS1R0Cza.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CPBtdiU2.js → ActionButton-BmlgBPsj.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-Dayq7Dp7.js → Analytics-CNKczv1S.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-6U7bPb2s.js → AppLayout-BuZGJARQ.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-D2Iqg_3D.js → Artifacts-Dm73Sl-O.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-CdoOB7WV.js → Audit-BGMW7A5e.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-DrnAVB8w.js → BackgroundAgents-BQ6M54JR.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CesMi5cy.js → Backup-DBzGP0bR.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DaX9ptax.js → BaseInput-D1mLCoOV.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-OrwOPxDS.js → Chat-BUfcN7p8.js} +4 -4
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CvPZFRxM.js → ChatBubbleRenderer-CY5m8ZHg.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-DiHbcysC.js → Checkbox-Du0Yg5Pi.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-CbgCkaBJ.js → Codegen-B2RXziHW.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-Du5hgrh4.js → Col-DWhekOrR.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-DsPOBW-p.js → Community-HQhrkon4.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BwHIFkNC.js → Compact-izHNb4uz.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BvrDQSgd.js → Compliance-BDwLy41-.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-gwAE6arx.js → Cowork-DFJhLa7K.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-DW-0l4uF.js → Cron-DYY9RG7-.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-j-NsLesB.js → Crosschain-rr7tJTtv.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-CibVEBOI.js → DID-D2sfHRLi.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-W4z9vSfe.js → Dashboard-q_eGdhha.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-DAcrkKxG.js → Dropdown-Cufrh2Bz.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-6GXah-89.js → EmailListRenderer-B-kdv10f.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-TKDCq8Ku.js → FamilyGuardDashboard-D21XjgfG.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-BXBLlcNm.js → Federation-CAwRTLZH.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-BoJJBkG3.js → FormItemContext-vx3daNDF.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-okjsl46v.js → GenericCardRenderer-CRWY2wU4.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-Rvs7i6nn.js → Git-Q6SwauyD.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CHSUxXXS.js → Governance-BJ1q4IQZ.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-V3BlfxsB.js → Inference-CSWjROgD.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-C_NlD4aR.js → KnowledgeGraph-fzuQsWuY.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-Nn4LNxhA.js → Logs-DVF8Mnns.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-BLif4QSg.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-DEmjFcg-.js → Marketplace-BQP7LOA4.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-DlopXipI.js → McpTools-BNlJCmNc.js} +4 -4
  39. package/src/assets/web-panel/assets/{Memory-BG3ynX60.js → Memory-DLLg5WQ4.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-DeRzWOfT.js → MobileBridge-CR2skNAF.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-Tyd3o2A0.js → MobileProjects-BxVavObl.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-BoPbOv1C.js → Mtc-B17pgqMI.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-un-rTHp7.js → MtcAudit-4UmV5cIL.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-Ds0oveEB.js → Multisig-DoMEXEcU.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-D09JI-yY.js → NLProgramming-h9DMXFX4.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-DTRhiKJn.js → Notes-Cihn-xX8.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-BAnnNCim.js → NotificationSettings-BE6ZGa3R.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-Yr-1fSYi.js → OrderTableRenderer-CnwojoSI.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-S9EAolpj.js → Organization-B2vpwmjb.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-CqcLKqJ8.js → Overflow-C4z28R0-.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-Dw0F9EcU.js → P2P-BVlFkwhW.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-BDRwUevN.js → PdhVaultBrowser-BXbEdL5B.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-D3_c3nKB.js → Permissions-C28xs4lp.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-CxdMV98x.js → PersonalDataHub-Dgl_rBjM.js} +3 -3
  55. package/src/assets/web-panel/assets/{Pipeline-CgjNQFLI.js → Pipeline-3QUIhrKI.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-BHghIIht.js → Privacy-8Gh33OZ5.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-De6pqaKM.js → ProjectInit-BNmg4tZi.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-Bg4ZkNYQ.js → ProjectSettings-vgMfeCf9.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-BhtAVilc.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-CUnHbNf-.js → Providers-CXoOa8eX.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-DA2f3Wts.js → QrScannerModal-BhfTF0oS.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-C1FeHDqp.js → QuickAsk-C746HEAj.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-B5guaUMN.js → Recommend-BSej8Eo0.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-PDADSds3.js → RemoteSession-f3gmnlG3.js} +3 -3
  65. package/src/assets/web-panel/assets/{Reputation-eTlRhgvK.js → Reputation-CyvybpkN.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-D7AqSGY0.js → Row-DwV2PeYn.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-JiuLm4Ja.js → RssFeed-11GrzjZy.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-CwruahW3.js → Search-BjKXkrAY.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-CdhqaR0b.js → Security-eWiFb9Yk.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-CU0ZIlcT.js → Services-CdCsMAtt.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-CtduPfAb.js → Skeleton-4Q2UTKQ5.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-CROXm6AY.js → Skills-v4rtYrRj.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-DiZiABFD.js → Sla-CRhsFvd_.js} +1 -1
  74. package/src/assets/web-panel/assets/SpeechSettings-DLjKsDVu.js +1 -0
  75. package/src/assets/web-panel/assets/{SyncSettings-DBX6J1Oe.js → SyncSettings-D16zonl7.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-BLyRJd3-.js → Tasks-Xxozz0i_.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-BKa5qzmk.js → Templates-CXJpPtCT.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-DnD3a4M6.js → Tenant-XRV0L1ZF.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-DEitQeTb.js → Terminal-CYuO1i_w.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-CjHggTDq.js → TimelineRenderer-BXqitWsu.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-CsGT7sfl.js → Tokens-BvPrDHIy.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-yr4rFDrW.js → Trigger-DhCrSTf5.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-CLvu1Sjp.js → Trust-DmsuZD6K.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-B0m7yUP8.js → UkeySign-D_yrts5C.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-C0VvP4lc.js → VideoEditing-B01ihPrm.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-kllBAG1M.js → Wallet-DpUjKa-N.js} +3 -3
  87. package/src/assets/web-panel/assets/{WebAuthn-C54UQNLx.js → WebAuthn-CL07yON6.js} +3 -3
  88. package/src/assets/web-panel/assets/{WorkflowEditor-B7y8qSvU.js → WorkflowEditor-CLMflnRr.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-DRzTh8CJ.js → chat-DtUqe8h_.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-BSMwSnCx.js → colors-DPKrgVfy.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-BTg602H5.js → compact-item-BTt2GtOm.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-B6EGsdvp.js → createContext-D_VeUc1J.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-Bj5nUW2v.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-DDKqJ8RD.js → hasIn-1kndiylj.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CUEU48o1.js → index-2eyAXE3d.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-rjzk9z1Q.js → index-4bna2_SR.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CmAubjDi.js → index-8nz_fmlj.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Co7oM1qr.js → index-B9KvcS7R.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BMuGd2--.js → index-BAXfRKfG.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BVTAl5N2.js → index-BHpBMWCh.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DpTHIRfZ.js → index-BaZAbw9A.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CWGax2QW.js → index-BepLZwgB.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DiW0sDkz.js → index-Bhudc_Ez.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CGNklbP6.js → index-BlDNVgBt.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-u2YVld9W.js → index-By5n8up9.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-pqfux8vZ.js → index-CHG-KcS4.js} +1 -1
  107. package/src/assets/web-panel/assets/index-CPcM-eqo.js +1 -0
  108. package/src/assets/web-panel/assets/{index-BRqt4fO-.js → index-CX81qSM4.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BsR7Y2NG.js → index-CauoBQkH.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-C_JzIXUq.js → index-CcO04eDn.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CQlHFN_g.js → index-CtF7EN49.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CwPUZbMI.js → index-CzjkKUmR.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-th2ihDc0.js → index-D95OFht7.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CHfLYwcW.js → index-DFIZ_1Sf.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C1GFfuqN.js → index-DG2MZQ3f.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-D1naNj4U.js → index-DJ8vXGOa.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DLdrHhML.js → index-Dbbymxpj.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DBT3YeQ9.js → index-DdkplL9R.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BICn3Qh1.js → index-DfGl8CqG.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DqFXGzzC.js → index-DfKBRdSS.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Bx044qDj.js → index-DsJCDUJG.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-XFe-1twF.js → index-Dwqmtk65.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-C66NpWy5.js → index-DxdTdBix.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CmAInUkX.js → index-FzdwcSy2.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Cf23wVMs.js → index-GsoUQ2M7.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D5CsBShd.js → index-brCInrzq.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-323Hhxxt.js → index-dVc-CXY4.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-p2HYn89m.js → index-fk2Rjacw.js} +3 -3
  129. package/src/assets/web-panel/assets/{index-Dfv2lKu3.js → index-l1BETrDb.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CNxg61YP.js → index-m31Ka8hZ.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CDTvsX8t.js → index-ocf06EVQ.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Dc77VR3H.js → index-sDoMHTNA.js} +1 -1
  133. package/src/assets/web-panel/assets/index-xeSyVoRe.js +1 -0
  134. package/src/assets/web-panel/assets/{initDefaultProps-C3Djh9fa.js → initDefaultProps-CvyYJd7z.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BzqFmbSe.js → motion-DYZkhUdz.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-DJo_FFaW.js → move-slnJRVT1.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-_tlTiBvk.js → mtc-parser-DVc0CKmy.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-CB2ZyxUg.js → omit-BCXAtHCq.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-DZwIFD4u.js → pickAttrs-DBsemz_K.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-DxZY0dgk.js → placementArrow-BRtkJ-nv.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-CzzGt7GL.js → responsiveObserve-Cebq7EZn.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-BaIK52yz.js → slide-DT7qvId2.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-3-FHu9_M.js → statusUtils-pQiITLkG.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-BkRT68fK.js → styleChecker-c-19BVKQ.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-DHYwKS-s.js → useFlexGapSupport-DsS5-0bE.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-DVVUhV8p.js → useFs-CxGiMe5n.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-CkrFKAzQ.js → usePersonalDataHub-D9btVID5.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-BuBLFz0c.js → vnode-CUYFsFEN.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-kpm6LtXU.js → zoom-CXmn_35j.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/command-help-index.json +1 -1
  152. package/src/commands/cowork.js +280 -5
  153. package/src/commands/plugin.js +819 -64
  154. package/src/commands/session-location.js +318 -7
  155. package/src/constants.js +2 -2
  156. package/src/data/changelog.json +14 -1
  157. package/src/gateways/ws/action-protocol.js +1 -1
  158. package/src/harness/jsonl-session-store.js +638 -2
  159. package/src/harness/prompt-compressor.js +4 -0
  160. package/src/lib/background-agent-keeper-client.js +29 -0
  161. package/src/lib/background-agent-keeper-protocol.js +4 -0
  162. package/src/lib/background-agent-supervisor.js +59 -29
  163. package/src/lib/cowork-task-runner.js +70 -0
  164. package/src/lib/cowork-workflow.js +42 -9
  165. package/src/lib/doctor-checkup.js +34 -10
  166. package/src/lib/dynamic-workflow-draft.js +535 -0
  167. package/src/lib/dynamic-workflow-facade.js +11 -11
  168. package/src/lib/dynamic-workflow-runtime.js +2974 -0
  169. package/src/lib/execution-location-contract.js +111 -7
  170. package/src/lib/execution-location-runtime.js +3 -1
  171. package/src/lib/execution-location-target.js +910 -0
  172. package/src/lib/llm-providers.js +1 -0
  173. package/src/lib/mcp-call-ledger-store.js +35 -0
  174. package/src/lib/mcp-call-ledger.js +30 -0
  175. package/src/lib/plugin-runtime/__tests__/remote-source.test.js +34 -16
  176. package/src/lib/plugin-runtime/install.js +4956 -657
  177. package/src/lib/plugin-runtime/manifest.js +3 -1
  178. package/src/lib/plugin-runtime/marketplace-artifact-readback.js +671 -31
  179. package/src/lib/plugin-runtime/marketplace-catalog.js +68 -2
  180. package/src/lib/plugin-runtime/marketplace-impact.js +208 -15
  181. package/src/lib/plugin-runtime/marketplace-network.js +317 -0
  182. package/src/lib/plugin-runtime/marketplace-pac-worker.js +15 -0
  183. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +25 -2
  184. package/src/lib/plugin-runtime/marketplace-source-cache.js +359 -0
  185. package/src/lib/plugin-runtime/policy.js +21 -6
  186. package/src/lib/plugin-runtime/publisher-trust.js +332 -0
  187. package/src/lib/plugin-runtime/remote-source.js +323 -27
  188. package/src/lib/plugin-runtime/scopes.js +317 -41
  189. package/src/lib/plugin-runtime/transaction-journal.js +806 -0
  190. package/src/lib/public-ide-capability-manifest.js +1 -1
  191. package/src/lib/remote-membership-coordinator.js +8 -6
  192. package/src/lib/sub-agent-context.js +268 -2
  193. package/src/lib/task-model-selector.js +1 -1
  194. package/src/lib/with-file-lock.js +95 -5
  195. package/src/runtime/agent-core.js +595 -41
  196. package/src/workers/background-agent-keeper.js +40 -10
  197. package/src/assets/web-panel/assets/MarkdownRenderer-SVAgNnkt.js +0 -1
  198. package/src/assets/web-panel/assets/Projects-CP8vPvzs.js +0 -1
  199. package/src/assets/web-panel/assets/SpeechSettings-B5pLcXUw.js +0 -1
  200. package/src/assets/web-panel/assets/devWarning-Dol8jLEP.js +0 -1
  201. package/src/assets/web-panel/assets/index-C3QX5tOl.js +0 -1
  202. package/src/assets/web-panel/assets/index-xYybvEic.js +0 -1
@@ -0,0 +1,535 @@
1
+ import { createHash } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { types as utilTypes } from "node:util";
5
+ import { createDynamicWorkflowManifest } from "./dynamic-workflow-facade.js";
6
+ import { containsSecret } from "./secret-scan.js";
7
+ import {
8
+ sameFileStatIdentity,
9
+ samePathHandleFileIdentity,
10
+ withTrustedFileParentSync,
11
+ } from "./secure-file-identity.js";
12
+ import { canonicalJson } from "./scheduler-kernel/contract.js";
13
+ import {
14
+ MAX_WORKFLOW_DEFINITION_BYTES,
15
+ WORKFLOW_DEFINITION_SCHEMA,
16
+ } from "./workflow-definition-contract.js";
17
+
18
+ export const DYNAMIC_WORKFLOW_DRAFT_SCHEMA = "cc-dynamic-workflow-draft/v1";
19
+ export const DYNAMIC_WORKFLOW_GENERATION_SCHEMA =
20
+ "cc-dynamic-workflow-generation/v1";
21
+ export const DYNAMIC_WORKFLOW_REVIEW_SCHEMA = "cc-dynamic-workflow-review/v1";
22
+ export const MAX_DYNAMIC_WORKFLOW_PROMPT_BYTES = 16 * 1024;
23
+ export const MAX_DYNAMIC_WORKFLOW_DRAFT_BYTES =
24
+ MAX_WORKFLOW_DEFINITION_BYTES + 256 * 1024;
25
+
26
+ const SHA256_RE = /^sha256:[a-f0-9]{64}$/u;
27
+ const DRAFT_FIELDS = new Set([
28
+ "schema",
29
+ "status",
30
+ "promptDigest",
31
+ "generator",
32
+ "createdAt",
33
+ "definitionSchema",
34
+ "definitionDigest",
35
+ "definition",
36
+ "projection",
37
+ "draftDigest",
38
+ ]);
39
+ const GENERATOR_FIELDS = new Set(["provider", "model"]);
40
+ const PROJECTION_FIELDS = new Set([
41
+ "adapter",
42
+ "engineCapabilities",
43
+ "usedCapabilities",
44
+ "plan",
45
+ "governance",
46
+ "runtimeClaims",
47
+ ]);
48
+
49
+ function digest(domain, value) {
50
+ return `sha256:${createHash("sha256")
51
+ .update(domain, "utf8")
52
+ .update(canonicalJson(value, "dynamicWorkflowDraft"), "utf8")
53
+ .digest("hex")}`;
54
+ }
55
+
56
+ function canonicalTimestamp(value, field) {
57
+ const raw = typeof value === "function" ? value() : value;
58
+ const date = raw == null ? new Date() : new Date(raw);
59
+ if (!Number.isFinite(date.getTime())) {
60
+ throw new TypeError(`${field} must be a canonical timestamp`);
61
+ }
62
+ return date.toISOString();
63
+ }
64
+
65
+ function boundedString(value, field, max = 256) {
66
+ if (typeof value !== "string") throw new TypeError(`${field} is required`);
67
+ const output = value.trim();
68
+ let hasControlCharacter = false;
69
+ for (let index = 0; index < output.length; index += 1) {
70
+ const code = output.charCodeAt(index);
71
+ if (code <= 0x1f || code === 0x7f) {
72
+ hasControlCharacter = true;
73
+ break;
74
+ }
75
+ }
76
+ if (!output || output.length > max || hasControlCharacter) {
77
+ throw new TypeError(`${field} is invalid`);
78
+ }
79
+ return output;
80
+ }
81
+
82
+ function assertExactObject(value, fields, field) {
83
+ if (
84
+ !value ||
85
+ typeof value !== "object" ||
86
+ Array.isArray(value) ||
87
+ utilTypes.isProxy(value) ||
88
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value))
89
+ ) {
90
+ throw new TypeError(`${field} must be a plain object`);
91
+ }
92
+ const keys = Reflect.ownKeys(value);
93
+ if (
94
+ keys.length !== fields.size ||
95
+ keys.some((key) => typeof key !== "string" || !fields.has(key))
96
+ ) {
97
+ throw new TypeError(`${field} contains missing or unknown fields`);
98
+ }
99
+ for (const key of keys) {
100
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
101
+ if (
102
+ !descriptor ||
103
+ descriptor.enumerable !== true ||
104
+ !Object.hasOwn(descriptor, "value")
105
+ ) {
106
+ throw new TypeError(`${field}.${key} must be an enumerable data field`);
107
+ }
108
+ }
109
+ }
110
+
111
+ function snapshotJson(value, field) {
112
+ let encoded;
113
+ try {
114
+ encoded = canonicalJson(value, field);
115
+ } catch {
116
+ throw new TypeError(`${field} must contain canonical JSON`);
117
+ }
118
+ if (Buffer.byteLength(encoded, "utf8") > MAX_DYNAMIC_WORKFLOW_DRAFT_BYTES) {
119
+ throw new TypeError(`${field} exceeds the draft byte limit`);
120
+ }
121
+ return JSON.parse(encoded);
122
+ }
123
+
124
+ function parseGeneratedDefinition(value) {
125
+ if (typeof value !== "string") {
126
+ throw new TypeError("workflow generator must return text");
127
+ }
128
+ const bytes = Buffer.byteLength(value, "utf8");
129
+ if (bytes <= 0 || bytes > MAX_WORKFLOW_DEFINITION_BYTES) {
130
+ throw new TypeError("workflow generator response exceeds its byte limit");
131
+ }
132
+ const trimmed = value.trim();
133
+ const fenced = /^```(?:json)?\s*\r?\n([\s\S]*?)\r?\n```$/iu.exec(trimmed);
134
+ const json = fenced ? fenced[1] : trimmed;
135
+ if (!fenced && !json.startsWith("{")) {
136
+ throw new TypeError("workflow generator response must be one JSON object");
137
+ }
138
+ let definition;
139
+ try {
140
+ definition = JSON.parse(json);
141
+ } catch {
142
+ throw new TypeError("workflow generator response is not valid JSON");
143
+ }
144
+ if (
145
+ !definition ||
146
+ typeof definition !== "object" ||
147
+ Array.isArray(definition)
148
+ ) {
149
+ throw new TypeError("workflow generator response must be one JSON object");
150
+ }
151
+ if (
152
+ definition.facade?.generation != null ||
153
+ definition.facade?.review != null
154
+ ) {
155
+ throw new TypeError("workflow generator may not declare review authority");
156
+ }
157
+ if (containsSecret(JSON.stringify(definition))) {
158
+ throw new TypeError(
159
+ "workflow generator response contains secret-shaped data",
160
+ );
161
+ }
162
+ return definition;
163
+ }
164
+
165
+ function projectionFromManifest(manifest) {
166
+ return Object.freeze({
167
+ adapter: manifest.adapter,
168
+ engineCapabilities: manifest.engineCapabilities,
169
+ usedCapabilities: manifest.usedCapabilities,
170
+ plan: manifest.plan,
171
+ governance: manifest.governance,
172
+ runtimeClaims: manifest.runtimeClaims,
173
+ });
174
+ }
175
+
176
+ function assertReviewableManifest(manifest) {
177
+ const { requirements, estimates, budget } = manifest.governance;
178
+ const problems = [];
179
+ if (
180
+ requirements.capabilityDeclarationInvalid ||
181
+ canonicalJson(requirements.capabilities) !==
182
+ canonicalJson(manifest.usedCapabilities)
183
+ ) {
184
+ problems.push("capabilities-must-exactly-match-plan");
185
+ }
186
+ if (
187
+ requirements.executionLocationDeclarationInvalid ||
188
+ requirements.executionLocations.length === 0
189
+ ) {
190
+ problems.push("execution-location-required");
191
+ }
192
+ if (!requirements.permissions || requirements.permissionDeclarationInvalid) {
193
+ problems.push("permission-declaration-required");
194
+ }
195
+ if (!requirements.sandbox) problems.push("sandbox-declaration-required");
196
+ if (!requirements.dataBoundary) {
197
+ problems.push("data-boundary-declaration-required");
198
+ }
199
+ if (
200
+ requirements.credentialValuePresent ||
201
+ requirements.credentialDeclarationInvalid
202
+ ) {
203
+ problems.push("credential-reference-invalid");
204
+ }
205
+ if (Object.values(estimates).some((value) => value == null)) {
206
+ problems.push("estimates-required");
207
+ }
208
+ if (Object.values(budget).some((value) => value == null)) {
209
+ problems.push("budget-required");
210
+ }
211
+ const taskCalls = manifest.plan.worstCaseTaskCalls;
212
+ if (taskCalls == null)
213
+ problems.push("runtime-expansion-unsupported-for-draft");
214
+ if (
215
+ budget.maxExpandedTasks != null &&
216
+ (budget.maxExpandedTasks > 64 || taskCalls > budget.maxExpandedTasks)
217
+ ) {
218
+ problems.push("expanded-task-budget-invalid");
219
+ }
220
+ if (
221
+ budget.maxParallel != null &&
222
+ (budget.maxParallel > 64 || budget.maxParallel > budget.maxExpandedTasks)
223
+ ) {
224
+ problems.push("parallel-budget-invalid");
225
+ }
226
+ if (
227
+ taskCalls != null &&
228
+ estimates.tokensPerTask != null &&
229
+ budget.maxTokens != null &&
230
+ taskCalls * estimates.tokensPerTask > budget.maxTokens
231
+ ) {
232
+ problems.push("token-budget-exceeded");
233
+ }
234
+ if (
235
+ taskCalls != null &&
236
+ estimates.usdPerTask != null &&
237
+ budget.maxUsd != null &&
238
+ taskCalls * estimates.usdPerTask > budget.maxUsd
239
+ ) {
240
+ problems.push("usd-budget-exceeded");
241
+ }
242
+ const durationSlots = manifest.plan.steps.reduce(
243
+ (total, step) => total + (step.worstCaseDurationSlots ?? 0),
244
+ 0,
245
+ );
246
+ if (
247
+ estimates.durationMsPerTask != null &&
248
+ budget.maxDurationMs != null &&
249
+ durationSlots * estimates.durationMsPerTask > budget.maxDurationMs
250
+ ) {
251
+ problems.push("duration-budget-exceeded");
252
+ }
253
+ if (problems.length > 0) {
254
+ throw new TypeError(
255
+ `generated workflow is not reviewable: ${problems.join(", ")}`,
256
+ );
257
+ }
258
+ }
259
+
260
+ function generationPrompt(prompt) {
261
+ return [
262
+ "Return exactly one JSON object and no prose.",
263
+ "Create a cc dynamic workflow definition with id, name, non-empty steps, and facade.",
264
+ "Each step needs id and message; use dependsOn for the DAG.",
265
+ "facade.requirements must exactly declare the capabilities used by the plan, one or more executionLocations, explicit permissions, sandbox, dataBoundary, and credential references containing only name/source/scope.",
266
+ "facade.estimates must declare positive tokensPerTask, usdPerTask, and durationMsPerTask.",
267
+ "facade.budget must declare maxExpandedTasks (at most 64), maxParallel (at most maxExpandedTasks), maxTokens, maxUsd, and maxDurationMs covering the projected plan.",
268
+ "Do not include credentials, secrets, generation metadata, review metadata, or unsupported capabilities.",
269
+ "Requested workflow:",
270
+ prompt,
271
+ ].join("\n");
272
+ }
273
+
274
+ function draftMaterial(value) {
275
+ const material = { ...value };
276
+ delete material.draftDigest;
277
+ return material;
278
+ }
279
+
280
+ export async function generateDynamicWorkflowDraft(input = {}, deps = {}) {
281
+ const prompt = typeof input.prompt === "string" ? input.prompt.trim() : "";
282
+ const promptBytes = Buffer.byteLength(prompt, "utf8");
283
+ if (promptBytes <= 0 || promptBytes > MAX_DYNAMIC_WORKFLOW_PROMPT_BYTES) {
284
+ throw new TypeError(
285
+ `workflow prompt must be 1..${MAX_DYNAMIC_WORKFLOW_PROMPT_BYTES} bytes`,
286
+ );
287
+ }
288
+ const provider = boundedString(input.provider, "provider", 128);
289
+ const model = boundedString(input.model, "model", 256);
290
+ if (typeof deps.chat !== "function") {
291
+ throw new TypeError("workflow draft chat provider is required");
292
+ }
293
+ const createdAt = canonicalTimestamp(deps.now, "createdAt");
294
+ const promptDigest = digest(
295
+ "chainlesschain.dynamic-workflow.prompt.v1\0",
296
+ prompt,
297
+ );
298
+ const response = await deps.chat(
299
+ [
300
+ {
301
+ role: "system",
302
+ content:
303
+ "You generate bounded workflow JSON for explicit human review. You never execute or persist it.",
304
+ },
305
+ { role: "user", content: generationPrompt(prompt) },
306
+ ],
307
+ { maxTokens: 8192 },
308
+ );
309
+ const proposed = parseGeneratedDefinition(response);
310
+ const definition = {
311
+ ...proposed,
312
+ facade: {
313
+ ...(proposed.facade || {}),
314
+ generation: {
315
+ schema: DYNAMIC_WORKFLOW_GENERATION_SCHEMA,
316
+ promptDigest,
317
+ provider,
318
+ model,
319
+ generatedAt: createdAt,
320
+ },
321
+ },
322
+ };
323
+ const manifest = createDynamicWorkflowManifest(definition);
324
+ assertReviewableManifest(manifest);
325
+ const material = Object.freeze({
326
+ schema: DYNAMIC_WORKFLOW_DRAFT_SCHEMA,
327
+ status: "pending-review",
328
+ promptDigest,
329
+ generator: Object.freeze({ provider, model }),
330
+ createdAt,
331
+ definitionSchema: WORKFLOW_DEFINITION_SCHEMA,
332
+ definitionDigest: manifest.definitionDigest,
333
+ definition: manifest.definition,
334
+ projection: projectionFromManifest(manifest),
335
+ });
336
+ return Object.freeze({
337
+ ...material,
338
+ draftDigest: digest("chainlesschain.dynamic-workflow.draft.v1\0", material),
339
+ });
340
+ }
341
+
342
+ export function verifyDynamicWorkflowDraft(value) {
343
+ assertExactObject(value, DRAFT_FIELDS, "workflow draft");
344
+ assertExactObject(
345
+ value.generator,
346
+ GENERATOR_FIELDS,
347
+ "workflow draft generator",
348
+ );
349
+ assertExactObject(
350
+ value.projection,
351
+ PROJECTION_FIELDS,
352
+ "workflow draft projection",
353
+ );
354
+ const snapshot = snapshotJson(value, "workflow draft");
355
+ if (
356
+ snapshot.schema !== DYNAMIC_WORKFLOW_DRAFT_SCHEMA ||
357
+ snapshot.status !== "pending-review" ||
358
+ !SHA256_RE.test(snapshot.promptDigest) ||
359
+ !SHA256_RE.test(snapshot.definitionDigest) ||
360
+ !SHA256_RE.test(snapshot.draftDigest) ||
361
+ snapshot.definitionSchema !== WORKFLOW_DEFINITION_SCHEMA ||
362
+ canonicalTimestamp(snapshot.createdAt, "createdAt") !== snapshot.createdAt
363
+ ) {
364
+ throw new TypeError("workflow draft identity is invalid");
365
+ }
366
+ const provider = boundedString(snapshot.generator.provider, "provider", 128);
367
+ const model = boundedString(snapshot.generator.model, "model", 256);
368
+ const generation = snapshot.definition?.facade?.generation;
369
+ if (
370
+ generation?.schema !== DYNAMIC_WORKFLOW_GENERATION_SCHEMA ||
371
+ generation.promptDigest !== snapshot.promptDigest ||
372
+ generation.provider !== provider ||
373
+ generation.model !== model ||
374
+ generation.generatedAt !== snapshot.createdAt ||
375
+ snapshot.definition?.facade?.review != null
376
+ ) {
377
+ throw new TypeError("workflow draft generation authority is invalid");
378
+ }
379
+ if (containsSecret(JSON.stringify(snapshot.definition))) {
380
+ throw new TypeError("workflow draft contains secret-shaped data");
381
+ }
382
+ const manifest = createDynamicWorkflowManifest(snapshot.definition);
383
+ assertReviewableManifest(manifest);
384
+ if (
385
+ manifest.definitionDigest !== snapshot.definitionDigest ||
386
+ canonicalJson(projectionFromManifest(manifest)) !==
387
+ canonicalJson(snapshot.projection)
388
+ ) {
389
+ throw new TypeError(
390
+ "workflow draft projection does not match its definition",
391
+ );
392
+ }
393
+ const expectedDigest = digest(
394
+ "chainlesschain.dynamic-workflow.draft.v1\0",
395
+ draftMaterial(snapshot),
396
+ );
397
+ if (expectedDigest !== snapshot.draftDigest) {
398
+ throw new TypeError("workflow draft digest mismatch");
399
+ }
400
+ return Object.freeze(snapshot);
401
+ }
402
+
403
+ export function reviewDynamicWorkflowDraft(input = {}, deps = {}) {
404
+ const draft = verifyDynamicWorkflowDraft(input.draft);
405
+ const expectedDraftDigest = String(input.expectedDraftDigest || "")
406
+ .trim()
407
+ .toLowerCase();
408
+ if (!SHA256_RE.test(expectedDraftDigest)) {
409
+ throw new TypeError("expected draft digest is required");
410
+ }
411
+ if (expectedDraftDigest !== draft.draftDigest) {
412
+ throw new TypeError("workflow draft changed before review");
413
+ }
414
+ if (!new Set(["accept", "reject"]).has(input.decision)) {
415
+ throw new TypeError("workflow review decision must be accept or reject");
416
+ }
417
+ const reviewer = boundedString(input.reviewer, "reviewer", 256);
418
+ const reason =
419
+ input.reason == null
420
+ ? null
421
+ : boundedString(input.reason, "review reason", 2048);
422
+ if (reason && containsSecret(reason)) {
423
+ throw new TypeError("workflow review reason contains secret-shaped data");
424
+ }
425
+ const reviewedAt = canonicalTimestamp(deps.now, "reviewedAt");
426
+ let definition = null;
427
+ let acceptedDefinitionDigest = null;
428
+ if (input.decision === "accept") {
429
+ const reviewedDefinition = {
430
+ ...draft.definition,
431
+ facade: {
432
+ ...draft.definition.facade,
433
+ review: {
434
+ schema: DYNAMIC_WORKFLOW_REVIEW_SCHEMA,
435
+ decision: "accepted",
436
+ draftDigest: draft.draftDigest,
437
+ sourceDefinitionDigest: draft.definitionDigest,
438
+ reviewer,
439
+ reason,
440
+ reviewedAt,
441
+ },
442
+ },
443
+ };
444
+ const manifest = createDynamicWorkflowManifest(reviewedDefinition);
445
+ assertReviewableManifest(manifest);
446
+ definition = manifest.definition;
447
+ acceptedDefinitionDigest = manifest.definitionDigest;
448
+ }
449
+ const material = Object.freeze({
450
+ schema: DYNAMIC_WORKFLOW_REVIEW_SCHEMA,
451
+ status: input.decision === "accept" ? "accepted" : "rejected",
452
+ draftDigest: draft.draftDigest,
453
+ promptDigest: draft.promptDigest,
454
+ sourceDefinitionDigest: draft.definitionDigest,
455
+ acceptedDefinitionDigest,
456
+ reviewer,
457
+ reason,
458
+ reviewedAt,
459
+ definition,
460
+ });
461
+ return Object.freeze({
462
+ ...material,
463
+ reviewDigest: digest(
464
+ "chainlesschain.dynamic-workflow.review.v1\0",
465
+ material,
466
+ ),
467
+ });
468
+ }
469
+
470
+ function parseDraftFile(raw) {
471
+ const text =
472
+ typeof raw === "string" ? raw : Buffer.from(raw).toString("utf8");
473
+ const bytes = Buffer.byteLength(text, "utf8");
474
+ if (bytes <= 0 || bytes > MAX_DYNAMIC_WORKFLOW_DRAFT_BYTES) {
475
+ throw new TypeError(
476
+ `workflow draft file must be 1..${MAX_DYNAMIC_WORKFLOW_DRAFT_BYTES} bytes`,
477
+ );
478
+ }
479
+ let value;
480
+ try {
481
+ value = JSON.parse(text);
482
+ } catch {
483
+ throw new TypeError("workflow draft file is not valid JSON");
484
+ }
485
+ return verifyDynamicWorkflowDraft(value);
486
+ }
487
+
488
+ export function readDynamicWorkflowDraftFile(filePath, deps = {}) {
489
+ const runtimeFs = deps.fs || fs;
490
+ const resolved = path.resolve(filePath);
491
+ return withTrustedFileParentSync(
492
+ runtimeFs,
493
+ resolved,
494
+ ({ canonicalPath, parentDevice }) => {
495
+ const before = runtimeFs.lstatSync(canonicalPath, { bigint: true });
496
+ if (
497
+ !before.isFile() ||
498
+ before.isSymbolicLink() ||
499
+ Number(before.nlink) !== 1 ||
500
+ Number(before.size) <= 0 ||
501
+ Number(before.size) > MAX_DYNAMIC_WORKFLOW_DRAFT_BYTES
502
+ ) {
503
+ throw new TypeError(
504
+ "workflow draft must be a bounded, regular, single-link file",
505
+ );
506
+ }
507
+ let descriptor;
508
+ try {
509
+ let flags = Number(runtimeFs.constants.O_RDONLY || 0);
510
+ if (typeof runtimeFs.constants.O_NOFOLLOW === "number") {
511
+ flags |= runtimeFs.constants.O_NOFOLLOW;
512
+ }
513
+ descriptor = runtimeFs.openSync(canonicalPath, flags);
514
+ const opened = runtimeFs.fstatSync(descriptor, { bigint: true });
515
+ if (
516
+ !opened.isFile() ||
517
+ Number(opened.nlink) !== 1 ||
518
+ !samePathHandleFileIdentity(before, opened, parentDevice)
519
+ ) {
520
+ throw new TypeError("workflow draft identity changed while opening");
521
+ }
522
+ const draft = parseDraftFile(
523
+ runtimeFs.readFileSync(descriptor, "utf8"),
524
+ );
525
+ const after = runtimeFs.fstatSync(descriptor, { bigint: true });
526
+ if (!sameFileStatIdentity(opened, after)) {
527
+ throw new TypeError("workflow draft changed while being read");
528
+ }
529
+ return draft;
530
+ } finally {
531
+ if (descriptor !== undefined) runtimeFs.closeSync(descriptor);
532
+ }
533
+ },
534
+ );
535
+ }
@@ -787,11 +787,14 @@ export function normalizeSessionExecutionLocationAuthority(value) {
787
787
  `executionLocationAuthority must use ${SESSION_EXECUTION_LOCATION_AUTHORITY_SCHEMA}`,
788
788
  );
789
789
  }
790
- const verified = authority.authority === "verified-session-start";
790
+ const verified = new Set([
791
+ "verified-session-start",
792
+ "verified-session-location-handoff",
793
+ ]).has(authority.authority);
791
794
  if (!verified) {
792
795
  throw admissionError(
793
796
  code,
794
- "executionLocationAuthority must be a verified session start",
797
+ "executionLocationAuthority must be a verified session location authority",
795
798
  );
796
799
  }
797
800
  let binding;
@@ -835,7 +838,7 @@ export function normalizeSessionExecutionLocationAuthority(value) {
835
838
  }
836
839
  return Object.freeze({
837
840
  schema: SESSION_EXECUTION_LOCATION_AUTHORITY_SCHEMA,
838
- authority: "verified-session-start",
841
+ authority: authority.authority,
839
842
  sessionId,
840
843
  headHash: authority.headHash,
841
844
  eventCount: authority.eventCount,
@@ -1143,14 +1146,11 @@ function prepareDynamicWorkflowRun(runInput, verifiedAuthorities, execution) {
1143
1146
  executionLocation: Object.freeze({
1144
1147
  authoritySchema: executionLocationAuthority.schema,
1145
1148
  authority: executionLocationAuthority.authority,
1146
- session:
1147
- executionLocationAuthority.authority === "verified-session-start"
1148
- ? Object.freeze({
1149
- sessionId: executionLocationAuthority.sessionId,
1150
- headHash: executionLocationAuthority.headHash,
1151
- eventCount: executionLocationAuthority.eventCount,
1152
- })
1153
- : null,
1149
+ session: Object.freeze({
1150
+ sessionId: executionLocationAuthority.sessionId,
1151
+ headHash: executionLocationAuthority.headHash,
1152
+ eventCount: executionLocationAuthority.eventCount,
1153
+ }),
1154
1154
  bindingSchema: executionLocationAuthority.binding.schema,
1155
1155
  location: executionLocationAuthority.binding.location,
1156
1156
  }),