chainlesschain 0.165.5 → 0.165.8

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 (256) hide show
  1. package/package.json +2 -1
  2. package/src/assets/web-panel/assets/{AIOps-CEeYTeDB.js → AIOps-B3gWmXjo.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BeRUQ3V2.js → ActionButton-G9pdT-0e.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DrV718XF.js → Analytics-Ca30J7m2.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-Cd2Frt7Q.js → AppLayout-BtVTm8PU.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-CUJMlORU.js → Artifacts-BhViNa6u.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-CXJcfT6p.js → Audit-DhKq-FnY.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-DOv6Z7H9.js → BackgroundAgents-BL0SVbnE.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-BwdDyBI0.js → Backup-BWkblnFi.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-BmLn4kYH.js → BaseInput-ClaRNrF8.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-COg8pAW2.js → Chat-sZE2Z77o.js} +4 -4
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-BAfKOnRe.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-BCP4uoU8.js → Checkbox-Cvhay5WM.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-pRt6Y9JI.js → Codegen-BpejL-4N.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DLaprKhS.js → Col-g2Ki6g_1.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DyATsz5f.js → Community-D2xKbNo9.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BXAaupZK.js → Compact-DbL1Pds3.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-DpcJBELr.js → Compliance-DGtZCV4c.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-DG4EFWyd.js → Cowork-4kQpoNsI.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-F6Oy5n2P.js → Cron-BxTYXXAN.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BOdgtalX.js → Crosschain-k0J0LT2N.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-DT1dSkjH.js → DID-BaqhoPgN.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-NBUIqWzC.js → Dashboard-T4RVPIM1.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-CSpHeMYB.js → Dropdown-DszOToWq.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-CEG0xISr.js → EmailListRenderer-C9KJU7HF.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BTZ0BZna.js → FamilyGuardDashboard-Cmr0JnsA.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BuuCTn2V.js → Federation-BI-_2xZX.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-KAVceevk.js → FormItemContext-DsnDEPsl.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-DnHpcQvW.js → GenericCardRenderer-BLncAKKK.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-C_B_0HwB.js → Git-BPQhGXDn.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-DPSZuzuu.js → Governance-CyElbUQW.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-BV-06V7q.js → Inference-CcSntBQD.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-wpDuupn6.js → KnowledgeGraph-p6e7HZ2r.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-Bseca1_I.js → Logs-CNEtr-wz.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-Bj9xI0YH.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-d3kM4DDL.js → Marketplace-Dd2notAJ.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-DQ_xZ23i.js → McpTools-BBsN2CSW.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-CRIeYO4L.js → Memory-Dg2uTvwx.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BsllIa9l.js → MobileBridge-r1YMRiJV.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-BUuQy30X.js → MobileProjects-C-89kSm4.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-BOFDIzrC.js → Mtc-CrPZcVgf.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-BQg-vyvG.js → MtcAudit-sxi7hqJb.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-Bo1jrPdN.js → Multisig-CAgOMfF1.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-Bmod8alw.js → NLProgramming-DafaPts3.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CGGFL8w-.js → Notes-CJM-xUW_.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-BsZvCJxC.js → NotificationSettings-L0ZjfAh_.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-C1-Quo_h.js → OrderTableRenderer-BB1CvCK0.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-BjOeDYOi.js → Organization-DeLtgAD8.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-DwVV3l5A.js → Overflow-CKC2b10z.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-Cu3DQT9W.js → P2P-eyf2rzY1.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-Cg0gR7dH.js → PdhVaultBrowser-5upNIOW8.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-CsAXxRN5.js → Permissions-B8p3W6JK.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-C-nNmnYp.js → PersonalDataHub-BnRMxTq3.js} +5 -5
  54. package/src/assets/web-panel/assets/{Pipeline-BOnW7nNc.js → Pipeline-DjCNI1li.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-ClLSyGKt.js → Privacy-u6gXLbWT.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-DuLvjjq7.js → ProjectInit-BZAw4tkM.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-DQYYbDD9.js → ProjectSettings-B1Tr72q7.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-Drw8MBGK.js → Projects-DO7HFuBQ.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-ckqHQe6K.js → Providers-BjCztyhj.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-DW5BXk-G.js → QrScannerModal-ZWyCUbR1.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-DDLnhNTp.js → QuickAsk-DhDjeW4G.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-PJQ2C91U.js → Recommend-R_CN2MuU.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-s6wmda34.js → RemoteSession-uxFcujeu.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-DC2sb-I3.js → Reputation-DX8D7rks.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-hPGk1eGj.js → Row-BYahQILD.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-RIvfZql0.js → RssFeed-CUSQ2tm-.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DFg1G1eR.js → Search-CnN_S8Cs.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-D6H5p8Dp.js → Security-DcZlh-O4.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-nxYiFV_w.js → Services-ZhBOjzIX.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-BmgFNAdB.js → Skeleton-D5Qnq_lI.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CsaaD2av.js → Skills-BC9cZ3Be.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-yM5y9yvK.js → Sla-DauJ3E8_.js} +1 -1
  73. package/src/assets/web-panel/assets/SpeechSettings-DbNeZ_fh.js +1 -0
  74. package/src/assets/web-panel/assets/{SyncSettings-CFVhEyyr.js → SyncSettings-DUvJbSct.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-DdO02Inn.js → Tasks-BXa-5noQ.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Eo2d8Llu.js → Templates-JxaiUt_3.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-ChESOXgy.js → Tenant-BW4ERQN8.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-BJ7oDxTI.js → Terminal-DltUbdtv.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-hWX0fUvz.js → TimelineRenderer-CMoZz0Tc.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DVBZQnd-.js → Tokens-D_VEV60K.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-D89cQfVq.js → Trigger-CCXTCs0R.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BIVSb4-V.js → Trust-lkGRIPcG.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-B58gWopl.js → UkeySign-BfGeQ9HX.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DhHI7bmG.js → VideoEditing-BEC7pYvc.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-C4FheWS_.js → Wallet-BZdG24o0.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-DnPRq-Bx.js → WebAuthn-yoEddedp.js} +3 -3
  87. package/src/assets/web-panel/assets/{WorkflowEditor-BerRPjpJ.js → WorkflowEditor-BXZEprOW.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BzZ52iKr.js → chat-gg0bzZal.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BI_E4BAn.js → colors-DjRVRuin.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-d50mr3yk.js → compact-item-su-dieAc.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-C6FsQ1IH.js → createContext-Ci3S8oKF.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-CxbFX9uH.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DLZEMgLP.js → hasIn-D8F10heH.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-D-aBumtY.js → index-11wtYQiF.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CjuKZBqJ.js → index-1IgxgALJ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-9H_M2jju.js → index-1agckWSq.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DE0V6cp-.js → index-5JqhujnR.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Y2-q7QLm.js → index-6Tniqk1s.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DoFtCVZ7.js → index-8Z-8BIlN.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-KNGgO4Wm.js → index-BCI5v0yB.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DY4j5zkF.js → index-BDJntYmJ.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BZjjdQ62.js → index-BGzixOGZ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BTpIOTfR.js → index-BMMOVoLD.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BB9SqVSt.js → index-BTFpdBtt.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-AHr7ryWf.js → index-Ba_HyPnE.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Pvf30m8Q.js → index-BbF1IHof.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CRN5TRTQ.js → index-BgT9su_e.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CUaEHfQ0.js → index-BzPB6kGZ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CdKt9fOd.js → index-C6ygzplr.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Dec0Kf_Z.js → index-CC3ZDjzY.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-IPkwSAW_.js → index-CEmXRhAE.js} +1 -1
  112. package/src/assets/web-panel/assets/index-CJGOlduY.js +1 -0
  113. package/src/assets/web-panel/assets/{index-C3k8kevG.js → index-CMPqd5Cv.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-A5CDWP7y.js → index-COWd8uGx.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CO8DAF7U.js → index-CPIYSp4H.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CVzuawCX.js → index-CR0h6seT.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Co7s9LsB.js → index-CUmDhC4j.js} +1 -1
  118. package/src/assets/web-panel/assets/index-CkBCN5yH.js +1 -0
  119. package/src/assets/web-panel/assets/{index-CLoTQr0W.js → index-CusgZPtc.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-B81mo1Et.js → index-DBAETXft.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BcSUl9fA.js → index-DIJ2qFOC.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Q5Tn735s.js → index-Dbq4NMET.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-GXE0D8Nx.js → index-DkMEF5VT.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-TWG-_D1M.js → index-DkfQR3hM.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BAE3hwev.js → index-DnLucOn9.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CgkoH3_g.js → index-DugB_aKa.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BRGx3w6T.js → index-DyLUarhZ.js} +3 -3
  128. package/src/assets/web-panel/assets/{index-BeM4hfht.js → index-T6_6ygJZ.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DsscwxPE.js → index-Tu8eWqh-.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Bmr_vxXD.js → index-W7XUgdVL.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BoNZlzhQ.js → index-dHZinfko.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DqkbHHg8.js → index-jyNgp5FI.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-D-4Hzgej.js → initDefaultProps-Cv4p8e4w.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-D4Wl4xU7.js → motion-B8EwmMOw.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-Cd5eQvL0.js → move-B8R9F8TK.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-B4ilslCW.js → mtc-parser-DoFYz5Bp.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-Ckarx-tf.js → omit-CHWYLBjI.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-QJ0bpCmc.js → pickAttrs-CXuPDO77.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-CKHm-tq8.js → placementArrow-BaAtUUon.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-CV6a_w_Y.js → responsiveObserve-DCc4zcDD.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-mHpeQFgk.js → slide-B_lx89oZ.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-DIaQNQWA.js → statusUtils-DE8DPmR0.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-PJpzavV8.js → styleChecker-1ktXOsL_.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-BH7zTw8S.js → useFlexGapSupport-xH89-wjh.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-BDNG3JDd.js → useFs-DscvfW5p.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-CY2VWdUg.js → usePersonalDataHub-RdMKQta7.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-D0kw9jhz.js → vnode-Z3wTni2T.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-B5g7TN7r.js → zoom-B0iChCsm.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +3 -3
  151. package/src/commands/agent.js +105 -62
  152. package/src/commands/background-session.js +100 -10
  153. package/src/commands/git.js +39 -0
  154. package/src/commands/mcp.js +5 -0
  155. package/src/commands/plugin.js +160 -29
  156. package/src/commands/remote-control.js +295 -110
  157. package/src/commands/session-group.js +131 -0
  158. package/src/commands/session-location.js +48 -0
  159. package/src/commands/session-message.js +171 -0
  160. package/src/commands/session.js +22 -0
  161. package/src/commands/sync-providers.js +4 -1
  162. package/src/commands/update.js +1 -0
  163. package/src/data/changelog.json +41 -2
  164. package/src/gateways/ws/ws-agent-handler.js +20 -12
  165. package/src/harness/jsonl-session-store.js +279 -37
  166. package/src/harness/mcp-client.js +832 -91
  167. package/src/harness/session-index.js +15 -4
  168. package/src/lib/agent-worktree.js +8 -1
  169. package/src/lib/auto-mode-safety-classifier.js +3 -17
  170. package/src/lib/background-agent-keeper-protocol.js +26 -6
  171. package/src/lib/background-agent-supervisor.js +17 -1
  172. package/src/lib/background-session-transport.js +153 -27
  173. package/src/lib/browser-evidence.js +1405 -0
  174. package/src/lib/chrome-connector.js +465 -79
  175. package/src/lib/claude-project-auto-memory.js +481 -0
  176. package/src/lib/claude-project-storage-layout.js +104 -0
  177. package/src/lib/cloud/cloud-client.js +40 -0
  178. package/src/lib/execution-location-local-supervisor.mjs +226 -0
  179. package/src/lib/execution-location-runner-lifecycle.js +991 -0
  180. package/src/lib/execution-location-target-preflight.js +333 -0
  181. package/src/lib/execution-location-target.js +783 -13
  182. package/src/lib/file-lines.js +6 -1
  183. package/src/lib/gateway-client-resilience.js +571 -0
  184. package/src/lib/gitlab-mr-worktree.js +176 -0
  185. package/src/lib/hooks-v2-producers.js +119 -15
  186. package/src/lib/hooks-v2-workspace-context.js +44 -1
  187. package/src/lib/host-resource-budget.js +295 -0
  188. package/src/lib/ide-context.js +15 -2
  189. package/src/lib/llm-config-defaults.js +43 -0
  190. package/src/lib/mcp-client.js +2 -0
  191. package/src/lib/mcp-headers-helper.js +47 -5
  192. package/src/lib/mcp-lifecycle-authority.js +887 -0
  193. package/src/lib/mcp-oauth.js +156 -26
  194. package/src/lib/mcp-tls.js +330 -0
  195. package/src/lib/output-styles.js +12 -0
  196. package/src/lib/paths.js +260 -32
  197. package/src/lib/permission-request.js +48 -0
  198. package/src/lib/plugin-runtime/bin.js +3 -1
  199. package/src/lib/plugin-runtime/hooks.js +3 -1
  200. package/src/lib/plugin-runtime/install.js +730 -71
  201. package/src/lib/plugin-runtime/lsp.js +4 -4
  202. package/src/lib/plugin-runtime/marketplace-archive-source.js +366 -0
  203. package/src/lib/plugin-runtime/marketplace-catalog.js +63 -6
  204. package/src/lib/plugin-runtime/marketplace-command-descriptor.js +343 -0
  205. package/src/lib/plugin-runtime/marketplace-command-source.js +580 -0
  206. package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1 -0
  207. package/src/lib/plugin-runtime/marketplace-source-adapter.js +188 -0
  208. package/src/lib/plugin-runtime/marketplace-source-cache.js +11 -1
  209. package/src/lib/plugin-runtime/mcp.js +3 -1
  210. package/src/lib/plugin-runtime/monitors.js +3 -1
  211. package/src/lib/plugin-runtime/remote-source.js +583 -58
  212. package/src/lib/plugin-runtime/settings.js +3 -1
  213. package/src/lib/plugin-runtime/trust.js +274 -13
  214. package/src/lib/plugin-security.js +393 -41
  215. package/src/lib/plugin-source-identity.js +850 -0
  216. package/src/lib/process-execution-broker/credential-agent.js +210 -41
  217. package/src/lib/process-execution-broker/index.js +15 -1
  218. package/src/lib/process-execution-broker/linux-cgroup-v2.js +391 -0
  219. package/src/lib/process-execution-broker/platform-sandbox.js +50 -28
  220. package/src/lib/project-mcp-trust.js +165 -10
  221. package/src/lib/remote-approval-bridge.js +136 -46
  222. package/src/lib/remote-control.js +217 -31
  223. package/src/lib/resume-session.js +9 -6
  224. package/src/lib/session-core-singletons.js +26 -11
  225. package/src/lib/session-host-lease.js +52 -16
  226. package/src/lib/session-lifecycle-scope.js +153 -0
  227. package/src/lib/session-message-fabric.js +1252 -0
  228. package/src/lib/session-projection.js +286 -3
  229. package/src/lib/session-runtime-retention.js +155 -0
  230. package/src/lib/session-store-guard.js +3 -1
  231. package/src/lib/session-workbench-store.js +466 -0
  232. package/src/lib/settings-loader.cjs +29 -0
  233. package/src/lib/spellcheck.js +211 -0
  234. package/src/lib/sub-agent-context.js +9 -9
  235. package/src/lib/sync-cli-db.js +485 -129
  236. package/src/lib/sync-credentials.js +31 -20
  237. package/src/lib/web-fetch.js +112 -40
  238. package/src/lib/web-search.js +127 -61
  239. package/src/lib/workspace-trust.js +793 -0
  240. package/src/repl/agent-repl.js +175 -19
  241. package/src/repl/permission-prompt.js +29 -8
  242. package/src/repl/repl-keybindings.js +55 -0
  243. package/src/runtime/agent-core.js +362 -20
  244. package/src/runtime/bootstrap.js +37 -13
  245. package/src/runtime/coding-agent-contract-shared.cjs +11 -4
  246. package/src/runtime/headless-runner.js +281 -102
  247. package/src/runtime/headless-stream.js +199 -30
  248. package/src/runtime/mcp-config.js +298 -6
  249. package/src/runtime/policies/agent-policy.js +10 -0
  250. package/src/runtime/status-diagnostics-lite.js +9 -1
  251. package/src/assets/web-panel/assets/ChatBubbleRenderer-4gGkdGgA.js +0 -1
  252. package/src/assets/web-panel/assets/MarkdownRenderer-B4RLp2zs.js +0 -1
  253. package/src/assets/web-panel/assets/SpeechSettings-DPy1XMYh.js +0 -1
  254. package/src/assets/web-panel/assets/devWarning-CagEcIex.js +0 -1
  255. package/src/assets/web-panel/assets/index-pzT9PpOU.js +0 -1
  256. package/src/assets/web-panel/assets/index-z1kFadaX.js +0 -1
@@ -136,6 +136,7 @@ import {
136
136
  } from "../harness/structured-handoff.js";
137
137
  import { isMcpRpcError } from "../harness/mcp-client.js";
138
138
  import { projectCanonicalResumeMessages } from "../lib/session-message-provenance.js";
139
+ import { releaseOldLiveSessionResults } from "../lib/session-runtime-retention.js";
139
140
  import {
140
141
  pathMatchesOpenedFileIdentitySync,
141
142
  sameOpenedFileIdentity,
@@ -515,6 +516,45 @@ export const _gitProcessDeps = {
515
516
  run: gitProcessRunner,
516
517
  };
517
518
 
519
+ function canonicalGitMetadataPath(value) {
520
+ const resolved = path.resolve(String(value || "").trim());
521
+ try {
522
+ const real = fs.realpathSync.native(resolved);
523
+ return process.platform === "win32" ? real.toLowerCase() : real;
524
+ } catch {
525
+ return null;
526
+ }
527
+ }
528
+
529
+ /**
530
+ * Distinguish the primary checkout from a linked worktree using Git's own
531
+ * metadata paths. Unknown/non-repository locations are deliberately not
532
+ * treated as linked worktrees.
533
+ */
534
+ export function classifyGitCheckout(cwd) {
535
+ const query = (argument) => {
536
+ const result = _gitProcessDeps.run(
537
+ "git",
538
+ ["rev-parse", "--path-format=absolute", argument],
539
+ {
540
+ cwd,
541
+ encoding: "utf8",
542
+ timeout: 10000,
543
+ windowsHide: true,
544
+ origin: "agent-core:git-checkout-authority",
545
+ policy: "allow",
546
+ scope: "agent-core",
547
+ },
548
+ );
549
+ if (result?.error || result?.status !== 0) return null;
550
+ return canonicalGitMetadataPath(result.stdout);
551
+ };
552
+ const gitDirectory = query("--git-dir");
553
+ const commonDirectory = query("--git-common-dir");
554
+ if (!gitDirectory || !commonDirectory) return "unknown";
555
+ return gitDirectory === commonDirectory ? "primary" : "linked";
556
+ }
557
+
518
558
  function _killTask(task) {
519
559
  const child = task?.child;
520
560
  if (!child || child.killed || task?.status !== "running") return false;
@@ -918,6 +958,8 @@ async function requestInteractivePermission(
918
958
  args && typeof args === "object" ? Object.keys(args).sort() : [],
919
959
  reason: confirmArgs?.reason || null,
920
960
  cwd,
961
+ trace_id: context.hookTraceId || null,
962
+ parent_id: context.hookParentId || null,
921
963
  },
922
964
  { failClosed: true },
923
965
  );
@@ -3252,25 +3294,35 @@ export async function executeTool(name, args, context = {}) {
3252
3294
  // command unguarded in auto mode — including `reset --hard`, `clean -fd`,
3253
3295
  // `restore .`, `push --force`, `branch -D`, `rebase`, `reflog expire` —
3254
3296
  // which irrecoverably discard work. An explicit settings `allow`/confirmed
3255
- // `ask` (ruleAllowed) pre-authorizes; headless without a confirmer fails
3256
- // closed. Plan mode already blocks non-read-only git below.
3297
+ // A confirmed `ask` pre-authorizes. A static `allow` only pre-authorizes a
3298
+ // linked worktree; primary/unknown checkout identity still needs a live
3299
+ // confirmation. Plan mode already blocks non-read-only git below.
3257
3300
  if (
3258
3301
  name === "git" &&
3259
- !ruleAllowed &&
3260
3302
  !planManager.isActive() &&
3261
3303
  isDangerousGitCommand(args?.command)
3262
3304
  ) {
3263
- const ok = await requestInteractivePermission(name, args, context, cwd, {
3264
- tool: name,
3265
- args,
3266
- rule: null,
3267
- reason: `destructive git command: git ${normalizeGitCommand(args.command)}`,
3268
- });
3269
- if (!ok) {
3270
- return {
3271
- error: `[Destructive Git] "git ${normalizeGitCommand(args.command)}" discards work irrecoverably and requires confirmation — denied. Add a settings allow rule to pre-authorize.`,
3272
- policy: { decision: "ask", via: "destructive-git" },
3273
- };
3305
+ const checkout = classifyGitCheckout(args?.cwd || cwd);
3306
+ const settingsAskWasConfirmed =
3307
+ settingsVerdict.decision === "ask" && ruleAllowed;
3308
+ const linkedWorktreeWasAllowed = checkout === "linked" && ruleAllowed;
3309
+ if (!settingsAskWasConfirmed && !linkedWorktreeWasAllowed) {
3310
+ const ok = await requestInteractivePermission(name, args, context, cwd, {
3311
+ tool: name,
3312
+ args,
3313
+ rule: null,
3314
+ reason: `destructive git command in ${checkout} checkout: git ${normalizeGitCommand(args.command)}`,
3315
+ });
3316
+ if (!ok) {
3317
+ return {
3318
+ error: `[Destructive Git] "git ${normalizeGitCommand(args.command)}" targets the ${checkout} checkout, discards work irrecoverably, and requires live confirmation — denied.`,
3319
+ policy: {
3320
+ decision: "ask",
3321
+ via: "destructive-git",
3322
+ checkout,
3323
+ },
3324
+ };
3325
+ }
3274
3326
  }
3275
3327
  }
3276
3328
 
@@ -3508,6 +3560,8 @@ export async function executeTool(name, args, context = {}) {
3508
3560
  input_keys:
3509
3561
  args && typeof args === "object" ? Object.keys(args).sort() : [],
3510
3562
  cwd,
3563
+ trace_id: context.hookTraceId || null,
3564
+ parent_id: context.hookParentId || null,
3511
3565
  },
3512
3566
  { failClosed: true },
3513
3567
  );
@@ -3659,6 +3713,7 @@ export async function executeTool(name, args, context = {}) {
3659
3713
  subAgentDepth: context.subAgentDepth || 0,
3660
3714
  subAgentBudget: context.subAgentBudget || null,
3661
3715
  sessionBudget: context.sessionBudget || null,
3716
+ hostResourceBudget: context.hostResourceBudget || null,
3662
3717
  // Effective contract of THIS loop (parent ceiling for a nested spawn) +
3663
3718
  // the MCP tool definitions this loop exposes (inheritable by a spawn).
3664
3719
  subAgentContract: context.subAgentContract || null,
@@ -3675,6 +3730,15 @@ export async function executeTool(name, args, context = {}) {
3675
3730
  managedCheckpoint: context.managedCheckpoint === true,
3676
3731
  fileMutationScope: context.fileMutationScope || null,
3677
3732
  hermeticExecution: context.hermeticExecution === true,
3733
+ browserEvidenceBinding: context.browserEvidenceBinding || null,
3734
+ browserOriginGrants: context.browserOriginGrants || null,
3735
+ browserExpectedGrantRevisions:
3736
+ context.browserExpectedGrantRevisions || null,
3737
+ browserReplaySourceEnvelope: context.browserReplaySourceEnvelope || null,
3738
+ browserReplayAllowSideEffects:
3739
+ context.browserReplayAllowSideEffects === true,
3740
+ browserReplayAllowCredentials:
3741
+ context.browserReplayAllowCredentials === true,
3678
3742
  });
3679
3743
  } catch (err) {
3680
3744
  if (
@@ -4756,9 +4820,9 @@ async function filterSkillsByCwd(skills, cwd) {
4756
4820
  }
4757
4821
  }
4758
4822
 
4759
- async function promoteBrowserScreenshot(
4823
+ async function promoteBrowserGeneratedArtifact(
4760
4824
  filePath,
4761
- { sessionId = null, title = "Browser screenshot" } = {},
4825
+ { sessionId = null, title, kind, failureLabel } = {},
4762
4826
  ) {
4763
4827
  if (!filePath) return { artifact: null, error: null };
4764
4828
  try {
@@ -4767,7 +4831,7 @@ async function promoteBrowserScreenshot(
4767
4831
  const entry = new ArtifactStore().publish({
4768
4832
  filePath,
4769
4833
  title,
4770
- kind: "screenshot",
4834
+ kind,
4771
4835
  sessionId: sessionId ? String(sessionId) : null,
4772
4836
  });
4773
4837
  return { artifact: publicArtifactMetadata(entry), error: null };
@@ -4778,7 +4842,7 @@ async function promoteBrowserScreenshot(
4778
4842
  : "";
4779
4843
  return {
4780
4844
  artifact: null,
4781
- error: `browser screenshot artifact publication failed${code ? ` (${code})` : ""}`,
4845
+ error: `${failureLabel} artifact publication failed${code ? ` (${code})` : ""}`,
4782
4846
  };
4783
4847
  } finally {
4784
4848
  try {
@@ -4789,6 +4853,155 @@ async function promoteBrowserScreenshot(
4789
4853
  }
4790
4854
  }
4791
4855
 
4856
+ async function promoteBrowserScreenshot(
4857
+ filePath,
4858
+ { sessionId = null, title = "Browser screenshot" } = {},
4859
+ ) {
4860
+ return promoteBrowserGeneratedArtifact(filePath, {
4861
+ sessionId,
4862
+ title,
4863
+ kind: "screenshot",
4864
+ failureLabel: "browser screenshot",
4865
+ });
4866
+ }
4867
+
4868
+ async function promoteBrowserDownload(
4869
+ filePath,
4870
+ { sessionId = null, title = "Browser download" } = {},
4871
+ ) {
4872
+ return promoteBrowserGeneratedArtifact(filePath, {
4873
+ sessionId,
4874
+ title,
4875
+ kind: "data",
4876
+ failureLabel: "browser download",
4877
+ });
4878
+ }
4879
+
4880
+ async function publishBrowserEvidence(envelope, sessionId) {
4881
+ if (!envelope?.envelopeDigest) return { artifact: null, error: null };
4882
+ try {
4883
+ const { ArtifactStore, publicArtifactMetadata } =
4884
+ await import("../lib/artifact-store.js");
4885
+ const {
4886
+ browserEvidenceDigest,
4887
+ canonicalBrowserEvidenceJson,
4888
+ verifyBrowserEvidenceEnvelope,
4889
+ } = await import("../lib/browser-evidence.js");
4890
+ verifyBrowserEvidenceEnvelope(envelope);
4891
+ if (!sessionId || String(sessionId) !== envelope.binding.session.id) {
4892
+ throw new Error("browser evidence is not bound to the active session");
4893
+ }
4894
+ const data = `${canonicalBrowserEvidenceJson(envelope)}\n`;
4895
+ const expectedFileDigest = browserEvidenceDigest(data).slice(
4896
+ "sha256:".length,
4897
+ );
4898
+ const expectedLineage = {
4899
+ schema: envelope.schema,
4900
+ sessionId: envelope.binding.session.id,
4901
+ sessionRevision: envelope.binding.session.revision,
4902
+ diffDigest: envelope.binding.diff.digest,
4903
+ testRunId: envelope.binding.testRun.id,
4904
+ };
4905
+ const store = new ArtifactStore();
4906
+ const published = store.publishDataOnce({
4907
+ data,
4908
+ fileName: "browser-evidence-envelope.json",
4909
+ title: `Browser evidence ${envelope.binding.session.id}@${envelope.binding.session.revision}`,
4910
+ kind: "data",
4911
+ mime: "application/json",
4912
+ sessionId: String(sessionId),
4913
+ immutable: true,
4914
+ recordDigest: envelope.envelopeDigest,
4915
+ lineage: expectedLineage,
4916
+ });
4917
+ const entry = published.entry;
4918
+ const integrity = store.verifyIntegrity(entry);
4919
+ if (
4920
+ !integrity.ok ||
4921
+ entry.sessionId !== String(sessionId) ||
4922
+ entry.immutable !== true ||
4923
+ entry.recordDigest !== envelope.envelopeDigest ||
4924
+ entry.sha256 !== expectedFileDigest ||
4925
+ canonicalBrowserEvidenceJson(entry.lineage) !==
4926
+ canonicalBrowserEvidenceJson(expectedLineage)
4927
+ ) {
4928
+ throw new Error("persisted evidence authority failed verification");
4929
+ }
4930
+ return {
4931
+ artifact: publicArtifactMetadata(entry),
4932
+ error: null,
4933
+ };
4934
+ } catch (error) {
4935
+ const code =
4936
+ typeof error?.code === "string"
4937
+ ? error.code.replace(/[^A-Z0-9_-]/giu, "").slice(0, 40)
4938
+ : "";
4939
+ return {
4940
+ artifact: null,
4941
+ error: `browser evidence artifact publication failed${code ? ` (${code})` : ""}`,
4942
+ };
4943
+ }
4944
+ }
4945
+
4946
+ async function resolveBrowserUploadArtifact(artifactId, sessionId) {
4947
+ const { ArtifactStore, publicArtifactMetadata } =
4948
+ await import("../lib/artifact-store.js");
4949
+ const store = new ArtifactStore();
4950
+ return store.withIndexSnapshot((entries) => {
4951
+ const matches = entries.filter((entry) => entry.id === artifactId);
4952
+ if (matches.length !== 1) {
4953
+ throw new Error(
4954
+ matches.length === 0
4955
+ ? "upload artifact was not found"
4956
+ : "upload artifact authority is ambiguous",
4957
+ );
4958
+ }
4959
+ const entry = matches[0];
4960
+ if (!sessionId || entry.sessionId !== String(sessionId)) {
4961
+ throw new Error("upload artifact is not bound to the active session");
4962
+ }
4963
+ if (
4964
+ typeof entry.file !== "string" ||
4965
+ path.basename(entry.file) !== entry.file ||
4966
+ !(entry.file === entry.id || entry.file.startsWith(`${entry.id}.`)) ||
4967
+ !/^[a-f0-9]{64}$/u.test(String(entry.sha256 || ""))
4968
+ ) {
4969
+ throw new Error("upload artifact storage authority is invalid");
4970
+ }
4971
+ const integrity = store.verifyIntegrity(entry);
4972
+ if (!integrity.ok) {
4973
+ throw new Error("upload artifact failed digest verification");
4974
+ }
4975
+ const storedPath = store.storedPath(entry);
4976
+ if (fs.statSync(storedPath).size !== Number(entry.size)) {
4977
+ throw new Error("upload artifact size authority mismatch");
4978
+ }
4979
+ const temporaryDirectory = fs.mkdtempSync(
4980
+ path.join(os.tmpdir(), "cc-browser-upload-"),
4981
+ );
4982
+ const temporaryPath = path.join(
4983
+ temporaryDirectory,
4984
+ path.basename(entry.file || "upload.bin"),
4985
+ );
4986
+ try {
4987
+ fs.writeFileSync(temporaryPath, fs.readFileSync(storedPath), {
4988
+ flag: "wx",
4989
+ mode: 0o600,
4990
+ flush: true,
4991
+ });
4992
+ } catch (error) {
4993
+ fs.rmSync(temporaryDirectory, { recursive: true, force: true });
4994
+ throw error;
4995
+ }
4996
+ return {
4997
+ path: temporaryPath,
4998
+ metadata: publicArtifactMetadata(entry),
4999
+ cleanup: () =>
5000
+ fs.rmSync(temporaryDirectory, { recursive: true, force: true }),
5001
+ };
5002
+ });
5003
+ }
5004
+
4792
5005
  const MCP_LEDGER_EFFECTS = new Set(["read", "unknown", "write", "destructive"]);
4793
5006
 
4794
5007
  /**
@@ -5053,10 +5266,17 @@ async function executeToolInner(
5053
5266
  onToolCallSettlement = null,
5054
5267
  backgroundUsageFailureState = null,
5055
5268
  toolAdmission = null,
5269
+ hostResourceBudget = null,
5056
5270
  unattendedActionPolicy = null,
5057
5271
  managedCheckpoint = false,
5058
5272
  fileMutationScope = null,
5059
5273
  hermeticExecution = false,
5274
+ browserEvidenceBinding = null,
5275
+ browserOriginGrants = null,
5276
+ browserExpectedGrantRevisions = null,
5277
+ browserReplaySourceEnvelope = null,
5278
+ browserReplayAllowSideEffects = false,
5279
+ browserReplayAllowCredentials = false,
5060
5280
  // Hook-envelope tracing: this run's trace id, threaded into child loops
5061
5281
  // (spawn_sub_agent / isolated run_skill) as their parent_id.
5062
5282
  hookTraceId = null,
@@ -6775,6 +6995,7 @@ async function executeToolInner(
6775
6995
  subAgentDepth,
6776
6996
  subAgentBudget,
6777
6997
  sessionBudget,
6998
+ hostResourceBudget,
6778
6999
  subAgentContract,
6779
7000
  settingsHooks,
6780
7001
  // Immutable parent execution authority. The child may only tighten
@@ -6839,6 +7060,7 @@ async function executeToolInner(
6839
7060
  maxBytes: args.maxBytes,
6840
7061
  timeout: args.timeout,
6841
7062
  config: webFetchConfig,
7063
+ hostResourceBudget,
6842
7064
  });
6843
7065
  return attachDescriptor(result);
6844
7066
  } catch (err) {
@@ -6866,6 +7088,7 @@ async function executeToolInner(
6866
7088
  maxResults: args.maxResults,
6867
7089
  timeout: args.timeout,
6868
7090
  config: webSearchConfig,
7091
+ hostResourceBudget,
6869
7092
  });
6870
7093
  return attachDescriptor(result);
6871
7094
  } catch (err) {
@@ -7331,6 +7554,14 @@ async function executeToolInner(
7331
7554
  tab: args.tab != null ? Number(args.tab) : undefined,
7332
7555
  continueOnError: args.continue_on_error === true,
7333
7556
  sessionId: sessionId ? String(sessionId) : null,
7557
+ evidenceBinding: browserEvidenceBinding,
7558
+ originGrants: browserOriginGrants,
7559
+ expectedGrantRevisions: browserExpectedGrantRevisions,
7560
+ replaySourceEnvelope: browserReplaySourceEnvelope,
7561
+ replayAllowSideEffects: browserReplayAllowSideEffects,
7562
+ replayAllowCredentials: browserReplayAllowCredentials,
7563
+ resolveUploadArtifact: (artifactId) =>
7564
+ resolveBrowserUploadArtifact(artifactId, sessionId),
7334
7565
  });
7335
7566
  if (!result.ok && result.error) {
7336
7567
  // Nothing ran (validation / attach failure) — surface as an error.
@@ -7363,8 +7594,45 @@ async function executeToolInner(
7363
7594
  step.detail = promoted.error;
7364
7595
  }
7365
7596
  }
7597
+ if (originalStep.downloadPath) {
7598
+ const promoted = await promoteBrowserDownload(
7599
+ originalStep.downloadPath,
7600
+ {
7601
+ sessionId,
7602
+ title: `Browser download ${i + 1} — ${originalStep.downloadSuggestedName || "file"}`,
7603
+ },
7604
+ );
7605
+ delete step.downloadPath;
7606
+ delete step.downloadRef;
7607
+ if (promoted.artifact) {
7608
+ step.downloadArtifact = promoted.artifact;
7609
+ step.downloadRef = promoted.artifact.id;
7610
+ step.detail = `download artifact: ${promoted.artifact.id}`;
7611
+ } else {
7612
+ step.downloadArtifactError = promoted.error;
7613
+ step.detail = promoted.error;
7614
+ }
7615
+ }
7366
7616
  safeResult.steps.push(step);
7367
7617
  }
7618
+ if (result.evidence) {
7619
+ const publishedEvidence = await publishBrowserEvidence(
7620
+ result.evidence,
7621
+ sessionId,
7622
+ );
7623
+ safeResult.evidence = result.evidence;
7624
+ if (publishedEvidence.artifact) {
7625
+ safeResult.evidenceArtifact = publishedEvidence.artifact;
7626
+ safeResult.evidenceRef = publishedEvidence.artifact.id;
7627
+ } else {
7628
+ safeResult.evidenceArtifactError = publishedEvidence.error;
7629
+ safeResult.evidencePublicationFailed = true;
7630
+ safeResult.ok = false;
7631
+ safeResult.retrySafe = false;
7632
+ safeResult.recovery =
7633
+ "Browser actions may have completed, but canonical evidence publication failed; do not retry side effects automatically.";
7634
+ }
7635
+ }
7368
7636
  return attachDescriptor(safeResult);
7369
7637
  } catch (err) {
7370
7638
  return attachDescriptor({
@@ -7797,6 +8065,7 @@ async function executeToolInner(
7797
8065
  ? { workflowEffectId: workflowChildEffectId }
7798
8066
  : {}),
7799
8067
  ...(sessionBudget ? { sessionBudget } : {}),
8068
+ ...(hostResourceBudget ? { hostResourceBudget } : {}),
7800
8069
  ...(permissionRules ? { permissionRules } : {}),
7801
8070
  ...(hostManagedToolPolicy
7802
8071
  ? {
@@ -9612,6 +9881,10 @@ async function _executeSpawnSubAgent(args, ctx) {
9612
9881
  const subLlmOptions = {
9613
9882
  ...parentLlm,
9614
9883
  model: mdModel || parentLlm.model || undefined,
9884
+ // Preserve the host's optional event channel across every nesting level.
9885
+ // It is observational only: child hooks/tools must never depend on a
9886
+ // headless consumer being connected.
9887
+ ...(interaction ? { interaction } : {}),
9615
9888
  // Contract `effort` is a compute hint (reasoning level), not authority —
9616
9889
  // forwarded to the child loop; harmless if the provider ignores it.
9617
9890
  ...(effectiveContract?.effort ? { effort: effectiveContract.effort } : {}),
@@ -9819,7 +10092,21 @@ async function _executeSpawnSubAgent(args, ctx) {
9819
10092
  // single total-sub-agent pool (breadth cap spans the whole tree).
9820
10093
  subAgentBudget: ctx.subAgentBudget || null,
9821
10094
  ...(ctx.sessionBudget ? { sessionBudget: ctx.sessionBudget } : {}),
10095
+ ...(ctx.hostResourceBudget
10096
+ ? { hostResourceBudget: ctx.hostResourceBudget }
10097
+ : {}),
9822
10098
  onUsage,
10099
+ ...(interaction && typeof interaction.emit === "function"
10100
+ ? {
10101
+ onProgress: (progress) =>
10102
+ emit("sub-agent.progress", {
10103
+ event_type: progress?.type || "unknown",
10104
+ tool: progress?.tool || null,
10105
+ iteration_count: progress?.iterationCount || 0,
10106
+ token_count: progress?.tokenCount || 0,
10107
+ }),
10108
+ }
10109
+ : {}),
9823
10110
  ...(ctx.strictUsageTelemetry === true
9824
10111
  ? {
9825
10112
  strictUsageTelemetry: true,
@@ -12571,6 +12858,7 @@ async function _settleAutomaticCompaction({
12571
12858
  compacted,
12572
12859
  stats,
12573
12860
  options,
12861
+ trigger = "auto",
12574
12862
  }) {
12575
12863
  if (!_sameMessageSnapshot(messages, liveExpectedMessages)) {
12576
12864
  throw _compactionSettlementError(
@@ -12590,7 +12878,7 @@ async function _settleAutomaticCompaction({
12590
12878
  settlement = options.onCompaction(stats, compacted, {
12591
12879
  expectedMessages: authorityExpectedMessages,
12592
12880
  liveExpectedMessages,
12593
- trigger: "auto",
12881
+ trigger,
12594
12882
  });
12595
12883
  } else if (options.sessionId && options.persistCompaction !== false) {
12596
12884
  const store = await import("../harness/jsonl-session-store.js");
@@ -12605,7 +12893,7 @@ async function _settleAutomaticCompaction({
12605
12893
  options.sessionId,
12606
12894
  {
12607
12895
  ...stats,
12608
- trigger: "auto",
12896
+ trigger,
12609
12897
  messages: projectCanonicalResumeMessages(compacted, { strict: true }),
12610
12898
  },
12611
12899
  authorityExpectedMessages,
@@ -12728,6 +13016,9 @@ export async function* agentLoop(messages, options) {
12728
13016
  const { IterationBudget, WarningLevel } =
12729
13017
  await import("../lib/iteration-budget.js");
12730
13018
  const budget = options.iterationBudget || new IterationBudget();
13019
+ const { HostResourceBudget } = await import("../lib/host-resource-budget.js");
13020
+ const hostResourceBudget =
13021
+ options.hostResourceBudget || new HostResourceBudget();
12731
13022
  const signal = options.signal || null;
12732
13023
  const workflowEffectId = _normalizeWorkflowEffectId(options.workflowEffectId);
12733
13024
  // Optional OpenTelemetry recorder (TelemetryRecorder). When present, the loop
@@ -12941,6 +13232,10 @@ export async function* agentLoop(messages, options) {
12941
13232
  // CLI root does not create one yet; when supplied, every nested child sees
12942
13233
  // the same object and cannot reset concurrency/spawn/depth totals.
12943
13234
  sessionBudget: options.sessionBudget || null,
13235
+ // Share bounded WebFetch cache and renderer/tool/event admission across
13236
+ // the main loop and every nested subagent. A host can tighten these limits
13237
+ // by supplying its own budget; otherwise the conservative defaults apply.
13238
+ hostResourceBudget,
12944
13239
  // This loop's EFFECTIVE subagent contract (set when this loop IS a spawned
12945
13240
  // sub-agent). Threaded so a nested spawn_sub_agent sees it as the parent
12946
13241
  // ceiling (tighten-only). null at the top level (no ceiling).
@@ -13180,6 +13475,53 @@ export async function* agentLoop(messages, options) {
13180
13475
  };
13181
13476
  }
13182
13477
 
13478
+ // Release result bodies that have left the recent display window before
13479
+ // every provider admission, independent of the semantic-compaction token
13480
+ // threshold. Settlement persists a bounded resume checkpoint before the
13481
+ // live array changes; the earlier hash-chained result events remain the
13482
+ // durable evidence for audit/recovery.
13483
+ if (options.runtimeResultRetention !== false && messages.length > 32) {
13484
+ const retentionConfig =
13485
+ options.runtimeResultRetention &&
13486
+ typeof options.runtimeResultRetention === "object"
13487
+ ? options.runtimeResultRetention
13488
+ : options.runtimeResultRetentionOptions;
13489
+ const retained = releaseOldLiveSessionResults(messages, retentionConfig);
13490
+ if (
13491
+ retained.stats.released > 0 &&
13492
+ !_sameMessageSnapshot(retained.messages, messages)
13493
+ ) {
13494
+ const authorityExpectedMessages = [...messages];
13495
+ const liveExpectedMessages = [...messages];
13496
+ try {
13497
+ await _settleAutomaticCompaction({
13498
+ messages,
13499
+ liveExpectedMessages,
13500
+ authorityExpectedMessages,
13501
+ compacted: retained.messages,
13502
+ stats: retained.stats,
13503
+ options,
13504
+ trigger: "runtime-retention",
13505
+ });
13506
+ yield {
13507
+ type: "session-runtime-retention",
13508
+ runId,
13509
+ stats: retained.stats,
13510
+ };
13511
+ } catch (error) {
13512
+ yield {
13513
+ type: "session-runtime-retention-degraded",
13514
+ runId,
13515
+ reason:
13516
+ error?.code === "SESSION_REVISION_STALE"
13517
+ ? "session_messages_changed_during_retention"
13518
+ : "canonical_retention_settlement_failed",
13519
+ code: error?.code || "CC_SESSION_RETENTION_SETTLEMENT_FAILED",
13520
+ };
13521
+ }
13522
+ }
13523
+ }
13524
+
13183
13525
  // Headless auto-compaction (Claude-Code `--print` parity). Keeps long
13184
13526
  // `-p` / `--resume` runs under the model's context window instead of
13185
13527
  // growing until the provider rejects the request. Opt-out with
@@ -13,6 +13,12 @@
13
13
  */
14
14
 
15
15
  import { logger } from "../lib/logger.js";
16
+ import { join } from "node:path";
17
+ import {
18
+ ensureDir as ensurePrivateDir,
19
+ ensureHomeDir,
20
+ resolveConfigDataRoot,
21
+ } from "../lib/paths.js";
16
22
 
17
23
  let _context = null;
18
24
 
@@ -40,19 +46,37 @@ export async function bootstrap(options = {}) {
40
46
  // Stage 1: Environment
41
47
  if (options.verbose) logger.verbose("Stage 1: Detecting environment...");
42
48
  const coreEnv = await import("@chainlesschain/core-env");
43
- ctx.env = {
44
- runtime: coreEnv.getRuntimeInfo(),
45
- userDataPath: coreEnv.getUserDataPath(),
46
- configDir: coreEnv.getConfigDir(),
47
- dataDir: coreEnv.getDataDir(),
48
- logsDir: coreEnv.getLogsDir(),
49
- };
50
-
51
- // Ensure directories exist
52
- coreEnv.ensureDir(ctx.env.userDataPath);
53
- coreEnv.ensureDir(ctx.env.configDir);
54
- coreEnv.ensureDir(ctx.env.dataDir);
55
- coreEnv.ensureDir(ctx.env.logsDir);
49
+ const configRoot = resolveConfigDataRoot();
50
+ if (configRoot.source === "claude") {
51
+ // core-env intentionally knows only native roots. Keep its runtime
52
+ // metadata but make all CLI runtime config/data state follow the
53
+ // validated CLAUDE_CONFIG_DIR root rather than silently splitting it
54
+ // into the platform-default user-data directory.
55
+ ctx.env = {
56
+ runtime: coreEnv.getRuntimeInfo(),
57
+ userDataPath: configRoot.path,
58
+ configDir: configRoot.path,
59
+ dataDir: join(configRoot.path, "data"),
60
+ logsDir: join(configRoot.path, "logs"),
61
+ };
62
+ ensureHomeDir();
63
+ ensurePrivateDir(ctx.env.dataDir);
64
+ ensurePrivateDir(ctx.env.logsDir);
65
+ } else {
66
+ ctx.env = {
67
+ runtime: coreEnv.getRuntimeInfo(),
68
+ userDataPath: coreEnv.getUserDataPath(),
69
+ configDir: coreEnv.getConfigDir(),
70
+ dataDir: coreEnv.getDataDir(),
71
+ logsDir: coreEnv.getLogsDir(),
72
+ };
73
+
74
+ // Ensure directories exist
75
+ coreEnv.ensureDir(ctx.env.userDataPath);
76
+ coreEnv.ensureDir(ctx.env.configDir);
77
+ coreEnv.ensureDir(ctx.env.dataDir);
78
+ coreEnv.ensureDir(ctx.env.logsDir);
79
+ }
56
80
 
57
81
  // Stage 2-3: Logger (shared-logger optional, CLI logger always works)
58
82
  if (options.verbose) logger.verbose("Stage 2-3: Logger ready");