chainlesschain 0.165.6 → 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 (238) hide show
  1. package/package.json +2 -1
  2. package/src/assets/web-panel/assets/{AIOps-vfoDb6HZ.js → AIOps-B3gWmXjo.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-Cm5f7p93.js → ActionButton-G9pdT-0e.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-yRuvgWxa.js → Analytics-Ca30J7m2.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-BROsC4h1.js → AppLayout-BtVTm8PU.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-CimHApb1.js → Artifacts-BhViNa6u.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-DI8kr8zI.js → Audit-DhKq-FnY.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-DSLzKy-n.js → BackgroundAgents-BL0SVbnE.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DkH_n2r1.js → Backup-BWkblnFi.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CKSrUoRA.js → BaseInput-ClaRNrF8.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-ClwfMXUS.js → Chat-sZE2Z77o.js} +4 -4
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CjMaqfL7.js → ChatBubbleRenderer-BAfKOnRe.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-BYTehcQG.js → Checkbox-Cvhay5WM.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-B8AMcp6J.js → Codegen-BpejL-4N.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-BNSogPo3.js → Col-g2Ki6g_1.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-JxPvGb8O.js → Community-D2xKbNo9.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-DF7bFAgE.js → Compact-DbL1Pds3.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-Bvhqnwrq.js → Compliance-DGtZCV4c.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-BDS0CJvM.js → Cowork-4kQpoNsI.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-DqvRfxoQ.js → Cron-BxTYXXAN.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-CDcIvnqS.js → Crosschain-k0J0LT2N.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-D7jaUxU3.js → DID-BaqhoPgN.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-B5A18wEV.js → Dashboard-T4RVPIM1.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-_6IVkGag.js → Dropdown-DszOToWq.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-C9PeiKCG.js → EmailListRenderer-C9KJU7HF.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DXjuEHrX.js → FamilyGuardDashboard-Cmr0JnsA.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-B4IAR9zv.js → Federation-BI-_2xZX.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CxQeSNx1.js → FormItemContext-DsnDEPsl.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-B8GS-Y3N.js → GenericCardRenderer-BLncAKKK.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-BS8SouUX.js → Git-BPQhGXDn.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-Dq9aYb5Q.js → Governance-CyElbUQW.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-BrCEe9AJ.js → Inference-CcSntBQD.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DybOpiY2.js → KnowledgeGraph-p6e7HZ2r.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-DBpzbRfx.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-Cc7CCSCu.js → Marketplace-Dd2notAJ.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-DFaIhOfu.js → McpTools-BBsN2CSW.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-KCqlp9ol.js → Memory-Dg2uTvwx.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-Bys84ySN.js → MobileBridge-r1YMRiJV.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-B-6qU-je.js → MobileProjects-C-89kSm4.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-BgY-fvCq.js → Mtc-CrPZcVgf.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-B8pCmqQJ.js → MtcAudit-sxi7hqJb.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-BbOmYutA.js → Multisig-CAgOMfF1.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-BocLQz_M.js → NLProgramming-DafaPts3.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-CSwbxEop.js → Notes-CJM-xUW_.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-CqFNSYG3.js → NotificationSettings-L0ZjfAh_.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-C6gMfAk7.js → OrderTableRenderer-BB1CvCK0.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-QrDXVdMJ.js → Organization-DeLtgAD8.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Cxntotjt.js → Overflow-CKC2b10z.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-CIdBOwNq.js → P2P-eyf2rzY1.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-CT5aP8rD.js → PdhVaultBrowser-5upNIOW8.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-DH7OM8XU.js → Permissions-B8p3W6JK.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-CnJqbWce.js → PersonalDataHub-BnRMxTq3.js} +5 -5
  54. package/src/assets/web-panel/assets/{Pipeline-5C3HG1kH.js → Pipeline-DjCNI1li.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-B4yIp7xK.js → Privacy-u6gXLbWT.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-BMvt-2M0.js → ProjectInit-BZAw4tkM.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-CvSTEMRG.js → ProjectSettings-B1Tr72q7.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-BKBJxEek.js → Projects-DO7HFuBQ.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-BdwUqFWN.js → Providers-BjCztyhj.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-DtnCKlTm.js → QrScannerModal-ZWyCUbR1.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-sTbgwyNr.js → QuickAsk-DhDjeW4G.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Bzr14gSb.js → Recommend-R_CN2MuU.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C_TF5IaJ.js → RemoteSession-uxFcujeu.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-GCAM4H2K.js → Reputation-DX8D7rks.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-Dir0r6OQ.js → Row-BYahQILD.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-CpGnlecX.js → RssFeed-CUSQ2tm-.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DMMamC6u.js → Search-CnN_S8Cs.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-yqay5yG-.js → Security-DcZlh-O4.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-C5i2wh9G.js → Services-ZhBOjzIX.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-vUqk35yj.js → Skeleton-D5Qnq_lI.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-DzcSkhot.js → Skills-BC9cZ3Be.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-CB6qbYNr.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-D-RrsxTJ.js → SyncSettings-DUvJbSct.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-DFxdOJiq.js → Tasks-BXa-5noQ.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-SKAob_Aq.js → Templates-JxaiUt_3.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-BPfsfHQ-.js → Tenant-BW4ERQN8.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-8iw7FpUf.js → Terminal-DltUbdtv.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-C4Gjj5Su.js → TimelineRenderer-CMoZz0Tc.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-COYhN18e.js → Tokens-D_VEV60K.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-B-JzXcf6.js → Trigger-CCXTCs0R.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BJ5bg0nI.js → Trust-lkGRIPcG.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-BG_ByRMf.js → UkeySign-BfGeQ9HX.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-B3kOnSiU.js → VideoEditing-BEC7pYvc.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-CcoGFnK7.js → Wallet-BZdG24o0.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-DdT8vRC_.js → WebAuthn-yoEddedp.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-CZu3M9N8.js → WorkflowEditor-BXZEprOW.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-DxJt3Qba.js → chat-gg0bzZal.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DdYfwJaB.js → colors-DjRVRuin.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-BG3SUzwj.js → compact-item-su-dieAc.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-By51z2-1.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-B0apZ3KJ.js → hasIn-D8F10heH.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-DE76D-kA.js → index-11wtYQiF.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BkvcEo4p.js → index-1IgxgALJ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-Bos5_aMV.js → index-1agckWSq.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BfWYsB9t.js → index-5JqhujnR.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CAhHirVH.js → index-6Tniqk1s.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BYINoRLK.js → index-8Z-8BIlN.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B5rLiEo0.js → index-BCI5v0yB.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BZ_0qm4g.js → index-BDJntYmJ.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CWEuZWCK.js → index-BGzixOGZ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BLIbGOLX.js → index-BMMOVoLD.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-bP_VlDb4.js → index-BTFpdBtt.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-B3rWuPMW.js → index-Ba_HyPnE.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Da_WBdLX.js → index-BbF1IHof.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-RD6O-0C6.js → index-BgT9su_e.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CpjZhgNd.js → index-BzPB6kGZ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Q2SCX-MI.js → index-C6ygzplr.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BIrJfqO4.js → index-CC3ZDjzY.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BBPf3TpM.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-Cp6e-hGw.js → index-CMPqd5Cv.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-kf57LJ93.js → index-COWd8uGx.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CW93tZDv.js → index-CPIYSp4H.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BewKYrX9.js → index-CR0h6seT.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-p1_8SbI1.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-ZxtP8jG7.js → index-CusgZPtc.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BWF8_mkx.js → index-DBAETXft.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BP94CrBV.js → index-DIJ2qFOC.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CNIxXMmN.js → index-Dbq4NMET.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CzmQElZy.js → index-DkMEF5VT.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-ZFbps9po.js → index-DkfQR3hM.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-Dz49VOyQ.js → index-DnLucOn9.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-oxRrmFO9.js → index-DugB_aKa.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Bissefox.js → index-DyLUarhZ.js} +3 -3
  128. package/src/assets/web-panel/assets/{index-DaIz0NAW.js → index-T6_6ygJZ.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-SQqOlR3d.js → index-Tu8eWqh-.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DCn8IcxV.js → index-W7XUgdVL.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-3jWkIu5j.js → index-dHZinfko.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-C1C9i79A.js → index-jyNgp5FI.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-BWJktcg8.js → initDefaultProps-Cv4p8e4w.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BEXBzUFV.js → motion-B8EwmMOw.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-BUKwn2sx.js → move-B8R9F8TK.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-FTI7btqQ.js → mtc-parser-DoFYz5Bp.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-CsLtSPH3.js → omit-CHWYLBjI.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-DWZxsT_S.js → pickAttrs-CXuPDO77.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-Bcfs43CX.js → placementArrow-BaAtUUon.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-a9bcC1p-.js → responsiveObserve-DCc4zcDD.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-BDTzgOXN.js → slide-B_lx89oZ.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-Iq1j_HUg.js → statusUtils-DE8DPmR0.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-DAZEYxeh.js → styleChecker-1ktXOsL_.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-DVkjyDrh.js → useFlexGapSupport-xH89-wjh.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-wXTpNTHt.js → useFs-DscvfW5p.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-CtQM_aZr.js → usePersonalDataHub-RdMKQta7.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-hjEoG85v.js → vnode-Z3wTni2T.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-BHVpyKg_.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 +91 -60
  152. package/src/commands/git.js +39 -0
  153. package/src/commands/plugin.js +17 -2
  154. package/src/commands/session-group.js +131 -0
  155. package/src/commands/session-location.js +48 -0
  156. package/src/commands/session.js +11 -0
  157. package/src/commands/sync-providers.js +4 -1
  158. package/src/commands/update.js +1 -0
  159. package/src/data/changelog.json +27 -1
  160. package/src/gateways/ws/ws-agent-handler.js +20 -12
  161. package/src/harness/jsonl-session-store.js +279 -37
  162. package/src/harness/mcp-client.js +701 -91
  163. package/src/harness/session-index.js +15 -4
  164. package/src/lib/agent-worktree.js +8 -1
  165. package/src/lib/auto-mode-safety-classifier.js +3 -17
  166. package/src/lib/background-agent-keeper-protocol.js +26 -6
  167. package/src/lib/background-agent-supervisor.js +17 -1
  168. package/src/lib/browser-evidence.js +1405 -0
  169. package/src/lib/chrome-connector.js +465 -79
  170. package/src/lib/claude-project-auto-memory.js +481 -0
  171. package/src/lib/claude-project-storage-layout.js +104 -0
  172. package/src/lib/cloud/cloud-client.js +40 -0
  173. package/src/lib/execution-location-local-supervisor.mjs +226 -0
  174. package/src/lib/execution-location-runner-lifecycle.js +991 -0
  175. package/src/lib/execution-location-target-preflight.js +333 -0
  176. package/src/lib/execution-location-target.js +783 -13
  177. package/src/lib/file-lines.js +6 -1
  178. package/src/lib/gateway-client-resilience.js +571 -0
  179. package/src/lib/gitlab-mr-worktree.js +176 -0
  180. package/src/lib/hooks-v2-producers.js +119 -15
  181. package/src/lib/hooks-v2-workspace-context.js +44 -1
  182. package/src/lib/host-resource-budget.js +295 -0
  183. package/src/lib/ide-context.js +15 -2
  184. package/src/lib/llm-config-defaults.js +43 -0
  185. package/src/lib/mcp-lifecycle-authority.js +887 -0
  186. package/src/lib/mcp-oauth.js +101 -20
  187. package/src/lib/mcp-tls.js +103 -3
  188. package/src/lib/paths.js +260 -32
  189. package/src/lib/permission-request.js +48 -0
  190. package/src/lib/plugin-runtime/bin.js +3 -1
  191. package/src/lib/plugin-runtime/hooks.js +3 -1
  192. package/src/lib/plugin-runtime/install.js +117 -1
  193. package/src/lib/plugin-runtime/lsp.js +4 -4
  194. package/src/lib/plugin-runtime/marketplace-archive-source.js +40 -5
  195. package/src/lib/plugin-runtime/marketplace-catalog.js +13 -2
  196. package/src/lib/plugin-runtime/marketplace-command-descriptor.js +343 -0
  197. package/src/lib/plugin-runtime/marketplace-command-source.js +580 -0
  198. package/src/lib/plugin-runtime/marketplace-source-adapter.js +33 -8
  199. package/src/lib/plugin-runtime/mcp.js +3 -1
  200. package/src/lib/plugin-runtime/monitors.js +3 -1
  201. package/src/lib/plugin-runtime/remote-source.js +151 -6
  202. package/src/lib/plugin-runtime/settings.js +3 -1
  203. package/src/lib/plugin-runtime/trust.js +274 -13
  204. package/src/lib/process-execution-broker/credential-agent.js +210 -41
  205. package/src/lib/process-execution-broker/index.js +15 -1
  206. package/src/lib/process-execution-broker/linux-cgroup-v2.js +391 -0
  207. package/src/lib/process-execution-broker/platform-sandbox.js +50 -28
  208. package/src/lib/project-mcp-trust.js +165 -10
  209. package/src/lib/resume-session.js +9 -6
  210. package/src/lib/session-core-singletons.js +26 -11
  211. package/src/lib/session-host-lease.js +52 -16
  212. package/src/lib/session-lifecycle-scope.js +153 -0
  213. package/src/lib/session-message-fabric.js +168 -21
  214. package/src/lib/session-projection.js +244 -4
  215. package/src/lib/session-store-guard.js +3 -1
  216. package/src/lib/session-workbench-store.js +466 -0
  217. package/src/lib/spellcheck.js +211 -0
  218. package/src/lib/sub-agent-context.js +9 -9
  219. package/src/lib/sync-cli-db.js +485 -129
  220. package/src/lib/sync-credentials.js +31 -20
  221. package/src/lib/web-fetch.js +112 -40
  222. package/src/lib/web-search.js +127 -61
  223. package/src/lib/workspace-trust.js +793 -0
  224. package/src/repl/agent-repl.js +124 -5
  225. package/src/repl/permission-prompt.js +10 -12
  226. package/src/runtime/agent-core.js +311 -18
  227. package/src/runtime/bootstrap.js +37 -13
  228. package/src/runtime/coding-agent-contract-shared.cjs +11 -4
  229. package/src/runtime/headless-runner.js +234 -36
  230. package/src/runtime/headless-stream.js +181 -6
  231. package/src/runtime/mcp-config.js +298 -8
  232. package/src/runtime/policies/agent-policy.js +8 -0
  233. package/src/runtime/status-diagnostics-lite.js +9 -1
  234. package/src/assets/web-panel/assets/MarkdownRenderer-CFyt8iUd.js +0 -1
  235. package/src/assets/web-panel/assets/SpeechSettings-BHUI7cox.js +0 -1
  236. package/src/assets/web-panel/assets/devWarning-DorRZcI9.js +0 -1
  237. package/src/assets/web-panel/assets/index-BETiL0a3.js +0 -1
  238. package/src/assets/web-panel/assets/index-BhAVHuW8.js +0 -1
@@ -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");
@@ -1225,14 +1225,14 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
1225
1225
  kind: "browser",
1226
1226
  tier: "extension",
1227
1227
  description:
1228
- "Perform EXPLICIT actions in the user's connected Chrome over loopback CDP: click, type, press, navigate (http/https only), waitForSelector, screenshot (published as a session-bound Artifact; never a caller-chosen path), assertText. Approval-gated (HIGH risk): use browser_state first to observe; only act when the task genuinely requires driving the browser. Steps run in order and fail fast unless continue_on_error; each returns {ok, action, detail, durationMs} and every executed step is audit-logged under ~/.chainlesschain/browser-actions/. Requires a debuggable Chrome (`cc browse chrome launch`).",
1228
+ "Perform EXPLICIT actions in the user's connected Chrome over loopback CDP: click, type, press, navigate (http/https only), waitForSelector, screenshot, assertText, upload from a managed session Artifact, and download into a generated session Artifact. Approval-gated (HIGH risk): use browser_state first to observe; only act when the task genuinely requires driving the browser. Host-provided evidence authority can bind every action to an origin grant/revision, session, diff and test run. Steps run in order and fail fast unless continue_on_error; every executed step is audit-logged under ~/.chainlesschain/browser-actions/. Requires a debuggable Chrome (`cc browse chrome launch`).",
1229
1229
  inputSchema: {
1230
1230
  type: "object",
1231
1231
  properties: {
1232
1232
  actions: {
1233
1233
  type: "array",
1234
1234
  description:
1235
- "Ordered action steps. Each item: {type: click|type|press|navigate|waitForSelector|screenshot|assertText} plus its fields — click/waitForSelector/assertText need selector; type needs selector+text; press needs key; navigate needs url (http/https); waitForSelector accepts timeout_ms (capped 30000); assertText needs expected (substring); screenshot takes NO path (generated internally).",
1235
+ "Ordered action steps. Each item: {type: click|type|press|navigate|waitForSelector|screenshot|assertText|upload|download}. Upload needs selector+artifact_id and accepts no path; download needs selector and writes only a generated session Artifact. Screenshot and download take no caller path.",
1236
1236
  items: {
1237
1237
  type: "object",
1238
1238
  properties: {
@@ -1246,13 +1246,15 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
1246
1246
  "waitForSelector",
1247
1247
  "screenshot",
1248
1248
  "assertText",
1249
+ "upload",
1250
+ "download",
1249
1251
  ],
1250
1252
  description: "Action kind",
1251
1253
  },
1252
1254
  selector: {
1253
1255
  type: "string",
1254
1256
  description:
1255
- "CSS selector (click/type/waitForSelector/assertText)",
1257
+ "CSS selector (click/type/waitForSelector/assertText/upload/download)",
1256
1258
  },
1257
1259
  text: { type: "string", description: "Text to type (type)" },
1258
1260
  key: {
@@ -1272,6 +1274,11 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
1272
1274
  type: "string",
1273
1275
  description: "Expected substring (assertText)",
1274
1276
  },
1277
+ artifact_id: {
1278
+ type: "string",
1279
+ description:
1280
+ "Managed Artifact id to upload (upload); must belong to the active session",
1281
+ },
1275
1282
  },
1276
1283
  required: ["type"],
1277
1284
  },
@@ -1300,7 +1307,7 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
1300
1307
  ...TOOL_POLICY_METADATA.browser_act,
1301
1308
  permissions: {
1302
1309
  level: "elevated",
1303
- scopes: ["browser:act"],
1310
+ scopes: ["browser:act", "artifact:read", "artifact:write"],
1304
1311
  },
1305
1312
  telemetry: {
1306
1313
  category: "browser",
@@ -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,
@@ -978,6 +1059,7 @@ async function runAgentHeadlessInWorkspace(
978
1059
  : "CC_OBSERVABILITY_SCOPE_AUTHORITY_UNAVAILABLE: existing session authority could not be excluded";
979
1060
  emitHeadlessError(message);
980
1061
  writeErr(`${message}\n`);
1062
+ disposePendingHookEvents();
981
1063
  return { exitCode: 1, result: message, isError: true };
982
1064
  }
983
1065
  }
@@ -1847,6 +1929,10 @@ async function runAgentHeadlessInWorkspace(
1847
1929
  },
1848
1930
  {
1849
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,
1850
1936
  loadMcpConfig: deps.loadMcpConfig,
1851
1937
  loadRegisteredMcp: deps.loadRegisteredMcp,
1852
1938
  loadIdeMcp: deps.loadIdeMcp,
@@ -2168,6 +2254,113 @@ async function runAgentHeadlessInWorkspace(
2168
2254
  }
2169
2255
  };
2170
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
+
2171
2364
  const childToolExecs = new Map();
2172
2365
  const loopOptions = {
2173
2366
  model,
@@ -2191,6 +2384,7 @@ async function runAgentHeadlessInWorkspace(
2191
2384
  sandbox: options.sandbox || null,
2192
2385
  sessionId,
2193
2386
  sessionBudget: options.sessionBudget || null,
2387
+ hostResourceBudget,
2194
2388
  // Content-free continuity metadata from the same verified sample used for
2195
2389
  // replay history and MCP recovery authority.
2196
2390
  sessionHostSnapshot: canonicalResume?.snapshot || null,
@@ -2224,42 +2418,8 @@ async function runAgentHeadlessInWorkspace(
2224
2418
  hermeticExecution,
2225
2419
  iterationBudget: budget,
2226
2420
  toolAdmission: hermeticExecution ? null : options.toolAdmission || null,
2227
- // `ask_user_question` in a BACKGROUND turn child: send a bound request to
2228
- // the worker over Node IPC and await the answer here. `executeTool` remains
2229
- // suspended, so the model continues the SAME turn/tool call after the user
2230
- // answers instead of receiving the answer as a follow-up turn.
2231
- ...(_bgPhase.enabled
2232
- ? {
2233
- interaction: {
2234
- askUser: async ({
2235
- question,
2236
- options: qOptions,
2237
- multiSelect,
2238
- timeoutMs,
2239
- defaultValue,
2240
- toolUseId,
2241
- turnId,
2242
- policyDigest,
2243
- } = {}) => {
2244
- _bgPhase.reportQuestion({
2245
- question: typeof question === "string" ? question : "",
2246
- options: Array.isArray(qOptions) ? qOptions : null,
2247
- });
2248
- return _backgroundInteraction.request({
2249
- kind: "question",
2250
- question,
2251
- options: qOptions,
2252
- multiSelect,
2253
- timeoutMs,
2254
- defaultValue,
2255
- toolUseId,
2256
- turnId,
2257
- policyDigest: policyDigest || _backgroundPolicyDigest,
2258
- sessionId,
2259
- });
2260
- },
2261
- },
2262
- }
2421
+ ...(Object.keys(headlessInteraction).length > 0
2422
+ ? { interaction: headlessInteraction }
2263
2423
  : {}),
2264
2424
  // --mcp-config wiring: tool defs for the LLM + dispatch map + live client.
2265
2425
  mcpClient: mcp?.mcpClient || null,
@@ -2464,6 +2624,27 @@ async function runAgentHeadlessInWorkspace(
2464
2624
  const emitStream = (obj) => {
2465
2625
  if (isStream) writeOut(JSON.stringify(obj) + "\n");
2466
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);
2467
2648
 
2468
2649
  // --include-partial-messages: forward live assistant-text deltas as
2469
2650
  // `stream_event` NDJSON lines (Claude-Code parity). Only meaningful for
@@ -2506,6 +2687,9 @@ async function runAgentHeadlessInWorkspace(
2506
2687
  mcp: Boolean(mcp),
2507
2688
  enabledToolNames,
2508
2689
  }),
2690
+ ...(Array.isArray(mcp?.mcpServerErrors) && mcp.mcpServerErrors.length > 0
2691
+ ? { mcp_server_errors: mcp.mcpServerErrors }
2692
+ : {}),
2509
2693
  // True isolation level for tool subprocesses: os-sandbox (bwrap) /
2510
2694
  // container (docker) / policy-only (no sandbox — rules are pre-execution).
2511
2695
  isolation_level: isolationLevel(options.sandbox),
@@ -2515,6 +2699,19 @@ async function runAgentHeadlessInWorkspace(
2515
2699
  additional_directories: additionalDirectories,
2516
2700
  goal_id: boundGoalId,
2517
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
+ }
2518
2715
 
2519
2716
  // --auto-rewake: after a turn finishes, run the async Stop hooks and, if an
2520
2717
  // `asyncRewake` check FAILED, append its report as a new user turn and re-run
@@ -3469,6 +3666,7 @@ async function runAgentHeadlessInWorkspace(
3469
3666
  }
3470
3667
  }
3471
3668
  });
3669
+ disposePendingHookEvents();
3472
3670
  const cleanupReport = cleanupDeadline.report();
3473
3671
  try {
3474
3672
  deps.onCleanupReport?.(cleanupReport);