chainlesschain 0.162.148 → 0.162.149
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/README.md +1 -1
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DwpCCp64.js → AIOps-BJif14yR.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C9pBYocA.js → ActionButton-CXek6gJY.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BWAkeXxK.js → Analytics-BgQhdAJi.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-CivFGH6B.js → AppLayout-DTYl5NtR.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-Cm8hRpZm.js → Audit-BzATQAeR.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DXdFMsE8.js → Backup-BzdPEQhL.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-uAwSTeql.js → BaseInput-BM0KVh8E.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-KU8eeJJE.js → Chat-D7fHXHkz.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-Wm34RR-b.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-C6AMDkjd.js → Checkbox-CAiSQ9vO.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-t2moDxcO.js → Codegen-Df40CrEe.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DCcsRRhN.js → Col-DIT2fNFU.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DtB-8SAC.js → Community-CSTIbW2k.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CZm8THYA.js → Compact-DtqXZZUi.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-LiQgC7g1.js → Compliance-CUtzw6o7.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CA8SAxht.js → Cowork-CezmlnmU.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-CtRaF1wD.js → Cron-P4BITarg.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-6-br6Hub.js → Crosschain-BRRiYwvq.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Do2EccrL.js → DID-L5ijB9i4.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-wrXcbzGe.js → Dashboard-CFxro4ob.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-p3FsT245.js → Dropdown-BmAFCQ71.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-D95A2L8q.js → EmailListRenderer-DJBCEuon.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-cLuJW2zo.js → FamilyGuardDashboard-z4oLq6eT.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Brgq_cbN.js → Federation-DsVCpHMF.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DWLCkNgh.js → FormItemContext-DP3bP5th.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BBqUfQd6.js → GenericCardRenderer-BAXP2Gc6.js} +1 -1
- package/src/assets/web-panel/assets/{Git-8F090w4I.js → Git-I3g_bAw9.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CCogEbxb.js → Governance-jHS5-ioS.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CfLD7v7C.js → Inference-CPL7sfx9.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DDuHJewd.js → KnowledgeGraph-Jf236h4C.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CE8KSEVC.js → Logs-Cm2tcSKg.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-DmwpZmhT.js → Marketplace-CZK82rhi.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Bf7AazU8.js → McpTools-CZCeji7a.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-D0QU_00S.js → Memory-3l2KVS9k.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-yXS9xdhx.js → MobileBridge-VYdpoLh6.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BuDUoGUP.js → MobileProjects-CiB9cmm1.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BYyHy28p.js → Mtc-wCFZbBuL.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-CK0aqpiZ.js → MtcAudit-1a3THIyG.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-mNimKYeb.js → Multisig-DMzLB2hG.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-AioAJ0YA.js → NLProgramming-D9wZbf6l.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CVVNCLHE.js → Notes-hrFe2ZM-.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C4ABj-TK.js → NotificationSettings-CHGX5Jwm.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-CRIFE2Tj.js +1 -0
- package/src/assets/web-panel/assets/{Organization-uozl_gWK.js → Organization-By7FkhtY.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BCZOM2hK.js → Overflow--khGSzJn.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CArcaiaj.js → P2P-CAG9dH35.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Sgq2Srr8.js → PdhVaultBrowser-B3SQZmK9.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BYrQrXnH.js → Permissions-D35ec6JA.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BzHStAbz.js → PersonalDataHub-CxBF7hW_.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-k7KqxX1M.js → Pipeline-s6EtOO1s.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-IumTUWqx.js → Privacy-BbJYmWmO.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BRyImYTf.js → ProjectInit-VGQq1jMT.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BFIqTBFk.js → ProjectSettings-B1ew3Teh.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CGcNIs_g.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CyyFnUPs.js → Providers-mrO47FIK.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-C82cRx-X.js → QrScannerModal-IJF2mHyw.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DGxDF521.js → QuickAsk-CU0wN_Z0.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Cns-Am1y.js → Recommend-DhN37R6G.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-R7OqAIlg.js → RemoteSession-D_xOX_hu.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-D7mgPIYV.js → Reputation-D_Ssv7uH.js} +1 -1
- package/src/assets/web-panel/assets/{Row-B3lEURyd.js → Row-Kx5dKxX7.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-9_UVrpBt.js → RssFeed-BlGwqZkY.js} +2 -2
- package/src/assets/web-panel/assets/{Search-ClZeO80q.js → Search-hLFQzxpb.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BNNJczEp.js → Security-DMlvsVt4.js} +3 -3
- package/src/assets/web-panel/assets/{Services-C5SjrWUj.js → Services-Bd0Qsj2m.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Ci_obQ-g.js → Skeleton-DFclq9X3.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DdebN15P.js → Skills-BNtln2qY.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-OinZP2vi.js → Sla-Dch5H19G.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CxzbNF51.js → SpeechSettings-2UfQcU1g.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-D06N_66b.js → SyncSettings-CD9YQr4i.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BdEdW0AZ.js → Tasks-BNu-7MzI.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-F1ctKmPa.js → Templates-D1n9CaIR.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CVz1Urot.js → Tenant-DenL3iBW.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-ZzU0Io1Y.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-Doitzjmf.js → TimelineRenderer-D87IfukO.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BpyVRpVA.js → Tokens-BkiZc8E3.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-nWhWYTbU.js → Trigger-BNRSytGN.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DK_G-wLx.js → Trust-Bwbd4X2m.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B5yBUojO.js → UkeySign-B8O2bs0o.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C5D51qAe.js → VideoEditing-C2fL8zmH.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CLbL9K7v.js → Wallet-BORYDdE1.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DZUelI3V.js → WebAuthn-C0V5S2FM.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-8RPxt4KW.js → WorkflowEditor-2dR0fcHL.js} +1 -1
- package/src/assets/web-panel/assets/{chat-4N4tOA3d.js → chat-BmuAFAn8.js} +1 -1
- package/src/assets/web-panel/assets/{colors-zbbGVrua.js → colors-CN3smMcK.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-D7iMkbnE.js → compact-item-DCnxb4kW.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CBzPJv-w.js → createContext-vlR43pHn.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DxwmsL4j.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-bHdrQSqZ.js → hasIn-D04tHYFd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbE5D0WL.js → index-0DnaZGkC.js} +1 -1
- package/src/assets/web-panel/assets/{index-308gCGh7.js → index-430S68MN.js} +1 -1
- package/src/assets/web-panel/assets/{index-kmh1TxRa.js → index-B78xL3s2.js} +1 -1
- package/src/assets/web-panel/assets/{index-QFObYeo1.js → index-BTPEZTk1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZb8F8YG.js → index-BXRg8GFQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE9j5YgT.js → index-BasvsWDM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiG1IZao.js → index-BeGDEXFs.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bqmx24kh.js → index-BqhASEL4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCr0geV9.js → index-BudvKQfG.js} +1 -1
- package/src/assets/web-panel/assets/{index-S74FpAIn.js → index-C-6NO5il.js} +1 -1
- package/src/assets/web-panel/assets/{index-DyoNgbXl.js → index-C5Sxb1sE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BtbbdLnf.js → index-CP9m9Ggr.js} +3 -3
- package/src/assets/web-panel/assets/{index-CkxK86vf.js → index-CTOCnIQ7.js} +1 -1
- package/src/assets/web-panel/assets/index-Cg2ldRfU.js +1 -0
- package/src/assets/web-panel/assets/{index-BTIjjXry.js → index-ClhAHDK3.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7b1hGry.js → index-CnXebZLL.js} +1 -1
- package/src/assets/web-panel/assets/{index-CPxkoKgA.js → index-CngCC8hC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ci009ijp.js → index-Cr-A0FYJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdmMoYN1.js → index-CsAsCPJ6.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBNr77E1.js → index-D28DeAAB.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1s0Bz9O.js → index-D5LZVZ0L.js} +1 -1
- package/src/assets/web-panel/assets/{index-oDKNgCsP.js → index-D65_XseV.js} +1 -1
- package/src/assets/web-panel/assets/{index-QNAG4JtR.js → index-D8vwp4qp.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQfu1U78.js → index-DDwLgQY9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnBOpqv3.js → index-DIpY0qM5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQ6NcfWz.js → index-DTWg-18U.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4XKpj6c.js → index-DTtRscUa.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1YDh7Wr.js → index-DYAtmqiv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CvRMA9uT.js → index-D_n8_vfI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CahryTX0.js → index-DbADHwhr.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJ4ZGyW0.js → index-DbVsQBOH.js} +1 -1
- package/src/assets/web-panel/assets/index-Dwzo-dtJ.js +1 -0
- package/src/assets/web-panel/assets/{index-xYCm6W2h.js → index-HhNjnCfe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BS4_Mwk6.js → index-ToUh2b1-.js} +1 -1
- package/src/assets/web-panel/assets/{index-DISWAYce.js → index-TslMTwNy.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmqlJed-.js → index-_FIkN3jd.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqdPyWm5.js → index-hpvvtAZ3.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsKehmmS.js → index-jzR7Ujuw.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUyjUkY7.js → index-ljuBiQW9.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BD55yNBt.js → initDefaultProps-C3wUb4je.js} +1 -1
- package/src/assets/web-panel/assets/{motion-B5Bbe77U.js → motion-D-jYFUNA.js} +1 -1
- package/src/assets/web-panel/assets/{move-CTvIqHEH.js → move-tqb8nwJ2.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BkNyPQKB.js → mtc-parser-DSOjMJMz.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BaXJXgHA.js → omit-CJ7VimIW.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Bw6-YTxH.js → pickAttrs-qXiG1iT3.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BLdbkLqJ.js → placementArrow-CkGBcy1Z.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-IVYkzntU.js → responsiveObserve-D3WvTlLO.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DFMFwwtY.js → slide-BEE2ftge.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CURYRtZ1.js → statusUtils-CsfBpxiG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Cfz63s1r.js → styleChecker-xPrIiJPI.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-COJL0KE3.js → useFlexGapSupport-C5Yd-SCR.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-YLLojQQf.js → useFs-D_MDS8HI.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BF_21qUC.js → usePersonalDataHub-BqJh-usA.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-9ZpkA7bb.js → vnode-chm_p-gz.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DhtAfhl8.js → zoom-3-YDNz0Z.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/assets/web-panel/remote-session-sw.js +43 -0
- package/src/command-manifest.json +22 -1
- package/src/commands/agent.js +44 -5
- package/src/commands/codeintel.js +252 -0
- package/src/commands/eval.js +248 -0
- package/src/commands/plugin.js +354 -0
- package/src/commands/team.js +456 -0
- package/src/gateways/ws/message-dispatcher.js +45 -2
- package/src/gateways/ws/remote-session-protocol.js +37 -0
- package/src/gateways/ws/ws-server.js +1 -1
- package/src/harness/prompt-compressor.js +27 -1
- package/src/harness/remote-command-ledger.js +158 -0
- package/src/harness/remote-session-push-apns.js +246 -0
- package/src/harness/remote-session-push-errors.js +15 -0
- package/src/harness/remote-session-push-fcm.js +9 -25
- package/src/harness/remote-session-push-huawei.js +174 -0
- package/src/harness/remote-session-push-oppo.js +171 -0
- package/src/harness/remote-session-push-senders.js +42 -0
- package/src/harness/remote-session-push-vivo.js +179 -0
- package/src/harness/remote-session-push-web.js +299 -0
- package/src/harness/remote-session-push-xiaomi.js +99 -0
- package/src/index.js +6 -0
- package/src/lib/agent-core.js +2 -0
- package/src/lib/agent-sandbox.js +161 -5
- package/src/lib/agent-team/task-lease.js +434 -0
- package/src/lib/agent-team/team-budget.js +165 -0
- package/src/lib/agent-team/team-mailbox.js +106 -0
- package/src/lib/agent-team/team-runner.js +266 -0
- package/src/lib/agent-team/team-worktree.js +204 -0
- package/src/lib/agents.js +18 -0
- package/src/lib/async-hook-supervisor.cjs +305 -0
- package/src/lib/eval/runner.js +163 -0
- package/src/lib/eval/tasks.js +456 -0
- package/src/lib/eval/trend.js +185 -0
- package/src/lib/lsp/__tests__/code-intelligence.integration.test.js +129 -0
- package/src/lib/lsp/__tests__/code-intelligence.test.js +228 -0
- package/src/lib/lsp/__tests__/jsonrpc-stream.test.js +104 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +258 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +264 -0
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +128 -0
- package/src/lib/lsp/code-intelligence.js +356 -0
- package/src/lib/lsp/jsonrpc-stream.js +139 -0
- package/src/lib/lsp/lsp-client.js +318 -0
- package/src/lib/lsp/lsp-manager.js +323 -0
- package/src/lib/lsp/lsp-server-registry.js +196 -0
- package/src/lib/plugin-monitor-supervisor.js +238 -0
- package/src/lib/plugin-runtime/agents.js +51 -0
- package/src/lib/plugin-runtime/bin.js +100 -0
- package/src/lib/plugin-runtime/hooks.js +100 -0
- package/src/lib/plugin-runtime/install.js +388 -0
- package/src/lib/plugin-runtime/lsp.js +75 -0
- package/src/lib/plugin-runtime/manifest.js +458 -0
- package/src/lib/plugin-runtime/mcp.js +89 -0
- package/src/lib/plugin-runtime/monitors.js +100 -0
- package/src/lib/plugin-runtime/policy.js +144 -0
- package/src/lib/plugin-runtime/reload.js +79 -0
- package/src/lib/plugin-runtime/scopes.js +197 -0
- package/src/lib/plugin-runtime/settings.js +119 -0
- package/src/lib/plugin-runtime/signature.js +107 -0
- package/src/lib/plugin-runtime/skills.js +43 -0
- package/src/lib/plugin-runtime/trust.js +140 -0
- package/src/lib/sandbox-egress-proxy.js +162 -0
- package/src/lib/sandbox-network-policy.js +134 -0
- package/src/lib/sandbox-v2.js +10 -4
- package/src/lib/settings-hook-events.cjs +78 -6
- package/src/lib/settings-hooks.cjs +29 -3
- package/src/lib/settings-loader.cjs +35 -1
- package/src/lib/skill-loader.js +18 -0
- package/src/lib/telemetry/span-recorder.js +237 -0
- package/src/repl/agent-repl.js +400 -4
- package/src/runtime/agent-core.js +546 -52
- package/src/runtime/coding-agent-contract-shared.cjs +82 -8
- package/src/runtime/coding-agent-policy.cjs +32 -7
- package/src/runtime/fallback-model.js +134 -7
- package/src/runtime/headless-runner.js +353 -108
- package/src/runtime/mcp-config.js +46 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DCNfbdlx.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-DIp8Xcbd.js +0 -1
- package/src/assets/web-panel/assets/Projects-Dpid9CDg.js +0 -1
- package/src/assets/web-panel/assets/Terminal-BvAK_Zel.js +0 -3
- package/src/assets/web-panel/assets/devWarning-C2Z5LRgq.js +0 -1
- package/src/assets/web-panel/assets/index-BGp6Yr-Y.js +0 -1
- package/src/assets/web-panel/assets/index-BXiw9dQf.js +0 -1
package/src/repl/agent-repl.js
CHANGED
|
@@ -121,6 +121,20 @@ let _permissionConfirm = null;
|
|
|
121
121
|
let _managedPermissionRulesOnly = false;
|
|
122
122
|
// .claude/settings.json `hooks` block (decision-capable PreToolUse/PostToolUse).
|
|
123
123
|
let _settingsHooks = null;
|
|
124
|
+
// Installed-plugin background monitors (Phase 3.3i) — a supervisor owning any
|
|
125
|
+
// long-running/interval watcher processes a trusted plugin declared; reaped in
|
|
126
|
+
// the SessionEnd cleanup so nothing outlives the REPL.
|
|
127
|
+
let _pluginMonitors = null;
|
|
128
|
+
// Installed-plugin `bin` PATH injection (Phase 3.3n) — restore() puts PATH back
|
|
129
|
+
// at SessionEnd so plugin executables are only resolvable during the session.
|
|
130
|
+
let _pluginBinRestore = null;
|
|
131
|
+
// Installed-plugin `settings` default env (Phase 3.3o) — restore() removes the
|
|
132
|
+
// plugin-provided env-var defaults at SessionEnd (session-scoped).
|
|
133
|
+
let _pluginSettingsRestore = null;
|
|
134
|
+
// Async settings-hook supervisor (Phase 6) — owns fire-and-forget `async:true`
|
|
135
|
+
// hook processes; their results/rewakes drain into the next turn's context.
|
|
136
|
+
// Lazily created when the first async hook is dispatched; reaped at SessionEnd.
|
|
137
|
+
let _asyncHookSupervisor = null;
|
|
124
138
|
// .claude/settings.json `respondToBashCommands` (Claude-Code 2.1.186): whether a
|
|
125
139
|
// `!command` auto-triggers an assistant response to its output. undefined =
|
|
126
140
|
// unset → defaults OFF (opt-in) in shouldRespondToBashCommands.
|
|
@@ -436,10 +450,12 @@ export async function startAgentRepl(options = {}) {
|
|
|
436
450
|
const _fallbackChatFn = _fallbackModels.length
|
|
437
451
|
? makeFallbackChatFn({
|
|
438
452
|
fallbackModels: _fallbackModels,
|
|
439
|
-
onFallback: ({ from, to, error }) =>
|
|
453
|
+
onFallback: ({ from, to, error, skipped, reason, crossProvider }) =>
|
|
440
454
|
logger.info(
|
|
441
455
|
chalk.yellow(
|
|
442
|
-
|
|
456
|
+
skipped
|
|
457
|
+
? `[fallback] "${to}" skipped (${reason})`
|
|
458
|
+
: `[fallback] model "${from}" failed (${error}); retrying with ${crossProvider ? "cross-provider " : ""}"${to}"`,
|
|
443
459
|
),
|
|
444
460
|
),
|
|
445
461
|
})
|
|
@@ -610,9 +626,14 @@ export async function startAgentRepl(options = {}) {
|
|
|
610
626
|
const { loadHooks, projectHookTrustNotice } =
|
|
611
627
|
await import("../lib/settings-hooks.cjs");
|
|
612
628
|
const loaded = loadHooks({ cwd: process.cwd() });
|
|
629
|
+
// Fold in installed plugins' hooks/hooks.json (Phase 3.3c).
|
|
630
|
+
const { mergePluginHooks } = await import("../lib/plugin-runtime/hooks.js");
|
|
631
|
+
const effectiveHooks = mergePluginHooks(loaded.hooks, {
|
|
632
|
+
cwd: process.cwd(),
|
|
633
|
+
});
|
|
613
634
|
_settingsHooks =
|
|
614
|
-
|
|
615
|
-
?
|
|
635
|
+
effectiveHooks && Object.keys(effectiveHooks).length > 0
|
|
636
|
+
? effectiveHooks
|
|
616
637
|
: null;
|
|
617
638
|
// First-run trust notice for an untrusted/cloned repo's shell-running
|
|
618
639
|
// hooks (Claude-Code 2.1.195 parity). Best-effort, stderr-only.
|
|
@@ -626,6 +647,60 @@ export async function startAgentRepl(options = {}) {
|
|
|
626
647
|
_settingsHooks = null;
|
|
627
648
|
}
|
|
628
649
|
|
|
650
|
+
// Start installed plugins' background monitors (Phase 3.3i). Trust-gated
|
|
651
|
+
// inside collectPluginMonitors — only user/local-scope and explicitly-trusted
|
|
652
|
+
// project plugins get a process spawned. Reaped in the SessionEnd cleanup +
|
|
653
|
+
// a process-exit backstop, so no monitor outlives the session.
|
|
654
|
+
try {
|
|
655
|
+
const { collectPluginMonitors } =
|
|
656
|
+
await import("../lib/plugin-runtime/monitors.js");
|
|
657
|
+
const monitors = collectPluginMonitors({ cwd: process.cwd() });
|
|
658
|
+
if (monitors.length > 0) {
|
|
659
|
+
const { PluginMonitorSupervisor } =
|
|
660
|
+
await import("../lib/plugin-monitor-supervisor.js");
|
|
661
|
+
_pluginMonitors = new PluginMonitorSupervisor();
|
|
662
|
+
const started = _pluginMonitors.start(monitors);
|
|
663
|
+
if (started.length > 0) {
|
|
664
|
+
process.stderr.write(
|
|
665
|
+
` monitors: started ${started.length} from trusted plugin(s): ${started.join(", ")}\n`,
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
} catch (_err) {
|
|
670
|
+
_pluginMonitors = null;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Put trusted plugins' bin/ executables on PATH for the session (Phase 3.3n),
|
|
674
|
+
// restored at SessionEnd. Trust-gated inside collectPluginBinDirs.
|
|
675
|
+
try {
|
|
676
|
+
const { applyPluginBinPath } = await import("../lib/plugin-runtime/bin.js");
|
|
677
|
+
const res = applyPluginBinPath({ cwd: process.cwd() });
|
|
678
|
+
_pluginBinRestore = res.restore;
|
|
679
|
+
if (res.added.length > 0) {
|
|
680
|
+
process.stderr.write(
|
|
681
|
+
` bin: added ${res.added.length} plugin bin dir(s) to PATH\n`,
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
} catch (_err) {
|
|
685
|
+
_pluginBinRestore = null;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Apply trusted plugins' default env vars (Phase 3.3o) — only for env keys the
|
|
689
|
+
// user/system didn't already set; restored at SessionEnd.
|
|
690
|
+
try {
|
|
691
|
+
const { applyPluginSettingsEnv } =
|
|
692
|
+
await import("../lib/plugin-runtime/settings.js");
|
|
693
|
+
const res = applyPluginSettingsEnv({ cwd: process.cwd() });
|
|
694
|
+
_pluginSettingsRestore = res.restore;
|
|
695
|
+
if (res.added.length > 0) {
|
|
696
|
+
process.stderr.write(
|
|
697
|
+
` settings: applied ${res.added.length} plugin env default(s)\n`,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
} catch (_err) {
|
|
701
|
+
_pluginSettingsRestore = null;
|
|
702
|
+
}
|
|
703
|
+
|
|
629
704
|
// Resume existing session or create new one
|
|
630
705
|
const useJsonl = feature("JSONL_SESSION");
|
|
631
706
|
|
|
@@ -980,6 +1055,27 @@ export async function startAgentRepl(options = {}) {
|
|
|
980
1055
|
} catch (_err) {
|
|
981
1056
|
// Non-critical
|
|
982
1057
|
}
|
|
1058
|
+
// settings.json SessionResume hooks: a persisted transcript was just
|
|
1059
|
+
// replayed into this interactive session (distinct from SessionStart).
|
|
1060
|
+
// Observe-only, best-effort — never blocks entering the REPL.
|
|
1061
|
+
if (_settingsHooks && messages.some((m) => m.role !== "system")) {
|
|
1062
|
+
try {
|
|
1063
|
+
const { runObserveHooks } =
|
|
1064
|
+
await import("../lib/settings-hook-events.cjs");
|
|
1065
|
+
runObserveHooks(
|
|
1066
|
+
_settingsHooks,
|
|
1067
|
+
"SessionResume",
|
|
1068
|
+
{
|
|
1069
|
+
session_id: sessionId,
|
|
1070
|
+
resumed_from: sessionId,
|
|
1071
|
+
cwd: process.cwd(),
|
|
1072
|
+
},
|
|
1073
|
+
{ cwd: process.cwd() },
|
|
1074
|
+
);
|
|
1075
|
+
} catch {
|
|
1076
|
+
/* observe-only */
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
983
1079
|
// Resume recap (offline, extractive — no LLM): a quick "where were we"
|
|
984
1080
|
// so the user doesn't have to scroll the old transcript.
|
|
985
1081
|
try {
|
|
@@ -1091,6 +1187,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
1091
1187
|
"/quit",
|
|
1092
1188
|
"/reindex",
|
|
1093
1189
|
"/release-notes",
|
|
1190
|
+
"/reload-plugins",
|
|
1094
1191
|
"/reload-skills",
|
|
1095
1192
|
"/review",
|
|
1096
1193
|
"/rewind",
|
|
@@ -1217,6 +1314,25 @@ export async function startAgentRepl(options = {}) {
|
|
|
1217
1314
|
/* already aborted */
|
|
1218
1315
|
}
|
|
1219
1316
|
_turnAbort = null;
|
|
1317
|
+
// settings.json SessionPause hooks: the user interrupted the in-flight
|
|
1318
|
+
// turn — the session stays open, the current work is suspended. The
|
|
1319
|
+
// keypress handler can't await, so fire observe-only fire-and-forget.
|
|
1320
|
+
if (_settingsHooks) {
|
|
1321
|
+
import("../lib/settings-hook-events.cjs")
|
|
1322
|
+
.then(({ runObserveHooks }) =>
|
|
1323
|
+
runObserveHooks(
|
|
1324
|
+
_settingsHooks,
|
|
1325
|
+
"SessionPause",
|
|
1326
|
+
{
|
|
1327
|
+
session_id: sessionId,
|
|
1328
|
+
reason: "user-interrupt",
|
|
1329
|
+
cwd: process.cwd(),
|
|
1330
|
+
},
|
|
1331
|
+
{ cwd: process.cwd() },
|
|
1332
|
+
),
|
|
1333
|
+
)
|
|
1334
|
+
.catch(() => {});
|
|
1335
|
+
}
|
|
1220
1336
|
return;
|
|
1221
1337
|
}
|
|
1222
1338
|
|
|
@@ -1604,6 +1720,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
1604
1720
|
logger.log(
|
|
1605
1721
|
` ${chalk.cyan("/reload-skills")} Re-scan skill layers without restarting`,
|
|
1606
1722
|
);
|
|
1723
|
+
logger.log(
|
|
1724
|
+
` ${chalk.cyan("/reload-plugins")} Re-scan installed plugins after add/trust/upgrade`,
|
|
1725
|
+
);
|
|
1607
1726
|
logger.log(
|
|
1608
1727
|
` ${chalk.cyan("/review")} Diff-first code review (/review [high] [--security|--simplify] [--fix])`,
|
|
1609
1728
|
);
|
|
@@ -2564,6 +2683,117 @@ export async function startAgentRepl(options = {}) {
|
|
|
2564
2683
|
return;
|
|
2565
2684
|
}
|
|
2566
2685
|
|
|
2686
|
+
// `/reload-plugins` (Phase 3.3m): re-scan installed plugins after an
|
|
2687
|
+
// install / trust / upgrade WITHOUT restarting — resets memoized LSP
|
|
2688
|
+
// registration + managed-policy/trust caches, re-merges the effective hook
|
|
2689
|
+
// map, and restarts the monitor supervisor with the fresh set. Already-
|
|
2690
|
+
// connected MCP servers stay for this session (new ones load next session).
|
|
2691
|
+
if (trimmed === "/reload-plugins") {
|
|
2692
|
+
try {
|
|
2693
|
+
const cwd = process.cwd();
|
|
2694
|
+
const { reloadPluginRuntime } =
|
|
2695
|
+
await import("../lib/plugin-runtime/reload.js");
|
|
2696
|
+
const sum = reloadPluginRuntime({ cwd });
|
|
2697
|
+
|
|
2698
|
+
// Re-merge plugin hooks onto the user's settings hooks (live session).
|
|
2699
|
+
try {
|
|
2700
|
+
const { loadHooks } = await import("../lib/settings-hooks.cjs");
|
|
2701
|
+
const { mergePluginHooks } =
|
|
2702
|
+
await import("../lib/plugin-runtime/hooks.js");
|
|
2703
|
+
const base = loadHooks({ cwd }).hooks;
|
|
2704
|
+
const merged = mergePluginHooks(base, { cwd });
|
|
2705
|
+
_settingsHooks =
|
|
2706
|
+
merged && Object.keys(merged).length > 0 ? merged : null;
|
|
2707
|
+
} catch {
|
|
2708
|
+
/* hooks re-merge is best-effort */
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
// settings.json ConfigChange hooks (Claude-Code parity): the live
|
|
2712
|
+
// hooks / permissions / trusted-plugin set just changed, so fire
|
|
2713
|
+
// ConfigChange with the FRESH hook set — a policy hook can observe or
|
|
2714
|
+
// react (e.g. re-audit the newly-trusted config). Best-effort.
|
|
2715
|
+
if (_settingsHooks) {
|
|
2716
|
+
try {
|
|
2717
|
+
const { runObserveHooks, dispatchAsyncHooks } =
|
|
2718
|
+
await import("../lib/settings-hook-events.cjs");
|
|
2719
|
+
const payload = {
|
|
2720
|
+
session_id: sessionId || null,
|
|
2721
|
+
source: "reload-plugins",
|
|
2722
|
+
};
|
|
2723
|
+
runObserveHooks(_settingsHooks, "ConfigChange", payload, { cwd });
|
|
2724
|
+
if (!_asyncHookSupervisor) {
|
|
2725
|
+
const { AsyncHookSupervisor } =
|
|
2726
|
+
await import("../lib/async-hook-supervisor.cjs");
|
|
2727
|
+
_asyncHookSupervisor = new AsyncHookSupervisor();
|
|
2728
|
+
}
|
|
2729
|
+
dispatchAsyncHooks(_settingsHooks, "ConfigChange", payload, {
|
|
2730
|
+
cwd,
|
|
2731
|
+
supervisor: _asyncHookSupervisor,
|
|
2732
|
+
});
|
|
2733
|
+
} catch {
|
|
2734
|
+
/* ConfigChange hooks are best-effort */
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
|
|
2738
|
+
// Restart background monitors with the fresh, trust-gated set.
|
|
2739
|
+
try {
|
|
2740
|
+
const { collectPluginMonitors } =
|
|
2741
|
+
await import("../lib/plugin-runtime/monitors.js");
|
|
2742
|
+
if (_pluginMonitors) {
|
|
2743
|
+
_pluginMonitors.stopAll();
|
|
2744
|
+
_pluginMonitors = null;
|
|
2745
|
+
}
|
|
2746
|
+
const monitors = collectPluginMonitors({ cwd });
|
|
2747
|
+
if (monitors.length > 0) {
|
|
2748
|
+
const { PluginMonitorSupervisor } =
|
|
2749
|
+
await import("../lib/plugin-monitor-supervisor.js");
|
|
2750
|
+
_pluginMonitors = new PluginMonitorSupervisor();
|
|
2751
|
+
_pluginMonitors.start(monitors);
|
|
2752
|
+
}
|
|
2753
|
+
} catch {
|
|
2754
|
+
/* monitor restart is best-effort */
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
// Re-apply plugin bin PATH (a newly-trusted plugin's executables).
|
|
2758
|
+
try {
|
|
2759
|
+
const { applyPluginBinPath } =
|
|
2760
|
+
await import("../lib/plugin-runtime/bin.js");
|
|
2761
|
+
if (_pluginBinRestore) _pluginBinRestore();
|
|
2762
|
+
const res = applyPluginBinPath({ cwd });
|
|
2763
|
+
_pluginBinRestore = res.restore;
|
|
2764
|
+
} catch {
|
|
2765
|
+
/* bin re-apply is best-effort */
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
// Re-apply plugin default env vars (a newly-trusted plugin's settings).
|
|
2769
|
+
try {
|
|
2770
|
+
const { applyPluginSettingsEnv } =
|
|
2771
|
+
await import("../lib/plugin-runtime/settings.js");
|
|
2772
|
+
if (_pluginSettingsRestore) _pluginSettingsRestore();
|
|
2773
|
+
const res = applyPluginSettingsEnv({ cwd });
|
|
2774
|
+
_pluginSettingsRestore = res.restore;
|
|
2775
|
+
} catch {
|
|
2776
|
+
/* settings re-apply is best-effort */
|
|
2777
|
+
}
|
|
2778
|
+
|
|
2779
|
+
logger.log(
|
|
2780
|
+
chalk.green(
|
|
2781
|
+
`✔ plugins reloaded — ${sum.plugins} plugin(s): ` +
|
|
2782
|
+
`${sum.skills} skill layer(s), ${sum.agents} agent dir(s), ` +
|
|
2783
|
+
`${sum.lspRegistered} LSP server(s), ${sum.hooks} hook event(s), ` +
|
|
2784
|
+
`${sum.mcp} MCP server(s), ${sum.monitors} monitor(s)`,
|
|
2785
|
+
),
|
|
2786
|
+
);
|
|
2787
|
+
logger.log(
|
|
2788
|
+
chalk.gray(" (newly-added MCP servers connect on the next session)"),
|
|
2789
|
+
);
|
|
2790
|
+
} catch (err) {
|
|
2791
|
+
logger.error(`/reload-plugins failed: ${err.message}`);
|
|
2792
|
+
}
|
|
2793
|
+
prompt();
|
|
2794
|
+
return;
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2567
2797
|
// `/review` — diff-first code review of your changes (Claude-Code
|
|
2568
2798
|
// /code-review parity). Reuses the `cc review` machinery: collects the git
|
|
2569
2799
|
// diff and runs ONE focused agent turn. Read-only by default; `--fix`
|
|
@@ -3743,11 +3973,95 @@ export async function startAgentRepl(options = {}) {
|
|
|
3743
3973
|
if (ups.additionalContext) {
|
|
3744
3974
|
userContent += `\n\n[hook context]\n${ups.additionalContext}`;
|
|
3745
3975
|
}
|
|
3976
|
+
// Fire-and-forget the `async:true` UserPromptSubmit hooks (Phase 6): a
|
|
3977
|
+
// long-running check (background tests, CI status) runs ALONGSIDE this
|
|
3978
|
+
// turn without blocking it; its result/rewake surfaces on a later turn
|
|
3979
|
+
// via the async-hook drain below. Lazily create the supervisor.
|
|
3980
|
+
const { dispatchAsyncHooks } =
|
|
3981
|
+
await import("../lib/settings-hook-events.cjs");
|
|
3982
|
+
if (!_asyncHookSupervisor) {
|
|
3983
|
+
const { AsyncHookSupervisor } =
|
|
3984
|
+
await import("../lib/async-hook-supervisor.cjs");
|
|
3985
|
+
_asyncHookSupervisor = new AsyncHookSupervisor();
|
|
3986
|
+
}
|
|
3987
|
+
dispatchAsyncHooks(
|
|
3988
|
+
_settingsHooks,
|
|
3989
|
+
"UserPromptSubmit",
|
|
3990
|
+
{ prompt: userContent },
|
|
3991
|
+
{ cwd: process.cwd(), supervisor: _asyncHookSupervisor },
|
|
3992
|
+
);
|
|
3746
3993
|
} catch (_err) {
|
|
3747
3994
|
// settings hook dispatch is best-effort
|
|
3748
3995
|
}
|
|
3749
3996
|
}
|
|
3750
3997
|
|
|
3998
|
+
// Plugin background-monitor output (Phase 3.3i/Phase 6): surface anything a
|
|
3999
|
+
// trusted plugin's monitor captured SINCE the last turn as additionalContext,
|
|
4000
|
+
// so the agent sees e.g. a background test failure or a tailed log on its
|
|
4001
|
+
// next turn. Drained (cleared) so each line is shown once; bounded so a noisy
|
|
4002
|
+
// monitor can't blow up the prompt.
|
|
4003
|
+
if (_pluginMonitors) {
|
|
4004
|
+
try {
|
|
4005
|
+
const recs = _pluginMonitors.drainOutputs();
|
|
4006
|
+
if (recs.length > 0) {
|
|
4007
|
+
const shown = recs.slice(-40);
|
|
4008
|
+
const lines = shown
|
|
4009
|
+
.map((r) => ` [${r.monitor}/${r.stream}] ${r.line}`)
|
|
4010
|
+
.join("\n");
|
|
4011
|
+
const omitted =
|
|
4012
|
+
recs.length > shown.length
|
|
4013
|
+
? `\n … (${recs.length - shown.length} earlier line(s) omitted)`
|
|
4014
|
+
: "";
|
|
4015
|
+
userContent += `\n\n[plugin monitors — new output since last turn]\n${lines}${omitted}`;
|
|
4016
|
+
}
|
|
4017
|
+
} catch (_err) {
|
|
4018
|
+
// monitor drain is best-effort — never blocks a turn
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
|
|
4022
|
+
// Async settings-hook output (Phase 6): fold in any `async:true` hook that
|
|
4023
|
+
// FINISHED since the last turn. Failed `asyncRewake` hooks are surfaced
|
|
4024
|
+
// first + prominently (the "rewake" — a background test failure re-engages
|
|
4025
|
+
// the agent with the structured error) followed by the plain results.
|
|
4026
|
+
// Drained (cleared) so each is shown once.
|
|
4027
|
+
if (_asyncHookSupervisor) {
|
|
4028
|
+
try {
|
|
4029
|
+
const rewakes = _asyncHookSupervisor.drainRewakes();
|
|
4030
|
+
const results = _asyncHookSupervisor.drainResults();
|
|
4031
|
+
if (rewakes.length > 0) {
|
|
4032
|
+
const lines = rewakes
|
|
4033
|
+
.map(
|
|
4034
|
+
(r) =>
|
|
4035
|
+
` ✗ ${r.command}${r.event ? ` (${r.event})` : ""}: ${
|
|
4036
|
+
r.error || "failed"
|
|
4037
|
+
}`,
|
|
4038
|
+
)
|
|
4039
|
+
.join("\n");
|
|
4040
|
+
userContent += `\n\n[async hook — REWAKE: a background hook failed, address it]\n${lines}`;
|
|
4041
|
+
}
|
|
4042
|
+
// Non-rewake informational results (successful context / non-opted
|
|
4043
|
+
// failures). Rewake records already shown above are excluded to avoid
|
|
4044
|
+
// duplication.
|
|
4045
|
+
const info = results.filter((r) => !(r.asyncRewake === true && !r.ok));
|
|
4046
|
+
const ctxLines = info
|
|
4047
|
+
.map((r) => {
|
|
4048
|
+
if (r.skipped) return ` … ${r.command}: ${r.error}`;
|
|
4049
|
+
if (r.ok && r.additionalContext)
|
|
4050
|
+
return ` ✔ ${r.command}: ${r.additionalContext}`;
|
|
4051
|
+
if (!r.ok) return ` ✗ ${r.command}: ${r.error || "failed"}`;
|
|
4052
|
+
return null;
|
|
4053
|
+
})
|
|
4054
|
+
.filter(Boolean);
|
|
4055
|
+
if (ctxLines.length > 0) {
|
|
4056
|
+
userContent += `\n\n[async hooks — finished since last turn]\n${ctxLines
|
|
4057
|
+
.slice(-20)
|
|
4058
|
+
.join("\n")}`;
|
|
4059
|
+
}
|
|
4060
|
+
} catch (_err) {
|
|
4061
|
+
// async-hook drain is best-effort — never blocks a turn
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
|
|
3751
4065
|
// IDE live context (Claude-Code parity): re-shared on every prompt while
|
|
3752
4066
|
// an IDE bridge is connected — the user's selection moves between turns.
|
|
3753
4067
|
// Ephemeral: persistence stores effectivePrompt, not this snapshot.
|
|
@@ -3933,6 +4247,14 @@ export async function startAgentRepl(options = {}) {
|
|
|
3933
4247
|
// merge fires exactly once (2.1.187 parity; see _sanitizeRolesNextTurn).
|
|
3934
4248
|
const _mergeRolesThisTurn = _sanitizeRolesNextTurn;
|
|
3935
4249
|
_sanitizeRolesNextTurn = false;
|
|
4250
|
+
// Ensure the async-hook supervisor exists so `async:true` PostToolUse
|
|
4251
|
+
// hooks (fired inside the loop, per tool call) can be dispatched
|
|
4252
|
+
// fire-and-forget; their results/rewakes drain into the next turn above.
|
|
4253
|
+
if (_settingsHooks && !_asyncHookSupervisor) {
|
|
4254
|
+
const { AsyncHookSupervisor } =
|
|
4255
|
+
await import("../lib/async-hook-supervisor.cjs");
|
|
4256
|
+
_asyncHookSupervisor = new AsyncHookSupervisor();
|
|
4257
|
+
}
|
|
3936
4258
|
const {
|
|
3937
4259
|
content: response,
|
|
3938
4260
|
usageEvents,
|
|
@@ -3996,6 +4318,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
3996
4318
|
permissionRules: _permissionRules,
|
|
3997
4319
|
permissionConfirm: _permissionConfirm,
|
|
3998
4320
|
settingsHooks: _settingsHooks,
|
|
4321
|
+
hookSupervisor: _asyncHookSupervisor,
|
|
3999
4322
|
classifyAllShell: _classifyAllShell,
|
|
4000
4323
|
// Interactive session: gate run_code through the ApprovalGate (like
|
|
4001
4324
|
// run_shell) so a strict tier prompts before arbitrary code runs.
|
|
@@ -4171,6 +4494,37 @@ export async function startAgentRepl(options = {}) {
|
|
|
4171
4494
|
// Non-critical
|
|
4172
4495
|
}
|
|
4173
4496
|
}
|
|
4497
|
+
|
|
4498
|
+
// settings.json Stop hooks (Claude-Code parity): the agent just finished a
|
|
4499
|
+
// turn. Sync Stop hooks observe; `async:true` Stop hooks fire-and-forget
|
|
4500
|
+
// (the canonical "run the test suite after the turn" trigger) with their
|
|
4501
|
+
// results/rewakes drained into the NEXT turn's context (see the async-hook
|
|
4502
|
+
// drain above). Best-effort — never break turn completion.
|
|
4503
|
+
if (_settingsHooks) {
|
|
4504
|
+
try {
|
|
4505
|
+
const { runObserveHooks, dispatchAsyncHooks } =
|
|
4506
|
+
await import("../lib/settings-hook-events.cjs");
|
|
4507
|
+
runObserveHooks(
|
|
4508
|
+
_settingsHooks,
|
|
4509
|
+
"Stop",
|
|
4510
|
+
{ session_id: sessionId || null },
|
|
4511
|
+
{ cwd: process.cwd() },
|
|
4512
|
+
);
|
|
4513
|
+
if (!_asyncHookSupervisor) {
|
|
4514
|
+
const { AsyncHookSupervisor } =
|
|
4515
|
+
await import("../lib/async-hook-supervisor.cjs");
|
|
4516
|
+
_asyncHookSupervisor = new AsyncHookSupervisor();
|
|
4517
|
+
}
|
|
4518
|
+
dispatchAsyncHooks(
|
|
4519
|
+
_settingsHooks,
|
|
4520
|
+
"Stop",
|
|
4521
|
+
{},
|
|
4522
|
+
{ cwd: process.cwd(), supervisor: _asyncHookSupervisor },
|
|
4523
|
+
);
|
|
4524
|
+
} catch (_e) {
|
|
4525
|
+
// Stop-hook dispatch is best-effort
|
|
4526
|
+
}
|
|
4527
|
+
}
|
|
4174
4528
|
} catch (err) {
|
|
4175
4529
|
_turnAbort = null;
|
|
4176
4530
|
// Esc interrupt: an aborted turn is normal flow, not an error — the
|
|
@@ -4331,6 +4685,48 @@ export async function startAgentRepl(options = {}) {
|
|
|
4331
4685
|
// Non-critical
|
|
4332
4686
|
}
|
|
4333
4687
|
|
|
4688
|
+
// Reap plugin background monitors (Phase 3.3i) — clear interval timers and
|
|
4689
|
+
// SIGTERM every watcher child so no monitor process outlives the session.
|
|
4690
|
+
if (_pluginMonitors) {
|
|
4691
|
+
try {
|
|
4692
|
+
_pluginMonitors.stopAll();
|
|
4693
|
+
} catch (_e) {
|
|
4694
|
+
// Non-critical
|
|
4695
|
+
}
|
|
4696
|
+
_pluginMonitors = null;
|
|
4697
|
+
}
|
|
4698
|
+
|
|
4699
|
+
// Reap async settings-hook processes (Phase 6) — SIGTERM any fire-and-forget
|
|
4700
|
+
// `async:true` hook still running so none outlives the session.
|
|
4701
|
+
if (_asyncHookSupervisor) {
|
|
4702
|
+
try {
|
|
4703
|
+
_asyncHookSupervisor.stopAll();
|
|
4704
|
+
} catch (_e) {
|
|
4705
|
+
// Non-critical
|
|
4706
|
+
}
|
|
4707
|
+
_asyncHookSupervisor = null;
|
|
4708
|
+
}
|
|
4709
|
+
|
|
4710
|
+
// Restore PATH — drop the plugin bin dirs added at startup (Phase 3.3n).
|
|
4711
|
+
if (_pluginBinRestore) {
|
|
4712
|
+
try {
|
|
4713
|
+
_pluginBinRestore();
|
|
4714
|
+
} catch (_e) {
|
|
4715
|
+
// Non-critical
|
|
4716
|
+
}
|
|
4717
|
+
_pluginBinRestore = null;
|
|
4718
|
+
}
|
|
4719
|
+
|
|
4720
|
+
// Drop plugin-provided default env vars added at startup (Phase 3.3o).
|
|
4721
|
+
if (_pluginSettingsRestore) {
|
|
4722
|
+
try {
|
|
4723
|
+
_pluginSettingsRestore();
|
|
4724
|
+
} catch (_e) {
|
|
4725
|
+
// Non-critical
|
|
4726
|
+
}
|
|
4727
|
+
_pluginSettingsRestore = null;
|
|
4728
|
+
}
|
|
4729
|
+
|
|
4334
4730
|
// Shutdown runtime
|
|
4335
4731
|
try {
|
|
4336
4732
|
await shutdown();
|