chainlesschain 0.162.180 → 0.162.182
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 +7 -3
- package/scripts/build-windows-sandbox-helper.ps1 +163 -0
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-D_TIL54O.js → AIOps-DzZ5_xoj.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-eQwy9r-f.js → ActionButton-DeLXddIg.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D2eNuDgT.js → Analytics-rvDCmet1.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CFhwOFsf.js → AppLayout-Yt6QVDnp.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CJUMw6PB.js → Artifacts-BS112K5L.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CDB9V58o.js → Audit-0wJuQrNu.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-TBppYFjN.js → BackgroundAgents-B90PMgbn.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CYEOUpzJ.js → Backup-TkgMglQQ.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-C88fFT2u.js → BaseInput-CQVS9p1l.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-mkr1vC3N.js → Chat-YTjQHoC7.js} +6 -6
- package/src/assets/web-panel/assets/ChatBubbleRenderer-PR074hUN.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-CVU4xqti.js → Checkbox-5bwaOabq.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-rrNcByz3.js → Codegen-BFmNQ_Xe.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Cqu-zCvh.js → Col-BT_u4Dzp.js} +1 -1
- package/src/assets/web-panel/assets/{Community-RGRlSgXV.js → Community-CJP52u5b.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DBm6epOK.js → Compact-BpzhJE9i.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BgKw5iaW.js → Compliance-Cg7rfslp.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BqQcNO3Z.js → Cowork-JisxL6Yy.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DO5gTFNb.js → Cron-Bu7Ug_MC.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B8hbJNuN.js → Crosschain-CvuqoLdj.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B08bFJ2C.js → DID-C2u9G8Pu.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-xNdy_ifo.js → Dashboard-BFt5Yv3d.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-D-KIZgWL.js → Dropdown-DIaT9Wxq.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DKCvsaGo.js → EmailListRenderer-D_A601Y4.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D_cfqama.js → FamilyGuardDashboard--IyQ8I8w.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-B-UqQD68.js → Federation-BihWHxuY.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BWWvWuJW.js → FormItemContext-BB8dOXc_.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CPchx6N7.js → GenericCardRenderer-DQYhj1HH.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Vx4co9Ff.js → Git-B-2QZxGf.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-D4x0pp_m.js → Governance-CusSb-nG.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-T3KvwPYR.js → Inference-BAjmvPPL.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Ddv3KUv3.js → KnowledgeGraph-DoNYWKYq.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DfH-Dkae.js → Logs-B8fKWD-n.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DHW3PbCq.js → MarkdownRenderer-BlJm1J7E.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-tjgb0R3D.js → Marketplace-CyOscbSL.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DHAk5nYX.js → McpTools-Ex6Om5da.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-A2Yx7thM.js → Memory-CDcD8l8r.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BEmTVfN5.js → MobileBridge-xfBqoFDg.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DuFHUgE4.js → MobileProjects-BwObMMA2.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BDSll0OZ.js → Mtc-CIWd36OV.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CuBvluaS.js → MtcAudit-CPX0ouuA.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BmXAA-Sb.js → Multisig-BDJsIUuW.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-ci2stZAe.js → NLProgramming-DEkbuD3N.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-D-1RpqnS.js → Notes-DJpHRhH1.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C0GyitIT.js → NotificationSettings-C1UZ-Qd5.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-U2bN-hj5.js → OrderTableRenderer-GlJtqLjT.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BNZgpPci.js → Organization-Bbhj0fac.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CDidKmUN.js → Overflow-1H04x3kx.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BnreBaXq.js → P2P-CDpPe3et.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DwJUxO9j.js → PdhVaultBrowser-MUX0Bpvw.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BQGgJPH0.js → Permissions-A07-0Ci1.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-k_fSkCwL.js → PersonalDataHub-DhhDWxAZ.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-WGqKMqau.js → Pipeline-CyfbJfe-.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DtHj9Ymq.js → Privacy-CNFps3ED.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-B3wH2SFC.js → ProjectInit--T-u3Dr5.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Cd0cgcA1.js → ProjectSettings-DJmrK2fC.js} +2 -2
- package/src/assets/web-panel/assets/Projects-Qx_MdX9k.js +1 -0
- package/src/assets/web-panel/assets/{Providers-DTpxEXur.js → Providers-DLzzbOZd.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-B2v6gR-C.js → QrScannerModal-CexOomKS.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D3Nr9xXR.js → QuickAsk-QklGi19_.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-C9inoMky.js → Recommend-Bb9kwSw8.js} +1 -1
- package/src/assets/web-panel/assets/RemoteSession-DZuVNNN5.js +5 -0
- package/src/assets/web-panel/assets/{Reputation-41KFG646.js → Reputation-Dr5cLP0N.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DqAaqqCv.js → Row-oCQHYv5t.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CMDpCDKc.js → RssFeed-IFDEykIR.js} +3 -3
- package/src/assets/web-panel/assets/{Search-B6mtegNL.js → Search-CspVIxDc.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BaePFVZ8.js → Security-Bm66o_DH.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DeG3Qscl.js → Services-DvanNqXl.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-D_QP7F90.js → Skeleton-CHjEe9_O.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DLGyUgIA.js → Skills-Cb8jWjMX.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BN2pxW1Q.js → Sla-DxZm1491.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BWsZPd8B.js → SpeechSettings-DWxEEclC.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-VOZRPODW.js → SyncSettings-FIvOFw5p.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-CyuLnDFR.js +1 -0
- package/src/assets/web-panel/assets/{Templates-eJSob-q0.js → Templates-CaNjzV_t.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Bdwk8Rwy.js → Tenant-DjlP6TmH.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-DwzGMniO.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-D5qkbPKT.js → TimelineRenderer-DoZ8y7y8.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DKgwn8hI.js → Tokens-390cg2TC.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-HlEHniGM.js → Trigger-CLrtCj5_.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CdPcsBpN.js → Trust-DpESfSPn.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-vAdXd-vG.js → UkeySign-CN6279O0.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-9hHBYFnH.js → VideoEditing-DPtAUlSe.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Dxh5d1yR.js → Wallet-nKOMV_1n.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BsFmLHkp.js → WebAuthn-HuXlSOc4.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-Cn0OIwLn.js → WorkflowEditor-CUfFjARi.js} +1 -1
- package/src/assets/web-panel/assets/chat-6Eq0PcZJ.js +1 -0
- package/src/assets/web-panel/assets/{colors-Du9jzLN0.js → colors-BP_Sf6Iy.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DhEscfzw.js → compact-item-BufMKIh5.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CwzEfF3i.js → createContext-BBMXxWSW.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DgVKduH2.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DT_GSE6J.js → hasIn-fUK_tRO2.js} +1 -1
- package/src/assets/web-panel/assets/{index-tND8-TDU.js → index-2A5ph8b2.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8s5FxJY.js → index-3FuwBewR.js} +1 -1
- package/src/assets/web-panel/assets/{index-53z1YUxX.js → index-6GmBa4Kg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFD0cEna.js → index-B2vS66eI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQWxDOvM.js → index-B7Etk0Te.js} +1 -1
- package/src/assets/web-panel/assets/{index-VeHs6qH0.js → index-B9WYSn4m.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGvgnfl9.js → index-BHy6yNiF.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3llLkYM.js → index-BMLHv389.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dny_ZnAO.js → index-BWKoBU8R.js} +1 -1
- package/src/assets/web-panel/assets/{index-DzjzrOli.js → index-Bkg4ZePE.js} +1 -1
- package/src/assets/web-panel/assets/{index-DN60VBn5.js → index-C44atv4k.js} +1 -1
- package/src/assets/web-panel/assets/{index-v5HLYCVa.js → index-CE2DdTP2.js} +1 -1
- package/src/assets/web-panel/assets/{index-BF-ZCVGE.js → index-CGjmILDm.js} +1 -1
- package/src/assets/web-panel/assets/{index-gFjYdstW.js → index-CW_G-MXw.js} +1 -1
- package/src/assets/web-panel/assets/{index-NA2oBLSB.js → index-CZ6Yt17L.js} +1 -1
- package/src/assets/web-panel/assets/{index-Mobw3PHs.js → index-CeASi4fr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWL3SYN3.js → index-CgiECHu2.js} +1 -1
- package/src/assets/web-panel/assets/{index-1LoutPJd.js → index-Cp8vhyZy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnHhFnwt.js → index-CwSf5pnf.js} +1 -1
- package/src/assets/web-panel/assets/{index-B6QDWRLk.js → index-D4_MuGkd.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-QkW1fp.js → index-D9vU25ij.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4SN3by5.js → index-DASluSqY.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyEhUJcu.js → index-DLpIs_P_.js} +1 -1
- package/src/assets/web-panel/assets/index-DOZTSoS7.js +1 -0
- package/src/assets/web-panel/assets/{index-BrkJ7JPm.js → index-DPdUNk1i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cnok8mhZ.js → index-DVsqvI4M.js} +1 -1
- package/src/assets/web-panel/assets/index-DhpvjpqI.js +1 -0
- package/src/assets/web-panel/assets/{index-CAVW0cWM.js → index-DmkMXwnR.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cc9aPkv-.js → index-DocdRcbd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DnVVYKCE.js → index-Dyngbd29.js} +20 -20
- package/src/assets/web-panel/assets/{index-D8gt0j7r.js → index-GwdRUZ-x.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIYTjbv_.js → index-LvCBfTLo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhXay17G.js → index-cpEli44X.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQWENaZf.js → index-fzaMtSJ8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfRDyY1q.js → index-pum7HYBA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BgSR2WMG.js → index-t8N1tSeX.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5IytTND.js → index-uCbEN7cY.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtRwLhee.js → index-wKTLbKyc.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4kZoXNr.js → index-wV6iGdpY.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Cvt59c10.js → initDefaultProps-V5Fo95FM.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D15pPEzl.js → motion-BYWU0hUT.js} +1 -1
- package/src/assets/web-panel/assets/{move-N55KeXJ7.js → move-Cr1M-J2h.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CyFO1bYP.js → mtc-parser-BysQKi2N.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B5IXfxU2.js → omit-D1zHU8GC.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CpVqsulV.js → pickAttrs-CUArxtfi.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-ME36sMF3.js → placementArrow-ChoYEys0.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BXAIR1r-.js → responsiveObserve-BQRs3Mo7.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BkOX3-Dp.js → slide-B8zbsCkg.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Cy4Aklpt.js → statusUtils-C2U8Gs6h.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-gUd2T206.js → styleChecker-Dd8MgL_V.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CaVD4o99.js → useFlexGapSupport-hknqY5NH.js} +1 -1
- package/src/assets/web-panel/assets/{useFs--pFGl0KD.js → useFs-CLTAmcfw.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-D45iP86i.js → usePersonalDataHub-ByegHbiB.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BayoChH_.js → vnode-DqlAy5DP.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CpP38poi.js → zoom-DiXiztQn.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agenda.js +115 -3
- package/src/commands/agent.js +10 -1
- package/src/commands/background-session.js +2 -1
- package/src/commands/context.js +69 -2
- package/src/data/changelog.json +26 -0
- package/src/gateways/terminal/PtyManager.js +45 -4
- package/src/gateways/ws/background-agent-protocol.js +38 -0
- package/src/gateways/ws/message-dispatcher.js +1 -0
- package/src/gateways/ws/remote-session-protocol.js +65 -6
- package/src/gateways/ws/ws-server.js +18 -2
- package/src/harness/background-task-manager.js +70 -2
- package/src/harness/feature-flags.js +15 -8
- package/src/harness/mcp-client.js +618 -43
- package/src/harness/worktree-isolator.js +14 -3
- package/src/lazy-dispatch.js +30 -1
- package/src/lib/agent-authority.js +22 -0
- package/src/lib/agent-core.js +3 -0
- package/src/lib/agent-sandbox.js +161 -0
- package/src/lib/agent-schedule-store.js +45 -22
- package/src/lib/agent-team/team-runner.js +22 -0
- package/src/lib/artifact-store.js +35 -0
- package/src/lib/async-hook-supervisor.cjs +13 -2
- package/src/lib/audit-mtc.js +3 -2
- package/src/lib/background-agent-supervisor.js +104 -3
- package/src/lib/background-interaction-journal.js +407 -0
- package/src/lib/background-interaction-resolver.js +23 -34
- package/src/lib/background-session-transport.js +12 -2
- package/src/lib/capability-manifest.js +41 -3
- package/src/lib/capability-negotiation.js +1 -1
- package/src/lib/channels/channel-manager.js +33 -0
- package/src/lib/channels/telegram-channel.js +23 -5
- package/src/lib/channels/webhook-channel.js +38 -15
- package/src/lib/chrome-connector.js +169 -23
- package/src/lib/config-manager.js +23 -9
- package/src/lib/context-breakdown.js +31 -0
- package/src/lib/cowork-cron.js +274 -32
- package/src/lib/cross-chain-mtc.js +3 -2
- package/src/lib/durable-security-store.js +124 -0
- package/src/lib/event-runtime-host.js +67 -6
- package/src/lib/event-runtime-store.js +163 -0
- package/src/lib/goal-store.js +32 -12
- package/src/lib/headless-manifest.js +2 -1
- package/src/lib/hook-environment.cjs +58 -0
- package/src/lib/hook-manager.js +12 -5
- package/src/lib/hook-runner.cjs +122 -28
- package/src/lib/hook-runner.js +7 -2
- package/src/lib/hooks-v2-producers.js +36 -0
- package/src/lib/hooks-v2-runtime.js +329 -52
- package/src/lib/interaction-adapter.js +60 -19
- package/src/lib/interaction-binding.js +64 -0
- package/src/lib/json-schema-output.js +439 -14
- package/src/lib/json-schema-validate.js +514 -883
- package/src/lib/lan-pairing-tokens.js +115 -57
- package/src/lib/lsp/__tests__/lsp-client.test.js +32 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +25 -0
- package/src/lib/lsp/lsp-client.js +4 -0
- package/src/lib/lsp/lsp-manager.js +3 -0
- package/src/lib/lsp/lsp-server-registry.js +18 -0
- package/src/lib/mcp-client.js +1 -0
- package/src/lib/mcp-oauth.js +35 -21
- package/src/lib/packer/pkg-config-generator.js +3 -0
- package/src/lib/permission-decision.js +99 -0
- package/src/lib/plugin-monitor-supervisor.js +3 -0
- package/src/lib/plugin-runtime/bin.js +1148 -70
- package/src/lib/plugin-runtime/capabilities.js +50 -0
- package/src/lib/plugin-runtime/capability-consent.js +42 -35
- package/src/lib/plugin-runtime/hooks.js +36 -9
- package/src/lib/plugin-runtime/install.js +23 -7
- package/src/lib/plugin-runtime/lsp.js +4 -0
- package/src/lib/plugin-runtime/manifest.js +112 -8
- package/src/lib/plugin-runtime/mcp.js +30 -5
- package/src/lib/plugin-runtime/monitors.js +11 -0
- package/src/lib/plugin-runtime/plugin-options.js +94 -38
- package/src/lib/plugin-runtime/policy.js +29 -2
- package/src/lib/plugin-runtime/sandbox-policy.js +84 -0
- package/src/lib/plugin-runtime/scopes.js +27 -13
- package/src/lib/plugin-runtime/trust.js +36 -31
- package/src/lib/process-execution-broker/credential-agent.js +114 -16
- package/src/lib/process-execution-broker/credential-transport-worker.js +312 -0
- package/src/lib/process-execution-broker/credential-transport.js +378 -0
- package/src/lib/process-execution-broker/index.js +765 -49
- package/src/lib/process-execution-broker/platform-sandbox.js +4233 -138
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +3856 -0
- package/src/lib/project-mcp-trust.js +21 -26
- package/src/lib/protocol-replay.js +19 -12
- package/src/lib/repl-bang-memorize.js +67 -10
- package/src/lib/settings-hooks.cjs +13 -0
- package/src/lib/skill-loader.js +83 -10
- package/src/lib/slash-commands.js +27 -4
- package/src/lib/sync-credentials.js +5 -4
- package/src/lib/turn-binding.js +8 -6
- package/src/repl/agent-repl.js +117 -31
- package/src/repl/repl-turn-binding.js +5 -2
- package/src/runtime/agent-core.js +699 -70
- package/src/runtime/agent-runtime.js +13 -1
- package/src/runtime/coding-agent-contract-shared.cjs +3 -3
- package/src/runtime/headless-runner.js +105 -7
- package/src/runtime/headless-stream.js +209 -23
- package/src/runtime/mcp-config.js +29 -17
- package/src/runtime/policies/agent-policy.js +2 -0
- package/src/workers/background-agent-worker.js +128 -13
- package/src/assets/web-panel/assets/ChatBubbleRenderer-C7bofJuA.js +0 -1
- package/src/assets/web-panel/assets/Projects-BbgmyQnS.js +0 -1
- package/src/assets/web-panel/assets/RemoteSession-Bqk3EYSu.js +0 -4
- package/src/assets/web-panel/assets/Tasks-3bDAUz8K.js +0 -1
- package/src/assets/web-panel/assets/Terminal-CsMLKIoV.js +0 -3
- package/src/assets/web-panel/assets/chat-CJ19O6Dh.js +0 -1
- package/src/assets/web-panel/assets/devWarning-BBMFnsja.js +0 -1
- package/src/assets/web-panel/assets/index-Do8JMV4N.js +0 -1
- package/src/assets/web-panel/assets/index-UYAJ6iNM.js +0 -1
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
* receives short-lived opaque references. Resolving a reference requires an
|
|
7
7
|
* attested agent id and the exact process/host target recorded at issuance.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* The production singleton also mirrors issued references into a broker-owned
|
|
10
|
+
* authenticated local transport. Per-launch capability tokens bind resolution
|
|
11
|
+
* to the approved process and destination host without putting credential
|
|
12
|
+
* values in the child environment or argv.
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
15
|
import crypto from "node:crypto";
|
|
16
|
+
import { CredentialTransport } from "./credential-transport.js";
|
|
15
17
|
|
|
16
18
|
const REDACTED_VALUE = "***REDACTED***";
|
|
17
19
|
const DEFAULT_TTL_MS = 60_000;
|
|
@@ -33,6 +35,7 @@ const CREDENTIAL_ERROR_CODES = Object.freeze({
|
|
|
33
35
|
REVOKED: "CC_CREDENTIAL_REF_REVOKED",
|
|
34
36
|
AGENT_MISMATCH: "CC_CREDENTIAL_AGENT_MISMATCH",
|
|
35
37
|
TARGET_MISMATCH: "CC_CREDENTIAL_TARGET_MISMATCH",
|
|
38
|
+
TRANSPORT_UNAVAILABLE: "CC_CREDENTIAL_TRANSPORT_UNAVAILABLE",
|
|
36
39
|
});
|
|
37
40
|
|
|
38
41
|
// Patterns for environment variables that contain secrets.
|
|
@@ -126,6 +129,10 @@ const RESERVED_AGENT_ENV_KEYS = new Set([
|
|
|
126
129
|
"CC_CREDENTIAL_AGENT_ID",
|
|
127
130
|
"CC_CREDENTIAL_PROXY",
|
|
128
131
|
"CC_CREDENTIAL_TRANSPORT",
|
|
132
|
+
"CC_CREDENTIAL_ENDPOINT",
|
|
133
|
+
"CC_CREDENTIAL_AUTH_TOKEN",
|
|
134
|
+
"CC_CREDENTIAL_TARGET_PROCESS",
|
|
135
|
+
"CC_CREDENTIAL_TARGET_HOST",
|
|
129
136
|
]);
|
|
130
137
|
|
|
131
138
|
function credentialError(code, message) {
|
|
@@ -251,9 +258,21 @@ class CredentialAgent {
|
|
|
251
258
|
Number.MAX_SAFE_INTEGER,
|
|
252
259
|
);
|
|
253
260
|
|
|
254
|
-
|
|
255
|
-
this.
|
|
256
|
-
|
|
261
|
+
this._transportMode = "broker-api";
|
|
262
|
+
this._credentialTransport = null;
|
|
263
|
+
if (options.transport) {
|
|
264
|
+
this._credentialTransport =
|
|
265
|
+
options.transport === true
|
|
266
|
+
? new CredentialTransport({
|
|
267
|
+
agentId: this._agentId,
|
|
268
|
+
onAudit: (entry) => this._recordAudit(entry),
|
|
269
|
+
onSettlement: (settlement) =>
|
|
270
|
+
this._applyTransportSettlement(settlement),
|
|
271
|
+
})
|
|
272
|
+
: options.transport;
|
|
273
|
+
this._transportMode =
|
|
274
|
+
this._credentialTransport?.version || "local-ipc-v1";
|
|
275
|
+
}
|
|
257
276
|
this._lastEnabledState = this._computeEnabled();
|
|
258
277
|
}
|
|
259
278
|
|
|
@@ -270,10 +289,11 @@ class CredentialAgent {
|
|
|
270
289
|
|
|
271
290
|
if (!enabled) {
|
|
272
291
|
let revoked = 0;
|
|
273
|
-
for (const record of this._credentialStore
|
|
292
|
+
for (const [refId, record] of this._credentialStore) {
|
|
274
293
|
if (record.status === "active") {
|
|
275
294
|
record.value = null;
|
|
276
295
|
record.status = "disabled";
|
|
296
|
+
this._credentialTransport?.revokeCredential(refId);
|
|
277
297
|
revoked += 1;
|
|
278
298
|
}
|
|
279
299
|
}
|
|
@@ -387,6 +407,19 @@ class CredentialAgent {
|
|
|
387
407
|
}
|
|
388
408
|
}
|
|
389
409
|
|
|
410
|
+
_applyTransportSettlement(settlement) {
|
|
411
|
+
const record = this._credentialStore.get(settlement?.refId);
|
|
412
|
+
if (!record || record.status !== "active") return;
|
|
413
|
+
const useCount = Number(settlement.useCount);
|
|
414
|
+
if (Number.isFinite(useCount) && useCount > record.useCount) {
|
|
415
|
+
record.useCount = useCount;
|
|
416
|
+
}
|
|
417
|
+
if (settlement.status && settlement.status !== "active") {
|
|
418
|
+
record.status = settlement.status;
|
|
419
|
+
record.value = null;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
390
423
|
_ensureStoreCapacity() {
|
|
391
424
|
this._expireStaleCredentials();
|
|
392
425
|
if (this._credentialStore.size < this._maxCredentials) return;
|
|
@@ -447,6 +480,9 @@ class CredentialAgent {
|
|
|
447
480
|
"Credential maxUses",
|
|
448
481
|
),
|
|
449
482
|
origin: String(request.origin ?? "unknown"),
|
|
483
|
+
capabilityToken: request.capabilityToken
|
|
484
|
+
? String(request.capabilityToken)
|
|
485
|
+
: null,
|
|
450
486
|
};
|
|
451
487
|
}
|
|
452
488
|
|
|
@@ -556,6 +592,38 @@ class CredentialAgent {
|
|
|
556
592
|
target: normalized.target,
|
|
557
593
|
approvalFingerprint: this._fingerprint(normalized.approvalId),
|
|
558
594
|
});
|
|
595
|
+
if (this._credentialTransport && normalized.capabilityToken) {
|
|
596
|
+
try {
|
|
597
|
+
this._credentialTransport.registerCredential({
|
|
598
|
+
refId,
|
|
599
|
+
key: normalized.key,
|
|
600
|
+
value: normalized.value,
|
|
601
|
+
target: normalized.target,
|
|
602
|
+
createdAt,
|
|
603
|
+
expiresAt: createdAt + normalized.ttlMs,
|
|
604
|
+
maxUses: normalized.maxUses,
|
|
605
|
+
useCount: 0,
|
|
606
|
+
status: "active",
|
|
607
|
+
capabilityToken: normalized.capabilityToken,
|
|
608
|
+
});
|
|
609
|
+
} catch (error) {
|
|
610
|
+
const record = this._credentialStore.get(refId);
|
|
611
|
+
record.value = null;
|
|
612
|
+
record.status = "revoked";
|
|
613
|
+
this._recordAudit({
|
|
614
|
+
event: "credential_ref_issue",
|
|
615
|
+
outcome: "denied",
|
|
616
|
+
reason: CREDENTIAL_ERROR_CODES.TRANSPORT_UNAVAILABLE,
|
|
617
|
+
key: normalized.key,
|
|
618
|
+
target: normalized.target,
|
|
619
|
+
refFingerprint: this._fingerprint(refId),
|
|
620
|
+
});
|
|
621
|
+
throw credentialError(
|
|
622
|
+
CREDENTIAL_ERROR_CODES.TRANSPORT_UNAVAILABLE,
|
|
623
|
+
error?.message || "Credential transport is unavailable",
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
559
627
|
this._recordAudit({
|
|
560
628
|
event: "credential_ref_issue",
|
|
561
629
|
outcome: "allowed",
|
|
@@ -695,6 +763,7 @@ class CredentialAgent {
|
|
|
695
763
|
record.value = null;
|
|
696
764
|
record.status = "exhausted";
|
|
697
765
|
}
|
|
766
|
+
this._credentialTransport?.updateCredential(refId, record);
|
|
698
767
|
this._recordAudit({
|
|
699
768
|
event: "credential_ref_resolve",
|
|
700
769
|
outcome: "allowed",
|
|
@@ -717,6 +786,7 @@ class CredentialAgent {
|
|
|
717
786
|
if (!record) return false;
|
|
718
787
|
record.value = null;
|
|
719
788
|
record.status = "revoked";
|
|
789
|
+
this._credentialTransport?.revokeCredential(refId);
|
|
720
790
|
this._recordAudit({
|
|
721
791
|
event: "credential_ref_revoke",
|
|
722
792
|
outcome: "allowed",
|
|
@@ -786,9 +856,18 @@ class CredentialAgent {
|
|
|
786
856
|
);
|
|
787
857
|
}
|
|
788
858
|
|
|
789
|
-
_setReferenceMarkers(safeEnv) {
|
|
859
|
+
_setReferenceMarkers(safeEnv, context) {
|
|
790
860
|
safeEnv.CC_CREDENTIAL_AGENT_ID = this._agentId;
|
|
791
|
-
safeEnv.CC_CREDENTIAL_TRANSPORT = this.
|
|
861
|
+
safeEnv.CC_CREDENTIAL_TRANSPORT = this._transportMode;
|
|
862
|
+
if (this._credentialTransport && context?.capabilityToken) {
|
|
863
|
+
safeEnv.CC_CREDENTIAL_ENDPOINT = this._credentialTransport.endpoint;
|
|
864
|
+
safeEnv.CC_CREDENTIAL_AUTH_TOKEN = context.capabilityToken;
|
|
865
|
+
safeEnv.CC_CREDENTIAL_TARGET_PROCESS = normalizeProcessTarget(
|
|
866
|
+
context.target?.process ?? context.process,
|
|
867
|
+
);
|
|
868
|
+
const host = normalizeHostTarget(context.target?.host ?? context.host);
|
|
869
|
+
if (host) safeEnv.CC_CREDENTIAL_TARGET_HOST = host;
|
|
870
|
+
}
|
|
792
871
|
}
|
|
793
872
|
|
|
794
873
|
/**
|
|
@@ -830,7 +909,7 @@ class CredentialAgent {
|
|
|
830
909
|
redacted.push(entry);
|
|
831
910
|
}
|
|
832
911
|
|
|
833
|
-
if (refsIssued > 0) this._setReferenceMarkers(safeEnv);
|
|
912
|
+
if (refsIssued > 0) this._setReferenceMarkers(safeEnv, context);
|
|
834
913
|
return {
|
|
835
914
|
safeEnv,
|
|
836
915
|
redacted,
|
|
@@ -984,7 +1063,17 @@ class CredentialAgent {
|
|
|
984
1063
|
);
|
|
985
1064
|
}
|
|
986
1065
|
|
|
987
|
-
|
|
1066
|
+
let context = this._contextForSpawn(spawnOptions);
|
|
1067
|
+
if (
|
|
1068
|
+
this._credentialTransport &&
|
|
1069
|
+
this.isEnabled() &&
|
|
1070
|
+
this._canIssueForContext(context)
|
|
1071
|
+
) {
|
|
1072
|
+
context = {
|
|
1073
|
+
...context,
|
|
1074
|
+
capabilityToken: this._credentialTransport.createCapabilityToken(),
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
988
1077
|
const env = spawnOptions.env || process.env;
|
|
989
1078
|
const {
|
|
990
1079
|
safeEnv,
|
|
@@ -1019,7 +1108,7 @@ class CredentialAgent {
|
|
|
1019
1108
|
}
|
|
1020
1109
|
|
|
1021
1110
|
const refsIssued = envRefsIssued + argRefsIssued;
|
|
1022
|
-
if (refsIssued > 0) this._setReferenceMarkers(safeEnv);
|
|
1111
|
+
if (refsIssued > 0) this._setReferenceMarkers(safeEnv, context);
|
|
1023
1112
|
spawnOptions.env = safeEnv;
|
|
1024
1113
|
spawnOptions.args = sanitizedArgs;
|
|
1025
1114
|
|
|
@@ -1094,6 +1183,14 @@ class CredentialAgent {
|
|
|
1094
1183
|
this._accessLog = [];
|
|
1095
1184
|
}
|
|
1096
1185
|
|
|
1186
|
+
waitForTransportReady() {
|
|
1187
|
+
return this._credentialTransport?.waitUntilReady() ?? Promise.resolve(null);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
closeTransport() {
|
|
1191
|
+
return this._credentialTransport?.close() ?? Promise.resolve();
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1097
1194
|
/**
|
|
1098
1195
|
* Get credential agent info for status reporting. No raw references or
|
|
1099
1196
|
* credential values are included.
|
|
@@ -1111,9 +1208,10 @@ class CredentialAgent {
|
|
|
1111
1208
|
mode: this._lastEnabledState
|
|
1112
1209
|
? "broker-reference"
|
|
1113
1210
|
: "redact-only-disabled",
|
|
1114
|
-
transport: this.
|
|
1115
|
-
proxyReady: this.
|
|
1116
|
-
ipcAvailable:
|
|
1211
|
+
transport: this._transportMode,
|
|
1212
|
+
proxyReady: this._credentialTransport?.ready === true,
|
|
1213
|
+
ipcAvailable: this._credentialTransport?.isAvailable() === true,
|
|
1214
|
+
transportInfo: this._credentialTransport?.getInfo() || null,
|
|
1117
1215
|
credentialsTracked: this._credentialStore.size,
|
|
1118
1216
|
activeCredentials: statusCounts.active || 0,
|
|
1119
1217
|
accessCount: this._accessLog.length,
|
|
@@ -1126,7 +1224,7 @@ class CredentialAgent {
|
|
|
1126
1224
|
}
|
|
1127
1225
|
}
|
|
1128
1226
|
|
|
1129
|
-
const credentialAgent = new CredentialAgent();
|
|
1227
|
+
const credentialAgent = new CredentialAgent({ transport: true });
|
|
1130
1228
|
|
|
1131
1229
|
export {
|
|
1132
1230
|
credentialAgent,
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Broker-owned credential transport worker.
|
|
3
|
+
*
|
|
4
|
+
* The worker owns the local named-pipe / Unix-domain-socket server so it can
|
|
5
|
+
* answer a child while the broker's main thread is blocked in spawnSync().
|
|
6
|
+
* Credential values never enter the spawned command's argv or environment.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import crypto from "node:crypto";
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import net from "node:net";
|
|
12
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
13
|
+
|
|
14
|
+
const MAX_FRAME_BYTES = 1024 * 1024;
|
|
15
|
+
const records = new Map();
|
|
16
|
+
const endpoint = workerData.endpoint;
|
|
17
|
+
const agentId = workerData.agentId;
|
|
18
|
+
const platform = workerData.platform;
|
|
19
|
+
|
|
20
|
+
function normalizeProcessTarget(value) {
|
|
21
|
+
const normalized = String(value ?? "").trim();
|
|
22
|
+
if (!normalized) return null;
|
|
23
|
+
return platform === "win32"
|
|
24
|
+
? normalized.replaceAll("/", "\\").toLowerCase()
|
|
25
|
+
: normalized;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function normalizeHostTarget(value) {
|
|
29
|
+
const candidate = String(value ?? "").trim();
|
|
30
|
+
if (!candidate) return null;
|
|
31
|
+
try {
|
|
32
|
+
const parsed = candidate.includes("://")
|
|
33
|
+
? new URL(candidate)
|
|
34
|
+
: new URL(`https://${candidate}`);
|
|
35
|
+
return parsed.hostname.toLowerCase().replace(/\.$/, "");
|
|
36
|
+
} catch {
|
|
37
|
+
return candidate.toLowerCase().replace(/\.$/, "");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function fingerprint(value) {
|
|
42
|
+
return crypto
|
|
43
|
+
.createHash("sha256")
|
|
44
|
+
.update(String(value ?? ""))
|
|
45
|
+
.digest("hex")
|
|
46
|
+
.slice(0, 16);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function capabilityMatches(expected, supplied) {
|
|
50
|
+
const expectedBuffer = Buffer.from(String(expected ?? ""));
|
|
51
|
+
const suppliedBuffer = Buffer.from(String(supplied ?? ""));
|
|
52
|
+
return (
|
|
53
|
+
expectedBuffer.length > 0 &&
|
|
54
|
+
expectedBuffer.length === suppliedBuffer.length &&
|
|
55
|
+
crypto.timingSafeEqual(expectedBuffer, suppliedBuffer)
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function send(socket, message) {
|
|
60
|
+
if (!socket.destroyed) {
|
|
61
|
+
socket.end(`${JSON.stringify(message)}\n`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function deny(socket, code, message, record, refId) {
|
|
66
|
+
parentPort.postMessage({
|
|
67
|
+
type: "audit",
|
|
68
|
+
entry: {
|
|
69
|
+
event: "credential_transport_resolve",
|
|
70
|
+
outcome: "denied",
|
|
71
|
+
reason: code,
|
|
72
|
+
key: record?.key,
|
|
73
|
+
target: record?.target,
|
|
74
|
+
refFingerprint: fingerprint(refId),
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
send(socket, { ok: false, code, message });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function handleResolution(socket, request) {
|
|
81
|
+
const refId = typeof request.refId === "string" ? request.refId : "";
|
|
82
|
+
const record = records.get(refId);
|
|
83
|
+
if (!record) {
|
|
84
|
+
deny(
|
|
85
|
+
socket,
|
|
86
|
+
"CC_CREDENTIAL_REF_NOT_FOUND",
|
|
87
|
+
"Credential reference was not found",
|
|
88
|
+
null,
|
|
89
|
+
refId,
|
|
90
|
+
);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (
|
|
94
|
+
request.agentId !== agentId ||
|
|
95
|
+
!capabilityMatches(record.capabilityToken, request.capabilityToken)
|
|
96
|
+
) {
|
|
97
|
+
deny(
|
|
98
|
+
socket,
|
|
99
|
+
"CC_CREDENTIAL_TRANSPORT_UNAUTHORIZED",
|
|
100
|
+
"Credential transport authentication failed",
|
|
101
|
+
record,
|
|
102
|
+
refId,
|
|
103
|
+
);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const requestTarget = {
|
|
108
|
+
process: normalizeProcessTarget(request.process),
|
|
109
|
+
host: normalizeHostTarget(request.host),
|
|
110
|
+
};
|
|
111
|
+
if (
|
|
112
|
+
!requestTarget.process ||
|
|
113
|
+
requestTarget.process !== record.target.process ||
|
|
114
|
+
requestTarget.host !== record.target.host
|
|
115
|
+
) {
|
|
116
|
+
deny(
|
|
117
|
+
socket,
|
|
118
|
+
"CC_CREDENTIAL_TARGET_MISMATCH",
|
|
119
|
+
"Credential resolution target does not match",
|
|
120
|
+
record,
|
|
121
|
+
refId,
|
|
122
|
+
);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (record.status !== "active") {
|
|
127
|
+
const code =
|
|
128
|
+
record.status === "expired"
|
|
129
|
+
? "CC_CREDENTIAL_REF_EXPIRED"
|
|
130
|
+
: record.status === "exhausted"
|
|
131
|
+
? "CC_CREDENTIAL_REF_EXHAUSTED"
|
|
132
|
+
: "CC_CREDENTIAL_REF_REVOKED";
|
|
133
|
+
deny(socket, code, "Credential reference is not active", record, refId);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (Date.now() >= record.expiresAt) {
|
|
137
|
+
record.status = "expired";
|
|
138
|
+
record.value = null;
|
|
139
|
+
deny(
|
|
140
|
+
socket,
|
|
141
|
+
"CC_CREDENTIAL_REF_EXPIRED",
|
|
142
|
+
"Credential reference has expired",
|
|
143
|
+
record,
|
|
144
|
+
refId,
|
|
145
|
+
);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (record.useCount >= record.maxUses) {
|
|
149
|
+
record.status = "exhausted";
|
|
150
|
+
record.value = null;
|
|
151
|
+
deny(
|
|
152
|
+
socket,
|
|
153
|
+
"CC_CREDENTIAL_REF_EXHAUSTED",
|
|
154
|
+
"Credential reference usage limit has been reached",
|
|
155
|
+
record,
|
|
156
|
+
refId,
|
|
157
|
+
);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const value = record.value;
|
|
162
|
+
record.useCount += 1;
|
|
163
|
+
const remainingUses = record.maxUses - record.useCount;
|
|
164
|
+
if (remainingUses <= 0) {
|
|
165
|
+
record.status = "exhausted";
|
|
166
|
+
record.value = null;
|
|
167
|
+
}
|
|
168
|
+
parentPort.postMessage({
|
|
169
|
+
type: "audit",
|
|
170
|
+
entry: {
|
|
171
|
+
event: "credential_transport_resolve",
|
|
172
|
+
outcome: "allowed",
|
|
173
|
+
key: record.key,
|
|
174
|
+
target: record.target,
|
|
175
|
+
refFingerprint: fingerprint(refId),
|
|
176
|
+
useCount: record.useCount,
|
|
177
|
+
remainingUses: Math.max(remainingUses, 0),
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
parentPort.postMessage({
|
|
181
|
+
type: "settlement",
|
|
182
|
+
refId,
|
|
183
|
+
useCount: record.useCount,
|
|
184
|
+
status: record.status,
|
|
185
|
+
});
|
|
186
|
+
send(socket, { ok: true, value });
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (platform !== "win32") {
|
|
190
|
+
try {
|
|
191
|
+
fs.unlinkSync(endpoint);
|
|
192
|
+
} catch {
|
|
193
|
+
// A socket normally does not exist on first start.
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const server = net.createServer((socket) => {
|
|
198
|
+
let carry = "";
|
|
199
|
+
let handled = false;
|
|
200
|
+
socket.setTimeout(5000, () => socket.destroy());
|
|
201
|
+
socket.on("data", (chunk) => {
|
|
202
|
+
if (handled) return;
|
|
203
|
+
carry += chunk.toString("utf8");
|
|
204
|
+
if (Buffer.byteLength(carry, "utf8") > MAX_FRAME_BYTES) {
|
|
205
|
+
handled = true;
|
|
206
|
+
deny(
|
|
207
|
+
socket,
|
|
208
|
+
"CC_CREDENTIAL_INVALID_REQUEST",
|
|
209
|
+
"Credential transport request is too large",
|
|
210
|
+
null,
|
|
211
|
+
"",
|
|
212
|
+
);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const newline = carry.indexOf("\n");
|
|
216
|
+
if (newline === -1) return;
|
|
217
|
+
handled = true;
|
|
218
|
+
const line = carry.slice(0, newline).replace(/\r$/, "");
|
|
219
|
+
let request;
|
|
220
|
+
try {
|
|
221
|
+
request = JSON.parse(line);
|
|
222
|
+
} catch {
|
|
223
|
+
deny(
|
|
224
|
+
socket,
|
|
225
|
+
"CC_CREDENTIAL_INVALID_REQUEST",
|
|
226
|
+
"Credential transport request is not valid JSON",
|
|
227
|
+
null,
|
|
228
|
+
"",
|
|
229
|
+
);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (!request || request.type !== "resolve") {
|
|
233
|
+
deny(
|
|
234
|
+
socket,
|
|
235
|
+
"CC_CREDENTIAL_INVALID_REQUEST",
|
|
236
|
+
"Credential transport request type is invalid",
|
|
237
|
+
null,
|
|
238
|
+
request?.refId,
|
|
239
|
+
);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
handleResolution(socket, request);
|
|
243
|
+
});
|
|
244
|
+
socket.on("error", () => {
|
|
245
|
+
// Per-client failures must not take down the credential service.
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
server.on("error", (error) => {
|
|
250
|
+
parentPort.postMessage({
|
|
251
|
+
type: "fatal",
|
|
252
|
+
error: {
|
|
253
|
+
code: error.code || "CC_CREDENTIAL_TRANSPORT_UNAVAILABLE",
|
|
254
|
+
message: error.message,
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
server.listen(endpoint, () => {
|
|
260
|
+
if (platform !== "win32") {
|
|
261
|
+
try {
|
|
262
|
+
fs.chmodSync(endpoint, 0o600);
|
|
263
|
+
} catch {
|
|
264
|
+
// The random per-launch capability remains mandatory if chmod is absent.
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
parentPort.postMessage({ type: "ready", endpoint });
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
parentPort.on("message", (message) => {
|
|
271
|
+
if (!message || typeof message !== "object") return;
|
|
272
|
+
if (message.type === "register") {
|
|
273
|
+
records.set(message.record.refId, {
|
|
274
|
+
...message.record,
|
|
275
|
+
target: {
|
|
276
|
+
process: normalizeProcessTarget(message.record.target?.process),
|
|
277
|
+
host: normalizeHostTarget(message.record.target?.host),
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (message.type === "update") {
|
|
283
|
+
const record = records.get(message.refId);
|
|
284
|
+
if (!record) return;
|
|
285
|
+
record.useCount = message.useCount;
|
|
286
|
+
record.status = message.status;
|
|
287
|
+
if (record.status !== "active") record.value = null;
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (message.type === "revoke") {
|
|
291
|
+
const record = records.get(message.refId);
|
|
292
|
+
if (!record) return;
|
|
293
|
+
record.status = "revoked";
|
|
294
|
+
record.value = null;
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (message.type === "close") {
|
|
298
|
+
for (const record of records.values()) record.value = null;
|
|
299
|
+
records.clear();
|
|
300
|
+
server.close(() => {
|
|
301
|
+
if (platform !== "win32") {
|
|
302
|
+
try {
|
|
303
|
+
fs.unlinkSync(endpoint);
|
|
304
|
+
} catch {
|
|
305
|
+
// The socket may already have been removed.
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
parentPort.postMessage({ type: "closed" });
|
|
309
|
+
parentPort.close();
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
});
|