chainlesschain 0.163.6 → 0.163.7

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 (218) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-DDIUofA8.js → AIOps-axqQfwv8.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-Bm-5xYRn.js → ActionButton-DV-Ro0By.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-D5UH4ljI.js → Analytics-Bt72WEVu.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-D_ifjOOP.js → AppLayout-BtepG55E.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BY1mXdC7.js → Artifacts-B7KaJ7S_.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-Bujr4Ml3.js → Audit-FNFaUg7A.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-sioKSTcC.js → BackgroundAgents-DFb6J2wQ.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DDOAK8RK.js → Backup-CC7YBhyj.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CtCsVVke.js → BaseInput-RkgTNVtj.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DpNj0vnd.js → Chat-hHEmGZy-.js} +4 -4
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZta3Ftr.js → ChatBubbleRenderer-CAP9YhHv.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-DoHVNSXq.js → Checkbox-z5wXOQP1.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DlVl7Qmv.js → Codegen-DVaDJnxy.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-GIqoPYty.js → Col-CJmaRDR5.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CIAPEVji.js → Community-DF29_2bI.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BN7JiI_h.js → Compact-DtkQkBzn.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CqUWCM9B.js → Compliance-xoHDxp7I.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-A4iPp7A4.js → Cowork-BUm-R7ht.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-B2zeXXWb.js → Cron-Cgl14ZkB.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BR2xmWr8.js → Crosschain-BNcbmoqh.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-BzFDjrIv.js → DID-Bwja0Zo9.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DKtDo3yA.js → Dashboard-Bk5XjEdJ.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-RNx43_YG.js → Dropdown-Ci36Oitq.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-SwMt4Rcy.js → EmailListRenderer--U04ZN4q.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CsYebZ4X.js → FamilyGuardDashboard-B2gNPR2s.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BmRKvBTy.js → Federation-C4KghYn7.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CVxGTA-0.js → FormItemContext-QL7x_Q_0.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-x2iXpyB7.js → GenericCardRenderer-F3Ryltwm.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DfqbkiOP.js → Git-2HassK5k.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-RuHyyj5O.js → Governance-DoBIp7oe.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-Bn7uZ7rI.js → Inference--W01QhZ-.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DlP7XefZ.js → KnowledgeGraph-DmvwqGpT.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-BYNdOiCd.js → Logs-BBJ4yAel.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-aMtgN-R6.js → MarkdownRenderer-BLCZMzhJ.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-JQYmDqM8.js → Marketplace-D5lNngSI.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Cyx4yZ-9.js → McpTools-CkEVOMKH.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-VDuGZTN2.js → Memory-B1Ow1xVE.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-_yKo97gi.js → MobileBridge-SgYbUfb6.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-CXRXW3q7.js → MobileProjects-BWdOvQAj.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-acTGtfLH.js → Mtc-DcTXSSma.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-ClpjXfkY.js → MtcAudit-Dt3WG4oj.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-_6Tn3o96.js → Multisig-B9B38UZx.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-CK7pbZzP.js → NLProgramming-B0S4GGvG.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-Czy6V_P8.js → Notes-DZ5U58Ng.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-Cqx-UVv3.js → NotificationSettings-PjL5ZW34.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-C69WDxGy.js → OrderTableRenderer-DrAX2ESt.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-DFnA9vLQ.js → Organization-Cv1GYs-c.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-ReZkk2yT.js → Overflow-Bbkp_PL3.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-DzjSI0aI.js → P2P-BD8QUgoZ.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-DKTf5xIP.js → PdhVaultBrowser-BO-2PeaB.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-DhQ5klhR.js → Permissions-D_OPVa02.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-CUL1iHrW.js → PersonalDataHub-mh-pEmaB.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-DU88iu4N.js → Pipeline-6JC2EDdb.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-Bw-sYfyK.js → Privacy-CUshzUAG.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-Bq3Q5y0z.js → ProjectInit-Cs2Aalri.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-C8spzpho.js → ProjectSettings-1ak49tcj.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-BV4oApsm.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-Bf4eTP9W.js → Providers-CXXxvafH.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-Dme9BDU1.js → QrScannerModal-PTcDsF58.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-CIXfv1rE.js → QuickAsk-CDwucrJw.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CIxvdeZ-.js → Recommend-CJlLVRXR.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C6k7MExI.js → RemoteSession-DlN-ETsO.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CISDz2bl.js → Reputation-DI23LR6m.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-CdnDxXyf.js → Row-Cl7UQMrM.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-C-QpRHsl.js → RssFeed-CexHNfh8.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DBjaGzSn.js → Search-BneBWvRN.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CQKukOeE.js → Security-DX7Phgrp.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-DZz86jWb.js → Services-BWXO8Mte.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-jb8RMK0d.js → Skeleton-DCyOjKPJ.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CdY76fZG.js → Skills-CXqERsTB.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-C_CSiZX9.js → Sla-bhbrbz8E.js} +1 -1
  73. package/src/assets/web-panel/assets/SpeechSettings-3IPU0HBZ.js +1 -0
  74. package/src/assets/web-panel/assets/{SyncSettings-qvimGO0O.js → SyncSettings-DBNTQLbM.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-Dng5LPJC.js → Tasks-quP0bkN-.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Bwqq5Wll.js → Templates-BouWmgho.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DNWuwP7Z.js → Tenant-qv0D9s7z.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-B-6Othpp.js → Terminal-BxvbE8BB.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DKpKZfzx.js → TimelineRenderer-D-IeLnJ2.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DzfGMd2J.js → Tokens-CFMKKyVG.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BXwUi74J.js → Trigger-L8as3UuJ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BNzUq4ui.js → Trust-MxmA4VZG.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-BYugxww4.js → UkeySign-C0VvJYRi.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DdauhtSJ.js → VideoEditing-Bf5QZj8N.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-CSC9bCe_.js → Wallet-BIJ9riRz.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Q8AN3bTO.js → WebAuthn-B8p9Mhkw.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-d-LBGCuA.js → WorkflowEditor-BVsuaPen.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BLVDCgsZ.js → chat-BfkjoKpV.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BZlPSEHl.js → colors-DeAlsWK8.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-IWseP6R6.js → compact-item-Cs97bz5j.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DnVRV3Ao.js → createContext-BqbG60LH.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DLQZA_Wn.js → hasIn-i_RY0b1X.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-B_N4-Gq9.js → index-0-agYlWL.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DB0MJgF_.js → index-79V_zv1s.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BOZJBTWZ.js → index-B-3tEpTc.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DUq0c7gq.js → index-B-JVTrpr.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Dy0R5ZED.js → index-B1CbOH1i.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-Bxp7uDD8.js → index-B5UkyA3c.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DpVrK6fr.js → index-BESLFt4q.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CT9vVN-X.js → index-BOVkf1K3.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DOoQpuQY.js → index-BYUVuwKt.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CINJQEj6.js → index-BcUXAB2s.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CarMTIyQ.js → index-BkBi5TmC.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C5dgnilC.js → index-Bm7lLR4c.js} +1 -1
  106. package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +1 -0
  107. package/src/assets/web-panel/assets/{index-CbQNL0ue.js → index-BuLQobzW.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CpBaJ3TD.js → index-CE2VtTlp.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-jWb70ZgZ.js → index-CED2PL_y.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BEu2lMBy.js → index-CG3PRyAL.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DocEhinm.js → index-CIG8fQ2_.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-D_LQodeJ.js → index-COdGA-8n.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DZpYeqrh.js → index-CeWoNHau.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-gt8bNefW.js → index-Cf3WCLmy.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-N_GoWZX4.js → index-CgsqdnRV.js} +1 -1
  116. package/src/assets/web-panel/assets/index-ChVT0p9u.js +1 -0
  117. package/src/assets/web-panel/assets/{index-CZDekj7T.js → index-D2B4VPyP.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-YSw_gxlZ.js → index-D9evtvg2.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DTbxp4UH.js → index-DUUrv141.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Bbj2NS_I.js → index-DiSkx4UB.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-BZs5bBnk.js → index-Dk2qouAz.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DalA0TKC.js → index-Dk7-v4hP.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-1jeAudHd.js → index-DmbfhJUP.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C1ifZtXo.js → index-DqBgBpgp.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BhA3QEni.js → index-PT_5sBMA.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BSjilZ9L.js → index-U4f5izHz.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-C2FqfMvU.js → index-YXgLng0K.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-COev0W2g.js → index-ZxO_-E8a.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-M7wxfAbm.js → index-dIHr4B_u.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DjWnONdy.js → index-gyFpvL7l.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Dkwsi1Kn.js → index-s1opAL-M.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-hwVDeoC0.js → index-yObj1O4n.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-Co67Kqmb.js → initDefaultProps-C9h9yKL3.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BMOxQSF_.js → motion-BvmLsPdu.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-C5fWDw-N.js → move-CoL4ekU1.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BJevpL0e.js → mtc-parser-C4pMy6xV.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-BCzNU8s6.js → omit-DPuJfNxx.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-CybWvDPk.js → pickAttrs-D0KEeaK2.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BMWS9HnW.js → placementArrow-BpkyINxt.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-BoL2UnGY.js → responsiveObserve-DQI_wOq8.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DWNfXraU.js → slide-DYfdDiRg.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BquTM3tX.js → statusUtils-B5dtvb0D.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-BEkCleim.js → styleChecker-CF310mSj.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Oecnq7EA.js → useFlexGapSupport-D1Qp4BLp.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-CkDffJ4F.js → useFs-C7_iyvJK.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-qbvKXesB.js → usePersonalDataHub-DZUt_fIm.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-C6v8n6mA.js → vnode-D3dsi0lZ.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-4CTeFILV.js → zoom-WdbOlvdQ.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +2 -2
  151. package/src/commands/agent.js +90 -1
  152. package/src/commands/chat.js +11 -2
  153. package/src/commands/compact.js +106 -23
  154. package/src/commands/loop.js +28 -10
  155. package/src/commands/routine.js +1 -1
  156. package/src/commands/scheduler-daemon.js +359 -2
  157. package/src/commands/session-observability.js +305 -0
  158. package/src/commands/session.js +38 -0
  159. package/src/data/changelog.json +14 -1
  160. package/src/gateways/ws/ws-agent-handler.js +439 -5
  161. package/src/harness/jsonl-session-store.js +463 -125
  162. package/src/harness/prompt-compressor.js +86 -13
  163. package/src/harness/provider-backed-compaction.js +100 -27
  164. package/src/lib/advisor-runtime.js +3 -1
  165. package/src/lib/agent-schedule-store.js +414 -4
  166. package/src/lib/agent-team/team-adjudication.js +40 -1
  167. package/src/lib/automation-engine.js +494 -0
  168. package/src/lib/background-agent-supervisor.js +793 -215
  169. package/src/lib/background-command-argv.js +24 -0
  170. package/src/lib/background-interaction-journal.js +361 -52
  171. package/src/lib/background-interaction-resolver.js +32 -0
  172. package/src/lib/background-launch-profile.js +2 -0
  173. package/src/lib/causal-observability.js +2661 -0
  174. package/src/lib/chat-session-admission.js +76 -0
  175. package/src/lib/cost-budget.js +5 -7
  176. package/src/lib/cowork/ab-comparator-cli.js +11 -0
  177. package/src/lib/cowork/debate-review-cli.js +12 -0
  178. package/src/lib/cowork-adapter.js +159 -38
  179. package/src/lib/cowork-cron.js +357 -1
  180. package/src/lib/cowork-task-runner.js +112 -17
  181. package/src/lib/delivery-coordinator.js +142 -0
  182. package/src/lib/direct-model-usage.js +121 -0
  183. package/src/lib/file-lines.js +183 -47
  184. package/src/lib/llm-pricing.js +12 -17
  185. package/src/lib/loop.js +26 -2
  186. package/src/lib/routine-store.js +380 -21
  187. package/src/lib/runtime-usage-ledger.js +182 -0
  188. package/src/lib/scheduler-kernel/agenda-adapter.js +308 -3
  189. package/src/lib/scheduler-kernel/automation-adapter.js +410 -8
  190. package/src/lib/scheduler-kernel/automation-event-adapter.js +36 -0
  191. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +285 -3
  192. package/src/lib/scheduler-kernel/loop-adapter.js +541 -6
  193. package/src/lib/scheduler-kernel/migration-admin.js +346 -0
  194. package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
  195. package/src/lib/scheduler-kernel/routine-adapter.js +394 -20
  196. package/src/lib/scheduler-kernel/runtime.js +63 -1
  197. package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
  198. package/src/lib/scheduler-kernel/store.js +2586 -85
  199. package/src/lib/session-host-lease.js +171 -2
  200. package/src/lib/session-host-snapshot.js +14 -3
  201. package/src/lib/session-persistence-failure.js +1 -0
  202. package/src/lib/session-tail.js +179 -34
  203. package/src/lib/session-transcript-structure.js +96 -0
  204. package/src/lib/sub-agent-context.js +328 -22
  205. package/src/lib/ws-agent-handler.js +4 -1
  206. package/src/repl/agent-repl.js +732 -91
  207. package/src/repl/chat-repl.js +5 -1
  208. package/src/runtime/agent-core.js +1272 -207
  209. package/src/runtime/fallback-model.js +5 -0
  210. package/src/runtime/headless-runner.js +324 -82
  211. package/src/runtime/headless-stream.js +232 -26
  212. package/src/runtime/policies/agent-policy.js +4 -0
  213. package/src/workers/background-agent-worker.js +403 -96
  214. package/src/assets/web-panel/assets/Projects-Dd-xuPIc.js +0 -1
  215. package/src/assets/web-panel/assets/SpeechSettings-C7tT9iad.js +0 -1
  216. package/src/assets/web-panel/assets/devWarning-Jzu62CLC.js +0 -1
  217. package/src/assets/web-panel/assets/index-Zb2MeDSy.js +0 -1
  218. package/src/assets/web-panel/assets/index-fikqml4k.js +0 -1
@@ -21,6 +21,8 @@ import {
21
21
  worktreeLog,
22
22
  } from "./worktree-isolator.js";
23
23
  import { isGitRepo } from "./git-integration.js";
24
+ import { markRuntimeLedgerPersistenceError } from "./runtime-usage-ledger.js";
25
+ import { IterationBudget } from "./iteration-budget.js";
24
26
 
25
27
  // ─── Constants ──────────────────────────────────────────────────────────────
26
28
 
@@ -30,6 +32,85 @@ const SUMMARY_SECTION_PATTERN =
30
32
  /^##\s*(Summary|Result|Output|Conclusion|Answer)/im;
31
33
  const TRUNCATE_LENGTH = 500;
32
34
 
35
+ function runtimeUsageObserverFailure(error, code, message) {
36
+ const failure =
37
+ error && (typeof error === "object" || typeof error === "function")
38
+ ? markRuntimeLedgerPersistenceError(error)
39
+ : markRuntimeLedgerPersistenceError(new Error(message));
40
+ try {
41
+ if (!failure.code) failure.code = code;
42
+ } catch {
43
+ // A frozen error was already wrapped by markRuntimeLedgerPersistenceError.
44
+ }
45
+ return failure;
46
+ }
47
+
48
+ function assertSyncUsageObserver(observer, phase) {
49
+ if (typeof observer === "function") return;
50
+ const upper = phase.toUpperCase();
51
+ throw runtimeUsageObserverFailure(
52
+ null,
53
+ `CC_USAGE_${upper}_OBSERVER_REQUIRED`,
54
+ `Strict child usage telemetry requires a synchronous ${phase} observer`,
55
+ );
56
+ }
57
+
58
+ function requireSyncUsageObserver(observer, event, phase) {
59
+ const upper = phase.toUpperCase();
60
+ assertSyncUsageObserver(observer, phase);
61
+ let observation;
62
+ try {
63
+ observation = observer(event);
64
+ } catch (error) {
65
+ throw runtimeUsageObserverFailure(
66
+ error,
67
+ `CC_USAGE_${upper}_PERSISTENCE_FAILED`,
68
+ `Child usage ${phase} persistence failed`,
69
+ );
70
+ }
71
+ let isThenable = false;
72
+ try {
73
+ isThenable = Boolean(observation && typeof observation.then === "function");
74
+ } catch (error) {
75
+ throw runtimeUsageObserverFailure(
76
+ error,
77
+ `CC_USAGE_${upper}_OBSERVER_ASYNC`,
78
+ `Child usage ${phase} observer must be synchronous`,
79
+ );
80
+ }
81
+ if (isThenable) {
82
+ void Promise.resolve(observation).catch(() => {});
83
+ throw runtimeUsageObserverFailure(
84
+ null,
85
+ `CC_USAGE_${upper}_OBSERVER_ASYNC`,
86
+ `Child usage ${phase} observer must be synchronous`,
87
+ );
88
+ }
89
+ }
90
+
91
+ function requireUsageCallId(event, phase) {
92
+ if (typeof event?.callId === "string" && event.callId.trim()) {
93
+ return event.callId;
94
+ }
95
+ const upper = phase.toUpperCase();
96
+ throw runtimeUsageObserverFailure(
97
+ null,
98
+ `CC_USAGE_${upper}_CALL_ID_REQUIRED`,
99
+ `Strict child usage ${phase} requires a real callId`,
100
+ );
101
+ }
102
+
103
+ function requireToolCallId(event, phase) {
104
+ const value = event?.tool_use_id ?? event?.callId ?? event?.id;
105
+ if (typeof value === "string" && value.trim()) return value;
106
+ const upper = phase.toUpperCase();
107
+ throw runtimeUsageObserverFailure(
108
+ null,
109
+ `CC_TOOL_${upper}_CALL_ID_REQUIRED`,
110
+ `Strict child tool ${phase} requires a real provider call id`,
111
+ );
112
+ }
113
+
33
114
  // ─── SubAgentContext ────────────────────────────────────────────────────────
34
115
 
35
116
  export class SubAgentContext {
@@ -53,6 +134,15 @@ export class SubAgentContext {
53
134
  * @param {object} [options.llmOptions] - LLM provider/model/key options
54
135
  * @param {string} [options.cwd] - Working directory
55
136
  * @param {boolean} [options.useWorktree] - Force worktree isolation (overrides flag)
137
+ * @param {function} [options.onUsageBoundary] - Synchronous observer for
138
+ * real child model-usage-started events. A failure is terminal so provider
139
+ * work cannot begin without a durable parent boundary.
140
+ * @param {function} [options.onUsageSettlement] - Synchronous observer for
141
+ * real child token-usage/model-usage-unknown settlements.
142
+ * @param {function} [options.onToolCallBoundary] - Synchronous observer for
143
+ * real child tool-executing boundaries.
144
+ * @param {function} [options.onToolCallSettlement] - Synchronous observer for
145
+ * matching child tool-result settlements.
56
146
  * @returns {SubAgentContext}
57
147
  */
58
148
  static create(options = {}) {
@@ -158,6 +248,23 @@ export class SubAgentContext {
158
248
  // the parent loop can re-yield attributed `token-usage` events.
159
249
  this._onUsage =
160
250
  typeof options.onUsage === "function" ? options.onUsage : null;
251
+ this._onUsageBoundary =
252
+ typeof options.onUsageBoundary === "function"
253
+ ? options.onUsageBoundary
254
+ : null;
255
+ this._onUsageSettlement =
256
+ typeof options.onUsageSettlement === "function"
257
+ ? options.onUsageSettlement
258
+ : null;
259
+ this._onToolCallBoundary =
260
+ typeof options.onToolCallBoundary === "function"
261
+ ? options.onToolCallBoundary
262
+ : null;
263
+ this._onToolCallSettlement =
264
+ typeof options.onToolCallSettlement === "function"
265
+ ? options.onToolCallSettlement
266
+ : null;
267
+ this._strictUsageTelemetry = options.strictUsageTelemetry === true;
161
268
 
162
269
  // Optional EXTERNAL abort signal for cancellation (e.g. a parent-provided
163
270
  // AbortSignal). In addition, every context owns an INTERNAL controller so a
@@ -439,6 +546,7 @@ export class SubAgentContext {
439
546
  }
440
547
  return result;
441
548
  } catch (err) {
549
+ if (err?.runtimeLedgerPersistence === true) throw err;
442
550
  // If worktree creation fails (e.g. not a git repo), fall back to direct
443
551
  this.status = "failed";
444
552
  this.completedAt = new Date().toISOString();
@@ -525,8 +633,103 @@ export class SubAgentContext {
525
633
  if (authority.unattendedActionPolicy) {
526
634
  options.unattendedActionPolicy = authority.unattendedActionPolicy;
527
635
  }
528
- if (this.iterationBudget) {
529
- options.iterationBudget = this.iterationBudget;
636
+ // Let agentLoop enforce model-turn admission at its real provider boundary.
637
+ // The former event-count guard could stop immediately after a yielded
638
+ // model/tool `started` event and strand it without a settlement.
639
+ options.iterationBudget =
640
+ this.iterationBudget ||
641
+ new IterationBudget({ limit: this.maxIterations, owner: this.id });
642
+ const strictUsageTelemetry =
643
+ this._strictUsageTelemetry || options.strictUsageTelemetry === true;
644
+ const pendingUsageCalls = new Set();
645
+ const pendingToolCalls = new Map();
646
+ let observeUsageBoundary = null;
647
+ let observeUsageSettlement = null;
648
+ let observeToolBoundary = null;
649
+ let observeToolSettlement = null;
650
+ if (strictUsageTelemetry) {
651
+ // Presence is checked without invoking either observer. In particular,
652
+ // do not manufacture a null "validation event" that a durable writer
653
+ // could mistake for a real provider-call boundary.
654
+ assertSyncUsageObserver(this._onUsageBoundary, "boundary");
655
+ assertSyncUsageObserver(this._onUsageSettlement, "settlement");
656
+
657
+ observeUsageBoundary = (event) => {
658
+ const callId = requireUsageCallId(event, "boundary");
659
+ if (pendingUsageCalls.has(callId)) {
660
+ throw runtimeUsageObserverFailure(
661
+ null,
662
+ "CC_USAGE_BOUNDARY_CALL_ID_DUPLICATE",
663
+ `Duplicate child usage boundary callId: ${callId}`,
664
+ );
665
+ }
666
+ requireSyncUsageObserver(this._onUsageBoundary, event, "boundary");
667
+ pendingUsageCalls.add(callId);
668
+ };
669
+ observeUsageSettlement = (event) => {
670
+ const callId = requireUsageCallId(event, "settlement");
671
+ if (!pendingUsageCalls.has(callId)) {
672
+ throw runtimeUsageObserverFailure(
673
+ null,
674
+ "CC_USAGE_SETTLEMENT_BOUNDARY_MISSING",
675
+ `Child usage settlement has no matching boundary: ${callId}`,
676
+ );
677
+ }
678
+ requireSyncUsageObserver(this._onUsageSettlement, event, "settlement");
679
+ pendingUsageCalls.delete(callId);
680
+ };
681
+
682
+ // agentLoop yields model-usage-started before provider work. Its consumer
683
+ // runs synchronously before requesting the next event, so a durable host
684
+ // write failure prevents the child provider call from starting.
685
+ // Automatic semantic compaction invokes this same wrapped boundary seam
686
+ // directly, before its provider query, rather than yielding a start event.
687
+ options.onUsageBoundary = observeUsageBoundary;
688
+ options.onUsageSettlement = observeUsageSettlement;
689
+ options.strictUsageTelemetry = true;
690
+
691
+ observeToolBoundary = (event) => {
692
+ const callId = requireToolCallId(event, "boundary");
693
+ if (pendingToolCalls.has(callId)) {
694
+ throw runtimeUsageObserverFailure(
695
+ null,
696
+ "CC_TOOL_BOUNDARY_CALL_ID_DUPLICATE",
697
+ `Duplicate child tool boundary callId: ${callId}`,
698
+ );
699
+ }
700
+ requireSyncUsageObserver(
701
+ this._onToolCallBoundary,
702
+ event,
703
+ "tool_boundary",
704
+ );
705
+ pendingToolCalls.set(callId, event.tool || null);
706
+ };
707
+ observeToolSettlement = (event) => {
708
+ const callId = requireToolCallId(event, "settlement");
709
+ if (!pendingToolCalls.has(callId)) {
710
+ throw runtimeUsageObserverFailure(
711
+ null,
712
+ "CC_TOOL_SETTLEMENT_BOUNDARY_MISSING",
713
+ `Child tool settlement has no matching boundary: ${callId}`,
714
+ );
715
+ }
716
+ const startedTool = pendingToolCalls.get(callId);
717
+ if (startedTool && event.tool && startedTool !== event.tool) {
718
+ throw runtimeUsageObserverFailure(
719
+ null,
720
+ "CC_TOOL_SETTLEMENT_IDENTITY_CHANGED",
721
+ `Child tool settlement changed tool identity for ${callId}`,
722
+ );
723
+ }
724
+ requireSyncUsageObserver(
725
+ this._onToolCallSettlement,
726
+ event,
727
+ "tool_settlement",
728
+ );
729
+ pendingToolCalls.delete(callId);
730
+ };
731
+ options.onToolCallBoundary = observeToolBoundary;
732
+ options.onToolCallSettlement = observeToolSettlement;
530
733
  }
531
734
 
532
735
  // Forward MCP / external tool plumbing into the agent loop
@@ -605,9 +808,32 @@ export class SubAgentContext {
605
808
  }
606
809
 
607
810
  if (event.type === "token-usage") {
811
+ const forwardedUsage = {
812
+ type: "token-usage",
813
+ ...(event.callId ? { callId: event.callId } : {}),
814
+ provider: event.provider || null,
815
+ model: event.model || null,
816
+ usage: event.usage || null,
817
+ ...(event.source ? { source: event.source } : {}),
818
+ attribution: event.attribution || null,
819
+ ...(event.boundaryNotified === true ||
820
+ event.ledgerPersisted === true
821
+ ? { boundaryNotified: true }
822
+ : {}),
823
+ ...(event.ledgerPersisted === true
824
+ ? { ledgerPersisted: true }
825
+ : {}),
826
+ };
827
+ if (strictUsageTelemetry && event.ledgerPersisted !== true) {
828
+ forwardedUsage.boundaryNotified = true;
829
+ observeUsageSettlement(forwardedUsage);
830
+ forwardedUsage.ledgerPersisted = true;
831
+ }
832
+ // Close the durable provider-call row before any secondary budget
833
+ // projection can fail. A budget writer error must never turn a paid
834
+ // call into a permanently open `started` row.
608
835
  // Attributed usage was already charged by the nested child sharing
609
- // this same authority. Only direct usage is folded here, otherwise a
610
- // child-of-child would be counted once at every ancestor level.
836
+ // this same authority, so only direct usage is folded here.
611
837
  if (!event.attribution && this.sessionBudget?.recordUsage) {
612
838
  this.sessionBudget.recordUsage({
613
839
  provider: event.provider || null,
@@ -618,16 +844,81 @@ export class SubAgentContext {
618
844
  if (this._onUsage) {
619
845
  // Forward real usage to the spawner. A nested child's event already
620
846
  // carries its own attribution frame — preserve it (deepest wins).
621
- try {
622
- this._onUsage({
623
- provider: event.provider || null,
624
- model: event.model || null,
625
- usage: event.usage || null,
626
- ...(event.source ? { source: event.source } : {}),
627
- attribution: event.attribution || null,
628
- });
629
- } catch (_e) {
630
- // Usage forwarding is best-effort — never break the child loop
847
+ if (strictUsageTelemetry) {
848
+ requireSyncUsageObserver(
849
+ this._onUsage,
850
+ forwardedUsage,
851
+ "forwarding",
852
+ );
853
+ } else {
854
+ try {
855
+ this._onUsage(forwardedUsage);
856
+ } catch {
857
+ // Legacy attribution forwarding remains best-effort.
858
+ }
859
+ }
860
+ }
861
+ }
862
+
863
+ if (event.type === "model-usage-started") {
864
+ if (strictUsageTelemetry) {
865
+ if (
866
+ event.boundaryNotified === true ||
867
+ event.ledgerPersisted === true
868
+ ) {
869
+ pendingUsageCalls.add(requireUsageCallId(event, "boundary"));
870
+ } else {
871
+ observeUsageBoundary(event);
872
+ }
873
+ }
874
+ }
875
+
876
+ if (event.type === "tool-executing" && strictUsageTelemetry) {
877
+ observeToolBoundary(event);
878
+ }
879
+
880
+ if (
881
+ event.type === "model-usage-unknown" ||
882
+ event.type === "compaction-usage-unknown"
883
+ ) {
884
+ const forwardedUnknown = {
885
+ type: "model-usage-unknown",
886
+ callId: event.callId,
887
+ provider: event.provider || null,
888
+ model: event.model || null,
889
+ source:
890
+ event.source ||
891
+ (event.type === "compaction-usage-unknown"
892
+ ? "semantic-compaction"
893
+ : "model"),
894
+ code: event.code || "provider_transport_outcome_unknown",
895
+ attribution: event.attribution || null,
896
+ ...(event.boundaryNotified === true ||
897
+ event.ledgerPersisted === true
898
+ ? { boundaryNotified: true }
899
+ : {}),
900
+ ...(event.ledgerPersisted === true
901
+ ? { ledgerPersisted: true }
902
+ : {}),
903
+ };
904
+ if (strictUsageTelemetry && event.ledgerPersisted !== true) {
905
+ forwardedUnknown.boundaryNotified = true;
906
+ observeUsageSettlement(forwardedUnknown);
907
+ forwardedUnknown.ledgerPersisted = true;
908
+ }
909
+ if (this._onUsage) {
910
+ if (strictUsageTelemetry) {
911
+ requireSyncUsageObserver(
912
+ this._onUsage,
913
+ forwardedUnknown,
914
+ "forwarding",
915
+ );
916
+ } else {
917
+ try {
918
+ this._onUsage(forwardedUnknown);
919
+ } catch {
920
+ // Legacy attribution forwarding remains best-effort.
921
+ }
631
922
  }
632
923
  }
633
924
  }
@@ -637,6 +928,9 @@ export class SubAgentContext {
637
928
  }
638
929
 
639
930
  if (event.type === "tool-result") {
931
+ if (strictUsageTelemetry && event.tool_use_id) {
932
+ observeToolSettlement(event);
933
+ }
640
934
  // Store large tool results as artifacts
641
935
  const resultStr = JSON.stringify(event.result);
642
936
  // Estimate token count from tool result (~4 chars per token)
@@ -672,7 +966,10 @@ export class SubAgentContext {
672
966
  }
673
967
 
674
968
  // Check abort signal (external OR this context's own `abort()`)
675
- if (this.isAborted()) {
969
+ const providerOrToolBoundaryPending =
970
+ event.type === "model-usage-started" ||
971
+ event.type === "tool-executing";
972
+ if (this.isAborted() && !providerOrToolBoundaryPending) {
676
973
  this.forceComplete(this._cancelReason || "cancelled", {
677
974
  partialContent: lastContent,
678
975
  artifacts,
@@ -681,21 +978,30 @@ export class SubAgentContext {
681
978
  }
682
979
 
683
980
  // Enforce token budget
684
- if (this.tokenBudget && this._tokenCount >= this.tokenBudget) {
981
+ if (
982
+ this.tokenBudget &&
983
+ this._tokenCount >= this.tokenBudget &&
984
+ !providerOrToolBoundaryPending
985
+ ) {
685
986
  this.forceComplete("token-budget-exceeded", {
686
987
  partialContent: lastContent,
687
988
  artifacts,
688
989
  });
689
990
  break;
690
991
  }
691
-
692
- // Enforce iteration limit
693
- if (this._iterationCount >= this.maxIterations * 3) {
694
- // 3 events per iteration (executing + result + potential response)
695
- break;
696
- }
992
+ }
993
+ if (
994
+ strictUsageTelemetry &&
995
+ (pendingUsageCalls.size > 0 || pendingToolCalls.size > 0)
996
+ ) {
997
+ throw runtimeUsageObserverFailure(
998
+ null,
999
+ "CC_CHILD_CALL_SETTLEMENT_INCOMPLETE",
1000
+ "Strict child execution ended with an unsettled provider or tool call",
1001
+ );
697
1002
  }
698
1003
  } catch (err) {
1004
+ if (err?.runtimeLedgerPersistence === true) throw err;
699
1005
  if (this.isAborted()) {
700
1006
  this.forceComplete(this._cancelReason || "cancelled", {
701
1007
  partialContent: lastContent,
@@ -9,4 +9,7 @@
9
9
  * in new code.
10
10
  */
11
11
 
12
- export { WSAgentHandler } from "../gateways/ws/ws-agent-handler.js";
12
+ export {
13
+ WSAgentHandler,
14
+ readCanonicalUsageProtocol,
15
+ } from "../gateways/ws/ws-agent-handler.js";