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
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
21
21
|
import { join, basename } from "node:path";
|
|
22
22
|
import { createRequire } from "node:module";
|
|
23
|
-
import { getHomeDir } from "../lib/paths.js";
|
|
23
|
+
import { ensureClaudeProjectStorageTree, getHomeDir } from "../lib/paths.js";
|
|
24
|
+
import { resolveClaudeProjectStorageDir } from "../lib/claude-project-storage-layout.js";
|
|
24
25
|
import { ensurePrivateDirectory, ensurePrivateFile } from "../lib/secure-fs.js";
|
|
25
26
|
import { readVerifiedProjection } from "./jsonl-session-store.js";
|
|
26
27
|
|
|
@@ -39,12 +40,22 @@ export const _deps = {
|
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
function sessionsDir() {
|
|
42
|
-
|
|
43
|
+
const homeDir = getHomeDir();
|
|
44
|
+
return resolveClaudeProjectStorageDir(homeDir) || join(homeDir, "sessions");
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
function indexPath() {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
+
const homeDir = getHomeDir();
|
|
49
|
+
const projectDir = resolveClaudeProjectStorageDir(homeDir);
|
|
50
|
+
if (projectDir) {
|
|
51
|
+
ensureClaudeProjectStorageTree(homeDir, projectDir);
|
|
52
|
+
}
|
|
53
|
+
const dir = projectDir || homeDir;
|
|
54
|
+
if (!projectDir) ensurePrivateDirectory(dir);
|
|
55
|
+
// Keep the long-standing global cache path for legacy sessions. A
|
|
56
|
+
// Claude-compatible project layout must not make one project's index scan
|
|
57
|
+
// another project's transcripts, so its derived index lives beside those
|
|
58
|
+
// project-local JSONL files.
|
|
48
59
|
return join(dir, "session-index.db");
|
|
49
60
|
}
|
|
50
61
|
|
|
@@ -244,7 +244,14 @@ export function finishAgentWorktree(info, { deps = _deps } = {}) {
|
|
|
244
244
|
let headSha = null;
|
|
245
245
|
let readable = false;
|
|
246
246
|
try {
|
|
247
|
-
|
|
247
|
+
// Do not inherit status.showUntrackedFiles=no from repository/user config:
|
|
248
|
+
// an untracked agent output is still work that finalize must preserve.
|
|
249
|
+
dirty =
|
|
250
|
+
git(
|
|
251
|
+
["status", "--porcelain=v1", "--untracked-files=all"],
|
|
252
|
+
info.path,
|
|
253
|
+
deps,
|
|
254
|
+
).trim().length > 0;
|
|
248
255
|
headSha = git(["rev-parse", "HEAD"], info.path, deps).trim();
|
|
249
256
|
readable = true;
|
|
250
257
|
} catch {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
isSecretEnvName,
|
|
21
21
|
} from "./credential-guard.js";
|
|
22
22
|
import { containsSecret } from "./secret-scan.js";
|
|
23
|
+
import { normalizePermissionRequest } from "./permission-request.js";
|
|
23
24
|
|
|
24
25
|
const require_ = createRequire(import.meta.url);
|
|
25
26
|
const shellPolicy = require_("../runtime/coding-agent-shell-policy.cjs");
|
|
@@ -459,21 +460,6 @@ function canonicalShellKeyword(token) {
|
|
|
459
460
|
.replace(/\\(.)/g, "$1");
|
|
460
461
|
}
|
|
461
462
|
|
|
462
|
-
function inputCommand(input) {
|
|
463
|
-
const command = input?.args?.command;
|
|
464
|
-
if (typeof command === "string") return command;
|
|
465
|
-
const argv = input?.args?.argv;
|
|
466
|
-
return Array.isArray(argv)
|
|
467
|
-
? argv
|
|
468
|
-
.map((value) => {
|
|
469
|
-
const token = String(value);
|
|
470
|
-
if (token && !/[\s|;&"'\\]/.test(token)) return token;
|
|
471
|
-
return `"${token.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
472
|
-
})
|
|
473
|
-
.join(" ")
|
|
474
|
-
: "";
|
|
475
|
-
}
|
|
476
|
-
|
|
477
463
|
function workspaceRoots(context = {}) {
|
|
478
464
|
const roots = [];
|
|
479
465
|
if (Array.isArray(context.workspaceRoots)) {
|
|
@@ -1817,7 +1803,7 @@ export function classifyAutoModeSafety(input = {}) {
|
|
|
1817
1803
|
const args = input.args && typeof input.args === "object" ? input.args : {};
|
|
1818
1804
|
const context =
|
|
1819
1805
|
input.context && typeof input.context === "object" ? input.context : {};
|
|
1820
|
-
const command =
|
|
1806
|
+
const command = normalizePermissionRequest({ tool, args }).command;
|
|
1821
1807
|
const segments = collectCommandSegments(command);
|
|
1822
1808
|
const argsText = stableSerialize(args);
|
|
1823
1809
|
const baseRiskLevel = normalizeRisk(input.baseRiskLevel, "medium");
|
|
@@ -2000,7 +1986,7 @@ export function evaluateAutoModeSafety(input = {}, opts = {}) {
|
|
|
2000
1986
|
: classifyAutoModeSafety;
|
|
2001
1987
|
const classification = classifier(input);
|
|
2002
1988
|
const tool = String(input?.tool || "unknown").toLowerCase();
|
|
2003
|
-
const command =
|
|
1989
|
+
const command = normalizePermissionRequest(input).command;
|
|
2004
1990
|
let policy = null;
|
|
2005
1991
|
if (tool === "run_shell") {
|
|
2006
1992
|
const result = evaluateShellCommandPolicy(command, {
|
|
@@ -257,12 +257,16 @@ export function prepareBackgroundAgentLocalPipePath(
|
|
|
257
257
|
{ platform = process.platform } = {},
|
|
258
258
|
) {
|
|
259
259
|
if (platform === "win32") return pipePath;
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
260
|
+
const normalizedPipePath = posix.resolve(
|
|
261
|
+
String(pipePath || "").replaceAll("\\", "/"),
|
|
262
|
+
);
|
|
263
|
+
const directory = posix.dirname(normalizedPipePath);
|
|
264
|
+
if (fallbackLocalPipeDirectory(pipePath)) {
|
|
265
|
+
try {
|
|
266
|
+
mkdirSync(directory, { mode: 0o700 });
|
|
267
|
+
} catch (error) {
|
|
268
|
+
if (error?.code !== "EEXIST") throw error;
|
|
269
|
+
}
|
|
266
270
|
}
|
|
267
271
|
const stat = lstatSync(directory);
|
|
268
272
|
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
@@ -274,6 +278,22 @@ export function prepareBackgroundAgentLocalPipePath(
|
|
|
274
278
|
) {
|
|
275
279
|
throw new Error("background agent socket directory is not private");
|
|
276
280
|
}
|
|
281
|
+
|
|
282
|
+
let socketStat = null;
|
|
283
|
+
try {
|
|
284
|
+
socketStat = lstatSync(normalizedPipePath);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (error?.code !== "ENOENT") throw error;
|
|
287
|
+
}
|
|
288
|
+
if (socketStat) {
|
|
289
|
+
if (
|
|
290
|
+
socketStat.isSymbolicLink() ||
|
|
291
|
+
!socketStat.isSocket() ||
|
|
292
|
+
(uid !== null && socketStat.uid !== uid)
|
|
293
|
+
) {
|
|
294
|
+
throw new Error("background agent socket path is not an owned socket");
|
|
295
|
+
}
|
|
296
|
+
}
|
|
277
297
|
return pipePath;
|
|
278
298
|
}
|
|
279
299
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
chmodSync,
|
|
2
3
|
closeSync,
|
|
3
4
|
existsSync,
|
|
5
|
+
lstatSync,
|
|
4
6
|
mkdirSync,
|
|
5
7
|
openSync,
|
|
6
8
|
readFileSync,
|
|
@@ -651,7 +653,21 @@ export function backgroundAgentsDir() {
|
|
|
651
653
|
const dir =
|
|
652
654
|
process.env.CC_BACKGROUND_AGENTS_DIR ||
|
|
653
655
|
join(getHomeDir(), "background-agents");
|
|
654
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
656
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
657
|
+
if (process.platform !== "win32") {
|
|
658
|
+
const stat = lstatSync(dir);
|
|
659
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : null;
|
|
660
|
+
if (
|
|
661
|
+
!stat.isDirectory() ||
|
|
662
|
+
stat.isSymbolicLink() ||
|
|
663
|
+
(uid !== null && stat.uid !== uid)
|
|
664
|
+
) {
|
|
665
|
+
throw new Error(
|
|
666
|
+
"background agent state directory is not owner-controlled",
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
chmodSync(dir, 0o700);
|
|
670
|
+
}
|
|
655
671
|
return dir;
|
|
656
672
|
}
|
|
657
673
|
|
|
@@ -33,6 +33,10 @@ import {
|
|
|
33
33
|
|
|
34
34
|
const HELLO_TIMEOUT_MS = 5000;
|
|
35
35
|
const MAX_LINE_BYTES = 1024 * 1024;
|
|
36
|
+
export const BACKGROUND_SESSION_BACKLOG_LIMITS = Object.freeze({
|
|
37
|
+
messages: 256,
|
|
38
|
+
bytes: 1024 * 1024,
|
|
39
|
+
});
|
|
36
40
|
|
|
37
41
|
/** Pipe endpoint for a session id (Windows named pipe / POSIX socket file). */
|
|
38
42
|
export function transportPipePath(id, dir, options = {}) {
|
|
@@ -70,14 +74,128 @@ export function createNdjsonReader(onMessage, onError = () => {}) {
|
|
|
70
74
|
};
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
/**
|
|
78
|
+
* A socket writer with an application-level queue above Node's native write
|
|
79
|
+
* buffer. Once `socket.write()` reports backpressure, later messages wait for
|
|
80
|
+
* `drain`; a consumer that exceeds either cap is disconnected instead of
|
|
81
|
+
* retaining an unbounded event history in the worker.
|
|
82
|
+
*/
|
|
83
|
+
export function createBoundedSocketWriter(socket, configured = {}) {
|
|
84
|
+
const maxMessages = Math.max(
|
|
85
|
+
1,
|
|
86
|
+
Number.isFinite(configured.messages)
|
|
87
|
+
? Math.floor(configured.messages)
|
|
88
|
+
: BACKGROUND_SESSION_BACKLOG_LIMITS.messages,
|
|
89
|
+
);
|
|
90
|
+
const maxBytes = Math.max(
|
|
91
|
+
1024,
|
|
92
|
+
Number.isFinite(configured.bytes)
|
|
93
|
+
? Math.floor(configured.bytes)
|
|
94
|
+
: BACKGROUND_SESSION_BACKLOG_LIMITS.bytes,
|
|
95
|
+
);
|
|
96
|
+
const queue = [];
|
|
97
|
+
let queuedBytes = 0;
|
|
98
|
+
let waitingForDrain = false;
|
|
99
|
+
let closed = false;
|
|
100
|
+
let overflowed = false;
|
|
101
|
+
|
|
102
|
+
const nativeBufferedBytes = () =>
|
|
103
|
+
Number.isFinite(socket?.writableLength)
|
|
104
|
+
? Math.max(0, socket.writableLength)
|
|
105
|
+
: 0;
|
|
106
|
+
const clear = () => {
|
|
107
|
+
queue.length = 0;
|
|
108
|
+
queuedBytes = 0;
|
|
109
|
+
waitingForDrain = false;
|
|
110
|
+
};
|
|
111
|
+
const overflow = () => {
|
|
112
|
+
if (overflowed) return false;
|
|
113
|
+
overflowed = true;
|
|
114
|
+
closed = true;
|
|
115
|
+
clear();
|
|
116
|
+
try {
|
|
117
|
+
configured.onOverflow?.({ maxMessages, maxBytes });
|
|
118
|
+
} catch {
|
|
119
|
+
/* observer errors do not change the fail-closed outcome */
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
socket?.destroy();
|
|
123
|
+
} catch {
|
|
124
|
+
/* already closed */
|
|
125
|
+
}
|
|
79
126
|
return false;
|
|
80
|
-
}
|
|
127
|
+
};
|
|
128
|
+
const writePayload = (payload) => {
|
|
129
|
+
try {
|
|
130
|
+
if (socket.write(payload) === false) waitingForDrain = true;
|
|
131
|
+
return true;
|
|
132
|
+
} catch {
|
|
133
|
+
closed = true;
|
|
134
|
+
clear();
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const flush = () => {
|
|
139
|
+
if (closed || socket?.destroyed) {
|
|
140
|
+
closed = true;
|
|
141
|
+
clear();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
waitingForDrain = false;
|
|
145
|
+
while (queue.length > 0 && !waitingForDrain) {
|
|
146
|
+
const next = queue.shift();
|
|
147
|
+
queuedBytes -= next.bytes;
|
|
148
|
+
if (!writePayload(next.payload)) break;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const close = () => {
|
|
152
|
+
if (closed) return;
|
|
153
|
+
closed = true;
|
|
154
|
+
clear();
|
|
155
|
+
socket?.removeListener?.("drain", flush);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
socket?.on?.("drain", flush);
|
|
159
|
+
socket?.once?.("close", close);
|
|
160
|
+
socket?.once?.("error", close);
|
|
161
|
+
|
|
162
|
+
return Object.freeze({
|
|
163
|
+
write(message) {
|
|
164
|
+
if (closed || !socket || socket.destroyed) return false;
|
|
165
|
+
let payload;
|
|
166
|
+
try {
|
|
167
|
+
payload = `${JSON.stringify(message)}\n`;
|
|
168
|
+
} catch {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const bytes = Buffer.byteLength(payload, "utf8");
|
|
172
|
+
if (bytes > maxBytes) return overflow();
|
|
173
|
+
if (waitingForDrain || queue.length > 0) {
|
|
174
|
+
if (
|
|
175
|
+
queue.length + 1 > maxMessages ||
|
|
176
|
+
nativeBufferedBytes() + queuedBytes + bytes > maxBytes
|
|
177
|
+
) {
|
|
178
|
+
return overflow();
|
|
179
|
+
}
|
|
180
|
+
queue.push({ payload, bytes });
|
|
181
|
+
queuedBytes += bytes;
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
if (nativeBufferedBytes() + bytes > maxBytes) return overflow();
|
|
185
|
+
return writePayload(payload);
|
|
186
|
+
},
|
|
187
|
+
close,
|
|
188
|
+
state: () => ({
|
|
189
|
+
queuedMessages: queue.length,
|
|
190
|
+
queuedBytes,
|
|
191
|
+
nativeBufferedBytes: nativeBufferedBytes(),
|
|
192
|
+
waitingForDrain,
|
|
193
|
+
overflowed,
|
|
194
|
+
closed,
|
|
195
|
+
maxMessages,
|
|
196
|
+
maxBytes,
|
|
197
|
+
}),
|
|
198
|
+
});
|
|
81
199
|
}
|
|
82
200
|
|
|
83
201
|
/**
|
|
@@ -117,7 +235,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
117
235
|
/* fine — usually ENOENT */
|
|
118
236
|
}
|
|
119
237
|
}
|
|
120
|
-
const clients = new
|
|
238
|
+
const clients = new Map();
|
|
121
239
|
const notifyClients = () => {
|
|
122
240
|
try {
|
|
123
241
|
onClientChange?.(clients.size);
|
|
@@ -128,6 +246,8 @@ export function startBackgroundSessionServer(opts) {
|
|
|
128
246
|
|
|
129
247
|
const server = net.createServer((socket) => {
|
|
130
248
|
let authed = false;
|
|
249
|
+
const writer = createBoundedSocketWriter(socket);
|
|
250
|
+
const send = (message) => writer.write(message);
|
|
131
251
|
const helloTimer = setTimeout(() => {
|
|
132
252
|
if (!authed) socket.destroy();
|
|
133
253
|
}, HELLO_TIMEOUT_MS);
|
|
@@ -141,8 +261,8 @@ export function startBackgroundSessionServer(opts) {
|
|
|
141
261
|
if (message.type === "hello" && message.token === token) {
|
|
142
262
|
authed = true;
|
|
143
263
|
clearTimeout(helloTimer);
|
|
144
|
-
clients.
|
|
145
|
-
|
|
264
|
+
clients.set(socket, writer);
|
|
265
|
+
send({
|
|
146
266
|
type: "hello",
|
|
147
267
|
...(getStatus ? getStatus() : { id }),
|
|
148
268
|
});
|
|
@@ -156,7 +276,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
156
276
|
case "prompt": {
|
|
157
277
|
const text = String(message.text || "").trim();
|
|
158
278
|
if (!text) {
|
|
159
|
-
|
|
279
|
+
send({
|
|
160
280
|
type: "error",
|
|
161
281
|
message: "prompt text is empty",
|
|
162
282
|
});
|
|
@@ -164,12 +284,12 @@ export function startBackgroundSessionServer(opts) {
|
|
|
164
284
|
}
|
|
165
285
|
try {
|
|
166
286
|
const result = onPrompt(text);
|
|
167
|
-
|
|
287
|
+
send({
|
|
168
288
|
type: "accepted",
|
|
169
289
|
queued: result?.queued ?? 1,
|
|
170
290
|
});
|
|
171
291
|
} catch (error) {
|
|
172
|
-
|
|
292
|
+
send({
|
|
173
293
|
type: "error",
|
|
174
294
|
message: error?.message || String(error),
|
|
175
295
|
});
|
|
@@ -177,7 +297,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
177
297
|
return;
|
|
178
298
|
}
|
|
179
299
|
case "status": {
|
|
180
|
-
|
|
300
|
+
send({
|
|
181
301
|
type: "status",
|
|
182
302
|
...(getStatus ? getStatus() : { id }),
|
|
183
303
|
});
|
|
@@ -186,9 +306,9 @@ export function startBackgroundSessionServer(opts) {
|
|
|
186
306
|
case "stop": {
|
|
187
307
|
try {
|
|
188
308
|
onStop?.();
|
|
189
|
-
|
|
309
|
+
send({ type: "stopping" });
|
|
190
310
|
} catch (error) {
|
|
191
|
-
|
|
311
|
+
send({
|
|
192
312
|
type: "error",
|
|
193
313
|
message: error?.message || String(error),
|
|
194
314
|
});
|
|
@@ -206,7 +326,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
206
326
|
message;
|
|
207
327
|
const resolvedId = requestId || intId;
|
|
208
328
|
if (!resolvedId) {
|
|
209
|
-
|
|
329
|
+
send({
|
|
210
330
|
type: "error",
|
|
211
331
|
message: "interaction_response requires requestId or intId",
|
|
212
332
|
});
|
|
@@ -219,7 +339,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
219
339
|
answer: answer ?? result,
|
|
220
340
|
error,
|
|
221
341
|
});
|
|
222
|
-
|
|
342
|
+
send({
|
|
223
343
|
type: "received",
|
|
224
344
|
requestId: resolvedId,
|
|
225
345
|
accepted:
|
|
@@ -232,7 +352,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
232
352
|
: false,
|
|
233
353
|
});
|
|
234
354
|
} catch (err) {
|
|
235
|
-
|
|
355
|
+
send({
|
|
236
356
|
type: "error",
|
|
237
357
|
message: err?.message || String(err),
|
|
238
358
|
});
|
|
@@ -240,7 +360,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
240
360
|
return;
|
|
241
361
|
}
|
|
242
362
|
default:
|
|
243
|
-
|
|
363
|
+
send({
|
|
244
364
|
type: "error",
|
|
245
365
|
message: `unknown message type: ${message.type}`,
|
|
246
366
|
});
|
|
@@ -256,6 +376,7 @@ export function startBackgroundSessionServer(opts) {
|
|
|
256
376
|
|
|
257
377
|
const drop = () => {
|
|
258
378
|
clearTimeout(helloTimer);
|
|
379
|
+
writer.close();
|
|
259
380
|
if (clients.delete(socket)) notifyClients();
|
|
260
381
|
};
|
|
261
382
|
socket.on("close", drop);
|
|
@@ -281,11 +402,11 @@ export function startBackgroundSessionServer(opts) {
|
|
|
281
402
|
pipePath,
|
|
282
403
|
clientCount: () => clients.size,
|
|
283
404
|
broadcast: (message) => {
|
|
284
|
-
for (const
|
|
405
|
+
for (const writer of clients.values()) writer.write(message);
|
|
285
406
|
},
|
|
286
407
|
broadcastInteractionRequest: (intId, payload, binding = null) => {
|
|
287
|
-
for (const
|
|
288
|
-
|
|
408
|
+
for (const writer of clients.values())
|
|
409
|
+
writer.write({
|
|
289
410
|
type: "interaction_request",
|
|
290
411
|
intId,
|
|
291
412
|
requestId: intId,
|
|
@@ -302,7 +423,10 @@ export function startBackgroundSessionServer(opts) {
|
|
|
302
423
|
},
|
|
303
424
|
close: () =>
|
|
304
425
|
new Promise((done) => {
|
|
305
|
-
for (const socket of clients)
|
|
426
|
+
for (const [socket, writer] of clients) {
|
|
427
|
+
writer.close();
|
|
428
|
+
socket.destroy();
|
|
429
|
+
}
|
|
306
430
|
clients.clear();
|
|
307
431
|
server.close(() => {
|
|
308
432
|
if (process.platform !== "win32") {
|
|
@@ -341,6 +465,7 @@ export function connectBackgroundSession(opts) {
|
|
|
341
465
|
return new Promise((resolve, reject) => {
|
|
342
466
|
let settled = false;
|
|
343
467
|
const socket = net.connect(pipePath);
|
|
468
|
+
const writer = createBoundedSocketWriter(socket);
|
|
344
469
|
const timer = setTimeout(() => {
|
|
345
470
|
if (!settled) {
|
|
346
471
|
settled = true;
|
|
@@ -367,7 +492,7 @@ export function connectBackgroundSession(opts) {
|
|
|
367
492
|
socket.unref?.();
|
|
368
493
|
resolve({
|
|
369
494
|
hello: message,
|
|
370
|
-
send: (msg) =>
|
|
495
|
+
send: (msg) => writer.write(msg),
|
|
371
496
|
close: () => {
|
|
372
497
|
// Best-effort graceful detach, then HARD destroy so the client
|
|
373
498
|
// handle is released synchronously. `socket.end()` alone leaves
|
|
@@ -380,10 +505,11 @@ export function connectBackgroundSession(opts) {
|
|
|
380
505
|
// the worker sees the socket close and finalizes the same as it
|
|
381
506
|
// would on an explicit detach.
|
|
382
507
|
try {
|
|
383
|
-
|
|
508
|
+
writer.write({ type: "detach" });
|
|
384
509
|
} catch {
|
|
385
510
|
/* peer already gone */
|
|
386
511
|
}
|
|
512
|
+
writer.close();
|
|
387
513
|
socket.destroy();
|
|
388
514
|
},
|
|
389
515
|
});
|
|
@@ -398,7 +524,7 @@ export function connectBackgroundSession(opts) {
|
|
|
398
524
|
}),
|
|
399
525
|
);
|
|
400
526
|
socket.on("connect", () => {
|
|
401
|
-
|
|
527
|
+
writer.write({ type: "hello", token });
|
|
402
528
|
});
|
|
403
529
|
socket.on("error", (error) => {
|
|
404
530
|
if (!settled) {
|