chainlesschain 0.162.179 → 0.162.181

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 (251) hide show
  1. package/package.json +6 -3
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-BF13YdB-.js → AIOps-cq0dwbnf.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-B9y67AjF.js → ActionButton-CvcgGl3w.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-FcdDHoSC.js → Analytics-hM2-jFqg.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-CRm_zwSp.js → AppLayout-B9_Gsd_g.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-Cbo7-usf.js → Artifacts-B7bu52Og.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-vMaLpkHC.js → Audit-DThfDgqB.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-FiUY692t.js → BackgroundAgents-DjlFiD4v.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-BK80j_GQ.js → Backup-CK9xJKnG.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-ChNMuYR1.js → BaseInput-DEiSU8K8.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-928UREpm.js → Chat-CpT96czj.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-BKPPNmZI.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-dFW-zDbe.js → Checkbox-C1GfDnO0.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-BCcNJUj2.js → Codegen-3DAKgiLx.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-DcEkLv70.js → Col-74cOwZU1.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-DihBRRqg.js → Community-tn9Kkz9j.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-DGYxwWET.js → Compact-BcoXH7m4.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-OnYe1vS4.js → Compliance-DIPGUBgi.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CmWB54c2.js → Cowork-doD5_91c.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-BrANb2uw.js → Cron-C-IDvubz.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-2HgWzSxg.js → Crosschain-CdcCoBdj.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DdDwNI6K.js → DID-DdH5aMMA.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-D6PnE78-.js → Dashboard-DHLA4mm0.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-ClzvSN4O.js → Dropdown-dEeCt7Md.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-BUk9B727.js → EmailListRenderer-BMaecFv9.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-C8hi3v7i.js → FamilyGuardDashboard-DUaUukTN.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-B5SP8xkg.js → Federation-CMBE0_rp.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-DWzJ8AU5.js → FormItemContext-PG-JDbXq.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-3E3Q3rjG.js → GenericCardRenderer-Bcb0p88m.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-z8IdCMId.js → Git-Bgv15myB.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CgqCF9lX.js → Governance-DB8YTArI.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-zgS-AuH9.js → Inference-BQMwCWaS.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-BdbgmESJ.js → KnowledgeGraph-B1_ZziiB.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-BHpknnjy.js → Logs-DovEEnt_.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-D201OL4T.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-Di9sAR7j.js → Marketplace-BlCXSpyB.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-DtnR9Z_A.js → McpTools-CsCR09Wj.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-BaX9uuXD.js → Memory-CBVRLKno.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-xelyKWTY.js → MobileBridge-C9OIafgA.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-BiFTOGBN.js → MobileProjects-D_zoJ8Xs.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-bV3OzTiO.js → Mtc-vE-HdvLj.js} +4 -4
  43. package/src/assets/web-panel/assets/{MtcAudit-BkwvFTdZ.js → MtcAudit-CPLaekCd.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-_6HQQ-oC.js → Multisig-C_UP9C2o.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-BBYhmWQZ.js → NLProgramming-2nODJcU1.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-Cq-6dQnU.js → Notes-BhE-SJGu.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-ILZ9zkX6.js → NotificationSettings-D21q7BNU.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-DgmTBEvk.js → OrderTableRenderer-0b62GYOD.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-CkLnWwCk.js → Organization-CEqmw_sb.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-CWVHZbhf.js → Overflow-MW-gMDO_.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-BXbqETkr.js → P2P-CY0hjI_G.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser--0JR-0ex.js → PdhVaultBrowser-BbWh7Man.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-Cz9_tfSy.js → Permissions-ChqEA_4Q.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-Dq7OWYtx.js → PersonalDataHub-B3YrbYfD.js} +5 -5
  55. package/src/assets/web-panel/assets/{Pipeline-DHPUNcc-.js → Pipeline-B8WBhhlW.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-CEAbrDkS.js → Privacy-Cmb0PXNx.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-CJYfclXE.js → ProjectInit-hF6zW3Nz.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-oCTgPCgp.js → ProjectSettings-BFSVfpW0.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-DAWkVFkc.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-BLTZtzTG.js → Providers-B8yux8Dx.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-C0b0TQB3.js → QrScannerModal-N76cQluO.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-tOl6N_gM.js → QuickAsk-ClvZ0KYR.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-DPzKr8yr.js → Recommend-B-GfgBpT.js} +1 -1
  64. package/src/assets/web-panel/assets/RemoteSession-mlglCdQi.js +5 -0
  65. package/src/assets/web-panel/assets/{Reputation-Cji1Vl79.js → Reputation-DJIZzQeG.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-D-NERWf2.js → Row-COzxu_bb.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-DzlgmAlB.js → RssFeed-CoYsJQuE.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-Cs0SWSa4.js → Search-DC77Mq9S.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-DL7EzcUO.js → Security-Loy2EdMO.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-CT-PzgTd.js → Services-GUD07Eu0.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-tByJWdJg.js → Skeleton-DWzkptYU.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-Dnr_6TTl.js → Skills-CEDn1r-Z.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-4O-yq0LY.js → Sla-ub_k4pXh.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-BYBVg1oR.js → SpeechSettings-D7HLX9CA.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-CpOYPbE5.js → SyncSettings-DbwOvl6m.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-CGVhOVh6.js → Tasks-CBQzoAu5.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-BuHFxR4X.js → Templates-BNVeIhud.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-DxDxHzgf.js → Tenant-PS9AzhXU.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-B9g_nISg.js → Terminal-Cgb4eLB_.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-DlrBC_4A.js → TimelineRenderer-CrmXMOkg.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-DvBlYZ6i.js → Tokens-DD-VDHw1.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-Dg8G9bhF.js → Trigger-BsoN_n-n.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-COICx4E-.js → Trust-n8LmN4ZV.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-B4pOBv7T.js → UkeySign-C9_7MImA.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-Qt4NMA8Q.js → VideoEditing-DyBteNgn.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-X1EkQc2Z.js → Wallet-BS5ixeXI.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-CyeEFBE5.js → WebAuthn-spc4UImU.js} +3 -3
  88. package/src/assets/web-panel/assets/{WorkflowEditor-nwzbMiVQ.js → WorkflowEditor-D7iVvaBO.js} +1 -1
  89. package/src/assets/web-panel/assets/chat-6CmBkHrL.js +1 -0
  90. package/src/assets/web-panel/assets/{colors-5Isz5lhJ.js → colors-BGoCLkxI.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-DsFQS3Oy.js → compact-item-fYZBetMO.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-OcEXp2uz.js → createContext-BeM-1UVj.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-BzPwHnw8.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-CZvC4p09.js → hasIn-CE7ZuEnV.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BF1sab0Q.js → index--lap6cf7.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-C7yeL3rf.js → index-ATcSr_2O.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-VkFXA9N-.js → index-B2U-ObMq.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DSmGGg5h.js → index-B3CDgvNW.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-jrNIrpq4.js → index-B4wiTEOM.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B8ibl7bc.js → index-B8BsdNV_.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DOLozRk8.js → index-BEVm0lCS.js} +10 -10
  102. package/src/assets/web-panel/assets/{index-BPgc_bdR.js → index-BNZDILcO.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BTZZzlMO.js → index-BU_2qiDk.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Vubi6Tf5.js → index-BV551878.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-nXrnztXp.js → index-BfPL-m46.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CN8lPVpQ.js → index-BowH1eLQ.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BgE2BZl2.js → index-BsMfoaeo.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Cd5b2JHB.js → index-BunaQCa0.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CQlGw0nQ.js → index-C0v6YKKO.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Do6FJK32.js → index-C4SJVjs4.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Bqvo1f9T.js → index-C9Y3k0HI.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-LUdgPZg9.js → index-CIpVrf5P.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BpD2O7_p.js → index-CRLjEP1H.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-r_9NG6P7.js → index-CRnUE8Cb.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-FIgMAfBh.js → index-Cip8emOQ.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-RsQ1lFDV.js → index-CpIGIB85.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DGJupV0S.js → index-D1r9tT3J.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BpglwPWl.js → index-DT3zPSVX.js} +1 -1
  119. package/src/assets/web-panel/assets/index-DacrAdc-.js +1 -0
  120. package/src/assets/web-panel/assets/{index-CG3B2wCF.js → index-De0quFDw.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CxA2PDK1.js → index-DoXk5KJ8.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DaGKOVvQ.js → index-DsvfrESp.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-C7CtJYXq.js → index-Dw1PyYPm.js} +1 -1
  124. package/src/assets/web-panel/assets/index-EHzNJozo.js +1 -0
  125. package/src/assets/web-panel/assets/{index-Bu9NXvIa.js → index-MtOuq2i6.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BsZkTaa3.js → index-Puq6Luf1.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CPE4zHXF.js → index-QIpnpZgz.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Bsb-iylv.js → index-RMZ8a7Yt.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DMtGRQqw.js → index-WUrJ6S1j.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-C3lWvhk4.js → index-YjcumOZ4.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-CmVbCGx_.js → index-lJBjB1QX.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-A5SHQW_M.js → index-ukg99D1V.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CFJgt6qM.js → index-zb7rVOhV.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-Cdgep9YT.js → initDefaultProps-CYHMs1ag.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-7yn1ACEm.js → motion-DDB2Ffk5.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-D8o133Xc.js → move-Bg3cD-dX.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-CClHIG9V.js → mtc-parser-B5nedjTS.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-CLnrPE2d.js → omit-BHyuUILu.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-1CTWoZWl.js → pickAttrs-C9YQnEN9.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-xNNtS4Sp.js → placementArrow-DBUFYUe7.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-ypzAofs7.js → responsiveObserve-nBs2Obnk.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-QsrY9UwD.js → slide-DkCEaXNU.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-DSdThzOB.js → statusUtils-aqE1Wi6U.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-B_kKM8Ob.js → styleChecker-CN5bhfHB.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-CcdTBNV9.js → useFlexGapSupport-B_oX_kvJ.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-BuAH2XFU.js → useFs-rCuXHeme.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-B3zWiG4A.js → usePersonalDataHub-DZR9Abyd.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-B45Rc-CQ.js → vnode-ConCYQlX.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-DaYZDU5f.js → zoom-CUdDxG5M.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/agent.js +4 -1
  152. package/src/commands/background-session.js +2 -1
  153. package/src/commands/context.js +69 -2
  154. package/src/commands/hub.js +30 -24
  155. package/src/data/changelog.json +27 -1
  156. package/src/gateways/ws/background-agent-protocol.js +38 -0
  157. package/src/gateways/ws/message-dispatcher.js +1 -0
  158. package/src/gateways/ws/remote-session-protocol.js +65 -6
  159. package/src/gateways/ws/ws-server.js +8 -1
  160. package/src/harness/feature-flags.js +15 -8
  161. package/src/harness/mcp-client.js +618 -43
  162. package/src/lazy-dispatch.js +30 -1
  163. package/src/lib/agent-authority.js +22 -0
  164. package/src/lib/agent-core.js +2 -0
  165. package/src/lib/agent-sandbox.js +161 -0
  166. package/src/lib/agent-team/team-runner.js +22 -0
  167. package/src/lib/artifact-store.js +35 -0
  168. package/src/lib/async-hook-supervisor.cjs +13 -2
  169. package/src/lib/audit-mtc.js +3 -2
  170. package/src/lib/background-agent-supervisor.js +104 -3
  171. package/src/lib/background-interaction-journal.js +407 -0
  172. package/src/lib/background-interaction-resolver.js +23 -34
  173. package/src/lib/background-session-transport.js +12 -2
  174. package/src/lib/capability-manifest.js +41 -3
  175. package/src/lib/capability-negotiation.js +1 -1
  176. package/src/lib/channels/channel-manager.js +33 -0
  177. package/src/lib/channels/telegram-channel.js +23 -5
  178. package/src/lib/channels/webhook-channel.js +38 -15
  179. package/src/lib/chrome-connector.js +169 -23
  180. package/src/lib/config-manager.js +23 -9
  181. package/src/lib/context-breakdown.js +31 -0
  182. package/src/lib/cowork-cron.js +274 -32
  183. package/src/lib/cross-chain-mtc.js +3 -2
  184. package/src/lib/durable-security-store.js +124 -0
  185. package/src/lib/event-runtime-host.js +67 -6
  186. package/src/lib/event-runtime-store.js +163 -0
  187. package/src/lib/goal-store.js +32 -12
  188. package/src/lib/headless-manifest.js +2 -1
  189. package/src/lib/hook-environment.cjs +58 -0
  190. package/src/lib/hook-manager.js +12 -5
  191. package/src/lib/hook-runner.cjs +122 -28
  192. package/src/lib/hook-runner.js +1 -0
  193. package/src/lib/hooks-v2-producers.js +36 -0
  194. package/src/lib/hooks-v2-runtime.js +329 -52
  195. package/src/lib/interaction-adapter.js +60 -19
  196. package/src/lib/interaction-binding.js +64 -0
  197. package/src/lib/json-schema-output.js +439 -14
  198. package/src/lib/json-schema-validate.js +514 -883
  199. package/src/lib/lan-pairing-tokens.js +115 -57
  200. package/src/lib/lsp/__tests__/lsp-client.test.js +32 -0
  201. package/src/lib/lsp/__tests__/lsp-manager.test.js +25 -0
  202. package/src/lib/lsp/lsp-client.js +4 -0
  203. package/src/lib/lsp/lsp-manager.js +3 -0
  204. package/src/lib/lsp/lsp-server-registry.js +18 -0
  205. package/src/lib/mcp-client.js +1 -0
  206. package/src/lib/mcp-oauth.js +35 -21
  207. package/src/lib/packer/pkg-config-generator.js +1 -0
  208. package/src/lib/permission-decision.js +99 -0
  209. package/src/lib/plugin-monitor-supervisor.js +3 -0
  210. package/src/lib/plugin-runtime/capabilities.js +50 -0
  211. package/src/lib/plugin-runtime/capability-consent.js +42 -35
  212. package/src/lib/plugin-runtime/hooks.js +36 -9
  213. package/src/lib/plugin-runtime/install.js +23 -7
  214. package/src/lib/plugin-runtime/lsp.js +4 -0
  215. package/src/lib/plugin-runtime/manifest.js +50 -2
  216. package/src/lib/plugin-runtime/mcp.js +30 -5
  217. package/src/lib/plugin-runtime/monitors.js +11 -0
  218. package/src/lib/plugin-runtime/plugin-options.js +94 -38
  219. package/src/lib/plugin-runtime/policy.js +29 -2
  220. package/src/lib/plugin-runtime/sandbox-policy.js +84 -0
  221. package/src/lib/plugin-runtime/scopes.js +7 -3
  222. package/src/lib/plugin-runtime/trust.js +36 -31
  223. package/src/lib/process-execution-broker/credential-agent.js +114 -16
  224. package/src/lib/process-execution-broker/credential-transport-worker.js +312 -0
  225. package/src/lib/process-execution-broker/credential-transport.js +378 -0
  226. package/src/lib/process-execution-broker/index.js +408 -19
  227. package/src/lib/process-execution-broker/platform-sandbox.js +561 -21
  228. package/src/lib/process-execution-broker/windows-sandbox.ps1 +999 -0
  229. package/src/lib/project-mcp-trust.js +21 -26
  230. package/src/lib/protocol-replay.js +19 -12
  231. package/src/lib/settings-hooks.cjs +13 -0
  232. package/src/lib/skill-loader.js +83 -10
  233. package/src/lib/sync-credentials.js +5 -4
  234. package/src/lib/turn-binding.js +8 -6
  235. package/src/repl/agent-repl.js +113 -28
  236. package/src/repl/repl-turn-binding.js +5 -2
  237. package/src/runtime/agent-core.js +331 -26
  238. package/src/runtime/coding-agent-contract-shared.cjs +3 -3
  239. package/src/runtime/headless-runner.js +101 -4
  240. package/src/runtime/headless-stream.js +209 -23
  241. package/src/runtime/mcp-config.js +29 -17
  242. package/src/runtime/policies/agent-policy.js +2 -0
  243. package/src/workers/background-agent-worker.js +128 -13
  244. package/src/assets/web-panel/assets/ChatBubbleRenderer-DvySUzxJ.js +0 -1
  245. package/src/assets/web-panel/assets/MarkdownRenderer-DkxCweb1.js +0 -1
  246. package/src/assets/web-panel/assets/Projects-ClomCrN0.js +0 -1
  247. package/src/assets/web-panel/assets/RemoteSession-pRgaWsUK.js +0 -4
  248. package/src/assets/web-panel/assets/chat-Bvl-ojg2.js +0 -1
  249. package/src/assets/web-panel/assets/devWarning-CSVgo71Z.js +0 -1
  250. package/src/assets/web-panel/assets/index-DMIWh9fu.js +0 -1
  251. package/src/assets/web-panel/assets/index-ssTvV1l6.js +0 -1
@@ -61,6 +61,11 @@ import { SIDE_EFFECT_LEDGER_EVENT } from "../lib/side-effect-ledger-store.js";
61
61
  import { TurnBindingLog, createTurnBindingFeed } from "../lib/turn-binding.js";
62
62
  import { TURN_BINDING_EVENT } from "../lib/turn-binding-store.js";
63
63
  import { operationIdempotencyKey } from "../lib/idempotency.js";
64
+ import {
65
+ emitHooksV2Event,
66
+ executeHooksV2Event,
67
+ resolvePromptExpansion,
68
+ } from "../lib/hooks-v2-producers.js";
64
69
  import { CLISkillLoader } from "../lib/skill-loader.js";
65
70
  import { expandFileRefsAsync } from "./file-ref-expander.js";
66
71
  import { composeSystemPrompt } from "./system-prompt.js";
@@ -367,6 +372,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
367
372
  // every existing risk-tier / shell-policy layer runs unchanged.
368
373
  let permissionRules = options.permissionRules || null;
369
374
  let managedSettings = null;
375
+ let settingsFiles = [];
370
376
  try {
371
377
  const { loadSettings, applyManagedPermissionPolicy } =
372
378
  await import("../lib/settings-loader.cjs");
@@ -376,6 +382,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
376
382
  managedSettingsFile: options.managedSettingsFile,
377
383
  });
378
384
  managedSettings = loaded.managed;
385
+ settingsFiles = Array.isArray(loaded.files) ? loaded.files : [];
379
386
  if (!permissionRules) {
380
387
  const total =
381
388
  loaded.rules.allow.length +
@@ -465,6 +472,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
465
472
 
466
473
  const runLoop = deps.agentLoop || coreAgentLoop;
467
474
  const doBootstrap = deps.bootstrap || bootstrap;
475
+ const executeLifecycleHooks = deps.executeHooksV2Event || executeHooksV2Event;
468
476
  const getApprovalGate =
469
477
  deps.getApprovalGate ||
470
478
  (async () => {
@@ -681,6 +689,48 @@ export async function runAgentHeadless(options = {}, deps = {}) {
681
689
  }
682
690
  };
683
691
 
692
+ const setupHooks = await executeLifecycleHooks(
693
+ "Setup",
694
+ {
695
+ schema_version: 1,
696
+ session_id: sessionId,
697
+ cwd,
698
+ database_available: db != null,
699
+ enabled_tools: enabledToolNames,
700
+ settings_files: settingsFiles,
701
+ },
702
+ { failClosed: true },
703
+ );
704
+ if (setupHooks.blocked || setupHooks.decision === "block") {
705
+ const reason =
706
+ setupHooks.blockingResult?.reason ||
707
+ setupHooks.error ||
708
+ "blocked by Setup hook";
709
+ writeErr(`[hook] ${reason}\n`);
710
+ emitHeadlessError(reason);
711
+ return { exitCode: 2, result: reason, isError: true };
712
+ }
713
+
714
+ const expansionHooks = await executeLifecycleHooks(
715
+ "UserPromptExpansion",
716
+ {
717
+ schema_version: 1,
718
+ session_id: sessionId,
719
+ cwd,
720
+ prompt: userContent,
721
+ original_prompt: prompt,
722
+ },
723
+ { failClosed: true },
724
+ );
725
+ const expansion = resolvePromptExpansion(userContent, expansionHooks);
726
+ if (expansion.blocked) {
727
+ const reason = expansion.reason || "blocked by UserPromptExpansion hook";
728
+ writeErr(`[hook] ${reason}\n`);
729
+ emitHeadlessError(reason);
730
+ return { exitCode: 2, result: reason, isError: true };
731
+ }
732
+ userContent = expansion.prompt;
733
+
684
734
  // Load prior conversation when resuming an existing session. The fresh
685
735
  // system prompt always leads; we drop any persisted system turns so it is
686
736
  // never duplicated.
@@ -1033,8 +1083,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
1033
1083
  let _loadedInstructions = null;
1034
1084
  let _loadedPersonaSkills = [];
1035
1085
  let _skillCacheLedger = null;
1036
- const _runtimeSkillLoader =
1037
- options.skillLoader || new CLISkillLoader();
1086
+ const _runtimeSkillLoader = options.skillLoader || new CLISkillLoader();
1038
1087
  const systemContent = composeSystemPrompt(
1039
1088
  buildSystemPrompt(cwd, {
1040
1089
  additionalDirectories,
@@ -1967,6 +2016,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
1967
2016
  // P0-2: settle the in-flight side-effect (commit on success, fail on
1968
2017
  // a clean error) and persist the updated ledger snapshot.
1969
2018
  if (persist && currentSideEffectOpId) {
2019
+ if (event.permission_decision) {
2020
+ sideEffectLedger.annotate(currentSideEffectOpId, {
2021
+ permissionDecision: event.permission_decision,
2022
+ });
2023
+ }
1970
2024
  if (event.result?._diffReviewAudit) {
1971
2025
  diffReviewFollowUps.observe(
1972
2026
  sideEffectLedger,
@@ -1991,6 +2045,12 @@ export async function runAgentHeadless(options = {}, deps = {}) {
1991
2045
  is_error: Boolean(err),
1992
2046
  error: err,
1993
2047
  result: event.result,
2048
+ ...(event.permission_decision_id
2049
+ ? { permission_decision_id: event.permission_decision_id }
2050
+ : {}),
2051
+ ...(event.permission_decision
2052
+ ? { permission_decision: event.permission_decision }
2053
+ : {}),
1994
2054
  });
1995
2055
  if (toolCalls.length > 0) {
1996
2056
  toolCalls[toolCalls.length - 1].is_error = Boolean(err);
@@ -2351,7 +2411,30 @@ export async function runAgentHeadless(options = {}, deps = {}) {
2351
2411
  const { runObserveHooks, dispatchAsyncHooks } =
2352
2412
  await import("../lib/settings-hook-events.js");
2353
2413
  const stopPayload = { reason: endReason, cwd, session_id: sessionId };
2354
- runObserveHooks(settingsHooks, "Stop", stopPayload, { cwd });
2414
+ const stopOutcome = runObserveHooks(
2415
+ settingsHooks,
2416
+ "Stop",
2417
+ stopPayload,
2418
+ { cwd },
2419
+ );
2420
+ const stopFailures = (stopOutcome?.results || []).filter(
2421
+ (result) =>
2422
+ result?.nonBlockingError === true ||
2423
+ result?.malformedDecision === true ||
2424
+ result?.breakerOpen === true,
2425
+ );
2426
+ if (stopFailures.length > 0) {
2427
+ emitHooksV2Event("StopFailure", {
2428
+ schema_version: 1,
2429
+ session_id: sessionId,
2430
+ phase: "stop-hook",
2431
+ failures: stopFailures.map((failure) => ({
2432
+ command: failure.command || null,
2433
+ exit_code: failure.exitCode ?? null,
2434
+ reason: failure.reason || failure.error || null,
2435
+ })),
2436
+ });
2437
+ }
2355
2438
  // Skip the async Stop dispatch/settle here if the auto-rewake re-drive
2356
2439
  // loop already fired + drained it this run (avoids double-execution).
2357
2440
  if (_hookSupervisor && !_asyncStopHandled) {
@@ -2377,6 +2460,14 @@ export async function runAgentHeadless(options = {}, deps = {}) {
2377
2460
  // re-engage the agent in an interactive session — flag it clearly so a
2378
2461
  // headless caller/CI can react.
2379
2462
  for (const rw of _hookSupervisor.drainRewakes()) {
2463
+ emitHooksV2Event("StopFailure", {
2464
+ schema_version: 1,
2465
+ session_id: sessionId,
2466
+ phase: "async-stop-hook",
2467
+ command: rw.command || null,
2468
+ exit_code: rw.exitCode ?? null,
2469
+ reason: rw.error || "async stop hook requested rewake",
2470
+ });
2380
2471
  writeErr(
2381
2472
  `[async-hook REWAKE] ${rw.command} failed` +
2382
2473
  `${rw.exitCode != null ? ` (exit ${rw.exitCode})` : ""}` +
@@ -2398,7 +2489,13 @@ export async function runAgentHeadless(options = {}, deps = {}) {
2398
2489
  { reason: "completed", cwd, session_id: sessionId },
2399
2490
  { cwd },
2400
2491
  );
2401
- } catch {
2492
+ } catch (error) {
2493
+ emitHooksV2Event("StopFailure", {
2494
+ schema_version: 1,
2495
+ session_id: sessionId,
2496
+ phase: "stop-hook-dispatch",
2497
+ reason: error?.message || String(error),
2498
+ });
2402
2499
  // observe-only + best-effort async surfacing
2403
2500
  }
2404
2501
  }
@@ -21,6 +21,15 @@ import {
21
21
  approvalBindingDigest,
22
22
  verifyApprovalBinding,
23
23
  } from "../lib/agent-authority.js";
24
+ import {
25
+ normalizeInteractionBinding,
26
+ sameInteractionBinding,
27
+ } from "../lib/interaction-binding.js";
28
+ import {
29
+ emitHooksV2Event,
30
+ executeHooksV2Event,
31
+ resolvePromptExpansion,
32
+ } from "../lib/hooks-v2-producers.js";
24
33
  import { bootstrap } from "./bootstrap.js";
25
34
  import { buildSystemPrompt, agentLoop as coreAgentLoop } from "./agent-core.js";
26
35
  import { composeSystemPrompt } from "./system-prompt.js";
@@ -183,6 +192,15 @@ export function createStreamCoalescer({
183
192
  const gateOn = (field) => !fieldGate || fieldGate[field] !== false;
184
193
  const rawEmit = (obj) => {
185
194
  let line = obj;
195
+ if (
196
+ !gateOn("permission_decision") &&
197
+ (Object.prototype.hasOwnProperty.call(line, "permission_decision") ||
198
+ Object.prototype.hasOwnProperty.call(line, "permission_decision_id"))
199
+ ) {
200
+ line = { ...line };
201
+ delete line.permission_decision;
202
+ delete line.permission_decision_id;
203
+ }
186
204
  if (traceId && gateOn("trace_id")) line = { ...line, trace_id: traceId };
187
205
  if (stampSeq && gateOn("seq")) line = { ...line, seq: ++seq };
188
206
  writeOut(JSON.stringify(line) + "\n");
@@ -488,6 +506,9 @@ export function parseInputEvent(line) {
488
506
  answer: {
489
507
  id: String(obj.id),
490
508
  value: obj.answer === undefined ? null : obj.answer,
509
+ ...(obj.binding && typeof obj.binding === "object"
510
+ ? { binding: normalizeInteractionBinding(obj.binding) }
511
+ : {}),
491
512
  },
492
513
  };
493
514
  }
@@ -761,8 +782,7 @@ async function runTurn(
761
782
  // agent-sdk docs/PROTOCOL.md §1.2.1): the matching tool_result below
762
783
  // echoes the same id so UIs can pair calls without adjacency.
763
784
  const toolUseId =
764
- event.tool_use_id ||
765
- (nextToolUseId ? nextToolUseId() : undefined);
785
+ event.tool_use_id || (nextToolUseId ? nextToolUseId() : undefined);
766
786
  const pm = getPlanModeManager();
767
787
  const planItem = pm.startPlanItemForTool(event.tool, {
768
788
  toolUseId,
@@ -822,6 +842,11 @@ async function runTurn(
822
842
  // P0-2: settle the in-flight side-effect (commit on success, fail on
823
843
  // a clean error) and persist the updated ledger snapshot.
824
844
  if (sideEffects && currentSideEffectOpId) {
845
+ if (event.permission_decision) {
846
+ sideEffects.ledger.annotate(currentSideEffectOpId, {
847
+ permissionDecision: event.permission_decision,
848
+ });
849
+ }
825
850
  if (event.result?._diffReviewAudit) {
826
851
  diffReviewFollowUps.observe(
827
852
  sideEffects.ledger,
@@ -866,6 +891,12 @@ async function runTurn(
866
891
  is_error: Boolean(err),
867
892
  error: err,
868
893
  result: event.result,
894
+ ...(event.permission_decision_id
895
+ ? { permission_decision_id: event.permission_decision_id }
896
+ : {}),
897
+ ...(event.permission_decision
898
+ ? { permission_decision: event.permission_decision }
899
+ : {}),
869
900
  });
870
901
  if (settledItem) {
871
902
  emit({ type: "plan_update", ...planSnapshot(pm) });
@@ -1046,6 +1077,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1046
1077
  const input = deps.input || process.stdin;
1047
1078
  const runLoop = deps.agentLoop || coreAgentLoop;
1048
1079
  const doBootstrap = deps.bootstrap || bootstrap;
1080
+ const executeLifecycleHooks = deps.executeHooksV2Event || executeHooksV2Event;
1049
1081
  const doExpand = deps.expandFileRefs || expandFileRefsAsync;
1050
1082
  const runSessionSlashCommand =
1051
1083
  deps.executeSessionSlashCommand || executeSessionSlashCommand;
@@ -1068,7 +1100,12 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1068
1100
  // client `hello` narrowing the wire features flips these to suppress the
1069
1101
  // additive fields it can't parse. All true by default = current behavior
1070
1102
  // byte-for-byte; the coalescer reads it per line.
1071
- const fieldGate = { seq: true, trace_id: true, tool_use_id: true };
1103
+ const fieldGate = {
1104
+ seq: true,
1105
+ trace_id: true,
1106
+ tool_use_id: true,
1107
+ permission_decision: true,
1108
+ };
1072
1109
  // Batch consecutive partial-message text/thinking deltas into one stream_event
1073
1110
  // line (Claude-Code 2.1.191 streaming-CPU optimization). `emit` flushes any
1074
1111
  // pending deltas before writing a non-delta line, so ordering is preserved;
@@ -1115,6 +1152,33 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1115
1152
  const sessionId =
1116
1153
  options.sessionId || `headless-stream-${Date.now()}-${process.pid}`;
1117
1154
 
1155
+ const setupHooks = await executeLifecycleHooks(
1156
+ "Setup",
1157
+ {
1158
+ schema_version: 1,
1159
+ session_id: sessionId,
1160
+ cwd,
1161
+ database_available: db != null,
1162
+ enabled_tools: enabledToolNames,
1163
+ settings_files: settingsFiles,
1164
+ },
1165
+ { failClosed: true },
1166
+ );
1167
+ if (setupHooks.blocked || setupHooks.decision === "block") {
1168
+ const reason =
1169
+ setupHooks.blockingResult?.reason ||
1170
+ setupHooks.error ||
1171
+ "blocked by Setup hook";
1172
+ emit({
1173
+ type: "result",
1174
+ subtype: "blocked",
1175
+ is_error: true,
1176
+ result: reason,
1177
+ session_id: sessionId,
1178
+ });
1179
+ return { exitCode: 2, turns: 0 };
1180
+ }
1181
+
1118
1182
  // Session persistence + resume (chat-panel "session resume" / --resume):
1119
1183
  // an EXPLICIT session id (--session / --resume) opts into JSONL persistence —
1120
1184
  // prior history is rebuilt into the conversation and every new turn is
@@ -1434,17 +1498,29 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1434
1498
  multiSelect,
1435
1499
  timeoutMs,
1436
1500
  metadata,
1501
+ sessionId: requestedSessionId,
1502
+ turnId,
1503
+ toolUseId,
1437
1504
  } = {}) =>
1438
1505
  new Promise((resolve, reject) => {
1439
1506
  const id = `q-${++questionSeq}`;
1507
+ const binding = normalizeInteractionBinding({
1508
+ sessionId: requestedSessionId ?? sessionId,
1509
+ turnId,
1510
+ toolUseId,
1511
+ sequence: questionSeq,
1512
+ });
1440
1513
  const ms = Number(timeoutMs) > 0 ? Number(timeoutMs) : questionTimeoutMs;
1441
1514
  const timer = setTimeout(() => failQuestion(id, "timeout"), ms);
1442
1515
  timer.unref?.();
1443
- pendingQuestions.set(id, { resolve, reject, timer });
1516
+ pendingQuestions.set(id, { resolve, reject, timer, binding });
1444
1517
  emit({
1445
1518
  type: "question_request",
1446
1519
  id,
1447
1520
  session_id: sessionId,
1521
+ binding,
1522
+ ...(binding.turnId ? { turn_id: binding.turnId } : {}),
1523
+ ...(binding.toolUseId ? { tool_use_id: binding.toolUseId } : {}),
1448
1524
  question: typeof question === "string" ? question : "",
1449
1525
  options: Array.isArray(qOptions) ? qOptions : null,
1450
1526
  multiSelect: multiSelect === true,
@@ -1491,7 +1567,10 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1491
1567
  if (options.jsonSchema) {
1492
1568
  try {
1493
1569
  _jso = await import("../lib/json-schema-output.js");
1494
- _jsonSchema = _jso.loadSchemaFile(_jso._deps.fs, options.jsonSchema);
1570
+ _jsonSchema = await _jso.loadSchemaFileWithRefs(
1571
+ _jso._deps.fs,
1572
+ options.jsonSchema,
1573
+ );
1495
1574
  } catch (err) {
1496
1575
  // Fail-fast, exactly like `cc agent -p --json-schema` on a bad schema.
1497
1576
  writeErr(`Error: ${err.message}\n`);
@@ -1761,32 +1840,91 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1761
1840
  // handler only after MCP resolution so the client is initialized before use.
1762
1841
  // Reuse the structured Desktop/headless question channel, while preserving
1763
1842
  // the MCP response shape (`action` + object `content`) at this boundary.
1843
+ if (mcp?.mcpClient?.on) {
1844
+ mcp.mcpClient.on("elicitation-deferred", (request) => {
1845
+ emit({
1846
+ type: "elicitation_deferred",
1847
+ session_id: sessionId,
1848
+ server: request.server || null,
1849
+ request_id: request.requestId ?? null,
1850
+ mode: request.mode || "form",
1851
+ message: request.message || "",
1852
+ requested_schema: request.requestedSchema || null,
1853
+ elicitation_id: request.elicitationId || null,
1854
+ url: request.url || null,
1855
+ url_host: request.urlHost || null,
1856
+ reason: request.reason || "no_interactive_host",
1857
+ wire_action: request.wireAction || "decline",
1858
+ });
1859
+ });
1860
+ mcp.mcpClient.on("elicitation-complete", (event) => {
1861
+ emit({
1862
+ type: "elicitation_complete",
1863
+ session_id: sessionId,
1864
+ server: event.server || null,
1865
+ elicitation_id: event.elicitationId || null,
1866
+ });
1867
+ });
1868
+ }
1764
1869
  if (mcp?.mcpClient?.setElicitationHandler && interactiveQuestions) {
1765
1870
  mcp.mcpClient.setElicitationHandler(async (request) => {
1766
- const { emitHooksV2Event } = await import("../lib/hooks-v2-producers.js");
1767
- emitHooksV2Event("MCPElicitation", {
1871
+ const hookContext = {
1872
+ schema_version: 1,
1768
1873
  server: request.server || null,
1769
1874
  request_id: request.requestId ?? null,
1770
1875
  message: request.message || "MCP server requests additional input",
1771
1876
  requested_schema: request.requestedSchema || null,
1877
+ mode: request.mode || "form",
1878
+ elicitation_id: request.elicitationId || null,
1879
+ url: request.url || null,
1880
+ url_host: request.urlHost || null,
1772
1881
  session_id: sessionId,
1773
- });
1774
- const answer = await interactionAskUser({
1775
- question: request.message || "MCP server requests additional input",
1776
- timeoutMs: request.timeoutMs,
1777
- metadata: {
1778
- kind: "mcp_elicitation",
1779
- server: request.server,
1780
- requestId: request.requestId,
1781
- requestedSchema: request.requestedSchema || null,
1782
- },
1783
- });
1784
- if (answer == null) return { action: "cancel" };
1785
- return {
1786
- action: "accept",
1787
- content:
1788
- answer && typeof answer === "object" ? answer : { value: answer },
1789
1882
  };
1883
+ emitHooksV2Event("MCPElicitation", hookContext);
1884
+ emitHooksV2Event("Elicitation", hookContext);
1885
+ try {
1886
+ const answer = await interactionAskUser({
1887
+ question:
1888
+ request.mode === "url"
1889
+ ? `${request.message || "MCP server requests an external interaction"}\nOpen secure URL on ${request.urlHost}?`
1890
+ : request.message || "MCP server requests additional input",
1891
+ timeoutMs: request.timeoutMs,
1892
+ metadata: {
1893
+ kind: "mcp_elicitation",
1894
+ server: request.server,
1895
+ requestId: request.requestId,
1896
+ mode: request.mode || "form",
1897
+ requestedSchema: request.requestedSchema || null,
1898
+ elicitationId: request.elicitationId || null,
1899
+ url: request.url || null,
1900
+ urlHost: request.urlHost || null,
1901
+ },
1902
+ });
1903
+ const response =
1904
+ answer == null
1905
+ ? { action: "cancel" }
1906
+ : request.mode === "url"
1907
+ ? { action: "accept" }
1908
+ : {
1909
+ action: "accept",
1910
+ content:
1911
+ answer && typeof answer === "object"
1912
+ ? answer
1913
+ : { value: answer },
1914
+ };
1915
+ emitHooksV2Event("ElicitationResult", {
1916
+ ...hookContext,
1917
+ action: response.action,
1918
+ });
1919
+ return response;
1920
+ } catch (error) {
1921
+ emitHooksV2Event("ElicitationResult", {
1922
+ ...hookContext,
1923
+ action: "cancel",
1924
+ reason: error?.code || error?.message || "interaction_failed",
1925
+ });
1926
+ throw error;
1927
+ }
1790
1928
  });
1791
1929
  }
1792
1930
 
@@ -2044,6 +2182,19 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
2044
2182
  if (parsed.answer) {
2045
2183
  // Answers settle a BLOCKED ask_user_question — never queued. A null
2046
2184
  // value (user cancelled the QuickPick) → user_timeout (model proceeds).
2185
+ const pending = pendingQuestions.get(parsed.answer.id);
2186
+ if (
2187
+ !pending ||
2188
+ !sameInteractionBinding(pending.binding, parsed.answer.binding)
2189
+ ) {
2190
+ emit({
2191
+ type: "question_response_rejected",
2192
+ id: parsed.answer.id,
2193
+ reason: "binding_mismatch",
2194
+ session_id: sessionId,
2195
+ });
2196
+ continue;
2197
+ }
2047
2198
  if (parsed.answer.value == null)
2048
2199
  failQuestion(parsed.answer.id, "cancelled");
2049
2200
  else
@@ -2196,6 +2347,15 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
2196
2347
  messages_before: before,
2197
2348
  messages_after: messages.length,
2198
2349
  });
2350
+ emitHooksV2Event("PostCompact", {
2351
+ schema_version: 1,
2352
+ trigger: "manual",
2353
+ session_id: sessionId,
2354
+ messages_before: before,
2355
+ messages_after: messages.length,
2356
+ stats,
2357
+ cwd,
2358
+ });
2199
2359
  continue;
2200
2360
  }
2201
2361
 
@@ -2439,6 +2599,32 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
2439
2599
  for (const w of expanded.warnings) writeErr(` @ref: ${w}\n`);
2440
2600
  }
2441
2601
 
2602
+ const expansionHooks = await executeLifecycleHooks(
2603
+ "UserPromptExpansion",
2604
+ {
2605
+ schema_version: 1,
2606
+ session_id: sessionId,
2607
+ turn: turns + 1,
2608
+ cwd,
2609
+ prompt: userContent,
2610
+ original_prompt: parsed.text,
2611
+ },
2612
+ { failClosed: true },
2613
+ );
2614
+ const expansion = resolvePromptExpansion(userContent, expansionHooks);
2615
+ if (expansion.blocked) {
2616
+ emit({
2617
+ type: "result",
2618
+ subtype: "blocked",
2619
+ is_error: true,
2620
+ result: expansion.reason || "blocked by UserPromptExpansion hook",
2621
+ session_id: sessionId,
2622
+ });
2623
+ sawError = true;
2624
+ continue;
2625
+ }
2626
+ userContent = expansion.prompt;
2627
+
2442
2628
  // settings.json UserPromptSubmit hooks. block → skip this turn; context → inject.
2443
2629
  if (settingsHooks) {
2444
2630
  try {
@@ -647,6 +647,12 @@ export async function loadProjectMcp(opts = {}, deps = {}) {
647
647
  const trust =
648
648
  deps.projectMcpTrust ||
649
649
  (await import("../lib/project-mcp-trust.js").catch(() => null));
650
+ if (!trust) {
651
+ writeErr(
652
+ " mcp: SKIPPING project .mcp.json — project trust service is unavailable.\n",
653
+ );
654
+ return deps.into || null;
655
+ }
650
656
 
651
657
  const servers = {};
652
658
  const seenFiles = [];
@@ -661,26 +667,32 @@ export async function loadProjectMcp(opts = {}, deps = {}) {
661
667
  writeErr(` mcp: ignoring malformed ${file} (${err.message})\n`);
662
668
  continue;
663
669
  }
664
- if (trust) {
665
- try {
666
- const check = trust.checkProjectMcpTrust(file, content);
667
- if (check.status === "changed") {
668
- if (trust.projectMcpRetrustRequested(env)) {
669
- trust.recordProjectMcpTrust(file, content);
670
- writeErr(` mcp: ${file} re-trusted (CC_PROJECT_MCP_TRUST).\n`);
671
- } else {
672
- writeErr(
673
- ` mcp: SKIPPING ${file} — its content changed since it was last trusted. ` +
674
- `Review the diff, then re-trust with CC_PROJECT_MCP_TRUST=1 or \`cc mcp trust-project\`.\n`,
675
- );
676
- continue;
670
+ try {
671
+ const check = trust.checkProjectMcpTrust(file, content);
672
+ if (check.status === "changed") {
673
+ if (trust.projectMcpRetrustRequested(env)) {
674
+ if (trust.recordProjectMcpTrust(file, content) !== true) {
675
+ throw new Error("project MCP trust record was not persisted");
677
676
  }
678
- } else if (check.status === "first-use") {
679
- trust.recordProjectMcpTrust(file, content);
677
+ writeErr(` mcp: ${file} re-trusted (CC_PROJECT_MCP_TRUST).\n`);
678
+ } else {
679
+ writeErr(
680
+ ` mcp: SKIPPING ${file} — its content changed since it was last trusted. ` +
681
+ `Review the diff, then re-trust with CC_PROJECT_MCP_TRUST=1 or \`cc mcp trust-project\`.\n`,
682
+ );
683
+ continue;
684
+ }
685
+ } else if (check.status === "first-use") {
686
+ if (trust.recordProjectMcpTrust(file, content) !== true) {
687
+ throw new Error("project MCP trust record was not persisted");
680
688
  }
681
- } catch {
682
- /* trust bookkeeping is best-effort; the opt-in gate above still holds */
683
689
  }
690
+ } catch (err) {
691
+ writeErr(
692
+ ` mcp: SKIPPING ${file} — project trust state is unavailable ` +
693
+ `(${err?.message || "unknown error"}).\n`,
694
+ );
695
+ continue;
684
696
  }
685
697
  const parsed = parseMcpServers(raw);
686
698
  if (Object.keys(parsed).length > 0) {
@@ -33,6 +33,8 @@ export function resolveAgentPolicy({
33
33
  : [],
34
34
  sandbox: overrides.sandbox || null,
35
35
  autoCheckpoint: overrides.autoCheckpoint === true,
36
+ worktreeId:
37
+ overrides.worktreeId == null ? null : String(overrides.worktreeId),
36
38
  systemPrompt: overrides.systemPrompt || null,
37
39
  appendSystemPrompt: overrides.appendSystemPrompt || null,
38
40
  fallbackModel: overrides.fallbackModel || null,