chainlesschain 0.162.187 → 0.162.189

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 (191) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-CETaO3s8.js → AIOps-DbZft8w0.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CAe7E9TW.js → ActionButton-DoOZpwfN.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BGr2mzwO.js → Analytics-B0J0KLTW.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-BEoY-NcT.js → AppLayout-D9eIR0qq.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-DUZivCgt.js → Artifacts-BnZXEVeo.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-C3yBs68k.js → Audit-X1ce4Bjn.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-C9KwiY3O.js → BackgroundAgents-BvWR-y5v.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-BoSWD_C8.js → Backup-BublSGEd.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-Dp09GkxL.js → BaseInput-CR_77Hso.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-5t9d-Ja0.js → Chat-DixW52tq.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DmVku4GH.js → ChatBubbleRenderer-DDHDpBBA.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-8QJFlkqI.js → Checkbox-CCv1C87K.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-BJVFQ3lL.js → Codegen-B03Cc3dd.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-6hdLD0oB.js → Col-CA06-6pU.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-B8opo0uY.js → Community-Bj881J52.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-Dv8HudiN.js → Compact-UZLTPoaL.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-DhxuCS5N.js → Compliance-kGwzRb_0.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-Dggy6VIL.js → Cowork-KundoYM8.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-DSmDqJTT.js → Cron-BYZyoqDe.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-7bZq0j5f.js → Crosschain-BhrrppBX.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-BWY4kh-H.js → DID-CdC6EguZ.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-bOzPZxlu.js → Dashboard-CcQx3J4y.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-BTFJHqQu.js → Dropdown-BpijtEzQ.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-BC3MOdtT.js → EmailListRenderer-DfZjeZTe.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CFHAdTTY.js → FamilyGuardDashboard-BFYSf69C.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-DZ_4aF_n.js → Federation-Okdi3pJm.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-BZje6UTj.js → FormItemContext-mH-HebKW.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-D7QfCvjN.js → GenericCardRenderer-xivV69x7.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DuG7qANG.js → Git-1rh_YBwg.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-BDmYAgTh.js → Governance-eAXkNxdY.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-DSXAfc1Q.js → Inference-CS6dMVTN.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DusleniP.js → KnowledgeGraph-Bq_TnkvD.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-CpImmA8p.js → Logs-KchHtiHt.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-BZ6LJBkk.js → MarkdownRenderer-TabqHW9B.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-DXS8CXkE.js → Marketplace-CsmGcX5X.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-D151UfUI.js → McpTools-BaPFnnyz.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-DKDxnoA1.js → Memory-2m-sUUf7.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BFZ95iKM.js → MobileBridge-D5nVZBRu.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-CDAR-grF.js → MobileProjects-Bo8MLZvT.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-OGJ95xJs.js → Mtc-3GDvamGa.js} +6 -6
  42. package/src/assets/web-panel/assets/{MtcAudit-BmGTo1XC.js → MtcAudit-D2zGuZCH.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-XumJRqOa.js → Multisig-BBVQ4t6t.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-DHhhRZed.js → NLProgramming-BIOCyOGp.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-B9rGxNNr.js → Notes-DVwBGpzc.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-DClLbMYV.js → NotificationSettings-BDnHfIfX.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-I8OohT7N.js → OrderTableRenderer-C7Ek20ag.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-M6WzaYVa.js → Organization-D3SRKaa7.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Cb3B5KtM.js → Overflow-C2B8ahyn.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-BGk57kya.js → P2P-2iwQzG65.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-CXcKyPqK.js → PdhVaultBrowser-CoPiWqMN.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-hsfJ-Y0e.js → Permissions-yV5XNXo5.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-BSBii4js.js → PersonalDataHub-uCDJhMUF.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-BNw52rey.js → Pipeline-hN7ucMOA.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-DUpfue4E.js → Privacy-CgU0ptN4.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-C68NsP3h.js → ProjectInit-CfYPiT6j.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-BJ2It9v4.js → ProjectSettings-B0A2C4nw.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-BE5C0ajn.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-EnU4VWwS.js → Providers-CstQPf8W.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-BRt5-B_I.js → QrScannerModal-Co3z_ynk.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-Jd5L9UL2.js → QuickAsk-DMTS6pQ6.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-BNDhoVIu.js → Recommend-ETw4odUa.js} +1 -1
  63. package/src/assets/web-panel/assets/RemoteSession-B0rkE09d.js +5 -0
  64. package/src/assets/web-panel/assets/{Reputation-D1wQPUNv.js → Reputation-BTVqQgKq.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-DnjRegul.js → Row-CBKKwwtO.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-C_T4I-nF.js → RssFeed-BHUQ438I.js} +2 -2
  67. package/src/assets/web-panel/assets/{Search-C4lrxlLh.js → Search-B4NqeUsF.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-ByYT-VzP.js → Security-BRjoYG5_.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-BHpyEqB5.js → Services-CxQzu3p3.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-C0I23vG-.js → Skeleton-BKzwwmWO.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-DGZXz22K.js → Skills-DrsFcgth.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-DL_urP9A.js → Sla-D21tmXCH.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-6x-hUNQ_.js → SpeechSettings-CjyjLfp8.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-Crk5TCXq.js → SyncSettings-Cu45-tnx.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-rZGq5PZs.js → Tasks-oMcILYOj.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-DT5el8Q8.js → Templates-Bh-Zcr5R.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-mlgeyMK8.js → Tenant-68ns63aI.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-C8HEA-lM.js → Terminal-BLJkFykE.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DvlqBayB.js → TimelineRenderer-xcrJLq-O.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-C7lDcNmT.js → Tokens-C6PpFJtf.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-CM8nCnIJ.js → Trigger-BaKA7tdM.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BQDLUQ9x.js → Trust-BzhA57Jc.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-CVqM0OFE.js → UkeySign-4_U3JkIR.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-BvAcQpzT.js → VideoEditing-162AANxX.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-zFVFaAZ2.js → Wallet-B1viuql_.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Cc522ums.js → WebAuthn-ZVWazhCy.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-Bg_wxpDo.js → WorkflowEditor-tzdyUk-1.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-jg0QwC8K.js → chat-DmrHNuwq.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-ALzYz1gO.js → colors-DAJ_M-PK.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-DXHYUoqi.js → compact-item-uIzmYwLs.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BsGsBM5m.js → createContext-D_ZmuLwb.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DIrncrV1.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-BccMLzxA.js → hasIn-CDt_shTL.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-Cg9cOVe9.js → index-BAvSmJXW.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BTTeAiOP.js → index-BDF6EQBs.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-C3k3ZwkQ.js → index-BHvlm0In.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CQ1ORdp-.js → index-BRa4kJ_S.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BcJzphrP.js → index-BTCXf1t-.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-rIy96PeM.js → index-Bbxjfstq.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CSFESurl.js → index-Bx4d6c1k.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-Cmg_Npx5.js → index-ByzGvpR9.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CahDve8M.js → index-C16fYKFD.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-2VstcImq.js → index-C5WcdJH2.js} +3 -3
  104. package/src/assets/web-panel/assets/{index-C3Rf8wIM.js → index-CG0lY4h3.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-uzykuL_R.js → index-CKyd472S.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CBVIFX-x.js → index-CaelyMgF.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-TeCof1s3.js → index-CbD_WW_6.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BfF0OGKU.js → index-CcZ9xJI9.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-oWltafBn.js → index-CeUpKjvi.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CWLWBgfe.js → index-Cvak6Oe2.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-C0AbXsDy.js → index-CzXqvMuP.js} +1 -1
  112. package/src/assets/web-panel/assets/index-D-Swwqld.js +1 -0
  113. package/src/assets/web-panel/assets/{index-BfV8RDlg.js → index-D4n1lGTB.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Dxqiu9-F.js → index-D9OE8B3d.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BdCmJ_bG.js → index-DBFmcaCQ.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DgjQ-kdT.js → index-DdUMcwRB.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BBbbr1YB.js → index-DeGBoLQA.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dmk7dD-T.js → index-DfSSy9uy.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-JS2LXdd0.js → index-DqDSF2RW.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D9oV2iRR.js → index-DvFhhe6r.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BvsII10i.js → index-DwfvPe-j.js} +1 -1
  122. package/src/assets/web-panel/assets/index-FMZAMKy8.js +1 -0
  123. package/src/assets/web-panel/assets/{index-CrZHUsOZ.js → index-FyplHuNt.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CLzPzN75.js → index-GcKOHD_c.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-koT8Q86Z.js → index-OzTxFIJP.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-08diKcTm.js → index-QsgfSZrV.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CJg6Wsjc.js → index-Z8P4BexE.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-srqW5_-X.js → index-clSX4PEc.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-mIQUoUx1.js → index-ifxmu8SY.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Cz_s25m3.js → index-rS3gl_68.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-UQXedWQz.js → index-rXdwUeE3.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-rcwgNMc0.js → index-saf3VNeP.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-xafkqrW3.js → initDefaultProps-pmfaD-aK.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BrtyQXLk.js → motion-CaQ2CpYF.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-BunUyg59.js → move-CkKTqNbI.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BPwjBeuE.js → mtc-parser-Dd4xsgRI.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-BpyqZlNO.js → omit-BFuA5YEs.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-DDrV0XjE.js → pickAttrs-DDfxOAJc.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-1A18Pcl2.js → placementArrow-Be595JCp.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-B8Fnlmso.js → responsiveObserve-7byljUM3.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-x-Fwb2Zm.js → slide-CTWfOTaY.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-aAG5yJl_.js → statusUtils-CNZOuIxM.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-BRQSTMRL.js → styleChecker-DwOcBV78.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-D5X_KozY.js → useFlexGapSupport-B6MNwAO9.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DN_YIjP-.js → useFs-CzyQjH9r.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-BizxAvjw.js → usePersonalDataHub-Dxh3KiVA.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-B5oAxN93.js → vnode-DVfZiS5N.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-DJhvyzKv.js → zoom-BYme7fbY.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/agent.js +22 -0
  151. package/src/commands/auto-mode.js +47 -0
  152. package/src/commands/checkpoint-managed.js +1059 -0
  153. package/src/commands/checkpoint.js +3 -0
  154. package/src/commands/team-distributed.js +3324 -0
  155. package/src/commands/team.js +1130 -74
  156. package/src/data/auto-mode-safety-eval-v1.json +3294 -0
  157. package/src/data/changelog.json +26 -0
  158. package/src/lib/agent-core.js +1 -0
  159. package/src/lib/agent-team/task-lease.js +271 -3
  160. package/src/lib/agent-team/team-adjudication.js +1501 -0
  161. package/src/lib/agent-team/team-budget.js +4 -1
  162. package/src/lib/agent-team/team-control-store.js +582 -0
  163. package/src/lib/agent-team/team-distributed-queue.js +5246 -0
  164. package/src/lib/agent-team/team-process-checkpoint.js +211 -0
  165. package/src/lib/agent-team/team-runner.js +319 -22
  166. package/src/lib/agent-team/team-worktree.js +1403 -95
  167. package/src/lib/auto-mode-safety-classifier.js +2034 -0
  168. package/src/lib/auto-mode-safety-eval.js +1022 -0
  169. package/src/lib/managed-checkpoint-render.js +60 -0
  170. package/src/lib/managed-tool-checkpoint.js +194 -0
  171. package/src/lib/process-execution-broker/index.js +438 -5
  172. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +28 -1
  173. package/src/lib/process-execution-broker/linux-generic-bwrap.js +28 -4
  174. package/src/lib/process-execution-broker/platform-sandbox.js +92 -70
  175. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  176. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  177. package/src/lib/process-execution-broker/windows-sandbox.cs +284 -19
  178. package/src/lib/process-execution-broker/workspace-transaction.js +3556 -0
  179. package/src/lib/secure-file-identity.js +433 -0
  180. package/src/lib/turn-binding.js +160 -2
  181. package/src/lib/with-file-lock.js +140 -23
  182. package/src/repl/agent-repl.js +19 -1
  183. package/src/runtime/agent-core.js +366 -122
  184. package/src/runtime/headless-runner.js +12 -0
  185. package/src/runtime/headless-stream.js +3 -0
  186. package/src/runtime/policies/agent-policy.js +14 -0
  187. package/src/assets/web-panel/assets/Projects-D2FHLUa-.js +0 -1
  188. package/src/assets/web-panel/assets/RemoteSession-BII41Mel.js +0 -5
  189. package/src/assets/web-panel/assets/devWarning-Dy1GJA4S.js +0 -1
  190. package/src/assets/web-panel/assets/index-8zbMbbuf.js +0 -1
  191. package/src/assets/web-panel/assets/index-C97f71oi.js +0 -1
@@ -95,6 +95,10 @@ import {
95
95
  } from "../lib/provider-http-error.js";
96
96
  import { buildPermissionDecision } from "../lib/permission-decision.js";
97
97
  import { resolveSandboxPolicyPath } from "../lib/agent-sandbox.js";
98
+ import {
99
+ beginManagedToolCheckpoint,
100
+ settleManagedToolCheckpoint,
101
+ } from "../lib/managed-tool-checkpoint.js";
98
102
 
99
103
  export { formatProviderHttpError };
100
104
 
@@ -2223,6 +2227,7 @@ export async function executeTool(name, args, context = {}) {
2223
2227
  backgroundSubAgents: context.backgroundSubAgents || null,
2224
2228
  toolAdmission: context.toolAdmission || null,
2225
2229
  unattendedActionPolicy: context.unattendedActionPolicy || null,
2230
+ managedCheckpoint: context.managedCheckpoint === true,
2226
2231
  });
2227
2232
  } catch (err) {
2228
2233
  if (hookDb) {
@@ -2866,12 +2871,19 @@ async function _postEditDiagnostics(filePath, cwd, additionalDirectories) {
2866
2871
  }
2867
2872
 
2868
2873
  /** Merge post-edit diagnostics into a successful edit result (no-op if none). */
2869
- async function _withPostEditDiagnostics(
2874
+ export async function _withPostEditDiagnostics(
2870
2875
  result,
2871
2876
  filePath,
2872
2877
  cwd,
2873
2878
  additionalDirectories,
2879
+ managedCheckpoint = false,
2874
2880
  ) {
2881
+ // A cold language server is a long-lived child process. Starting one inside
2882
+ // a managed workspace transaction would keep a writer bound past tool
2883
+ // settlement and make commit/rollback unverifiable. Managed edits therefore
2884
+ // skip this best-effort enrichment; callers can request diagnostics after the
2885
+ // checkpoint has sealed.
2886
+ if (managedCheckpoint) return result;
2875
2887
  const newDiagnostics = await _postEditDiagnostics(
2876
2888
  filePath,
2877
2889
  cwd,
@@ -3061,6 +3073,7 @@ async function executeToolInner(
3061
3073
  subAgentUsageSink = null,
3062
3074
  toolAdmission = null,
3063
3075
  unattendedActionPolicy = null,
3076
+ managedCheckpoint = false,
3064
3077
  // Hook-envelope tracing: this run's trace id, threaded into child loops
3065
3078
  // (spawn_sub_agent / isolated run_skill) as their parent_id.
3066
3079
  hookTraceId = null,
@@ -3220,6 +3233,7 @@ async function executeToolInner(
3220
3233
  filePath,
3221
3234
  cwd,
3222
3235
  additionalDirectories,
3236
+ managedCheckpoint,
3223
3237
  ),
3224
3238
  filePath,
3225
3239
  cwd,
@@ -3300,6 +3314,7 @@ async function executeToolInner(
3300
3314
  targetPath,
3301
3315
  cwd,
3302
3316
  additionalDirectories,
3317
+ managedCheckpoint,
3303
3318
  ),
3304
3319
  targetPath,
3305
3320
  cwd,
@@ -3399,6 +3414,7 @@ async function executeToolInner(
3399
3414
  filePath,
3400
3415
  cwd,
3401
3416
  additionalDirectories,
3417
+ managedCheckpoint,
3402
3418
  ),
3403
3419
  filePath,
3404
3420
  cwd,
@@ -3463,6 +3479,7 @@ async function executeToolInner(
3463
3479
  filePath,
3464
3480
  cwd,
3465
3481
  additionalDirectories,
3482
+ managedCheckpoint,
3466
3483
  ),
3467
3484
  filePath,
3468
3485
  cwd,
@@ -8172,6 +8189,55 @@ async function _autoCheckpointBeforeTool(toolContext, toolName, toolArgs) {
8172
8189
  }
8173
8190
  }
8174
8191
 
8192
+ function _managedCheckpointUncoveredWriterReason(toolContext) {
8193
+ if (
8194
+ Array.isArray(toolContext?.additionalDirectories) &&
8195
+ toolContext.additionalDirectories.length > 0
8196
+ ) {
8197
+ return "additional_workspace_roots_not_transactional";
8198
+ }
8199
+ if (
8200
+ toolContext?.mcpClient?.servers instanceof Map &&
8201
+ toolContext.mcpClient.servers.size > 0
8202
+ ) {
8203
+ return "ambient_mcp_server_writer_not_quiescent";
8204
+ }
8205
+ const workspaceRoot = path.resolve(toolContext?.cwd || process.cwd());
8206
+ const hasOverlappingCodeIntel = [..._codeIntelPool.keys()].some(
8207
+ (candidate) => {
8208
+ const lspRoot = path.resolve(candidate);
8209
+ const workspaceToLsp = path.relative(workspaceRoot, lspRoot);
8210
+ const lspToWorkspace = path.relative(lspRoot, workspaceRoot);
8211
+ const isInside = (relative) =>
8212
+ relative === "" ||
8213
+ (relative !== ".." &&
8214
+ !relative.startsWith(`..${path.sep}`) &&
8215
+ !path.isAbsolute(relative));
8216
+ return isInside(workspaceToLsp) || isInside(lspToWorkspace);
8217
+ },
8218
+ );
8219
+ if (hasOverlappingCodeIntel) {
8220
+ return "ambient_lsp_writer_not_quiescent";
8221
+ }
8222
+ if (
8223
+ [..._backgroundShellTasks.values()].some(
8224
+ (task) => task?.status === "running",
8225
+ )
8226
+ ) {
8227
+ return "ambient_background_shell_writer_not_quiescent";
8228
+ }
8229
+ if (
8230
+ toolContext?.backgroundSubAgents instanceof Map &&
8231
+ toolContext.backgroundSubAgents.size > 0
8232
+ ) {
8233
+ return "ambient_background_agent_writer_not_quiescent";
8234
+ }
8235
+ if (toolContext?.hookSupervisor && toolContext?.settingsHooks) {
8236
+ return "asynchronous_hook_writer_not_quiescent";
8237
+ }
8238
+ return null;
8239
+ }
8240
+
8175
8241
  /**
8176
8242
  * Async generator that drives the agentic tool-use loop.
8177
8243
  *
@@ -8399,6 +8465,13 @@ export async function* agentLoop(messages, options) {
8399
8465
  autoCheckpoint: options.autoCheckpoint || false,
8400
8466
  checkpointSession:
8401
8467
  options.checkpointSession || options.sessionId || "agent",
8468
+ managedCheckpoint: options.managedCheckpoint === true,
8469
+ managedCheckpointStateDir: options.managedCheckpointStateDir || null,
8470
+ managedCheckpointExclusions: Array.isArray(
8471
+ options.managedCheckpointExclusions,
8472
+ )
8473
+ ? [...options.managedCheckpointExclusions]
8474
+ : [],
8402
8475
  // Sub-agent nesting level (0 = main loop); spawn_sub_agent caps at
8403
8476
  // MAX_SUB_AGENT_DEPTH using this.
8404
8477
  subAgentDepth: options.subAgentDepth || 0,
@@ -9230,136 +9303,307 @@ export async function* agentLoop(messages, options) {
9230
9303
  turn_id: `${runId}:t${budget.consumed}`,
9231
9304
  };
9232
9305
 
9233
- yield {
9234
- type: "tool-executing",
9235
- tool: toolName,
9236
- args: toolArgs,
9237
- tool_use_id: call.id,
9238
- turn_id: `${runId}:t${budget.consumed}`,
9239
- };
9306
+ let managedCheckpointHandle = null;
9307
+ let managedCheckpointPreparationError = null;
9308
+ try {
9309
+ managedCheckpointHandle = beginManagedToolCheckpoint({
9310
+ enabled: toolContext.managedCheckpoint === true,
9311
+ broker,
9312
+ workspaceRoot: toolContext.cwd || process.cwd(),
9313
+ stateDir: toolContext.managedCheckpointStateDir || undefined,
9314
+ runId,
9315
+ taskKey: `${runId}:t${budget.consumed}:${call.id}:${toolName}`,
9316
+ toolName,
9317
+ toolArgs,
9318
+ externalToolExecutor:
9319
+ toolContext.externalToolExecutors?.[toolName] || null,
9320
+ unmanagedWriterReason:
9321
+ _managedCheckpointUncoveredWriterReason(toolContext),
9322
+ exclusions: toolContext.managedCheckpointExclusions || [],
9323
+ });
9324
+ } catch (error) {
9325
+ managedCheckpointPreparationError = error;
9326
+ yield {
9327
+ type: "managed-checkpoint-error",
9328
+ phase: "prepare",
9329
+ tool: toolName,
9330
+ error: error.message,
9331
+ code: error.code || null,
9332
+ coverage: "none",
9333
+ tool_use_id: call.id,
9334
+ turn_id: `${runId}:t${budget.consumed}`,
9335
+ };
9336
+ }
9337
+ let managedCheckpointSettled = managedCheckpointHandle?.skipped === true;
9338
+ let managedCheckpointSettlementAttempted = false;
9339
+ try {
9340
+ if (managedCheckpointHandle) {
9341
+ yield {
9342
+ type: "managed-checkpoint",
9343
+ phase: managedCheckpointHandle.skipped ? "unavailable" : "prepared",
9344
+ id: managedCheckpointHandle.checkpointId || null,
9345
+ transaction_id: managedCheckpointHandle.transactionId || null,
9346
+ tool: toolName,
9347
+ coverage: managedCheckpointHandle.skipped
9348
+ ? managedCheckpointHandle.coverage
9349
+ : managedCheckpointHandle.prepared?.coverage || "partial",
9350
+ reason: managedCheckpointHandle.reason || null,
9351
+ tool_use_id: call.id,
9352
+ turn_id: `${runId}:t${budget.consumed}`,
9353
+ };
9354
+ }
9240
9355
 
9241
- let toolResult;
9242
- let toolError = null;
9243
- // Per-span unified ids (P2 observability): a tool span carries its turn.id
9244
- // (correlating with the model span of the same iteration), the provider's
9245
- // tool_use.id (so a tool-result event can be tied back to its call), and —
9246
- // when auto-checkpoint fired before a mutating tool — the checkpoint.id the
9247
- // user could restore to. All normalized through buildTelemetryAttributes.
9248
- // tool_arguments CONTENT is opt-in (--otlp-content): the alias key is only
9249
- // present when explicitly enabled, so by default the field is omitted
9250
- // entirely (byte-identical default OTLP), and even opted-in it's length-
9251
- // capped by redactContent. Mirrors the run-level content.prompt opt-in.
9252
- const toolContentOptIn = options.otlpIncludeContent === true;
9253
- const toolIdAttrs = recorder
9254
- ? buildTelemetryAttributes(
9255
- {
9256
- turnId: `${runId}:t${budget.consumed}`,
9257
- toolUseId: call.id,
9258
- checkpointId: cpId || undefined,
9259
- ...(toolContentOptIn ? { toolArguments: toolArgs } : {}),
9356
+ // A preparation failure is a strict admission failure: the tool never
9357
+ // starts, so do not emit the observationally stronger `tool-executing`
9358
+ // event. Consumers use that event to bind hooks, telemetry and turns to
9359
+ // an actual invocation.
9360
+ if (!managedCheckpointPreparationError) {
9361
+ yield {
9362
+ type: "tool-executing",
9363
+ tool: toolName,
9364
+ args: toolArgs,
9365
+ tool_use_id: call.id,
9366
+ turn_id: `${runId}:t${budget.consumed}`,
9367
+ };
9368
+ }
9369
+
9370
+ let toolResult;
9371
+ let toolError = null;
9372
+ // Per-span unified ids (P2 observability): a tool span carries its turn.id
9373
+ // (correlating with the model span of the same iteration), the provider's
9374
+ // tool_use.id (so a tool-result event can be tied back to its call), and —
9375
+ // when auto-checkpoint fired before a mutating tool — the checkpoint.id the
9376
+ // user could restore to. All normalized through buildTelemetryAttributes.
9377
+ // tool_arguments CONTENT is opt-in (--otlp-content): the alias key is only
9378
+ // present when explicitly enabled, so by default the field is omitted
9379
+ // entirely (byte-identical default OTLP), and even opted-in it's length-
9380
+ // capped by redactContent. Mirrors the run-level content.prompt opt-in.
9381
+ const toolContentOptIn = options.otlpIncludeContent === true;
9382
+ const toolIdAttrs = recorder
9383
+ ? buildTelemetryAttributes(
9384
+ {
9385
+ turnId: `${runId}:t${budget.consumed}`,
9386
+ toolUseId: call.id,
9387
+ checkpointId: cpId || undefined,
9388
+ ...(toolContentOptIn ? { toolArguments: toolArgs } : {}),
9389
+ },
9390
+ { includeContent: toolContentOptIn },
9391
+ )
9392
+ : null;
9393
+ if (managedCheckpointPreparationError) {
9394
+ toolError = managedCheckpointPreparationError.message;
9395
+ toolResult = {
9396
+ error: `[Managed checkpoint] Preparation failed; "${toolName}" was blocked before execution: ${managedCheckpointPreparationError.message}`,
9397
+ managedCheckpoint: {
9398
+ status: "not_started",
9399
+ coverage: "none",
9400
+ code: managedCheckpointPreparationError.code || null,
9260
9401
  },
9261
- { includeContent: toolContentOptIn },
9262
- )
9263
- : null;
9264
- try {
9265
- toolResult = await _withSpan(
9266
- recorder,
9267
- "agent.tool",
9268
- { "tool.name": toolName, ...(toolIdAttrs || {}) },
9269
- () =>
9270
- executeTool(toolName, toolArgs, {
9271
- ...toolContext,
9272
- toolCallId: call.id,
9273
- turnId: `${runId}:t${budget.consumed}`,
9274
- }),
9275
- (span, r) => {
9276
- span.setAttribute(
9277
- "tool.is_error",
9278
- !!(r && typeof r === "object" && r.error),
9279
- );
9280
- // permission.decision_id (P2): a GATED tool result carries a
9281
- // `policy` (deny / ask-fail / host-block / sandbox); allow-path
9282
- // tools execute with no distinct decision. Stamp a stable id
9283
- // (derived from the call + gate, so it's recomputable from the
9284
- // tool-result's policy + tool_call_id) plus the low-cardinality
9285
- // decision, letting a blocked tool span be tied to its decision.
9286
- const decision =
9287
- r && typeof r === "object"
9288
- ? permissionDecision(call.id, toolName, r)
9289
- : null;
9290
- if (decision?.id) {
9291
- const permAttrs = buildTelemetryAttributes({
9292
- decisionId: decision.id,
9293
- "permission.decision": decision.decision,
9294
- });
9295
- if (permAttrs["permission.decision_id"]) {
9296
- span.setAttribute(
9297
- "permission.decision_id",
9298
- permAttrs["permission.decision_id"],
9299
- );
9300
- }
9301
- if (permAttrs["permission.decision"]) {
9402
+ };
9403
+ } else {
9404
+ try {
9405
+ toolResult = await _withSpan(
9406
+ recorder,
9407
+ "agent.tool",
9408
+ { "tool.name": toolName, ...(toolIdAttrs || {}) },
9409
+ () =>
9410
+ executeTool(toolName, toolArgs, {
9411
+ ...toolContext,
9412
+ toolCallId: call.id,
9413
+ turnId: `${runId}:t${budget.consumed}`,
9414
+ }),
9415
+ (span, r) => {
9302
9416
  span.setAttribute(
9303
- "permission.decision",
9304
- permAttrs["permission.decision"],
9417
+ "tool.is_error",
9418
+ !!(r && typeof r === "object" && r.error),
9305
9419
  );
9306
- }
9420
+ // permission.decision_id (P2): a GATED tool result carries a
9421
+ // `policy` (deny / ask-fail / host-block / sandbox); allow-path
9422
+ // tools execute with no distinct decision. Stamp a stable id
9423
+ // (derived from the call + gate, so it's recomputable from the
9424
+ // tool-result's policy + tool_call_id) plus the low-cardinality
9425
+ // decision, letting a blocked tool span be tied to its decision.
9426
+ const decision =
9427
+ r && typeof r === "object"
9428
+ ? permissionDecision(call.id, toolName, r)
9429
+ : null;
9430
+ if (decision?.id) {
9431
+ const permAttrs = buildTelemetryAttributes({
9432
+ decisionId: decision.id,
9433
+ "permission.decision": decision.decision,
9434
+ });
9435
+ if (permAttrs["permission.decision_id"]) {
9436
+ span.setAttribute(
9437
+ "permission.decision_id",
9438
+ permAttrs["permission.decision_id"],
9439
+ );
9440
+ }
9441
+ if (permAttrs["permission.decision"]) {
9442
+ span.setAttribute(
9443
+ "permission.decision",
9444
+ permAttrs["permission.decision"],
9445
+ );
9446
+ }
9447
+ }
9448
+ },
9449
+ "tool_error",
9450
+ );
9451
+ } catch (err) {
9452
+ toolResult = { error: err.message };
9453
+ toolError = err.message;
9454
+ }
9455
+ }
9456
+ if (recorder) recorder.counter("agent.tool.calls", 1);
9457
+
9458
+ if (managedCheckpointHandle) {
9459
+ const interrupted = signal?.aborted === true;
9460
+ const toolSucceeded =
9461
+ !interrupted &&
9462
+ !toolError &&
9463
+ !(toolResult && typeof toolResult === "object" && toolResult.error);
9464
+ try {
9465
+ managedCheckpointSettlementAttempted = true;
9466
+ const managedCheckpoint = settleManagedToolCheckpoint(
9467
+ managedCheckpointHandle,
9468
+ {
9469
+ success: toolSucceeded,
9470
+ reason: interrupted
9471
+ ? "agent tool interrupted"
9472
+ : toolError ||
9473
+ (toolResult && typeof toolResult === "object"
9474
+ ? toolResult.error
9475
+ : null) ||
9476
+ "agent tool failed",
9477
+ },
9478
+ );
9479
+ managedCheckpointSettled = true;
9480
+ if (toolResult && typeof toolResult === "object") {
9481
+ toolResult.managedCheckpoint = managedCheckpoint;
9307
9482
  }
9308
- },
9309
- "tool_error",
9310
- );
9311
- } catch (err) {
9312
- toolResult = { error: err.message };
9313
- toolError = err.message;
9314
- }
9315
- if (recorder) recorder.counter("agent.tool.calls", 1);
9483
+ yield {
9484
+ type: "managed-checkpoint-settled",
9485
+ phase: managedCheckpoint?.skipped
9486
+ ? "unavailable"
9487
+ : toolSucceeded
9488
+ ? "committed"
9489
+ : "rolled_back",
9490
+ id: managedCheckpoint?.checkpointId || null,
9491
+ transaction_id: managedCheckpoint?.transactionId || null,
9492
+ evidence_digest:
9493
+ managedCheckpoint?.evidence?.evidenceDigest || null,
9494
+ coverage: managedCheckpoint?.coverage || "none",
9495
+ file_coverage: managedCheckpoint?.fileCoverage || "none",
9496
+ reason: managedCheckpoint?.reason || null,
9497
+ tool: toolName,
9498
+ tool_use_id: call.id,
9499
+ turn_id: `${runId}:t${budget.consumed}`,
9500
+ };
9501
+ } catch (checkpointError) {
9502
+ toolError = checkpointError.message;
9503
+ toolResult = {
9504
+ error: `[Managed checkpoint] ${checkpointError.message}. Manual recovery/adjudication is required before this workspace is reused.`,
9505
+ managedCheckpoint: {
9506
+ status: "recovery_required",
9507
+ coverage: "none",
9508
+ code: checkpointError.code || null,
9509
+ transactionId: checkpointError.transactionId || null,
9510
+ checkpointId: checkpointError.checkpointId || null,
9511
+ settlement: checkpointError.settlement || null,
9512
+ originalToolError:
9513
+ toolResult && typeof toolResult === "object"
9514
+ ? toolResult.error || null
9515
+ : null,
9516
+ },
9517
+ };
9518
+ yield {
9519
+ type: "managed-checkpoint-error",
9520
+ phase: checkpointError.settlement || "settle",
9521
+ tool: toolName,
9522
+ error: checkpointError.message,
9523
+ code: checkpointError.code || null,
9524
+ transaction_id: checkpointError.transactionId || null,
9525
+ checkpoint_id: checkpointError.checkpointId || null,
9526
+ coverage: "none",
9527
+ recovery_required: true,
9528
+ tool_use_id: call.id,
9529
+ turn_id: `${runId}:t${budget.consumed}`,
9530
+ };
9531
+ }
9532
+ }
9316
9533
 
9317
- throwIfAborted(signal);
9534
+ throwIfAborted(signal);
9318
9535
 
9319
- // Append budget warning to tool result so the LLM sees it
9320
- const warningMsg = budget.toWarningMessage();
9321
- // Cap an individual tool result so one giant output can't blow the
9322
- // context — but tell the model when we cut it (no more silent
9323
- // mid-content slice). See MAX_TOOL_RESULT_CHARS / capToolResultString.
9324
- const resultStr = capToolResultString(
9325
- safeStringifyToolResult(toolResult),
9326
- );
9327
- const toolContent = warningMsg
9328
- ? `${resultStr}\n\n${warningMsg}`
9329
- : resultStr;
9536
+ // Append budget warning to tool result so the LLM sees it
9537
+ const warningMsg = budget.toWarningMessage();
9538
+ // Cap an individual tool result so one giant output can't blow the
9539
+ // context — but tell the model when we cut it (no more silent
9540
+ // mid-content slice). See MAX_TOOL_RESULT_CHARS / capToolResultString.
9541
+ const resultStr = capToolResultString(
9542
+ safeStringifyToolResult(toolResult),
9543
+ );
9544
+ const toolContent = warningMsg
9545
+ ? `${resultStr}\n\n${warningMsg}`
9546
+ : resultStr;
9330
9547
 
9331
- const decision = permissionDecision(call.id, toolName, toolResult);
9332
- yield {
9333
- type: "tool-result",
9334
- tool: toolName,
9335
- result: toolResult,
9336
- error: toolError,
9337
- tool_use_id: call.id,
9338
- turn_id: `${runId}:t${budget.consumed}`,
9339
- permission_decision_id: decision?.id || null,
9340
- permission_decision: decision,
9341
- };
9548
+ const decision = permissionDecision(call.id, toolName, toolResult);
9549
+ yield {
9550
+ type: "tool-result",
9551
+ tool: toolName,
9552
+ result: toolResult,
9553
+ error: toolError,
9554
+ tool_use_id: call.id,
9555
+ turn_id: `${runId}:t${budget.consumed}`,
9556
+ permission_decision_id: decision?.id || null,
9557
+ permission_decision: decision,
9558
+ };
9342
9559
 
9343
- messages.push({
9344
- role: "tool",
9345
- content: toolContent,
9346
- tool_call_id: call.id,
9347
- });
9348
- const failed = emitToolHookLifecycle({
9349
- tool: toolName,
9350
- args: toolArgs,
9351
- result: toolResult,
9352
- error: toolError,
9353
- sessionId: options.sessionId || null,
9354
- turnId,
9355
- toolUseId: call.id,
9356
- cwd: options.cwd || process.cwd(),
9357
- });
9358
- toolBatchRecords.push({
9359
- tool: toolName,
9360
- toolUseId: call.id,
9361
- failed,
9362
- });
9560
+ messages.push({
9561
+ role: "tool",
9562
+ content: toolContent,
9563
+ tool_call_id: call.id,
9564
+ });
9565
+ const failed = emitToolHookLifecycle({
9566
+ tool: toolName,
9567
+ args: toolArgs,
9568
+ result: toolResult,
9569
+ error: toolError,
9570
+ sessionId: options.sessionId || null,
9571
+ turnId,
9572
+ toolUseId: call.id,
9573
+ cwd: options.cwd || process.cwd(),
9574
+ });
9575
+ toolBatchRecords.push({
9576
+ tool: toolName,
9577
+ toolUseId: call.id,
9578
+ failed,
9579
+ });
9580
+ } finally {
9581
+ if (
9582
+ managedCheckpointHandle &&
9583
+ !managedCheckpointHandle.skipped &&
9584
+ !managedCheckpointSettled &&
9585
+ !managedCheckpointSettlementAttempted
9586
+ ) {
9587
+ try {
9588
+ managedCheckpointSettlementAttempted = true;
9589
+ settleManagedToolCheckpoint(managedCheckpointHandle, {
9590
+ success: false,
9591
+ reason:
9592
+ "agent event consumer closed before managed tool settlement",
9593
+ });
9594
+ managedCheckpointSettled = true;
9595
+ } catch (abandonError) {
9596
+ // Async-generator return() executes this finally. Propagate a
9597
+ // settlement failure so cancellation cannot silently strand a
9598
+ // PREPARED transaction or advertise recoverable/full evidence.
9599
+ abandonError.message = `managed checkpoint cancellation rollback failed: ${abandonError.message}`;
9600
+ // Intentionally override the generator's pending return(): a failed
9601
+ // rollback is security-relevant and must remain observable.
9602
+ // eslint-disable-next-line no-unsafe-finally
9603
+ throw abandonError;
9604
+ }
9605
+ }
9606
+ }
9363
9607
  }
9364
9608
  emitToolBatchHookLifecycle({
9365
9609
  records: toolBatchRecords,
@@ -99,6 +99,7 @@ import {
99
99
  } from "../lib/repl-denials.js";
100
100
  import executionBroker from "../lib/process-execution-broker/index.js";
101
101
  import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
102
+ import { formatManagedCheckpointEvent } from "../lib/managed-checkpoint-render.js";
102
103
 
103
104
  const goalBrokerRunner = executionBroker.spawnSync.bind(executionBroker);
104
105
 
@@ -1579,6 +1580,9 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
1579
1580
  autoPin: _autoPinResolved,
1580
1581
  autoCheckpoint: options.autoCheckpoint || false,
1581
1582
  checkpointSession: options.checkpointSession || sessionId,
1583
+ managedCheckpoint: options.managedCheckpoint === true,
1584
+ managedCheckpointStateDir: options.managedCheckpointStateDir || null,
1585
+ managedCheckpointExclusions: options.managedCheckpointExclusions || [],
1582
1586
  hookDb: db,
1583
1587
  approvalGate,
1584
1588
  permissionRules,
@@ -2006,6 +2010,14 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
2006
2010
  for await (const event of runLoop(messages, loopOptions)) {
2007
2011
  if (turnBindingFeed) turnBindingFeed.handleEvent(event);
2008
2012
  switch (event.type) {
2013
+ case "managed-checkpoint":
2014
+ case "managed-checkpoint-settled":
2015
+ case "managed-checkpoint-error": {
2016
+ const line = formatManagedCheckpointEvent(event);
2017
+ if (isText && line) writeErr(`${line}\n`);
2018
+ if (isStream) emitStream(event);
2019
+ break;
2020
+ }
2009
2021
  case "checkpoint": {
2010
2022
  if (isText)
2011
2023
  writeErr(` ⎌ checkpoint ${event.id} (before ${event.tool})\n`);
@@ -2065,6 +2065,9 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
2065
2065
  // only, a no-op outside a git repo.
2066
2066
  autoCheckpoint: options.autoCheckpoint || false,
2067
2067
  checkpointSession: options.checkpointSession || sessionId,
2068
+ managedCheckpoint: options.managedCheckpoint === true,
2069
+ managedCheckpointStateDir: options.managedCheckpointStateDir || null,
2070
+ managedCheckpointExclusions: options.managedCheckpointExclusions || [],
2068
2071
  hookDb: db,
2069
2072
  approvalGate,
2070
2073
  permissionRules,
@@ -33,6 +33,20 @@ export function resolveAgentPolicy({
33
33
  : [],
34
34
  sandbox: overrides.sandbox || null,
35
35
  autoCheckpoint: overrides.autoCheckpoint === true,
36
+ // Managed workspace checkpoints are consumed by both headless runners and
37
+ // the interactive REPL. Keep these explicit because this policy is an
38
+ // allowlist; dropping them would silently disable the requested safety
39
+ // boundary for interactive tool execution.
40
+ managedCheckpoint: overrides.managedCheckpoint === true,
41
+ managedCheckpointStateDir:
42
+ overrides.managedCheckpointStateDir == null
43
+ ? null
44
+ : String(overrides.managedCheckpointStateDir),
45
+ managedCheckpointExclusions: Array.isArray(
46
+ overrides.managedCheckpointExclusions,
47
+ )
48
+ ? [...overrides.managedCheckpointExclusions]
49
+ : [],
36
50
  worktreeId:
37
51
  overrides.worktreeId == null ? null : String(overrides.worktreeId),
38
52
  systemPrompt: overrides.systemPrompt || null,