chainlesschain 0.162.188 → 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 (188) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-Brr1LVcE.js → AIOps-DbZft8w0.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-DQU74DKG.js → ActionButton-DoOZpwfN.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-CYp9178y.js → Analytics-B0J0KLTW.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-DW4SCYsW.js → AppLayout-D9eIR0qq.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-CYlD_ed1.js → Artifacts-BnZXEVeo.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CWl1rZOi.js → Audit-X1ce4Bjn.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-BOR-LPsa.js → BackgroundAgents-BvWR-y5v.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DLpG7j1X.js → Backup-BublSGEd.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-B35K9wdr.js → BaseInput-CR_77Hso.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-CwUJb9gB.js → Chat-DixW52tq.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-1v6aMS1m.js → ChatBubbleRenderer-DDHDpBBA.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-pi3-tPNW.js → Checkbox-CCv1C87K.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-FyNF35eL.js → Codegen-B03Cc3dd.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-tGt_JDEr.js → Col-CA06-6pU.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CC7LonQX.js → Community-Bj881J52.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BGXrHHjE.js → Compact-UZLTPoaL.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-DSW0TBZ8.js → Compliance-kGwzRb_0.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-Bhk7rbvE.js → Cowork-KundoYM8.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-DxyiQ2NZ.js → Cron-BYZyoqDe.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-B2ZkxHok.js → Crosschain-BhrrppBX.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-yOJV99eJ.js → DID-CdC6EguZ.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-CKsttz7D.js → Dashboard-CcQx3J4y.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-CVFldXSL.js → Dropdown-BpijtEzQ.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-Bufv638J.js → EmailListRenderer-DfZjeZTe.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-4ncjoIjL.js → FamilyGuardDashboard-BFYSf69C.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-DsknEDoX.js → Federation-Okdi3pJm.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-Cqe5jWXA.js → FormItemContext-mH-HebKW.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-NAJaFKxc.js → GenericCardRenderer-xivV69x7.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-CszKQpnl.js → Git-1rh_YBwg.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-BXGodXi6.js → Governance-eAXkNxdY.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CkoYuG2c.js → Inference-CS6dMVTN.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DFlEr_T0.js → KnowledgeGraph-Bq_TnkvD.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-CVaENddA.js → Logs-KchHtiHt.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-TabqHW9B.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-CDlLT0fw.js → Marketplace-CsmGcX5X.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-DdwOyszN.js → McpTools-BaPFnnyz.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-DKQnkKuG.js → Memory-2m-sUUf7.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-DGseqlzJ.js → MobileBridge-D5nVZBRu.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-Bo8MLZvT.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-O61Vwyli.js → Mtc-3GDvamGa.js} +6 -6
  42. package/src/assets/web-panel/assets/{MtcAudit-Dw2SyasS.js → MtcAudit-D2zGuZCH.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-hSu_l8kf.js → Multisig-BBVQ4t6t.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-CX1Epurr.js → NLProgramming-BIOCyOGp.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-R9xX8o8_.js → Notes-DVwBGpzc.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-jtSNLCuK.js → NotificationSettings-BDnHfIfX.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-BU2Yqq5H.js → OrderTableRenderer-C7Ek20ag.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Pu2WO-U3.js → Organization-D3SRKaa7.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-BjnqUyFp.js → Overflow-C2B8ahyn.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-jjkvz44c.js → P2P-2iwQzG65.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-69ca_WeR.js → PdhVaultBrowser-CoPiWqMN.js} +4 -4
  52. package/src/assets/web-panel/assets/{Permissions-D4yDpivd.js → Permissions-yV5XNXo5.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-0qsL6iH1.js → PersonalDataHub-uCDJhMUF.js} +5 -5
  54. package/src/assets/web-panel/assets/{Pipeline-Cx7Ybrk2.js → Pipeline-hN7ucMOA.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-PbfR_M_V.js → Privacy-CgU0ptN4.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-CyV6Gsub.js → ProjectInit-CfYPiT6j.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-C7KZ2Wdk.js → ProjectSettings-B0A2C4nw.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-DQDjO-yK.js → Projects-BE5C0ajn.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-DyFVBBMX.js → Providers-CstQPf8W.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-CzB1BC9_.js → QrScannerModal-Co3z_ynk.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-Bk636mC1.js → QuickAsk-DMTS6pQ6.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-DoWxHIT3.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-BucoReGG.js → Reputation-BTVqQgKq.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-DzmOdJU7.js → Row-CBKKwwtO.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-C1tK7KGU.js → RssFeed-BHUQ438I.js} +2 -2
  67. package/src/assets/web-panel/assets/{Search-CSnInOqk.js → Search-B4NqeUsF.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-dlejr15l.js → Security-BRjoYG5_.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-BioPZuNh.js → Services-CxQzu3p3.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-DWMibwpC.js → Skeleton-BKzwwmWO.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-BAAnx1B2.js → Skills-DrsFcgth.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-jWNp4hNO.js → Sla-D21tmXCH.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-y5kqKha-.js → SpeechSettings-CjyjLfp8.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-B9GNsc3e.js → SyncSettings-Cu45-tnx.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-BDBYKRen.js → Tasks-oMcILYOj.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-DRiE5eaN.js → Templates-Bh-Zcr5R.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-BGlAvExF.js → Tenant-68ns63aI.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-B8uzrbNY.js → Terminal-BLJkFykE.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-Df48iveY.js → TimelineRenderer-xcrJLq-O.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-CcmHndN6.js → Tokens-C6PpFJtf.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-DPkWxmQ2.js → Trigger-BaKA7tdM.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-DTb5a5AV.js → Trust-BzhA57Jc.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-CBmg5vch.js → UkeySign-4_U3JkIR.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-B0mZrz4O.js → VideoEditing-162AANxX.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-Bxs7_mpd.js → Wallet-B1viuql_.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-C8x3cMxU.js → WebAuthn-ZVWazhCy.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-DPrNznrP.js → WorkflowEditor-tzdyUk-1.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-D3bYWu7S.js → chat-DmrHNuwq.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DY-PwMu4.js → colors-DAJ_M-PK.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-LDk10Kw6.js → compact-item-uIzmYwLs.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-C-2MZnFq.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-BQIBjcnB.js → hasIn-CDt_shTL.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-8JC9BJa1.js → index-BAvSmJXW.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-KFZO_lcx.js → index-BDF6EQBs.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CiTvBAr-.js → index-BHvlm0In.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-COG61sRv.js → index-BRa4kJ_S.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-lmm9p-jm.js → index-BTCXf1t-.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DTIZpPtG.js → index-Bbxjfstq.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-_HRO_cIu.js → index-Bx4d6c1k.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BRI3ngNg.js → index-ByzGvpR9.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-C3GNvExG.js → index-C16fYKFD.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-D3Oq-DLL.js → index-C5WcdJH2.js} +3 -3
  104. package/src/assets/web-panel/assets/{index-L3smcoQX.js → index-CG0lY4h3.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Dh-tkpKQ.js → index-CKyd472S.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CQVb2dWp.js → index-CaelyMgF.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DY2FIrmz.js → index-CbD_WW_6.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DYyLJPlF.js → index-CcZ9xJI9.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-C7FC8cP2.js → index-CeUpKjvi.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BN-xdSWZ.js → index-Cvak6Oe2.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DSvo_bp0.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-BdXnYMCZ.js → index-D4n1lGTB.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-L6qixyLc.js → index-D9OE8B3d.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-VCh5zNJo.js → index-DBFmcaCQ.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DlRYqt3S.js → index-DdUMcwRB.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-k7C_oDCO.js → index-DeGBoLQA.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-7xKu7Fns.js → index-DfSSy9uy.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CY4KnaO9.js → index-DqDSF2RW.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-HasPt4-h.js → index-DvFhhe6r.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CaslYch6.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-B5pgtZnY.js → index-FyplHuNt.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Cz4b6Z_7.js → index-GcKOHD_c.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BI4KgcYC.js → index-OzTxFIJP.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BX2b9Orc.js → index-QsgfSZrV.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CbR6ROOa.js → index-Z8P4BexE.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BrnRO9yE.js → index-clSX4PEc.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Dd2Km97U.js → index-ifxmu8SY.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DhRt9cYJ.js → index-rS3gl_68.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-D4K1weKc.js → index-rXdwUeE3.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Cx6D_dx2.js → index-saf3VNeP.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-zQPSHf2C.js → initDefaultProps-pmfaD-aK.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-CKCStGVk.js → motion-CaQ2CpYF.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-BufVDGYF.js → move-CkKTqNbI.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-DcaFxy5D.js → mtc-parser-Dd4xsgRI.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-EScpkGdo.js → omit-BFuA5YEs.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-72hG_qfT.js → pickAttrs-DDfxOAJc.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-CMFWiH20.js → placementArrow-Be595JCp.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-DKQHS41p.js → responsiveObserve-7byljUM3.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-QVAFHTIQ.js → slide-CTWfOTaY.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-DIz38e2G.js → statusUtils-CNZOuIxM.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-zK5cyLby.js → styleChecker-DwOcBV78.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-DhZngk62.js → useFlexGapSupport-B6MNwAO9.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-BvV2cvkg.js → useFs-CzyQjH9r.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-CRmxb9l3.js → usePersonalDataHub-Dxh3KiVA.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-CgQIbobP.js → vnode-DVfZiS5N.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-D4XrrO0R.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/checkpoint-managed.js +1059 -0
  152. package/src/commands/checkpoint.js +3 -0
  153. package/src/commands/team-distributed.js +3324 -0
  154. package/src/commands/team.js +1130 -74
  155. package/src/data/changelog.json +13 -0
  156. package/src/lib/agent-core.js +1 -0
  157. package/src/lib/agent-team/task-lease.js +271 -3
  158. package/src/lib/agent-team/team-adjudication.js +1501 -0
  159. package/src/lib/agent-team/team-budget.js +4 -1
  160. package/src/lib/agent-team/team-control-store.js +582 -0
  161. package/src/lib/agent-team/team-distributed-queue.js +5246 -0
  162. package/src/lib/agent-team/team-process-checkpoint.js +211 -0
  163. package/src/lib/agent-team/team-runner.js +319 -22
  164. package/src/lib/agent-team/team-worktree.js +1403 -95
  165. package/src/lib/managed-checkpoint-render.js +60 -0
  166. package/src/lib/managed-tool-checkpoint.js +194 -0
  167. package/src/lib/process-execution-broker/index.js +438 -5
  168. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +28 -1
  169. package/src/lib/process-execution-broker/linux-generic-bwrap.js +28 -4
  170. package/src/lib/process-execution-broker/platform-sandbox.js +92 -70
  171. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  172. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  173. package/src/lib/process-execution-broker/windows-sandbox.cs +284 -19
  174. package/src/lib/process-execution-broker/workspace-transaction.js +3556 -0
  175. package/src/lib/secure-file-identity.js +433 -0
  176. package/src/lib/turn-binding.js +160 -2
  177. package/src/lib/with-file-lock.js +140 -23
  178. package/src/repl/agent-repl.js +19 -1
  179. package/src/runtime/agent-core.js +366 -122
  180. package/src/runtime/headless-runner.js +12 -0
  181. package/src/runtime/headless-stream.js +3 -0
  182. package/src/runtime/policies/agent-policy.js +14 -0
  183. package/src/assets/web-panel/assets/MarkdownRenderer-7iWGwZ-r.js +0 -1
  184. package/src/assets/web-panel/assets/MobileProjects-COBbEOlj.js +0 -1
  185. package/src/assets/web-panel/assets/RemoteSession-oOVIv9wq.js +0 -5
  186. package/src/assets/web-panel/assets/devWarning-B4dXIJqD.js +0 -1
  187. package/src/assets/web-panel/assets/index-C-C7DaG6.js +0 -1
  188. package/src/assets/web-panel/assets/index-DkfWzWtd.js +0 -1
@@ -14,6 +14,8 @@
14
14
  * reclaimed merely because the directory is old, and corrupt ownership fails
15
15
  * closed. Confirmed-dead owners are reclaimed with an exact-token marker inside
16
16
  * the lock directory so a delayed contender cannot delete a replacement lock.
17
+ * Strict callers may use bounded jittered retries and an after-release yield to
18
+ * avoid Windows sharing transients and fixed-interval lock convoys.
17
19
  *
18
20
  * @param {string} targetPath the file being guarded (lock is `${targetPath}.lock`)
19
21
  * @param {(ctx:{locked:boolean})=>T} fn critical section; receives whether the lock was held
@@ -24,9 +26,13 @@ export function withFileLock(targetPath, fn, opts = {}) {
24
26
  timeoutMs = 2000,
25
27
  staleMs = 30000,
26
28
  retryMs = 25,
29
+ maxRetryMs = Math.max(retryMs, 100),
30
+ retryJitterMs = retryMs,
31
+ yieldAfterReleaseMs = 0,
27
32
  _fs = defaultFs,
28
33
  _now = () => Date.now(),
29
34
  _sleep = sleepSync,
35
+ _random = Math.random,
30
36
  _isProcessAlive = isProcessAlive,
31
37
  _ownerToken = () => randomUUID(),
32
38
  failIfUnavailable = false,
@@ -40,6 +46,8 @@ export function withFileLock(targetPath, fn, opts = {}) {
40
46
  token: _ownerToken(),
41
47
  };
42
48
  let held = false;
49
+ let acquisitionError = null;
50
+ let retryAttempt = 0;
43
51
  const deadline = _now() + timeoutMs;
44
52
 
45
53
  for (;;) {
@@ -55,13 +63,50 @@ export function withFileLock(targetPath, fn, opts = {}) {
55
63
  break;
56
64
  } catch (error) {
57
65
  _fs.rmSync(lockDir, { recursive: true, force: true });
58
- if (failIfUnavailable) throw error;
66
+ acquisitionError = error;
67
+ if (
68
+ failIfUnavailable &&
69
+ isTransientLockError(error) &&
70
+ waitForRetry({
71
+ _now,
72
+ _sleep,
73
+ _random,
74
+ deadline,
75
+ retryAttempt: retryAttempt++,
76
+ retryMs,
77
+ maxRetryMs,
78
+ retryJitterMs,
79
+ })
80
+ ) {
81
+ continue;
82
+ }
83
+ break;
84
+ }
85
+ } catch (error) {
86
+ if (!error || error.code !== "EEXIST") {
87
+ acquisitionError = error;
88
+ if (
89
+ failIfUnavailable &&
90
+ isTransientLockError(error) &&
91
+ waitForRetry({
92
+ _now,
93
+ _sleep,
94
+ _random,
95
+ deadline,
96
+ retryAttempt: retryAttempt++,
97
+ retryMs,
98
+ maxRetryMs,
99
+ retryJitterMs,
100
+ })
101
+ ) {
102
+ continue;
103
+ }
59
104
  break;
60
105
  }
61
- } catch (err) {
62
- if (!err || err.code !== "EEXIST") break; // unexpected fs error → run unlocked
63
106
 
64
- const incumbent = readOwner(_fs, ownerPath);
107
+ const ownerRead = readOwnerResult(_fs, ownerPath);
108
+ const incumbent = ownerRead.owner;
109
+ acquisitionError = ownerRead.error;
65
110
  if (incumbent) {
66
111
  if (!_isProcessAlive(incumbent.pid)) {
67
112
  if (reclaimOwnedDirectory(_fs, lockDir, incumbent, _isProcessAlive)) {
@@ -81,14 +126,30 @@ export function withFileLock(targetPath, fn, opts = {}) {
81
126
  /* stat lost a race with the holder releasing — retry/wait below */
82
127
  }
83
128
  }
84
- if (_now() >= deadline) break; // timed out → run unlocked (best-effort)
85
- _sleep(retryMs);
129
+ if (
130
+ !waitForRetry({
131
+ _now,
132
+ _sleep,
133
+ _random,
134
+ deadline,
135
+ retryAttempt: retryAttempt++,
136
+ retryMs,
137
+ maxRetryMs,
138
+ retryJitterMs,
139
+ })
140
+ ) {
141
+ break;
142
+ }
86
143
  }
87
144
  }
88
145
 
89
146
  if (!held && failIfUnavailable) {
90
- const error = new Error(`Could not acquire state lock: ${targetPath}`);
147
+ const error = new Error(
148
+ `Could not acquire state lock: ${targetPath}`,
149
+ acquisitionError ? { cause: acquisitionError } : undefined,
150
+ );
91
151
  error.code = "STATE_LOCK_UNAVAILABLE";
152
+ error.attempts = retryAttempt + 1;
92
153
  throw error;
93
154
  }
94
155
 
@@ -116,6 +177,11 @@ export function withFileLock(targetPath, fn, opts = {}) {
116
177
  if (!error.code) error.code = "STATE_LOCK_OWNERSHIP_LOST";
117
178
  throw error;
118
179
  }
180
+ if (held && released && yieldAfterReleaseMs > 0) {
181
+ // The lock is already gone. This lets an existing waiter run before a
182
+ // process performing many tiny transactions can immediately reacquire it.
183
+ _sleep(yieldAfterReleaseMs);
184
+ }
119
185
  return result;
120
186
  }
121
187
 
@@ -140,25 +206,76 @@ function isProcessAlive(pid) {
140
206
  }
141
207
  }
142
208
 
209
+ const TRANSIENT_LOCK_ERROR_CODES = new Set([
210
+ "EACCES",
211
+ "EBUSY",
212
+ "EMFILE",
213
+ "ENFILE",
214
+ "ENOENT",
215
+ "ENOTEMPTY",
216
+ "EPERM",
217
+ ]);
218
+
219
+ function isTransientLockError(error) {
220
+ return !!error && TRANSIENT_LOCK_ERROR_CODES.has(error.code);
221
+ }
222
+
223
+ function waitForRetry({
224
+ _now,
225
+ _sleep,
226
+ _random,
227
+ deadline,
228
+ retryAttempt,
229
+ retryMs,
230
+ maxRetryMs,
231
+ retryJitterMs,
232
+ }) {
233
+ const remaining = deadline - _now();
234
+ if (remaining <= 0) return false;
235
+
236
+ const base = Math.max(1, Number(retryMs) || 1);
237
+ const maximum = Math.max(base, Number(maxRetryMs) || base);
238
+ const exponent = Math.min(Math.max(0, retryAttempt), 8);
239
+ const exponential = Math.min(maximum, base * 2 ** exponent);
240
+ const jitterLimit = Math.max(0, Number(retryJitterMs) || 0);
241
+ const sample = Number(_random());
242
+ const jitter =
243
+ jitterLimit > 0 && Number.isFinite(sample)
244
+ ? Math.floor(Math.min(1, Math.max(0, sample)) * jitterLimit)
245
+ : 0;
246
+ _sleep(Math.min(remaining, exponential + jitter));
247
+ return true;
248
+ }
249
+
143
250
  function readOwner(_fs, ownerPath) {
251
+ return readOwnerResult(_fs, ownerPath).owner;
252
+ }
253
+
254
+ function readOwnerResult(_fs, ownerPath) {
255
+ let owner;
144
256
  try {
145
- const owner = JSON.parse(_fs.readFileSync(ownerPath, "utf8"));
146
- if (
147
- !owner ||
148
- typeof owner !== "object" ||
149
- Array.isArray(owner) ||
150
- !Number.isSafeInteger(owner.pid) ||
151
- owner.pid <= 0 ||
152
- !Number.isFinite(owner.startedAt) ||
153
- typeof owner.token !== "string" ||
154
- !/^[a-zA-Z0-9-]{16,128}$/.test(owner.token)
155
- ) {
156
- return null;
157
- }
158
- return owner;
159
- } catch {
160
- return null;
257
+ owner = JSON.parse(_fs.readFileSync(ownerPath, "utf8"));
258
+ } catch (cause) {
259
+ if (cause?.code) return { owner: null, error: cause };
260
+ const error = new Error("State lock owner metadata is corrupt", { cause });
261
+ error.code = "STATE_LOCK_OWNER_CORRUPT";
262
+ return { owner: null, error };
263
+ }
264
+ if (
265
+ !owner ||
266
+ typeof owner !== "object" ||
267
+ Array.isArray(owner) ||
268
+ !Number.isSafeInteger(owner.pid) ||
269
+ owner.pid <= 0 ||
270
+ !Number.isFinite(owner.startedAt) ||
271
+ typeof owner.token !== "string" ||
272
+ !/^[a-zA-Z0-9-]{16,128}$/.test(owner.token)
273
+ ) {
274
+ const error = new Error("State lock owner metadata is corrupt");
275
+ error.code = "STATE_LOCK_OWNER_CORRUPT";
276
+ return { owner: null, error };
161
277
  }
278
+ return { owner, error: null };
162
279
  }
163
280
 
164
281
  function sameOwner(left, right) {
@@ -111,6 +111,7 @@ import { resolveSlashMacro } from "./slash-macro.js";
111
111
  import { expandMcpPrompt, renderMcpSurface } from "./mcp-prompt.js";
112
112
  import { newCostStore, addUsage } from "./session-cost.js";
113
113
  import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
114
+ import { formatManagedCheckpointEvent } from "../lib/managed-checkpoint-render.js";
114
115
  import { parseThinkCommand, parseEffortCommand } from "./think-command.js";
115
116
  import { parseBtwCommand, buildAsideBlock, applyAside } from "./btw-command.js";
116
117
  import { shouldStreamLive } from "./stream-decision.js";
@@ -340,7 +341,14 @@ export async function agentLoop(messages, options) {
340
341
  /* advisory — never break the turn */
341
342
  }
342
343
  }
343
- if (event.type === "checkpoint") {
344
+ const managedCheckpointLine = formatManagedCheckpointEvent(event);
345
+ if (managedCheckpointLine) {
346
+ const render =
347
+ event.type === "managed-checkpoint-error" || event.coverage === "none"
348
+ ? chalk.yellow
349
+ : chalk.gray;
350
+ process.stdout.write(render(`${managedCheckpointLine}\n`));
351
+ } else if (event.type === "checkpoint") {
344
352
  // Remember which file snapshot lines up with the live conversation so
345
353
  // `/rewind <n>` can restore code + conversation together (Claude-Code
346
354
  // parity). atMessageCount = messages.length at snapshot time; see
@@ -588,6 +596,13 @@ async function startAgentReplInWorkspace(options = {}) {
588
596
  // Snapshot the work tree before each mutating tool (git engine) so the user
589
597
  // can `cc checkpoint restore` to just before any tool call.
590
598
  const autoCheckpoint = options.autoCheckpoint === true;
599
+ const managedCheckpoint = options.managedCheckpoint === true;
600
+ const managedCheckpointStateDir = options.managedCheckpointStateDir || null;
601
+ const managedCheckpointExclusions = Array.isArray(
602
+ options.managedCheckpointExclusions,
603
+ )
604
+ ? options.managedCheckpointExclusions
605
+ : [];
591
606
 
592
607
  // --fallback-model: walk an ordered backup-model chain when a turn's LLM
593
608
  // call fails (transient error or model-not-found). Built once; passed into
@@ -5653,6 +5668,9 @@ async function startAgentReplInWorkspace(options = {}) {
5653
5668
  sandbox: _sandbox,
5654
5669
  autoCheckpoint,
5655
5670
  checkpointSession: sessionId,
5671
+ managedCheckpoint,
5672
+ managedCheckpointStateDir,
5673
+ managedCheckpointExclusions,
5656
5674
  checkpointMarks: _checkpointMarks,
5657
5675
  // Explicit turn-binding producer (null unless a JSONL session): the
5658
5676
  // wrapper folds every loop event into the live table.