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.
- package/package.json +2 -1
- package/src/assets/web-panel/assets/{AIOps-CEeYTeDB.js → AIOps-B3gWmXjo.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BeRUQ3V2.js → ActionButton-G9pdT-0e.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DrV718XF.js → Analytics-Ca30J7m2.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Cd2Frt7Q.js → AppLayout-BtVTm8PU.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CUJMlORU.js → Artifacts-BhViNa6u.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CXJcfT6p.js → Audit-DhKq-FnY.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DOv6Z7H9.js → BackgroundAgents-BL0SVbnE.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BwdDyBI0.js → Backup-BWkblnFi.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BmLn4kYH.js → BaseInput-ClaRNrF8.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-COg8pAW2.js → Chat-sZE2Z77o.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BAfKOnRe.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-BCP4uoU8.js → Checkbox-Cvhay5WM.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-pRt6Y9JI.js → Codegen-BpejL-4N.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DLaprKhS.js → Col-g2Ki6g_1.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DyATsz5f.js → Community-D2xKbNo9.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BXAaupZK.js → Compact-DbL1Pds3.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DpcJBELr.js → Compliance-DGtZCV4c.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DG4EFWyd.js → Cowork-4kQpoNsI.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-F6Oy5n2P.js → Cron-BxTYXXAN.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BOdgtalX.js → Crosschain-k0J0LT2N.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DT1dSkjH.js → DID-BaqhoPgN.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-NBUIqWzC.js → Dashboard-T4RVPIM1.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CSpHeMYB.js → Dropdown-DszOToWq.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CEG0xISr.js → EmailListRenderer-C9KJU7HF.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BTZ0BZna.js → FamilyGuardDashboard-Cmr0JnsA.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BuuCTn2V.js → Federation-BI-_2xZX.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-KAVceevk.js → FormItemContext-DsnDEPsl.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DnHpcQvW.js → GenericCardRenderer-BLncAKKK.js} +1 -1
- package/src/assets/web-panel/assets/{Git-C_B_0HwB.js → Git-BPQhGXDn.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DPSZuzuu.js → Governance-CyElbUQW.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BV-06V7q.js → Inference-CcSntBQD.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-wpDuupn6.js → KnowledgeGraph-p6e7HZ2r.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Bseca1_I.js → Logs-CNEtr-wz.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-Bj9xI0YH.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-d3kM4DDL.js → Marketplace-Dd2notAJ.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DQ_xZ23i.js → McpTools-BBsN2CSW.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-CRIeYO4L.js → Memory-Dg2uTvwx.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BsllIa9l.js → MobileBridge-r1YMRiJV.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BUuQy30X.js → MobileProjects-C-89kSm4.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BOFDIzrC.js → Mtc-CrPZcVgf.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BQg-vyvG.js → MtcAudit-sxi7hqJb.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-Bo1jrPdN.js → Multisig-CAgOMfF1.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Bmod8alw.js → NLProgramming-DafaPts3.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CGGFL8w-.js → Notes-CJM-xUW_.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BsZvCJxC.js → NotificationSettings-L0ZjfAh_.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C1-Quo_h.js → OrderTableRenderer-BB1CvCK0.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BjOeDYOi.js → Organization-DeLtgAD8.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DwVV3l5A.js → Overflow-CKC2b10z.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Cu3DQT9W.js → P2P-eyf2rzY1.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Cg0gR7dH.js → PdhVaultBrowser-5upNIOW8.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CsAXxRN5.js → Permissions-B8p3W6JK.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C-nNmnYp.js → PersonalDataHub-BnRMxTq3.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-BOnW7nNc.js → Pipeline-DjCNI1li.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-ClLSyGKt.js → Privacy-u6gXLbWT.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DuLvjjq7.js → ProjectInit-BZAw4tkM.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DQYYbDD9.js → ProjectSettings-B1Tr72q7.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Drw8MBGK.js → Projects-DO7HFuBQ.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-ckqHQe6K.js → Providers-BjCztyhj.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DW5BXk-G.js → QrScannerModal-ZWyCUbR1.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DDLnhNTp.js → QuickAsk-DhDjeW4G.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-PJQ2C91U.js → Recommend-R_CN2MuU.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-s6wmda34.js → RemoteSession-uxFcujeu.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DC2sb-I3.js → Reputation-DX8D7rks.js} +1 -1
- package/src/assets/web-panel/assets/{Row-hPGk1eGj.js → Row-BYahQILD.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-RIvfZql0.js → RssFeed-CUSQ2tm-.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DFg1G1eR.js → Search-CnN_S8Cs.js} +1 -1
- package/src/assets/web-panel/assets/{Security-D6H5p8Dp.js → Security-DcZlh-O4.js} +4 -4
- package/src/assets/web-panel/assets/{Services-nxYiFV_w.js → Services-ZhBOjzIX.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BmgFNAdB.js → Skeleton-D5Qnq_lI.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CsaaD2av.js → Skills-BC9cZ3Be.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-yM5y9yvK.js → Sla-DauJ3E8_.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-DbNeZ_fh.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-CFVhEyyr.js → SyncSettings-DUvJbSct.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DdO02Inn.js → Tasks-BXa-5noQ.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Eo2d8Llu.js → Templates-JxaiUt_3.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-ChESOXgy.js → Tenant-BW4ERQN8.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BJ7oDxTI.js → Terminal-DltUbdtv.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-hWX0fUvz.js → TimelineRenderer-CMoZz0Tc.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DVBZQnd-.js → Tokens-D_VEV60K.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-D89cQfVq.js → Trigger-CCXTCs0R.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BIVSb4-V.js → Trust-lkGRIPcG.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B58gWopl.js → UkeySign-BfGeQ9HX.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DhHI7bmG.js → VideoEditing-BEC7pYvc.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-C4FheWS_.js → Wallet-BZdG24o0.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DnPRq-Bx.js → WebAuthn-yoEddedp.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-BerRPjpJ.js → WorkflowEditor-BXZEprOW.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BzZ52iKr.js → chat-gg0bzZal.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BI_E4BAn.js → colors-DjRVRuin.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-d50mr3yk.js → compact-item-su-dieAc.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C6FsQ1IH.js → createContext-Ci3S8oKF.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CxbFX9uH.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DLZEMgLP.js → hasIn-D8F10heH.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-aBumtY.js → index-11wtYQiF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CjuKZBqJ.js → index-1IgxgALJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-9H_M2jju.js → index-1agckWSq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE0V6cp-.js → index-5JqhujnR.js} +1 -1
- package/src/assets/web-panel/assets/{index-Y2-q7QLm.js → index-6Tniqk1s.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoFtCVZ7.js → index-8Z-8BIlN.js} +1 -1
- package/src/assets/web-panel/assets/{index-KNGgO4Wm.js → index-BCI5v0yB.js} +1 -1
- package/src/assets/web-panel/assets/{index-DY4j5zkF.js → index-BDJntYmJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZjjdQ62.js → index-BGzixOGZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTpIOTfR.js → index-BMMOVoLD.js} +1 -1
- package/src/assets/web-panel/assets/{index-BB9SqVSt.js → index-BTFpdBtt.js} +1 -1
- package/src/assets/web-panel/assets/{index-AHr7ryWf.js → index-Ba_HyPnE.js} +1 -1
- package/src/assets/web-panel/assets/{index-Pvf30m8Q.js → index-BbF1IHof.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRN5TRTQ.js → index-BgT9su_e.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUaEHfQ0.js → index-BzPB6kGZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdKt9fOd.js → index-C6ygzplr.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dec0Kf_Z.js → index-CC3ZDjzY.js} +1 -1
- package/src/assets/web-panel/assets/{index-IPkwSAW_.js → index-CEmXRhAE.js} +1 -1
- package/src/assets/web-panel/assets/index-CJGOlduY.js +1 -0
- package/src/assets/web-panel/assets/{index-C3k8kevG.js → index-CMPqd5Cv.js} +1 -1
- package/src/assets/web-panel/assets/{index-A5CDWP7y.js → index-COWd8uGx.js} +1 -1
- package/src/assets/web-panel/assets/{index-CO8DAF7U.js → index-CPIYSp4H.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVzuawCX.js → index-CR0h6seT.js} +1 -1
- package/src/assets/web-panel/assets/{index-Co7s9LsB.js → index-CUmDhC4j.js} +1 -1
- package/src/assets/web-panel/assets/index-CkBCN5yH.js +1 -0
- package/src/assets/web-panel/assets/{index-CLoTQr0W.js → index-CusgZPtc.js} +1 -1
- package/src/assets/web-panel/assets/{index-B81mo1Et.js → index-DBAETXft.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcSUl9fA.js → index-DIJ2qFOC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Q5Tn735s.js → index-Dbq4NMET.js} +1 -1
- package/src/assets/web-panel/assets/{index-GXE0D8Nx.js → index-DkMEF5VT.js} +1 -1
- package/src/assets/web-panel/assets/{index-TWG-_D1M.js → index-DkfQR3hM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAE3hwev.js → index-DnLucOn9.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgkoH3_g.js → index-DugB_aKa.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRGx3w6T.js → index-DyLUarhZ.js} +3 -3
- package/src/assets/web-panel/assets/{index-BeM4hfht.js → index-T6_6ygJZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsscwxPE.js → index-Tu8eWqh-.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bmr_vxXD.js → index-W7XUgdVL.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoNZlzhQ.js → index-dHZinfko.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqkbHHg8.js → index-jyNgp5FI.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-D-4Hzgej.js → initDefaultProps-Cv4p8e4w.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D4Wl4xU7.js → motion-B8EwmMOw.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cd5eQvL0.js → move-B8R9F8TK.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-B4ilslCW.js → mtc-parser-DoFYz5Bp.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Ckarx-tf.js → omit-CHWYLBjI.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-QJ0bpCmc.js → pickAttrs-CXuPDO77.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CKHm-tq8.js → placementArrow-BaAtUUon.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CV6a_w_Y.js → responsiveObserve-DCc4zcDD.js} +1 -1
- package/src/assets/web-panel/assets/{slide-mHpeQFgk.js → slide-B_lx89oZ.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DIaQNQWA.js → statusUtils-DE8DPmR0.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-PJpzavV8.js → styleChecker-1ktXOsL_.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BH7zTw8S.js → useFlexGapSupport-xH89-wjh.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BDNG3JDd.js → useFs-DscvfW5p.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CY2VWdUg.js → usePersonalDataHub-RdMKQta7.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D0kw9jhz.js → vnode-Z3wTni2T.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-B5g7TN7r.js → zoom-B0iChCsm.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +105 -62
- package/src/commands/background-session.js +100 -10
- package/src/commands/git.js +39 -0
- package/src/commands/mcp.js +5 -0
- package/src/commands/plugin.js +160 -29
- package/src/commands/remote-control.js +295 -110
- package/src/commands/session-group.js +131 -0
- package/src/commands/session-location.js +48 -0
- package/src/commands/session-message.js +171 -0
- package/src/commands/session.js +22 -0
- package/src/commands/sync-providers.js +4 -1
- package/src/commands/update.js +1 -0
- package/src/data/changelog.json +41 -2
- package/src/gateways/ws/ws-agent-handler.js +20 -12
- package/src/harness/jsonl-session-store.js +279 -37
- package/src/harness/mcp-client.js +832 -91
- package/src/harness/session-index.js +15 -4
- package/src/lib/agent-worktree.js +8 -1
- package/src/lib/auto-mode-safety-classifier.js +3 -17
- package/src/lib/background-agent-keeper-protocol.js +26 -6
- package/src/lib/background-agent-supervisor.js +17 -1
- package/src/lib/background-session-transport.js +153 -27
- package/src/lib/browser-evidence.js +1405 -0
- package/src/lib/chrome-connector.js +465 -79
- package/src/lib/claude-project-auto-memory.js +481 -0
- package/src/lib/claude-project-storage-layout.js +104 -0
- package/src/lib/cloud/cloud-client.js +40 -0
- package/src/lib/execution-location-local-supervisor.mjs +226 -0
- package/src/lib/execution-location-runner-lifecycle.js +991 -0
- package/src/lib/execution-location-target-preflight.js +333 -0
- package/src/lib/execution-location-target.js +783 -13
- package/src/lib/file-lines.js +6 -1
- package/src/lib/gateway-client-resilience.js +571 -0
- package/src/lib/gitlab-mr-worktree.js +176 -0
- package/src/lib/hooks-v2-producers.js +119 -15
- package/src/lib/hooks-v2-workspace-context.js +44 -1
- package/src/lib/host-resource-budget.js +295 -0
- package/src/lib/ide-context.js +15 -2
- package/src/lib/llm-config-defaults.js +43 -0
- package/src/lib/mcp-client.js +2 -0
- package/src/lib/mcp-headers-helper.js +47 -5
- package/src/lib/mcp-lifecycle-authority.js +887 -0
- package/src/lib/mcp-oauth.js +156 -26
- package/src/lib/mcp-tls.js +330 -0
- package/src/lib/output-styles.js +12 -0
- package/src/lib/paths.js +260 -32
- package/src/lib/permission-request.js +48 -0
- package/src/lib/plugin-runtime/bin.js +3 -1
- package/src/lib/plugin-runtime/hooks.js +3 -1
- package/src/lib/plugin-runtime/install.js +730 -71
- package/src/lib/plugin-runtime/lsp.js +4 -4
- package/src/lib/plugin-runtime/marketplace-archive-source.js +366 -0
- package/src/lib/plugin-runtime/marketplace-catalog.js +63 -6
- package/src/lib/plugin-runtime/marketplace-command-descriptor.js +343 -0
- package/src/lib/plugin-runtime/marketplace-command-source.js +580 -0
- package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1 -0
- package/src/lib/plugin-runtime/marketplace-source-adapter.js +188 -0
- package/src/lib/plugin-runtime/marketplace-source-cache.js +11 -1
- package/src/lib/plugin-runtime/mcp.js +3 -1
- package/src/lib/plugin-runtime/monitors.js +3 -1
- package/src/lib/plugin-runtime/remote-source.js +583 -58
- package/src/lib/plugin-runtime/settings.js +3 -1
- package/src/lib/plugin-runtime/trust.js +274 -13
- package/src/lib/plugin-security.js +393 -41
- package/src/lib/plugin-source-identity.js +850 -0
- package/src/lib/process-execution-broker/credential-agent.js +210 -41
- package/src/lib/process-execution-broker/index.js +15 -1
- package/src/lib/process-execution-broker/linux-cgroup-v2.js +391 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +50 -28
- package/src/lib/project-mcp-trust.js +165 -10
- package/src/lib/remote-approval-bridge.js +136 -46
- package/src/lib/remote-control.js +217 -31
- package/src/lib/resume-session.js +9 -6
- package/src/lib/session-core-singletons.js +26 -11
- package/src/lib/session-host-lease.js +52 -16
- package/src/lib/session-lifecycle-scope.js +153 -0
- package/src/lib/session-message-fabric.js +1252 -0
- package/src/lib/session-projection.js +286 -3
- package/src/lib/session-runtime-retention.js +155 -0
- package/src/lib/session-store-guard.js +3 -1
- package/src/lib/session-workbench-store.js +466 -0
- package/src/lib/settings-loader.cjs +29 -0
- package/src/lib/spellcheck.js +211 -0
- package/src/lib/sub-agent-context.js +9 -9
- package/src/lib/sync-cli-db.js +485 -129
- package/src/lib/sync-credentials.js +31 -20
- package/src/lib/web-fetch.js +112 -40
- package/src/lib/web-search.js +127 -61
- package/src/lib/workspace-trust.js +793 -0
- package/src/repl/agent-repl.js +175 -19
- package/src/repl/permission-prompt.js +29 -8
- package/src/repl/repl-keybindings.js +55 -0
- package/src/runtime/agent-core.js +362 -20
- package/src/runtime/bootstrap.js +37 -13
- package/src/runtime/coding-agent-contract-shared.cjs +11 -4
- package/src/runtime/headless-runner.js +281 -102
- package/src/runtime/headless-stream.js +199 -30
- package/src/runtime/mcp-config.js +298 -6
- package/src/runtime/policies/agent-policy.js +10 -0
- package/src/runtime/status-diagnostics-lite.js +9 -1
- package/src/assets/web-panel/assets/ChatBubbleRenderer-4gGkdGgA.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-B4RLp2zs.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-DPy1XMYh.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CagEcIex.js +0 -1
- package/src/assets/web-panel/assets/index-pzT9PpOU.js +0 -1
- 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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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
|
-
|
|
2242
|
-
|
|
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 } =
|
|
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 } =
|
|
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
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
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 } =
|
|
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 } =
|
|
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 } =
|
|
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.
|