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
@@ -39,6 +39,7 @@ import {
39
39
  } from "./mcp-config.js";
40
40
  import { maybeApplyToolSearch } from "./mcp-tool-search.js";
41
41
  import { IterationBudget } from "../lib/iteration-budget.js";
42
+ import { HostResourceBudget } from "../lib/host-resource-budget.js";
42
43
  import {
43
44
  startSession as jsonlStartSession,
44
45
  appendUserMessage as jsonlAppendUserMessage,
@@ -83,6 +84,7 @@ import { TurnBindingLog, createTurnBindingFeed } from "../lib/turn-binding.js";
83
84
  import { TURN_BINDING_EVENT } from "../lib/turn-binding-store.js";
84
85
  import { operationIdempotencyKey } from "../lib/idempotency.js";
85
86
  import {
87
+ addHooksV2EventObserver,
86
88
  emitHooksV2Event,
87
89
  executeHooksV2Event,
88
90
  resolvePromptExpansion,
@@ -434,6 +436,10 @@ export function applyForkSession(opts = {}, store = {}) {
434
436
  */
435
437
  const HEADLESS_SESSION_RESOLUTION = Symbol("headlessSessionResolution");
436
438
  const HEADLESS_SESSION_HOST_LEASE = Symbol("headlessSessionHostLease");
439
+ const HEADLESS_HOOK_EVENT_CLEANUP = Symbol("headlessHookEventCleanup");
440
+ const HOST_EVENT_BACKLOG_CODE = "CC_HOST_EVENT_BACKLOG_EXHAUSTED";
441
+ const HOST_EVENT_BACKLOG_ERROR =
442
+ "CC_HOST_EVENT_BACKLOG_EXHAUSTED: event backlog limit reached";
437
443
 
438
444
  async function withHeadlessSessionHostLease(options, deps, task) {
439
445
  const prompt = (options.prompt || "").trim();
@@ -561,11 +567,16 @@ export async function runAgentHeadless(options = {}, deps = {}) {
561
567
  ? abortSignals[0]
562
568
  : AbortSignal.any(abortSignals),
563
569
  };
570
+ // The inner runner can return before its long-lived cleanup `finally` is
571
+ // installed. Keep its pre-manifest hook queue disposer in this shared scope
572
+ // so the top-level host still releases every event slot on any early throw.
573
+ const hookEventCleanup = { dispose: null };
564
574
  const runtimeDeps = {
565
575
  ...deps,
566
576
  writeOut: outputFlow.writeOut,
567
577
  writeErr: outputFlow.writeErr,
568
578
  outputFlow,
579
+ [HEADLESS_HOOK_EVENT_CLEANUP]: hookEventCleanup,
569
580
  };
570
581
  const installSafety = deps.installPipeSafety || installPipeSafety;
571
582
  const disposePipeSafety = shouldInstallPipeSafety
@@ -586,6 +597,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
586
597
  } catch (error) {
587
598
  failure = error;
588
599
  } finally {
600
+ try {
601
+ hookEventCleanup.dispose?.();
602
+ } catch {
603
+ // Queue-slot cleanup is best-effort and must not replace the run error.
604
+ }
589
605
  try {
590
606
  await outputFlow.wait();
591
607
  } catch (error) {
@@ -653,6 +669,69 @@ async function runAgentHeadlessInWorkspace(
653
669
  `headless-${Date.now()}-${process.pid}`,
654
670
  );
655
671
  const sessionHostLease = deps[HEADLESS_SESSION_HOST_LEASE] || null;
672
+ const includeHookEvents = isStream && options.includeHookEvents === true;
673
+ // One headless invocation owns one bounded queue/cache authority. Keep an
674
+ // injected authority intact so an embedding can share it with its host.
675
+ // Do not wire sessionBudget here: executeTool already owns that lease.
676
+ const hostResourceBudget =
677
+ options.hostResourceBudget || new HostResourceBudget();
678
+ const pendingHookEvents = [];
679
+ let writeHookEvent = null;
680
+ let removeHookObserver = null;
681
+ let hookEventBacklogExhausted = false;
682
+ let hookEventQueueDisposed = false;
683
+ const disposePendingHookEvents = () => {
684
+ if (hookEventQueueDisposed) return;
685
+ hookEventQueueDisposed = true;
686
+ try {
687
+ removeHookObserver?.();
688
+ } finally {
689
+ removeHookObserver = null;
690
+ while (pendingHookEvents.length > 0) {
691
+ const queued = pendingHookEvents.shift();
692
+ try {
693
+ queued?.lease?.release?.();
694
+ } catch {
695
+ // Budget slots are idempotent, but injected authorities may throw
696
+ // during teardown. Continue draining every remaining slot.
697
+ }
698
+ }
699
+ }
700
+ };
701
+ const queuePendingHookEvent = (event) => {
702
+ if (hookEventQueueDisposed || hookEventBacklogExhausted) return;
703
+ if (writeHookEvent) {
704
+ writeHookEvent(event);
705
+ return;
706
+ }
707
+ try {
708
+ if (typeof hostResourceBudget?.admitEvent !== "function") {
709
+ throw new TypeError(
710
+ "host resource budget does not provide admitEvent()",
711
+ );
712
+ }
713
+ const lease = hostResourceBudget.admitEvent();
714
+ if (!lease || typeof lease.release !== "function") {
715
+ throw new TypeError("host resource budget event admission is invalid");
716
+ }
717
+ pendingHookEvents.push({ event, lease });
718
+ } catch {
719
+ // Hook lifecycle projection is diagnostic-only, but retaining arbitrary
720
+ // events before the manifest is ready is not. Stop observing and fail the
721
+ // run at the next safe protocol boundary without exposing hook/input data.
722
+ hookEventBacklogExhausted = true;
723
+ disposePendingHookEvents();
724
+ }
725
+ };
726
+ const hookEventCleanupScope = deps[HEADLESS_HOOK_EVENT_CLEANUP];
727
+ if (hookEventCleanupScope) {
728
+ hookEventCleanupScope.dispose = disposePendingHookEvents;
729
+ }
730
+ if (includeHookEvents) {
731
+ const subscribeHookEvents =
732
+ deps.addHooksV2EventObserver || addHooksV2EventObserver;
733
+ removeHookObserver = subscribeHookEvents(sessionId, queuePendingHookEvent);
734
+ }
656
735
 
657
736
  const emitHeadlessError = (resultMsg) => {
658
737
  if (isStream) {
@@ -707,6 +786,7 @@ async function runAgentHeadlessInWorkspace(
707
786
  "fully verified; resume/write admission was refused";
708
787
  emitHeadlessError(message);
709
788
  writeErr(`${message}\n`);
789
+ disposePendingHookEvents();
710
790
  return {
711
791
  exitCode: 1,
712
792
  result: message,
@@ -723,6 +803,7 @@ async function runAgentHeadlessInWorkspace(
723
803
  "CC_OBSERVABILITY_SCOPE_IMMUTABLE: an existing session scope cannot be overwritten; create a new scoped session";
724
804
  emitHeadlessError(message);
725
805
  writeErr(`${message}\n`);
806
+ disposePendingHookEvents();
726
807
  return {
727
808
  exitCode: 1,
728
809
  result: message,
@@ -800,9 +881,8 @@ async function runAgentHeadlessInWorkspace(
800
881
  const loaded = loadHooks({ cwd, settingsFile: options.settingsFile });
801
882
  // Fold in installed plugins' hooks/hooks.json (Phase 3.3c) — plugins ADD
802
883
  // to the user's settings hooks, never replace them.
803
- const { mergePluginHooks } = await import(
804
- "../lib/plugin-runtime/hooks.js"
805
- );
884
+ const { mergePluginHooks } =
885
+ await import("../lib/plugin-runtime/hooks.js");
806
886
  const effectiveHooks = mergePluginHooks(
807
887
  attachAuthorityErrors(loaded.hooks, loaded.authorityErrors),
808
888
  { cwd },
@@ -843,9 +923,8 @@ async function runAgentHeadlessInWorkspace(
843
923
  // the run, so no explicit restore is needed.
844
924
  if (!hermeticExecution) {
845
925
  try {
846
- const { applyPluginBinPath } = await import(
847
- "../lib/plugin-runtime/bin.js"
848
- );
926
+ const { applyPluginBinPath } =
927
+ await import("../lib/plugin-runtime/bin.js");
849
928
  applyPluginBinPath({ cwd });
850
929
  } catch {
851
930
  /* best-effort — plugin bin PATH never blocks a headless run */
@@ -856,9 +935,8 @@ async function runAgentHeadlessInWorkspace(
856
935
  // keys not already set; the process exits at the end so no restore is needed.
857
936
  if (!hermeticExecution) {
858
937
  try {
859
- const { applyPluginSettingsEnv } = await import(
860
- "../lib/plugin-runtime/settings.js"
861
- );
938
+ const { applyPluginSettingsEnv } =
939
+ await import("../lib/plugin-runtime/settings.js");
862
940
  applyPluginSettingsEnv({ cwd });
863
941
  } catch {
864
942
  /* best-effort — plugin settings never block a headless run */
@@ -981,6 +1059,7 @@ async function runAgentHeadlessInWorkspace(
981
1059
  : "CC_OBSERVABILITY_SCOPE_AUTHORITY_UNAVAILABLE: existing session authority could not be excluded";
982
1060
  emitHeadlessError(message);
983
1061
  writeErr(`${message}\n`);
1062
+ disposePendingHookEvents();
984
1063
  return { exitCode: 1, result: message, isError: true };
985
1064
  }
986
1065
  }
@@ -991,9 +1070,8 @@ async function runAgentHeadlessInWorkspace(
991
1070
  if (isHeadlessConfigCommand(prompt)) {
992
1071
  const cm = await import("../lib/config-manager.js");
993
1072
  const { getConfigPath } = await import("../lib/paths.js");
994
- const { runConfigDirective } = await import(
995
- "../lib/headless-config-command.js"
996
- );
1073
+ const { runConfigDirective } =
1074
+ await import("../lib/headless-config-command.js");
997
1075
  const { text, isError } = runConfigDirective(prompt, {
998
1076
  configManager: cm,
999
1077
  getConfigPath,
@@ -1069,9 +1147,8 @@ async function runAgentHeadlessInWorkspace(
1069
1147
  model = macro.model;
1070
1148
  writeErr(` command: model → ${model}\n`);
1071
1149
  try {
1072
- const { maybeWarnDeprecatedModel } = await import(
1073
- "../lib/model-deprecation.js"
1074
- );
1150
+ const { maybeWarnDeprecatedModel } =
1151
+ await import("../lib/model-deprecation.js");
1075
1152
  maybeWarnDeprecatedModel({ model });
1076
1153
  } catch {
1077
1154
  // deprecation notice is best-effort
@@ -1108,9 +1185,8 @@ async function runAgentHeadlessInWorkspace(
1108
1185
 
1109
1186
  // ── Permission + tool resolution ──────────────────────────────────────
1110
1187
  if (managedSettings) {
1111
- const { assertManagedPermissionMode } = await import(
1112
- "../lib/settings-loader.cjs"
1113
- );
1188
+ const { assertManagedPermissionMode } =
1189
+ await import("../lib/settings-loader.cjs");
1114
1190
  assertManagedPermissionMode(options.permissionMode, managedSettings);
1115
1191
  }
1116
1192
  const perm = resolvePermissionMode(options.permissionMode);
@@ -1566,9 +1642,8 @@ async function runAgentHeadlessInWorkspace(
1566
1642
  : null;
1567
1643
  if (!hermeticExecution && !instructionExcludes) {
1568
1644
  try {
1569
- const { readStringArraySetting } = await import(
1570
- "../lib/settings-loader.cjs"
1571
- );
1645
+ const { readStringArraySetting } =
1646
+ await import("../lib/settings-loader.cjs");
1572
1647
  const fromSettings = readStringArraySetting("instructionExcludes", {
1573
1648
  cwd,
1574
1649
  settingsFile: options.settingsFile,
@@ -1622,9 +1697,8 @@ async function runAgentHeadlessInWorkspace(
1622
1697
  // settings.json UserPromptSubmit hooks. block → abort the run; context → inject.
1623
1698
  if (settingsHooks) {
1624
1699
  try {
1625
- const { runUserPromptSubmitHooks } = await import(
1626
- "../lib/settings-hook-events.js"
1627
- );
1700
+ const { runUserPromptSubmitHooks } =
1701
+ await import("../lib/settings-hook-events.js");
1628
1702
  const ups = runUserPromptSubmitHooks(settingsHooks, {
1629
1703
  prompt: userContent,
1630
1704
  cwd,
@@ -1654,9 +1728,8 @@ async function runAgentHeadlessInWorkspace(
1654
1728
  let instructionsLoadedContext = null;
1655
1729
  if (settingsHooks && _loadedInstructions) {
1656
1730
  try {
1657
- const { runInstructionsLoadedHooks } = await import(
1658
- "../lib/settings-hook-events.js"
1659
- );
1731
+ const { runInstructionsLoadedHooks } =
1732
+ await import("../lib/settings-hook-events.js");
1660
1733
  instructionsLoadedContext = runInstructionsLoadedHooks(settingsHooks, {
1661
1734
  files: _loadedInstructions.files,
1662
1735
  cwd,
@@ -1671,9 +1744,8 @@ async function runAgentHeadlessInWorkspace(
1671
1744
  let sessionStartContext = null;
1672
1745
  if (settingsHooks) {
1673
1746
  try {
1674
- const { runSessionStartHooks } = await import(
1675
- "../lib/settings-hook-events.js"
1676
- );
1747
+ const { runSessionStartHooks } =
1748
+ await import("../lib/settings-hook-events.js");
1677
1749
  sessionStartContext = runSessionStartHooks(settingsHooks, {
1678
1750
  source: resumeId ? "resume" : "startup",
1679
1751
  cwd,
@@ -1691,9 +1763,8 @@ async function runAgentHeadlessInWorkspace(
1691
1763
  // back up" — e.g. re-run a workspace sanity check. Observe-only, best-effort.
1692
1764
  if (settingsHooks && resumeId && history.length > 0) {
1693
1765
  try {
1694
- const { runObserveHooks } = await import(
1695
- "../lib/settings-hook-events.js"
1696
- );
1766
+ const { runObserveHooks } =
1767
+ await import("../lib/settings-hook-events.js");
1697
1768
  runObserveHooks(
1698
1769
  settingsHooks,
1699
1770
  "SessionResume",
@@ -1858,6 +1929,10 @@ async function runAgentHeadlessInWorkspace(
1858
1929
  },
1859
1930
  {
1860
1931
  writeErr,
1932
+ // `mcp_server_errors` carries skipped config entries for machine
1933
+ // consumers. Text-mode terminal runs additionally receive the short
1934
+ // human warning; JSON/NDJSON keep stderr quiet for stable parsing.
1935
+ mcpConfigWarnings: isText,
1861
1936
  loadMcpConfig: deps.loadMcpConfig,
1862
1937
  loadRegisteredMcp: deps.loadRegisteredMcp,
1863
1938
  loadIdeMcp: deps.loadIdeMcp,
@@ -1924,9 +1999,8 @@ async function runAgentHeadlessInWorkspace(
1924
1999
  // --add-dir → workspaceRootDirs = [cwd] and this is a no-op. Best-effort.
1925
2000
  if (hostMcp?.mcpClient && additionalDirectories.length > 0) {
1926
2001
  try {
1927
- const { notifyMcpRootsChanged, workspaceRootDirs } = await import(
1928
- "../repl/add-dir.js"
1929
- );
2002
+ const { notifyMcpRootsChanged, workspaceRootDirs } =
2003
+ await import("../repl/add-dir.js");
1930
2004
  notifyMcpRootsChanged(
1931
2005
  [hostMcp.mcpClient],
1932
2006
  workspaceRootDirs(options.cwd || process.cwd(), additionalDirectories),
@@ -2034,15 +2108,16 @@ async function runAgentHeadlessInWorkspace(
2034
2108
  error.code = "CC_REMOTE_APPROVAL_GATE_UNAVAILABLE";
2035
2109
  throw error;
2036
2110
  }
2037
- const { startHeadlessRemoteApproval } = await import(
2038
- "../lib/remote-approval-bridge.js"
2039
- );
2111
+ const { startHeadlessRemoteApproval } =
2112
+ await import("../lib/remote-approval-bridge.js");
2040
2113
  _remoteApproval = await (
2041
2114
  deps.startHeadlessRemoteApproval || startHeadlessRemoteApproval
2042
2115
  )({
2043
2116
  agentSessionId: sessionId,
2044
2117
  writeErr,
2045
2118
  isText,
2119
+ allowLan: options.remoteControlAllowLan === true,
2120
+ env: process.env,
2046
2121
  });
2047
2122
  approvalGate.setConfirmer(
2048
2123
  _bgPhase.wrapConfirmer(_remoteApproval.confirmer),
@@ -2065,9 +2140,8 @@ async function runAgentHeadlessInWorkspace(
2065
2140
  let _collectorEnabled = false;
2066
2141
  if (!hermeticExecution) {
2067
2142
  try {
2068
- const { isOtlpCollectorEnabled } = await import(
2069
- "../lib/observability/index.js"
2070
- );
2143
+ const { isOtlpCollectorEnabled } =
2144
+ await import("../lib/observability/index.js");
2071
2145
  _collectorEnabled = isOtlpCollectorEnabled();
2072
2146
  } catch {
2073
2147
  _collectorEnabled = false;
@@ -2075,9 +2149,8 @@ async function runAgentHeadlessInWorkspace(
2075
2149
  }
2076
2150
  if (!hermeticExecution && (options.otlp || _collectorEnabled)) {
2077
2151
  try {
2078
- const { TelemetryRecorder } = await import(
2079
- "../lib/telemetry/span-recorder.js"
2080
- );
2152
+ const { TelemetryRecorder } =
2153
+ await import("../lib/telemetry/span-recorder.js");
2081
2154
  _otlpRecorder = new TelemetryRecorder({ serviceName: "cc-agent" });
2082
2155
  } catch {
2083
2156
  _otlpRecorder = null; // telemetry is best-effort, never blocks the run
@@ -2091,9 +2164,8 @@ async function runAgentHeadlessInWorkspace(
2091
2164
  let _hookSupervisor = null;
2092
2165
  if (settingsHooks) {
2093
2166
  try {
2094
- const { AsyncHookSupervisor } = await import(
2095
- "../lib/async-hook-supervisor.js"
2096
- );
2167
+ const { AsyncHookSupervisor } =
2168
+ await import("../lib/async-hook-supervisor.js");
2097
2169
  _hookSupervisor = new AsyncHookSupervisor({
2098
2170
  persistStats: true,
2099
2171
  // Durably park failed-rewake signals keyed by session so a crash before
@@ -2182,6 +2254,113 @@ async function runAgentHeadlessInWorkspace(
2182
2254
  }
2183
2255
  };
2184
2256
 
2257
+ // Subagent internals may contain prompts and tool results. The public
2258
+ // stream exposes only stable lifecycle/progress metadata, and only with the
2259
+ // explicit --include-hook-events opt-in.
2260
+ const headlessInteraction = {};
2261
+ if (includeHookEvents) {
2262
+ headlessInteraction.emit = (kind, payload = {}) => {
2263
+ const subAgentId =
2264
+ typeof payload.subAgentId === "string" && payload.subAgentId.trim()
2265
+ ? payload.subAgentId.slice(0, 160)
2266
+ : null;
2267
+ if (!subAgentId) return;
2268
+ const parentId =
2269
+ typeof payload.parentSessionId === "string" &&
2270
+ payload.parentSessionId.trim()
2271
+ ? payload.parentSessionId.slice(0, 160)
2272
+ : sessionId;
2273
+ const base = {
2274
+ schema_version: 1,
2275
+ subagent_id: subAgentId,
2276
+ parent_id: parentId,
2277
+ ...(typeof payload.role === "string" && payload.role.trim()
2278
+ ? { role: payload.role.trim().slice(0, 96) }
2279
+ : {}),
2280
+ };
2281
+ if (kind === "sub-agent.started") {
2282
+ emitStream({
2283
+ type: "subagent_started",
2284
+ ...base,
2285
+ background: payload.background === true,
2286
+ ...(Number.isFinite(payload.maxIterations)
2287
+ ? { max_iterations: Math.max(0, Math.floor(payload.maxIterations)) }
2288
+ : {}),
2289
+ });
2290
+ } else if (
2291
+ kind === "sub-agent.completed" ||
2292
+ kind === "sub-agent.failed"
2293
+ ) {
2294
+ emitStream({
2295
+ type: "subagent_completed",
2296
+ ...base,
2297
+ status: kind === "sub-agent.failed" ? "failed" : "completed",
2298
+ background: payload.background === true,
2299
+ ...(Number.isFinite(payload.iterationCount)
2300
+ ? {
2301
+ iteration_count: Math.max(
2302
+ 0,
2303
+ Math.floor(payload.iterationCount),
2304
+ ),
2305
+ }
2306
+ : {}),
2307
+ });
2308
+ } else if (kind === "sub-agent.progress") {
2309
+ emitStream({
2310
+ type: "subagent_progress",
2311
+ ...base,
2312
+ event_type:
2313
+ typeof payload.event_type === "string"
2314
+ ? payload.event_type.slice(0, 96)
2315
+ : "unknown",
2316
+ ...(typeof payload.tool === "string" && payload.tool
2317
+ ? { tool: payload.tool.slice(0, 128) }
2318
+ : {}),
2319
+ ...(Number.isFinite(payload.iteration_count)
2320
+ ? {
2321
+ iteration_count: Math.max(
2322
+ 0,
2323
+ Math.floor(payload.iteration_count),
2324
+ ),
2325
+ }
2326
+ : {}),
2327
+ ...(Number.isFinite(payload.token_count)
2328
+ ? { token_count: Math.max(0, Math.floor(payload.token_count)) }
2329
+ : {}),
2330
+ });
2331
+ }
2332
+ };
2333
+ }
2334
+ if (_bgPhase.enabled) {
2335
+ headlessInteraction.askUser = async ({
2336
+ question,
2337
+ options: qOptions,
2338
+ multiSelect,
2339
+ timeoutMs,
2340
+ defaultValue,
2341
+ toolUseId,
2342
+ turnId,
2343
+ policyDigest,
2344
+ } = {}) => {
2345
+ _bgPhase.reportQuestion({
2346
+ question: typeof question === "string" ? question : "",
2347
+ options: Array.isArray(qOptions) ? qOptions : null,
2348
+ });
2349
+ return _backgroundInteraction.request({
2350
+ kind: "question",
2351
+ question,
2352
+ options: qOptions,
2353
+ multiSelect,
2354
+ timeoutMs,
2355
+ defaultValue,
2356
+ toolUseId,
2357
+ turnId,
2358
+ policyDigest: policyDigest || _backgroundPolicyDigest,
2359
+ sessionId,
2360
+ });
2361
+ };
2362
+ }
2363
+
2185
2364
  const childToolExecs = new Map();
2186
2365
  const loopOptions = {
2187
2366
  model,
@@ -2205,6 +2384,7 @@ async function runAgentHeadlessInWorkspace(
2205
2384
  sandbox: options.sandbox || null,
2206
2385
  sessionId,
2207
2386
  sessionBudget: options.sessionBudget || null,
2387
+ hostResourceBudget,
2208
2388
  // Content-free continuity metadata from the same verified sample used for
2209
2389
  // replay history and MCP recovery authority.
2210
2390
  sessionHostSnapshot: canonicalResume?.snapshot || null,
@@ -2238,42 +2418,8 @@ async function runAgentHeadlessInWorkspace(
2238
2418
  hermeticExecution,
2239
2419
  iterationBudget: budget,
2240
2420
  toolAdmission: hermeticExecution ? null : options.toolAdmission || null,
2241
- // `ask_user_question` in a BACKGROUND turn child: send a bound request to
2242
- // the worker over Node IPC and await the answer here. `executeTool` remains
2243
- // suspended, so the model continues the SAME turn/tool call after the user
2244
- // answers instead of receiving the answer as a follow-up turn.
2245
- ...(_bgPhase.enabled
2246
- ? {
2247
- interaction: {
2248
- askUser: async ({
2249
- question,
2250
- options: qOptions,
2251
- multiSelect,
2252
- timeoutMs,
2253
- defaultValue,
2254
- toolUseId,
2255
- turnId,
2256
- policyDigest,
2257
- } = {}) => {
2258
- _bgPhase.reportQuestion({
2259
- question: typeof question === "string" ? question : "",
2260
- options: Array.isArray(qOptions) ? qOptions : null,
2261
- });
2262
- return _backgroundInteraction.request({
2263
- kind: "question",
2264
- question,
2265
- options: qOptions,
2266
- multiSelect,
2267
- timeoutMs,
2268
- defaultValue,
2269
- toolUseId,
2270
- turnId,
2271
- policyDigest: policyDigest || _backgroundPolicyDigest,
2272
- sessionId,
2273
- });
2274
- },
2275
- },
2276
- }
2421
+ ...(Object.keys(headlessInteraction).length > 0
2422
+ ? { interaction: headlessInteraction }
2277
2423
  : {}),
2278
2424
  // --mcp-config wiring: tool defs for the LLM + dispatch map + live client.
2279
2425
  mcpClient: mcp?.mcpClient || null,
@@ -2417,9 +2563,8 @@ async function runAgentHeadlessInWorkspace(
2417
2563
  if (options.goal !== undefined && options.goal !== false) {
2418
2564
  try {
2419
2565
  const explicitId = typeof options.goal === "string" ? options.goal : null;
2420
- const { resolveActiveGoal, linkSession } = await import(
2421
- "../lib/goal-store.js"
2422
- );
2566
+ const { resolveActiveGoal, linkSession } =
2567
+ await import("../lib/goal-store.js");
2423
2568
  const goal = (deps.resolveActiveGoal || resolveActiveGoal)({
2424
2569
  explicitId,
2425
2570
  sessionId,
@@ -2479,6 +2624,27 @@ async function runAgentHeadlessInWorkspace(
2479
2624
  const emitStream = (obj) => {
2480
2625
  if (isStream) writeOut(JSON.stringify(obj) + "\n");
2481
2626
  };
2627
+ if (hookEventBacklogExhausted) {
2628
+ // Do not emit a partial pre-manifest hook projection. The fixed diagnostic
2629
+ // contains no event payload, hook output, command, path, or user content.
2630
+ writeOut(
2631
+ JSON.stringify({
2632
+ type: "result",
2633
+ subtype: "error_host_resource_budget",
2634
+ is_error: true,
2635
+ code: HOST_EVENT_BACKLOG_CODE,
2636
+ error: HOST_EVENT_BACKLOG_ERROR,
2637
+ }) + "\n",
2638
+ );
2639
+ writeErr(`${HOST_EVENT_BACKLOG_CODE}: event backlog limit reached\n`);
2640
+ disposePendingHookEvents();
2641
+ return {
2642
+ exitCode: 1,
2643
+ result: HOST_EVENT_BACKLOG_ERROR,
2644
+ isError: true,
2645
+ };
2646
+ }
2647
+ writeHookEvent = (event) => emitStream(event);
2482
2648
 
2483
2649
  // --include-partial-messages: forward live assistant-text deltas as
2484
2650
  // `stream_event` NDJSON lines (Claude-Code parity). Only meaningful for
@@ -2521,6 +2687,9 @@ async function runAgentHeadlessInWorkspace(
2521
2687
  mcp: Boolean(mcp),
2522
2688
  enabledToolNames,
2523
2689
  }),
2690
+ ...(Array.isArray(mcp?.mcpServerErrors) && mcp.mcpServerErrors.length > 0
2691
+ ? { mcp_server_errors: mcp.mcpServerErrors }
2692
+ : {}),
2524
2693
  // True isolation level for tool subprocesses: os-sandbox (bwrap) /
2525
2694
  // container (docker) / policy-only (no sandbox — rules are pre-execution).
2526
2695
  isolation_level: isolationLevel(options.sandbox),
@@ -2530,6 +2699,19 @@ async function runAgentHeadlessInWorkspace(
2530
2699
  additional_directories: additionalDirectories,
2531
2700
  goal_id: boundGoalId,
2532
2701
  });
2702
+ // Setup/prompt-expansion hooks can run before the stream manifest is ready.
2703
+ // Keep the protocol ordered by emitting their queued projection immediately
2704
+ // after `system:init`, never before it.
2705
+ while (pendingHookEvents.length > 0) {
2706
+ const queued = pendingHookEvents.shift();
2707
+ try {
2708
+ writeHookEvent(queued.event);
2709
+ } finally {
2710
+ // The event is no longer buffered once its wire projection is written.
2711
+ // Keep the host slot only for queue residency, never for renderer I/O.
2712
+ queued.lease.release();
2713
+ }
2714
+ }
2533
2715
 
2534
2716
  // --auto-rewake: after a turn finishes, run the async Stop hooks and, if an
2535
2717
  // `asyncRewake` check FAILED, append its report as a new user turn and re-run
@@ -2547,9 +2729,8 @@ async function runAgentHeadlessInWorkspace(
2547
2729
  let _asyncStopHandled = false;
2548
2730
  const _settleAsyncStop = async () => {
2549
2731
  if (!settingsHooks || !_hookSupervisor) return { rewakes: [], results: [] };
2550
- const { dispatchAsyncHooks } = await import(
2551
- "../lib/settings-hook-events.js"
2552
- );
2732
+ const { dispatchAsyncHooks } =
2733
+ await import("../lib/settings-hook-events.js");
2553
2734
  dispatchAsyncHooks(
2554
2735
  settingsHooks,
2555
2736
  "Stop",
@@ -3301,9 +3482,9 @@ async function runAgentHeadlessInWorkspace(
3301
3482
  ? err.message
3302
3483
  : sessionBudgetFailed
3303
3484
  ? sessionBudgetAdmissionError(
3304
- options.sessionBudget?.reason?.() || err?.budgetReason,
3305
- "run",
3306
- ).message
3485
+ options.sessionBudget?.reason?.() || err?.budgetReason,
3486
+ "run",
3487
+ ).message
3307
3488
  : err?.message || String(err);
3308
3489
  const errorSubtype = runtimeLedgerPersistenceFailed
3309
3490
  ? "error_persistence"
@@ -3383,9 +3564,8 @@ async function runAgentHeadlessInWorkspace(
3383
3564
  await cleanupDeadline.run("settings-hooks", async () => {
3384
3565
  if (settingsHooks) {
3385
3566
  try {
3386
- const { runObserveHooks, dispatchAsyncHooks } = await import(
3387
- "../lib/settings-hook-events.js"
3388
- );
3567
+ const { runObserveHooks, dispatchAsyncHooks } =
3568
+ await import("../lib/settings-hook-events.js");
3389
3569
  const stopPayload = {
3390
3570
  reason: pipeState.closed ? "pipe_closed" : endReason,
3391
3571
  cwd,
@@ -3486,6 +3666,7 @@ async function runAgentHeadlessInWorkspace(
3486
3666
  }
3487
3667
  }
3488
3668
  });
3669
+ disposePendingHookEvents();
3489
3670
  const cleanupReport = cleanupDeadline.report();
3490
3671
  try {
3491
3672
  deps.onCleanupReport?.(cleanupReport);
@@ -3648,9 +3829,8 @@ async function runAgentHeadlessInWorkspace(
3648
3829
  emitStream({ type: "denials_summary", count: denials.length, denials });
3649
3830
  }
3650
3831
  try {
3651
- const { appendRecentDenials } = await import(
3652
- "../lib/permission-denial-store.js"
3653
- );
3832
+ const { appendRecentDenials } =
3833
+ await import("../lib/permission-denial-store.js");
3654
3834
  appendRecentDenials(denials, {
3655
3835
  sessionId,
3656
3836
  permissionMode: options.permissionMode || "default",
@@ -3721,9 +3901,8 @@ async function runAgentHeadlessInWorkspace(
3721
3901
  }
3722
3902
  if (_collectorEnabled) {
3723
3903
  try {
3724
- const { exportTelemetryRecorder } = await import(
3725
- "../lib/observability/index.js"
3726
- );
3904
+ const { exportTelemetryRecorder } =
3905
+ await import("../lib/observability/index.js");
3727
3906
  exportTelemetryRecorder(_otlpRecorder);
3728
3907
  } catch {
3729
3908
  // Telemetry is observational only and never changes the agent result.