chainlesschain 0.166.6 → 0.166.9

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 (214) hide show
  1. package/README.md +21 -0
  2. package/package.json +5 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-CVnFjTfG.js → AIOps-DJvpifGx.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-BxkwuuQC.js → ActionButton-D2UhuF_A.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-C2670q6z.js → Analytics-C9ho9obu.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CU_rylW6.js → AppLayout-BvRCpFK3.js} +3 -3
  8. package/src/assets/web-panel/assets/{Artifacts-DGJmYqnj.js → Artifacts-jxrySvpk.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-BZOQbINJ.js → Audit-ovEw0ZYl.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-DghB4QwF.js → BackgroundAgents-D7H5z6zS.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-l0mwPbta.js → Backup-BuXob8za.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-Bv3WSZOh.js → BaseInput-CtnszuQ2.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-s88nBdvt.js → Chat-B_mYE8fJ.js} +6 -6
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Z8CBuB1a.js → ChatBubbleRenderer-DaiA6CsX.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-B5icasEs.js → Checkbox-ierdtcJD.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-CsUFqNud.js → Codegen-3VKPJD_B.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-DlBtClaW.js → Col-1EdMyf5P.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-xRn1IdLB.js → Community-D6H7UA8K.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-naIr8a_o.js → Compact-BBAZvYIm.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-Dp9esfFE.js → Compliance-CgsTrAoj.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-DQlMYJB-.js → Cowork-tnZgLoTE.js} +4 -4
  22. package/src/assets/web-panel/assets/{Cron-Cd0oNLzJ.js → Cron-CPpZw2Nh.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-BtDIx3XX.js → Crosschain-BymBcp5z.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-BOlpzEwg.js → DID-DKPxS_K1.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-DV15Axk1.js → Dashboard-DvJhEmH9.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-COXrewN1.js → Dropdown-b8iQyQIZ.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-EjIt0Cm7.js → EmailListRenderer--0-A-zKb.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DJlhwb-R.js → FamilyGuardDashboard-C12iDN06.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-BMiFl82k.js → Federation-BRhaE2Z8.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-BUcDQyxn.js → FormItemContext-C4dnq7yf.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-C25uFxvK.js → GenericCardRenderer-CGAdbR5n.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-D20uaEUU.js → Git-4eA2fYzL.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-CQxYJjCX.js → Governance-BJuY9Y-9.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-m-sczpS5.js → Inference-DZ5Dy4up.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-CBsIlU0S.js → KnowledgeGraph-BMTjRs4A.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-D0-5bqeu.js → Logs-BKEeQEfJ.js} +2 -2
  37. package/src/assets/web-panel/assets/MarkdownRenderer-B05DgASC.js +1 -0
  38. package/src/assets/web-panel/assets/{Marketplace-CwDGFu2Q.js → Marketplace-Dhho4fEg.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-7FxJ3omT.js → McpTools-BW6xxSlU.js} +2 -2
  40. package/src/assets/web-panel/assets/{Memory-DOVyb59U.js → Memory-mPqlpSkq.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-DZXl-Hje.js → MobileBridge-Cb9N_DQI.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-DlZ8tRXt.js → MobileProjects-BNs8tah_.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-D7Pjx1s_.js → Mtc-CaxBt8tn.js} +5 -5
  44. package/src/assets/web-panel/assets/{MtcAudit-BND7lX8p.js → MtcAudit-DRPQbp3t.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-BknS7B-p.js → Multisig-CRm-d8bK.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-7C2-KPHt.js → NLProgramming-BCCk3LPs.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-DNWdTndN.js → Notes-Cv8SN8gN.js} +4 -4
  48. package/src/assets/web-panel/assets/{NotificationSettings-DCm4KcJZ.js → NotificationSettings-CggIvTh5.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-DyVwwjJx.js → OrderTableRenderer-BW3_bV12.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-Dl2O_qJ9.js → Organization-BuRE-VCO.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-BOFCvk9Q.js → Overflow-DBrm1gju.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-DgdVowY1.js → P2P-CWVnDYgS.js} +2 -2
  53. package/src/assets/web-panel/assets/PdhVaultBrowser-8RKUIpte.js +7 -0
  54. package/src/assets/web-panel/assets/{Permissions-BHNEUUwa.js → Permissions-tDUAxogW.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-CaZbrOdz.js → PersonalDataHub-Dv2-CFis.js} +4 -4
  56. package/src/assets/web-panel/assets/{Pipeline-DJDnoXmE.js → Pipeline-DM6kvFni.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-CBQr2eX8.js → Privacy-DzK-yL0d.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-Yghqa06z.js → ProjectInit-B5UrNpkj.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-HBAtJi8U.js → ProjectSettings-CxJD43oW.js} +2 -2
  60. package/src/assets/web-panel/assets/Projects-Z2Orm8Ma.js +1 -0
  61. package/src/assets/web-panel/assets/{Providers-uJTz77GI.js → Providers-CYl4jRYK.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-k3M5ouTp.js → QrScannerModal-DeH2T0fH.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-CMji45PH.js → QuickAsk-Bw9k_kTk.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-DyoZYPls.js → Recommend-Bl_jGwoi.js} +1 -1
  65. package/src/assets/web-panel/assets/RemoteSession-d6u01Kq0.js +5 -0
  66. package/src/assets/web-panel/assets/{Reputation-D4hIs4vV.js → Reputation-Ds_Dfr-k.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-mzE-ElTg.js → Row-BpQUQTNj.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-cg7J3hI6.js → RssFeed-BatpZBGt.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-6M0TkGSZ.js → Search-D7hOObzi.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-B1GQ67qh.js → Security-dXQ4FKNt.js} +4 -4
  71. package/src/assets/web-panel/assets/{Services-D_RwU_5S.js → Services-D8wInGPa.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-TZjk-dsW.js → Skeleton-DXQCoYpM.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-CG6FcaCV.js → Skills-D3oLRIVn.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-BI190QDv.js → Sla-BmP4-LnJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-BWmxF2Wu.js → SpeechSettings-DLj-xzro.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-CwPiGw6L.js → SyncSettings-8KKaaRMr.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-BIXgCeSk.js → Tasks-GyK42I7C.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-CQFgGCoK.js → Templates-n1y_8UBG.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-DAelEdkL.js → Tenant-B39nBph8.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-BbqWK6qh.js → Terminal-DCQoOKXe.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-cmG3zvY5.js → TimelineRenderer-BkhbDfXk.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-C8444NKU.js → Tokens-BeHIIU8D.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-C1Rpnz0I.js → Trigger-BHvWXVOb.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-u4koPiFD.js → Trust-y2WaOSto.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-oPWKn80Z.js → UkeySign-DBFeJBzt.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-D0CUUY_5.js → VideoEditing-BEOWitC-.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-fu9pIAbt.js → Wallet-BITedTe6.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-Bc5ciuOx.js → WebAuthn-DMwlJVin.js} +2 -2
  89. package/src/assets/web-panel/assets/{WorkflowEditor-BCin4_4N.js → WorkflowEditor-CKfGFEu1.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-B2jbM-XN.js → chat-DR6gnBGF.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-CUVoUQ_2.js → colors-C_Hw5NCn.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-DgOGpkRH.js → compact-item-B8IPwsEu.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-DIxU6eKI.js → createContext-D-u4JVnJ.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-Cq6lSd_q.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-DoKRKMav.js → hasIn-CZubdS4D.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-ByjrulIZ.js → index-11ASqx-A.js} +1 -1
  97. package/src/assets/web-panel/assets/index-BQ3213fz.js +1 -0
  98. package/src/assets/web-panel/assets/{index-BwYofQJg.js → index-BXS6wYJZ.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CLdpHe6w.js → index-Bi21Etg4.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-2flsPFIX.js → index-Bizm87cX.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BXb-Smmm.js → index-Bv2132PO.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-B5ySiGYy.js → index-BzoFanEQ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CWbL1-N0.js → index-C25rOz7O.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Cj-us-D_.js → index-C2VmtNaQ.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C9TsO9T9.js → index-Cbm8F0M2.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-eTWPaeBI.js → index-CfniPP5p.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-D2yo6ast.js → index-Cg2bCeol.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CPXdBnGi.js → index-CiXkhOkY.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BCLeNqIL.js → index-Cl5RpreD.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BtSPhEyC.js → index-CqmLw8cs.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-eYxUASSG.js → index-Ctje8Vl3.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-i5MB455u.js → index-D1w96gg9.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CpvyOt5Z.js → index-D47jt8ET.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CeWSw-z5.js → index-DJ6pG79m.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-B3F_p8NA.js → index-DTosx2Wu.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B9mSYovv.js → index-DY6MHo9D.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DJMHnbmu.js → index-DcFjRT-K.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-D-ufbAJB.js → index-DfnzrUxU.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BFUprhNd.js → index-DjRrqooR.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Co4lDEk-.js → index-DmRcgiYT.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DGTZdZOE.js → index-DpjHpRoq.js} +3 -3
  122. package/src/assets/web-panel/assets/{index-DHugFl3v.js → index-Dt-w3xQ7.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-B-f6l4Vm.js → index-DuOU5apg.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DtyAuGOm.js → index-LvjAKDSl.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-be8SonCh.js → index-_nL79NT8.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BRMEO2Tl.js → index-auyNYjLo.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-C88m9lsi.js → index-cVqbas5C.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CqlwIjJx.js → index-ffe7bvqP.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DpTFx8Xx.js → index-idZKyADQ.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Cskz--fd.js → index-k1Xa5iw1.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CF80xxPG.js → index-mYZJxGH6.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Ds8r3Fzb.js → index-rYBHSDcJ.js} +1 -1
  133. package/src/assets/web-panel/assets/index-vJagfET2.js +1 -0
  134. package/src/assets/web-panel/assets/{index-C846lPGD.js → index-xoNssgz_.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-B4chl7iR.js → initDefaultProps-lcU_dT2r.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-DruN9h96.js → motion-Dc7UNXZ1.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-Cl0UtCgU.js → move-Cll8ZXaL.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-FX2ttw70.js → mtc-parser-CAb_yLIM.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-BDCneY46.js → omit-DurYMyTe.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-DycsEg8b.js → pickAttrs-BITQyOlw.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-Bc-dBuMv.js → placementArrow-Dg1rH91i.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve--Wwaf8lu.js → responsiveObserve-D_EWIeac.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-vDmHQqHH.js → slide-lK4d3zsh.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-9c52yv3G.js → statusUtils-Bflq-Git.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-BT4BiO6_.js → styleChecker-Ccp0I-wt.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-C7XxWPcP.js → useFlexGapSupport-CYZbByYA.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-BHoMqh4i.js → useFs-B_x0nxFD.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-BOLxvsAG.js → usePersonalDataHub-DW55rL85.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-CA7poeeP.js → vnode-Ca6MH3W8.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-B_sAn-co.js → zoom-NdHelOog.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +1 -1
  153. package/src/commands/graph.js +215 -5
  154. package/src/commands/orchestrate.js +61 -9
  155. package/src/commands/team-distributed.js +342 -2
  156. package/src/commands/team.js +169 -7
  157. package/src/data/changelog.json +46 -0
  158. package/src/gateways/ws/message-dispatcher.js +4 -0
  159. package/src/gateways/ws/session-protocol.js +89 -11
  160. package/src/gateways/ws/ws-agent-handler.js +65 -9
  161. package/src/gateways/ws/ws-approval-gate.js +181 -16
  162. package/src/gateways/ws/ws-server.js +16 -6
  163. package/src/generated/cc-agent-protocol.schema.json +154 -3
  164. package/src/lib/agent-team/task-lease.js +487 -3
  165. package/src/lib/agent-team/team-agent-stream.js +16 -0
  166. package/src/lib/agent-team/team-distributed-graph-bridge.js +257 -0
  167. package/src/lib/agent-team/team-distributed-graph-writer.js +523 -0
  168. package/src/lib/agent-team/team-distributed-queue.js +251 -0
  169. package/src/lib/agent-team/team-graph-runtime-adapter.js +1918 -0
  170. package/src/lib/agent-team/team-runner.js +285 -3
  171. package/src/lib/app-server/graph-runtime.js +1078 -0
  172. package/src/lib/app-server/rollout-store.js +32 -0
  173. package/src/lib/app-server/server.js +200 -0
  174. package/src/lib/approval-grant-ledger.js +69 -0
  175. package/src/lib/autonomous-agent.js +11 -0
  176. package/src/lib/codex-app-server-adapter.js +11 -20
  177. package/src/lib/cowork-graph-authority-adapter.js +455 -0
  178. package/src/lib/dynamic-workflow-facade.js +83 -16
  179. package/src/lib/graph-kernel/adapters.js +93 -20
  180. package/src/lib/graph-kernel/authority.js +324 -0
  181. package/src/lib/graph-kernel/compiler.js +67 -21
  182. package/src/lib/graph-kernel/cutover-authority-resolver.js +245 -0
  183. package/src/lib/graph-kernel/cutover-ledger.js +692 -0
  184. package/src/lib/graph-kernel/event-store.js +15 -1
  185. package/src/lib/graph-kernel/graph-runtime-surfaces.json +1427 -0
  186. package/src/lib/graph-kernel/index.js +4 -0
  187. package/src/lib/graph-kernel/migration-saga.js +309 -0
  188. package/src/lib/graph-kernel/retirement-evidence.js +567 -0
  189. package/src/lib/graph-kernel/runtime-surface-manifest.js +481 -0
  190. package/src/lib/graph-kernel/runtime.js +737 -38
  191. package/src/lib/graph-kernel/store-cutover-evidence.js +354 -0
  192. package/src/lib/graph-kernel/trace-reducer.js +6 -0
  193. package/src/lib/graph-kernel/trigger-adapter.js +60 -3
  194. package/src/lib/interaction-adapter.js +61 -9
  195. package/src/lib/legacy-runtime-authority.js +160 -0
  196. package/src/lib/orchestrator.js +28 -0
  197. package/src/lib/policy-decision-event.js +149 -0
  198. package/src/lib/process-execution-broker/platform-sandbox.js +15 -1
  199. package/src/lib/record-replay/index.js +1 -0
  200. package/src/lib/record-replay/playwright-ui-driver.js +327 -0
  201. package/src/lib/scheduler-kernel/graph-authority-adapter.js +512 -0
  202. package/src/lib/scheduler-kernel/runtime.js +75 -2
  203. package/src/lib/webhook-security.js +484 -36
  204. package/src/runtime/coding-agent-events.cjs +13 -11
  205. package/src/runtime/headless-runner.js +17 -1
  206. package/src/runtime/headless-stream.js +66 -3
  207. package/src/runtime/session-slash-commands.js +57 -6
  208. package/src/assets/web-panel/assets/MarkdownRenderer-BwH414Ms.js +0 -1
  209. package/src/assets/web-panel/assets/PdhVaultBrowser-BiaZfQIM.js +0 -7
  210. package/src/assets/web-panel/assets/Projects-DiCGnMjz.js +0 -1
  211. package/src/assets/web-panel/assets/RemoteSession-s1gR38IO.js +0 -5
  212. package/src/assets/web-panel/assets/devWarning-DiSlgCC4.js +0 -1
  213. package/src/assets/web-panel/assets/index-9WIQEHvv.js +0 -1
  214. package/src/assets/web-panel/assets/index-B7mDobAl.js +0 -1
@@ -17,7 +17,7 @@
17
17
 
18
18
  import fs from "fs";
19
19
  import path from "path";
20
- import { randomUUID } from "node:crypto";
20
+ import { createHash, randomUUID } from "node:crypto";
21
21
  import { fileURLToPath } from "url";
22
22
  import { TaskLeaseRegistry } from "../lib/agent-team/task-lease.js";
23
23
  import { TeamRunner } from "../lib/agent-team/team-runner.js";
@@ -32,6 +32,8 @@ import {
32
32
  computeTeamGraphRevisionDigest,
33
33
  projectTeamGraphCollaboration,
34
34
  } from "../lib/agent-team/team-graph-projection.js";
35
+ import { TeamGraphRuntimeAdapter } from "../lib/agent-team/team-graph-runtime-adapter.js";
36
+ import { createRuntimeGraphCutoverAuthorityResolver } from "../lib/graph-kernel/cutover-authority-resolver.js";
35
37
  import { resolveTeamTaskContract } from "../lib/agent-team/team-task-contract.js";
36
38
  import {
37
39
  TeamScopeLock,
@@ -326,6 +328,41 @@ function teamExecutionMode(options) {
326
328
  return "dry-run";
327
329
  }
328
330
 
331
+ export function teamGraphAuthorityMode(
332
+ options,
333
+ env = process.env,
334
+ { runKey = undefined, optIn = false, resolver = undefined } = {},
335
+ ) {
336
+ const executionMode = teamExecutionMode(options);
337
+ const configured = String(env.CHAINLESSCHAIN_GRAPH_CLI_TEAM || "")
338
+ .trim()
339
+ .toLowerCase();
340
+ if (configured && !["legacy", "shadow", "canonical"].includes(configured)) {
341
+ throw new Error(
342
+ "CHAINLESSCHAIN_GRAPH_CLI_TEAM must be legacy, shadow, or canonical",
343
+ );
344
+ }
345
+ const fallbackMode =
346
+ executionMode === "dry-run" ? "shadow" : configured || "legacy";
347
+ const authorityResolver =
348
+ resolver ||
349
+ createRuntimeGraphCutoverAuthorityResolver({
350
+ env,
351
+ surface: "cli_team",
352
+ entryId: "cli-team-local",
353
+ fallbackMode,
354
+ });
355
+ const resolved =
356
+ typeof authorityResolver === "function"
357
+ ? authorityResolver({ runKey, optIn })
358
+ : authorityResolver.resolve({ runKey, optIn, fallbackMode });
359
+ const mode = typeof resolved === "string" ? resolved : resolved?.mode;
360
+ if (!["legacy", "shadow", "canonical"].includes(mode)) {
361
+ throw new Error("Team Graph authority resolver returned an invalid mode");
362
+ }
363
+ return mode;
364
+ }
365
+
329
366
  function optionWasProvided(command, name) {
330
367
  const source = command?.getOptionValueSource?.(name);
331
368
  return source != null && source !== "default";
@@ -1008,8 +1045,23 @@ export function makeShellRunTask() {
1008
1045
  settle(terminationError);
1009
1046
  return;
1010
1047
  }
1011
- if (code === 0) settle(null, { code });
1012
- else {
1048
+ if (code === 0) {
1049
+ settle(null, {
1050
+ code,
1051
+ terminalEvidence: {
1052
+ outputDigest: `sha256:${createHash("sha256")
1053
+ .update(
1054
+ JSON.stringify({
1055
+ command,
1056
+ cwd: process.cwd(),
1057
+ exitCode: code,
1058
+ }),
1059
+ "utf8",
1060
+ )
1061
+ .digest("hex")}`,
1062
+ },
1063
+ });
1064
+ } else {
1013
1065
  const stderr = Buffer.concat(stderrChunks).toString("utf8");
1014
1066
  settle(new Error(safeProcessError(stderr, `command exited ${code}`)));
1015
1067
  }
@@ -1310,6 +1362,7 @@ function spawnAgentProcess(prompt, cwd, opts = {}) {
1310
1362
  return;
1311
1363
  }
1312
1364
  const result = { code };
1365
+ result.terminalEvidence = parser.terminalEvidence();
1313
1366
  if (sawStdout || summary.usage || summary.provider || summary.model) {
1314
1367
  if (summary.usage) result.usage = summary.usage;
1315
1368
  if (summary.provider) result.provider = summary.provider;
@@ -1994,6 +2047,10 @@ export function registerTeamCommand(program, { logger } = {}) {
1994
2047
  "--resume",
1995
2048
  "Restore progress from --state (completed tasks stay done; stale leases freed)",
1996
2049
  )
2050
+ .option(
2051
+ "--graph-canary-opt-in",
2052
+ "Opt this new Team run into an entry-scoped Graph canary",
2053
+ )
1997
2054
  .option("--json", "Emit the event stream as JSON lines")
1998
2055
  .option(
1999
2056
  "--otlp <file>",
@@ -2642,6 +2699,42 @@ export function registerTeamCommand(program, { logger } = {}) {
2642
2699
  (_, index) => `teammate-${index + 1}`,
2643
2700
  ),
2644
2701
  });
2702
+ const graphAuthorityMode =
2703
+ resumeSnapshot?.graphProjection?.authorityMode ||
2704
+ teamGraphAuthorityMode(options, process.env, {
2705
+ runKey: teamGraphRunId,
2706
+ optIn: options.graphCanaryOptIn === true,
2707
+ });
2708
+ let graphRuntime = null;
2709
+ const shadowDivergences = [];
2710
+ const recordShadowDivergence = (divergence) => {
2711
+ shadowDivergences.push(divergence);
2712
+ while (shadowDivergences.length > 256) shadowDivergences.shift();
2713
+ };
2714
+ if (["shadow", "canonical"].includes(graphAuthorityMode)) {
2715
+ graphRuntime = new TeamGraphRuntimeAdapter();
2716
+ graphRuntime.open({
2717
+ registry: reg,
2718
+ runId: teamGraphRunId,
2719
+ executionMode: executionContract.mode,
2720
+ worktree: options.worktree === true,
2721
+ teammates,
2722
+ budget: limits,
2723
+ authorityMode: graphAuthorityMode,
2724
+ dynamic: true,
2725
+ });
2726
+ if (graphAuthorityMode === "canonical") {
2727
+ reg = graphRuntime.bindRegistry(reg);
2728
+ mailbox = graphRuntime.bindMailbox(mailbox);
2729
+ } else {
2730
+ reg = graphRuntime.bindRegistry(reg, {
2731
+ onDivergence: recordShadowDivergence,
2732
+ });
2733
+ mailbox = graphRuntime.bindMailbox(mailbox, {
2734
+ onDivergence: recordShadowDivergence,
2735
+ });
2736
+ }
2737
+ }
2645
2738
  const settleGovernance = (key, status, extra = {}) => {
2646
2739
  const governanceKey = sessionTaskKeyFor(key);
2647
2740
  const unit = collaborationUnits.get(governanceKey);
@@ -2704,6 +2797,9 @@ export function registerTeamCommand(program, { logger } = {}) {
2704
2797
  revisionDigest: teamGraphRevisionDigest,
2705
2798
  authorityDigest: teamGraphAuthorityDigest,
2706
2799
  }),
2800
+ graphAuthorityMode,
2801
+ graphAuthority: graphRuntime?.status() || null,
2802
+ graphShadowDivergences: [...shadowDivergences],
2707
2803
  });
2708
2804
  };
2709
2805
 
@@ -2956,13 +3052,34 @@ export function registerTeamCommand(program, { logger } = {}) {
2956
3052
  realtimeMessaging: options.agent === true,
2957
3053
  scopeLock,
2958
3054
  recorder,
2959
- beforeTask: ({ key }) => {
2960
- settleGovernance(key, "running", {
2961
- startedAt: Date.now(),
2962
- });
3055
+ beforeTask: (context) => {
3056
+ const { key } = context;
3057
+ if (graphAuthorityMode === "canonical") {
3058
+ graphRuntime?.beforeTask(context);
3059
+ } else if (graphAuthorityMode === "shadow") {
3060
+ try {
3061
+ graphRuntime?.beforeTask(context);
3062
+ } catch (error) {
3063
+ recordShadowDivergence({
3064
+ phase: "assignment",
3065
+ key,
3066
+ code: error?.code || "CC_TEAM_GRAPH_SHADOW_DIVERGED",
3067
+ error: error?.message || String(error),
3068
+ });
3069
+ }
3070
+ }
2963
3071
  try {
3072
+ settleGovernance(key, "running", {
3073
+ startedAt: Date.now(),
3074
+ });
2964
3075
  persist();
2965
3076
  } catch (error) {
3077
+ try {
3078
+ graphRuntime?.abandonTask(key, error);
3079
+ } catch (canonicalError) {
3080
+ canonicalError.cause ||= error;
3081
+ throw canonicalError;
3082
+ }
2966
3083
  try {
2967
3084
  settleGovernance(key, "pending", {
2968
3085
  startedAt: null,
@@ -2973,6 +3090,38 @@ export function registerTeamCommand(program, { logger } = {}) {
2973
3090
  throw error;
2974
3091
  }
2975
3092
  },
3093
+ canonicalSettlement:
3094
+ graphAuthorityMode === "canonical" && graphRuntime
3095
+ ? (settlement) => graphRuntime.settleTask(settlement)
3096
+ : null,
3097
+ canonicalReady:
3098
+ graphAuthorityMode === "canonical" && graphRuntime
3099
+ ? ({ excludeKeys }) =>
3100
+ graphRuntime.nextReadyTaskKey({ excludeKeys })
3101
+ : null,
3102
+ shadowSettlement:
3103
+ graphAuthorityMode === "shadow" && graphRuntime
3104
+ ? (settlement) => graphRuntime.settleTask(settlement)
3105
+ : null,
3106
+ canonicalCancellation:
3107
+ graphAuthorityMode === "canonical" && graphRuntime
3108
+ ? ({ reason }) => graphRuntime.cancel(reason)
3109
+ : null,
3110
+ shadowCancellation:
3111
+ graphAuthorityMode === "shadow" && graphRuntime
3112
+ ? async ({ reason }) => {
3113
+ try {
3114
+ return await graphRuntime.cancel(reason);
3115
+ } catch (error) {
3116
+ recordShadowDivergence({
3117
+ phase: "run-cancel",
3118
+ code: error?.code || "CC_TEAM_GRAPH_SHADOW_DIVERGED",
3119
+ error: error?.message || String(error),
3120
+ });
3121
+ return null;
3122
+ }
3123
+ }
3124
+ : null,
2976
3125
  afterTask: ({ key, status, retry }) => {
2977
3126
  const governanceStatus =
2978
3127
  status === "completion-discarded" ||
@@ -3094,6 +3243,19 @@ export function registerTeamCommand(program, { logger } = {}) {
3094
3243
  }
3095
3244
  throw err;
3096
3245
  }
3246
+ if (graphRuntime) {
3247
+ const graphStatus = graphRuntime.finalize();
3248
+ summary.graphAuthorityMode = graphAuthorityMode;
3249
+ summary.graphRuntime = graphStatus;
3250
+ summary.graphShadowDivergences = [...shadowDivergences];
3251
+ if (
3252
+ graphAuthorityMode === "canonical" &&
3253
+ graphStatus.status !== "succeeded"
3254
+ ) {
3255
+ summary.success = false;
3256
+ summary.done = false;
3257
+ }
3258
+ }
3097
3259
  if (controlStore) {
3098
3260
  for (const request of controlStore.pending({
3099
3261
  anchor: controlCursor,
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.166.9",
7
+ "cliVersions": ["0.166.8", "0.166.9"],
8
+ "date": "2026-08-29",
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Added - cc CLI 0.166.9: governed UI replay and Codex compatibility gates",
13
+ "body": "> `chainlesschain` **0.166.8 -> 0.166.9** (release candidate,\n> 2026-08-29). Agent Protocol and TypeScript Agent SDK candidate versions\n> remain `0.1.6` and `0.2.5`; Python Agent SDK moves to `0.2.6` after the\n> immutable `0.2.5` candidate was withheld from PyPI because its release\n> metadata named an unpublished CLI.\n\n- **Real UI driver**: reviewed Record & Replay drafts can execute the bounded\n `observe/click/type/select/assert` vocabulary in an ephemeral Playwright\n Chromium context instead of relying on a fake executor.\n- **Fail-closed isolation**: the driver denies filesystem, HTTP(S), and\n WebSocket requests, requires exact reviewed capabilities and selectors, and\n rejects ambiguous targets, environment drift, network attempts, or missing\n terminal evidence.\n- **Content-free receipts**: selectors, typed values, page text, URLs, and\n screenshots never enter reports; only domain-separated state, page,\n screenshot, target, and receipt digests plus bounded structural metadata are\n retained.\n- **Cross-platform authority**: a dedicated exact-SHA GitHub Actions matrix\n runs the positive journey and an active network-escape probe in real Chromium\n on Linux, Windows, and macOS, then refuses partial evidence in its aggregate.\n- **Exact Codex admission**: the optional experimental App Server adapter now\n admits only explicitly listed upstream patch versions; prereleases and\n unverified future patches fail closed to the stable `codex exec --json`\n fallback before turn admission.\n- **Version-bound App Server evidence**: a second exact-SHA Actions matrix\n generates each upstream version's own schema and exercises the documented\n `initialize -> initialized -> thread/list` stdio lifecycle on Linux,\n Windows, and macOS without making a model request.\n- **Removal readiness**: every compatibility job proves that production CLI\n source has no dependency on the optional adapter and that the stable Codex\n JSONL fallback still executes and projects terminal output independently.\n- **Windows strict-sandbox cleanup**: target-identity cleanup remains bound to\n the stable file object while tolerating size and timestamp metadata settling\n after the native helper closes its writer; same-path replacement is still\n rejected.\n- **JetBrains real-host gate**: plan-review document access now runs inside\n explicit IntelliJ read/write actions, and the UI journey targets the current\n one-time permission label on every supported host/version pair.\n- **Python release metadata**: the `0.2.6` patch keeps the `0.2.5` runtime API\n and generated protocol bindings while pointing install guidance at the latest\n CLI that is actually available from the public npm registry."
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "productVersion": null,
19
+ "cliVersion": "0.166.8",
20
+ "cliVersions": [
21
+ "0.1.6",
22
+ "0.2.5",
23
+ "0.4.104",
24
+ "0.37.73",
25
+ "0.166.7",
26
+ "0.166.8"
27
+ ],
28
+ "date": "2026-08-29",
29
+ "title": "",
30
+ "sections": [
31
+ {
32
+ "heading": "Added - cc CLI 0.166.8 + Agent Platform and IDE patches: durable Graph review and recovery",
33
+ "body": "> `chainlesschain` **0.166.7 -> 0.166.8**,\n> `@chainlesschain/agent-protocol` **0.1.5 -> 0.1.6**,\n> `@chainlesschain/agent-sdk` **0.2.4 -> 0.2.5**, and\n> `chainlesschain-agent-sdk` **0.2.4 -> 0.2.5** (release candidate,\n> 2026-08-29).\n> VS Code **0.37.72 -> 0.37.73** and JetBrains\n> **0.4.103 -> 0.4.104** carry the paired governed review surfaces.\n\n- **Durable Graph history**: fixed App Server/SDK clients expose bounded,\n metadata-only event and snapshot history for blocked-root, revision-diff,\n and time-travel debugging across CLI, Desktop, and VS Code.\n- **Recoverable HumanTask quorum**: Graph human nodes persist exact\n revision/attempt/operation bindings, release Agent capacity while waiting,\n and enforce single-winner cancel/decision CAS, quorum, and separation of\n duties through the Desktop product surface.\n- **IDE review parity**: VS Code adds bounded Graph history/diff projection;\n both IDEs enforce revision-bound approval grants and single-winner\n settlement without accepting UI-derived authority.\n- **Migration and retirement evidence**: N-1 definition backups, rollback\n digests, replay validation, replacement reachability, historical reads, and\n zero-success legacy-writer observations are bound to durable exact-SHA\n evidence rather than prose-only rollout claims.\n- **Reliability gates**: temporal message custody, dependency/scope fairness,\n cross-process DAG recovery, effect idempotency, and worktree cleanup have\n explicit bounded artifacts and fail-closed aggregate checks.\n- **Release validation**: publication requires this exact candidate to pass\n Agent Protocol and Python SDK conformance, Linux/Windows/macOS `CLI CI` and\n `CLI Strict Sandbox`, the Graph real-journey matrix, immutable package\n checks, and public-registry provenance readback."
34
+ }
35
+ ]
36
+ },
37
+ {
38
+ "productVersion": null,
39
+ "cliVersion": "0.166.7",
40
+ "cliVersions": ["0.166.6", "0.166.7"],
41
+ "date": "2026-08-28",
42
+ "title": "",
43
+ "sections": [
44
+ {
45
+ "heading": "Added - cc CLI 0.166.7: authoritative Graph Kernel cutover",
46
+ "body": "> `chainlesschain` **0.166.6 -> 0.166.7**, published 2026-08-28 from exact\n> commit `19834a18457c1b763b5a7a2cfada713340e7c273`.\n\n- **Canonical execution authority**: CLI graph, Team, distributed-team,\n Cowork, Scheduler, and App Server entry points now resolve through the\n Graph Kernel cutover ledger instead of silently retaining parallel mutation\n paths.\n- **Durable fencing and recovery**: graph writers, leases, receipts, takeover,\n migration, and crash/resume flows are bound to persisted authority and\n checked-out source evidence so stale owners cannot resume mutations.\n- **Legacy containment**: retired runtimes retain explicitly read-only history\n access while unclassified or mutating legacy routes fail closed and report\n their canonical replacement targets.\n- **Release validation**: the exact SHA passed Linux/Windows/macOS `CLI CI`\n and `CLI Strict Sandbox`; immutable package, Trusted Publishing, npm\n provenance, public-registry readback, Open VSX `0.37.72`, and JetBrains\n Marketplace `0.4.103` were verified independently."
47
+ }
48
+ ]
49
+ },
4
50
  {
5
51
  "productVersion": null,
6
52
  "cliVersion": "0.166.6",
@@ -182,6 +182,10 @@ export function createWsMessageDispatcher(server) {
182
182
  handleConfigSetSecret(server, id, ws, message),
183
183
  "slash-command": () => server._handleSlashCommand(id, ws, message),
184
184
  "session-answer": () => server._handleSessionAnswer(id, ws, message),
185
+ "approval-grants-list": () =>
186
+ server._handleApprovalGrantsList(id, ws, message),
187
+ "approval-grant-revoke": () =>
188
+ server._handleApprovalGrantRevoke(id, ws, message),
185
189
  "remote-session-create": () =>
186
190
  handleRemoteSessionCreate(server, clientId, ws, message),
187
191
  "remote-session-close": () =>
@@ -606,9 +606,11 @@ async function ensureSessionHandler(
606
606
  if (budgetConfig.enabled) {
607
607
  const priceTable =
608
608
  budgetConfig.limits.maxUsd != null
609
- ? wsBudgetDependency(server, "mergePricing", mergePricing)(
610
- server.sessionManager.config?.llm?.pricing,
611
- )
609
+ ? wsBudgetDependency(
610
+ server,
611
+ "mergePricing",
612
+ mergePricing,
613
+ )(server.sessionManager.config?.llm?.pricing)
612
614
  : undefined;
613
615
  sessionBudgetRoot = wsBudgetDependency(
614
616
  server,
@@ -627,9 +629,7 @@ async function ensureSessionHandler(
627
629
  sessionBudgetRoot.budget ||
628
630
  typeof sessionBudgetRoot.close !== "function"
629
631
  ) {
630
- const error = new Error(
631
- "WebSocket session budget root is invalid",
632
- );
632
+ const error = new Error("WebSocket session budget root is invalid");
633
633
  error.code = "CC_SESSION_BUDGET_ROOT_INVALID";
634
634
  throw error;
635
635
  }
@@ -746,9 +746,7 @@ export async function handleSessionCreate(server, id, ws, message) {
746
746
  worktreeIsolation,
747
747
  systemPromptExtension,
748
748
  shellPolicyOverrides,
749
- sessionBudgetRoot: sessionBudgetRoot.enabled
750
- ? sessionBudgetRoot
751
- : null,
749
+ sessionBudgetRoot: sessionBudgetRoot.enabled ? sessionBudgetRoot : null,
752
750
  requireDurable: sessionBudgetRoot.enabled,
753
751
  });
754
752
  createdSessionId = sessionId;
@@ -1487,16 +1485,96 @@ export function handleSessionAnswer(server, id, ws, message) {
1487
1485
  }
1488
1486
 
1489
1487
  const session = server.sessionManager.getSession(sessionId);
1488
+ let settlement = null;
1489
+ let settlementAttempted = false;
1490
1490
  if (session && session.interaction && session.interaction.resolveAnswer) {
1491
- session.interaction.resolveAnswer(requestId, answer, binding);
1491
+ settlementAttempted = true;
1492
+ settlement = session.interaction.resolveAnswer(requestId, answer, binding);
1492
1493
  }
1493
1494
 
1495
+ // New adapters return an explicit settlement result. Legacy/custom
1496
+ // interactions return undefined and preserve the historical success ACK.
1497
+ const settled = settlementAttempted && settlement?.settled !== false;
1498
+
1494
1499
  server._send(
1495
1500
  ws,
1496
1501
  envelopeResponse(
1497
1502
  CODING_AGENT_EVENT_TYPES.COMMAND_RESPONSE,
1498
1503
  id,
1499
- { success: true },
1504
+ {
1505
+ success: settled,
1506
+ settled,
1507
+ ...(settlement?.reason ? { reason: settlement.reason } : {}),
1508
+ },
1509
+ sessionId,
1510
+ ),
1511
+ );
1512
+ }
1513
+
1514
+ export async function handleApprovalGrantsList(server, id, ws, message) {
1515
+ const sessionId = message.sessionId;
1516
+ const session = server.sessionManager?.getSession?.(sessionId) || null;
1517
+ const handler = server.sessionHandlers?.get?.(sessionId) || null;
1518
+ if (!session || !handler?.listApprovalGrants) {
1519
+ server._send(
1520
+ ws,
1521
+ envelopeError(
1522
+ id,
1523
+ "APPROVAL_GRANT_SESSION_UNAVAILABLE",
1524
+ "Approval grant session is not active",
1525
+ sessionId,
1526
+ ),
1527
+ );
1528
+ return;
1529
+ }
1530
+ const grants = await handler.listApprovalGrants();
1531
+ server._send(
1532
+ ws,
1533
+ envelopeResponse(
1534
+ CODING_AGENT_EVENT_TYPES.COMMAND_RESPONSE,
1535
+ id,
1536
+ { success: true, grants },
1537
+ sessionId,
1538
+ ),
1539
+ );
1540
+ }
1541
+
1542
+ export async function handleApprovalGrantRevoke(server, id, ws, message) {
1543
+ const sessionId = message.sessionId;
1544
+ const grantId = String(message.grantId || "");
1545
+ const handler = server.sessionHandlers?.get?.(sessionId) || null;
1546
+ if (!grantId || !handler?.revokeApprovalGrant) {
1547
+ server._send(
1548
+ ws,
1549
+ envelopeError(
1550
+ id,
1551
+ "APPROVAL_GRANT_REVOKE_INVALID",
1552
+ "An active approval grant and grantId are required",
1553
+ sessionId,
1554
+ ),
1555
+ );
1556
+ return;
1557
+ }
1558
+ const result = await handler.revokeApprovalGrant(grantId);
1559
+ if (!result?.success) {
1560
+ server._send(
1561
+ ws,
1562
+ envelopeError(
1563
+ id,
1564
+ "APPROVAL_GRANT_REVOKE_FAILED",
1565
+ result?.error || "Approval grant could not be revoked",
1566
+ sessionId,
1567
+ ),
1568
+ );
1569
+ return;
1570
+ }
1571
+ const grants = await handler.listApprovalGrants();
1572
+ server._send(
1573
+ ws,
1574
+ envelopeResponse(
1575
+ CODING_AGENT_EVENT_TYPES.COMMAND_RESPONSE,
1576
+ id,
1577
+ { success: true, revoked: result.grant, grants },
1500
1578
  sessionId,
1501
1579
  ),
1502
1580
  );
@@ -29,6 +29,11 @@ import { runnableTaskModel } from "../../lib/runnable-provider.js";
29
29
  import { PlanState } from "../../lib/plan-mode.js";
30
30
  import { CLISlotFiller } from "../../lib/slot-filler.js";
31
31
  import { createAbortError, isAbortError } from "../../lib/abort-utils.js";
32
+ import { addHooksV2EventObserver } from "../../lib/hooks-v2-producers.js";
33
+ import {
34
+ projectHookPolicyDecision,
35
+ projectToolPolicyDecision,
36
+ } from "../../lib/policy-decision-event.js";
32
37
  import {
33
38
  resolveRegisteredHostHooksV2Workspace,
34
39
  runWithHostHooksV2Workspace,
@@ -1081,6 +1086,7 @@ export class WSAgentHandler {
1081
1086
  this._approvalGate = await createWsApprovalGate({
1082
1087
  sessionId: this.session.id,
1083
1088
  interaction: this.interaction,
1089
+ cwd: this.session.projectRoot,
1084
1090
  });
1085
1091
  }
1086
1092
  return this._approvalGate;
@@ -1234,7 +1240,11 @@ export class WSAgentHandler {
1234
1240
  });
1235
1241
  const mcpRecoveryRuntime = this._ensureMcpRecoveryRuntime();
1236
1242
 
1237
- // Run agent loop
1243
+ // Run agent loop. Turn-scoped approval grants are reset before the
1244
+ // model/tool boundary for every user message; session grants remain in
1245
+ // the verified authority ledger owned by the session-scoped gate.
1246
+ const approvalGate = await this._ensureApprovalGate();
1247
+ approvalGate?.beginTurn?.(requestId || `turn-${Date.now()}`);
1238
1248
  const loopOptions = {
1239
1249
  provider: session.provider,
1240
1250
  model: activeModel,
@@ -1265,7 +1275,7 @@ export class WSAgentHandler {
1265
1275
  sessionBudget: this._sessionBudget,
1266
1276
  // P0 authority: null unless opted in (byte-identical default — agent
1267
1277
  // core already defaults `options.approvalGate || null`).
1268
- approvalGate: await this._ensureApprovalGate(),
1278
+ approvalGate,
1269
1279
  // Canonical WS history is compacted before ws_turn_prepare. Compaction
1270
1280
  // inside agent-core would include the staged pending user, which is not
1271
1281
  // part of the canonical message projection until turn settlement.
@@ -1435,7 +1445,23 @@ export class WSAgentHandler {
1435
1445
  tool: event.tool,
1436
1446
  result: event.result,
1437
1447
  error: event.error,
1448
+ permission_decision_id: event.permission_decision_id || null,
1449
+ permission_decision: event.permission_decision || null,
1438
1450
  });
1451
+ {
1452
+ const policyEvent = projectToolPolicyDecision(event, {
1453
+ sessionId: session.id,
1454
+ turnId: event.turn_id,
1455
+ toolUseId: event.tool_use_id,
1456
+ });
1457
+ if (policyEvent) {
1458
+ const { type: _type, ...payload } = policyEvent;
1459
+ this.interaction.emit("policy-decision", {
1460
+ requestId,
1461
+ ...payload,
1462
+ });
1463
+ }
1464
+ }
1439
1465
  if (
1440
1466
  event.tool === "todo_write" &&
1441
1467
  currentTodoWrite &&
@@ -1583,13 +1609,29 @@ export class WSAgentHandler {
1583
1609
  )
1584
1610
  : executeAgentTurn();
1585
1611
 
1586
- if (session.mcpClient?.withElicitationContext) {
1587
- await session.mcpClient.withElicitationContext(
1588
- session.id,
1589
- runAgentTurn,
1590
- );
1591
- } else {
1592
- await runAgentTurn();
1612
+ const removeHookPolicyObserver = addHooksV2EventObserver(
1613
+ session.id,
1614
+ (event) => {
1615
+ const policyEvent = projectHookPolicyDecision(event);
1616
+ if (!policyEvent) return;
1617
+ const { type: _type, ...payload } = policyEvent;
1618
+ this.interaction.emit("policy-decision", {
1619
+ requestId,
1620
+ ...payload,
1621
+ });
1622
+ },
1623
+ );
1624
+ try {
1625
+ if (session.mcpClient?.withElicitationContext) {
1626
+ await session.mcpClient.withElicitationContext(
1627
+ session.id,
1628
+ runAgentTurn,
1629
+ );
1630
+ } else {
1631
+ await runAgentTurn();
1632
+ }
1633
+ } finally {
1634
+ removeHookPolicyObserver();
1593
1635
  }
1594
1636
  if (session.canonicalJsonlSession === true && !canonicalTurn?.settled) {
1595
1637
  const error = new Error(
@@ -1714,6 +1756,20 @@ export class WSAgentHandler {
1714
1756
  }
1715
1757
  }
1716
1758
 
1759
+ async listApprovalGrants() {
1760
+ const gate = await this._ensureApprovalGate();
1761
+ if (!gate?.listGrants) return [];
1762
+ return gate.listGrants();
1763
+ }
1764
+
1765
+ async revokeApprovalGrant(grantId) {
1766
+ const gate = await this._ensureApprovalGate();
1767
+ if (!gate?.revokeGrant) {
1768
+ return { success: false, error: "Approval grant authority unavailable" };
1769
+ }
1770
+ return gate.revokeGrant(grantId);
1771
+ }
1772
+
1717
1773
  async interrupt() {
1718
1774
  const wasProcessing = this._processing;
1719
1775
  const interruptedRequestId = this._activeRequestId || null;