chainlesschain 0.162.175 → 0.162.176
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 +10 -10
- package/src/assets/web-panel/assets/{AIOps-DherW0Rh.js → AIOps-BDLu5Elz.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CDGfqt2Y.js → ActionButton-DH5us-CK.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BYhkzdgD.js → Analytics-BZ0u8IFG.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-cEKk1cpb.js → AppLayout-Duu8xR14.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-_aXR3WWc.js → Artifacts-Br2YBbh_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CYAf-gY7.js → Audit-C3C6a482.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-D4Q20phR.js → BackgroundAgents-CzHvebcj.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Cq0Tyk58.js → Backup-DZNHYDFd.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CPj_CdAv.js → BaseInput-VRiC4fIx.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-BQ-Qq0es.js → Chat-Cm08WWAD.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Ci97vNTs.js → ChatBubbleRenderer-CGHYrugQ.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-rke6l3yg.js → Checkbox-DtByk7d7.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DiacrIPq.js → Codegen-CphXXOfD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Cx3BY-Up.js → Col-Hz86TnLR.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DfmWiQy8.js → Community-HP03ltpD.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DdQnpxy5.js → Compact-B_N1mqQz.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-lzliOH_r.js → Compliance-CVztRpi8.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CYx4Un5k.js → Cowork-wUVOyZih.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-BGDcPFlo.js → Cron-DW5TLJKw.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-0_X5g2ri.js → Crosschain-CrAFGhWH.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C0PEf3Eu.js → DID-pA-oD8ke.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DULQjQ58.js → Dashboard-CXrd5gAw.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DGRHRbW6.js → Dropdown-EweJcsek.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-ChX8XPwB.js → EmailListRenderer-C9xVLPG4.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dyq6IBNu.js → FamilyGuardDashboard-CDcEEqlu.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DH1NfAL2.js → Federation-DtZda9A_.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BN1I_uNi.js → FormItemContext-CiYdcVz3.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Dq_2UYpe.js → GenericCardRenderer-DA13uwA0.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BAy1yvI2.js → Git-DzRhZD1O.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-Db6Q2iSy.js → Governance-D5RMgOSb.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-0ub6yHcr.js → Inference-BgrPfSNk.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DtLetM36.js → KnowledgeGraph-DzjnD571.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Bcoy7CUd.js → Logs-BhWzVDtN.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BfEMFAXf.js → MarkdownRenderer-BDape9cx.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-tt2rzwRR.js → Marketplace-DJtL5GV7.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BhOgX-MU.js → McpTools-CZcQygI7.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-BJUxeWBL.js → Memory-DUWSDUUu.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BwUY2G9w.js → MobileBridge-BTwq2WKY.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B2WMboOm.js → Mtc-BiGugEQm.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-8pNEXO63.js → MtcAudit-DY7a6gUe.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-C1wm5a_1.js → Multisig-BQbDu_w7.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C1QpKF7g.js → NLProgramming-CM2wXTLv.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CiQUcxFu.js → Notes-DI6gGs1v.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BblDPJ_x.js → NotificationSettings-BsZOLWAB.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DRjYcPtb.js → OrderTableRenderer-C48mu09U.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Dp3VKB0X.js → Organization-Cds0_tXr.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Czx161m9.js → Overflow-WunYMD87.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-ClFi6wOs.js → P2P-Bo6j4DDv.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CRweW0lz.js → PdhVaultBrowser-Bh2XPD5f.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BzcRoqTn.js → Permissions-EMvMMC8N.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-ChGTpNMd.js → PersonalDataHub-AX3ypUDV.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-BMOOpKWA.js → Pipeline-BOx8HOgL.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-D0AZHObH.js → Privacy-tBeTVQVM.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-yYFlZ6Ja.js → ProjectInit-CVYg1W4M.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DJNVuMQs.js → ProjectSettings-Dvt5I7y1.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Br0rBWH1.js → Projects-Cc7FC9-e.js} +1 -1
- package/src/assets/web-panel/assets/Providers-Ct8xqY-E.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-81NZOitV.js → QrScannerModal-Cni8Ooja.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Dic2lCbJ.js → QuickAsk-BJVLKdxr.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Dh9iwViE.js → Recommend-DPG8Rbbm.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Bq9VYEFy.js → RemoteSession-DsdR7dCt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CxFZ-NbJ.js → Reputation-Csg1YM-b.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BVSLcaX2.js → Row-D9DoFoEf.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BbC-5DOH.js → RssFeed-BsvKrXMS.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BfjZ1GCr.js → Search-DFUStfgQ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CVjhOV5r.js → Security-ILg1zxdK.js} +4 -4
- package/src/assets/web-panel/assets/{Services-D45u-Aqe.js → Services-Dd41PCaY.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-WkGoK4he.js → Skeleton-Bzo1cN80.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-D_jvQZcj.js → Skills-BDHh17P0.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Bf4QTF3E.js → Sla-jl7UTiRY.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DVpZdbMN.js → SpeechSettings-BePa-RF6.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DEEojoMS.js → SyncSettings-DiqqDKGZ.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DFwxpLIk.js → Tasks-DYQ_6lxj.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Bzl-9wY5.js → Templates-JiDeI06L.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-0khxUOB8.js → Tenant-hhgI6zwS.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-B0Y4LONc.js → TimelineRenderer-B8uB5Llk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DEE07SFh.js → Tokens-C3b_6r2z.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BM7xvA5z.js → Trigger-tIP7HKVe.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Dv3ijvvZ.js → Trust-vjoc11vJ.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B1-enmMt.js → UkeySign-DUPBnGuH.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DYiIPByd.js → VideoEditing-CBvhUY5T.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-D-y374BQ.js → Wallet-DUaQ0uA5.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-HBDjcUhi.js → WebAuthn-DllSivjE.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-sKn4qTID.js → WorkflowEditor-xc8D3uO6.js} +1 -1
- package/src/assets/web-panel/assets/{chat-TVYhaBXj.js → chat-BVicU7oA.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DMADxY9v.js → colors-DJzLmhLm.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-OftcHpO_.js → compact-item-BvYRfThE.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DW1zVUSN.js → createContext-DGXxCBKR.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BT46Y_QI.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CaUathNp.js → hasIn-SBDJB1y4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeCIYYG7.js → index-1SdDS6lR.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAfT3EMd.js → index-9gdI7uUW.js} +1 -1
- package/src/assets/web-panel/assets/index-B7nuIywP.js +1 -0
- package/src/assets/web-panel/assets/{index-sm1sGIxW.js → index-BJZf9DhV.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBNg08cD.js → index-BO1itZaY.js} +3 -3
- package/src/assets/web-panel/assets/{index-CKNdnJRo.js → index-BTrBGBJs.js} +1 -1
- package/src/assets/web-panel/assets/{index--5UvwqH_.js → index-BYqz4Wrr.js} +1 -1
- package/src/assets/web-panel/assets/{index-8YelceUU.js → index-Bf-ctERC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Lr0MO-GU.js → index-CKyEivf8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZdT8nio.js → index-CdGY9P8a.js} +1 -1
- package/src/assets/web-panel/assets/{index-s-EnkUCn.js → index-Cf-O_g_8.js} +1 -1
- package/src/assets/web-panel/assets/{index-pSVCBsG4.js → index-CloCgBUR.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-19mFhn.js → index-CoJAO1Lm.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKjqFpYa.js → index-Crk5NTb0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJ1PjRY3.js → index-Cs2rmLFt.js} +1 -1
- package/src/assets/web-panel/assets/{index-77kgkUgY.js → index-CtwqO5qo.js} +1 -1
- package/src/assets/web-panel/assets/{index-D63QVAiJ.js → index-D7HimK0M.js} +1 -1
- package/src/assets/web-panel/assets/{index-B52Ztt8Q.js → index-DCdRAgjy.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHi634g9.js → index-DCqRS6da.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFVbDpqg.js → index-DHVLJ8q0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvRw4Fna.js → index-DKrvvWm4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZXYI5LU.js → index-DMarmfrv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CM8W07sc.js → index-DRfiXB_p.js} +1 -1
- package/src/assets/web-panel/assets/{index-iDmgT2Dg.js → index-Dm_77jgR.js} +1 -1
- package/src/assets/web-panel/assets/{index-hXq7QRA_.js → index-DnjPdvR6.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEzLLVYd.js → index-DonCnfMr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYwwUKDg.js → index-DvUTDYXX.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXcqvWBp.js → index-FxZzRyE1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cmdv6Dev.js → index-MjC4G09d.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9JoaYSs.js → index-VMfwIH5G.js} +1 -1
- package/src/assets/web-panel/assets/{index-CK-p7Hji.js → index-YJkzy8ZF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BupSWDcl.js → index-d5BVd-cL.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bg-7FpaL.js → index-e4fXH_WO.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpDtN0dl.js → index-hxTODbM1.js} +1 -1
- package/src/assets/web-panel/assets/{index-kdMl_0zL.js → index-lpaGoTH3.js} +1 -1
- package/src/assets/web-panel/assets/{index-GUKz4Pv9.js → index-wcCL-miV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWVZ3T0t.js → index-xfluRkCT.js} +1 -1
- package/src/assets/web-panel/assets/index-ycwAfC-i.js +1 -0
- package/src/assets/web-panel/assets/{index-BSp1Ofvx.js → index-z1ZylsLq.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DdcKTlQR.js → initDefaultProps-C1zO1KnY.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CL-hTBQj.js → motion-CWLtEGmC.js} +1 -1
- package/src/assets/web-panel/assets/{move-qYSAkxNG.js → move-DzD_C3Vm.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-ZwRSZtRP.js → mtc-parser-D880PYJl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Bld-8ftI.js → omit-CFR_z2ov.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DGHs-a9Z.js → pickAttrs-srIhgrSC.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DRQPMyI5.js → placementArrow-C1rXpibP.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C5MJG_Yo.js → responsiveObserve-C30gRcSS.js} +1 -1
- package/src/assets/web-panel/assets/{slide-VZ-fpZCD.js → slide-CvtKiMfV.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-9ocfCyHk.js → statusUtils-DNHO7ITG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-B6QAwAN5.js → styleChecker-Dt_Sl-g4.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Bq1twor3.js → useFlexGapSupport-Cjev42Gh.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DKZq96tz.js → useFs-Baxglj2V.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-D0RmRVXf.js → usePersonalDataHub-B4NkcLaP.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D6kEj_tt.js → vnode-mIRkdT7o.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-2yfasoQf.js → zoom-HzI5DlH_.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/auth/npm-auth.js +30 -5
- package/src/commands/agenda.js +64 -2
- package/src/commands/agent.js +39 -1
- package/src/commands/config.js +70 -5
- package/src/commands/context.js +36 -2
- package/src/commands/hub.js +19 -1
- package/src/commands/memory.js +21 -6
- package/src/commands/permissions.js +57 -1
- package/src/commands/plugin.js +2 -0
- package/src/commands/review.js +23 -11
- package/src/commands/routine.js +31 -8
- package/src/commands/session.js +11 -3
- package/src/commands/team.js +20 -7
- package/src/commands/update.js +65 -10
- package/src/gateways/terminal/PtyManager.js +8 -1
- package/src/gateways/ws/message-dispatcher.js +3 -0
- package/src/gateways/ws/session-protocol.js +26 -0
- package/src/gateways/ws/ws-agent-handler.js +107 -69
- package/src/gateways/ws/ws-server.js +74 -2
- package/src/harness/jsonl-session-store.js +13 -6
- package/src/harness/mcp-client.js +200 -1
- package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +15 -0
- package/src/lib/agent-coordinator.js +4 -0
- package/src/lib/agent-ipc-bus.js +32 -2
- package/src/lib/agent-sandbox.js +16 -2
- package/src/lib/agent-schedule-store.js +55 -0
- package/src/lib/agent-tool-admission.js +104 -0
- package/src/lib/api-key-helper.js +10 -2
- package/src/lib/async-hook-supervisor.cjs +12 -2
- package/src/lib/changelog.js +19 -11
- package/src/lib/channels/channel-manager.js +6 -0
- package/src/lib/channels/telegram-channel.js +11 -1
- package/src/lib/channels/webhook-channel.js +15 -3
- package/src/lib/checkpoint-store.js +10 -2
- package/src/lib/cloud/bundle.js +12 -2
- package/src/lib/code-review.js +32 -8
- package/src/lib/computer-use/control-backend.js +18 -3
- package/src/lib/context-breakdown.js +46 -0
- package/src/lib/context-source-ledger.js +43 -0
- package/src/lib/diff-review-follow-up.js +154 -0
- package/src/lib/downloader.js +17 -3
- package/src/lib/ensure-utf8.js +11 -3
- package/src/lib/event-runtime-producer.js +58 -0
- package/src/lib/event-runtime-store.js +354 -0
- package/src/lib/event-runtime-worker.js +109 -0
- package/src/lib/execution-backend.js +72 -21
- package/src/lib/git-integration.js +19 -4
- package/src/lib/hook-manager.js +6 -15
- package/src/lib/hook-runner.cjs +48 -3
- package/src/lib/hooks-v2-producers.js +15 -0
- package/src/lib/hooks-v2-runtime.js +70 -21
- package/src/lib/host-adb-bridge.js +111 -21
- package/src/lib/ide-context.js +128 -1
- package/src/lib/interaction-adapter.js +39 -0
- package/src/lib/json-schema-validate.js +190 -36
- package/src/lib/lan-pairing-preflight.js +13 -2
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +18 -0
- package/src/lib/lsp/lsp-client.js +18 -1
- package/src/lib/lsp/lsp-manager.js +4 -0
- package/src/lib/lsp/lsp-server-registry.js +11 -0
- package/src/lib/mcp-oauth.js +8 -2
- package/src/lib/npm-invocation.js +29 -0
- package/src/lib/packer/pkg-runner.js +13 -2
- package/src/lib/packer/precheck.js +33 -16
- package/src/lib/packer/web-panel-builder.js +16 -2
- package/src/lib/permission-rules.cjs +5 -1
- package/src/lib/personal-data-hub-aichat-wizard.js +22 -6
- package/src/lib/personal-data-hub-wiring.js +27 -3
- package/src/lib/plan-mode.js +204 -11
- package/src/lib/plugin-monitor-supervisor.js +39 -4
- package/src/lib/plugin-runtime/bin.js +45 -0
- package/src/lib/plugin-runtime/hooks.js +14 -1
- package/src/lib/plugin-runtime/install.js +2 -1
- package/src/lib/plugin-runtime/lsp.js +3 -0
- package/src/lib/plugin-runtime/mcp.js +8 -1
- package/src/lib/plugin-runtime/monitors.js +4 -0
- package/src/lib/plugin-runtime/plugin-options.js +74 -7
- package/src/lib/plugin-runtime/signature.js +45 -0
- package/src/lib/pr-create.js +21 -8
- package/src/lib/pr-link-ledger.js +15 -3
- package/src/lib/process-execution-broker/credential-agent.js +23 -3
- package/src/lib/process-execution-broker/index.js +315 -38
- package/src/lib/process-execution-broker/patch-child-process.js +2 -3
- package/src/lib/process-manager.js +18 -3
- package/src/lib/publish-workspace.js +14 -6
- package/src/lib/secret-store.js +159 -0
- package/src/lib/service-manager.js +64 -29
- package/src/lib/settings-hook-events.cjs +61 -1
- package/src/lib/settings-hooks.cjs +4 -0
- package/src/lib/side-effect-ledger.js +22 -0
- package/src/lib/sub-agent-context.js +5 -0
- package/src/lib/sub-agent-profiles.js +4 -0
- package/src/lib/turn-context.js +14 -8
- package/src/lib/unattended-action-policy.js +83 -0
- package/src/lib/update-notice.js +6 -2
- package/src/lib/with-file-lock.js +7 -0
- package/src/lib/ws-server.js +1 -0
- package/src/repl/agent-repl.js +32 -0
- package/src/repl/clipboard-copy.js +8 -2
- package/src/repl/pr-comments.js +30 -7
- package/src/runtime/agent-core.js +439 -87
- package/src/runtime/agent-runtime.js +1 -0
- package/src/runtime/coding-agent-contract-shared.cjs +52 -0
- package/src/runtime/coding-agent-policy.cjs +20 -0
- package/src/runtime/diagnostics.js +73 -8
- package/src/runtime/headless-runner.js +63 -0
- package/src/runtime/headless-stream.js +269 -17
- package/src/runtime/mcp-config.js +16 -1
- package/src/assets/web-panel/assets/MobileProjects-BLRfHhqi.js +0 -1
- package/src/assets/web-panel/assets/Providers-zZRhNtSu.js +0 -1
- package/src/assets/web-panel/assets/Terminal-DWGYhAYU.js +0 -3
- package/src/assets/web-panel/assets/devWarning-CLOk6rdE.js +0 -1
- package/src/assets/web-panel/assets/index-CSgUfMTM.js +0 -1
- package/src/assets/web-panel/assets/index-DliSZvAP.js +0 -1
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import path from "path";
|
|
20
|
+
import fs from "fs";
|
|
20
21
|
import { discoverPlugins } from "./scopes.js";
|
|
21
22
|
import { partitionByTrust, warnUntrustedOnce } from "./trust.js";
|
|
22
23
|
import { componentCapabilityDenial } from "./capabilities.js";
|
|
@@ -135,3 +136,47 @@ export function applyPluginBinPath(opts = {}) {
|
|
|
135
136
|
},
|
|
136
137
|
};
|
|
137
138
|
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Resolve the first executable token of a shell command to a trusted plugin
|
|
142
|
+
* bin. This is intentionally conservative: only an existing file directly
|
|
143
|
+
* under a collected plugin bin directory is attributed.
|
|
144
|
+
*
|
|
145
|
+
* @param {string} command
|
|
146
|
+
* @param {object} [opts] { cwd, scopes }
|
|
147
|
+
* @returns {{pluginId:string,pluginVersion:string,pluginSource:string,scope:string,binPath:string}|null}
|
|
148
|
+
*/
|
|
149
|
+
export function resolvePluginBinCommand(command, opts = {}) {
|
|
150
|
+
if (typeof command !== "string") return null;
|
|
151
|
+
const match = command.match(/^\s*(?:"([^"]+)"|'([^']+)'|([^\s]+))/);
|
|
152
|
+
const token = match?.[1] || match?.[2] || match?.[3] || "";
|
|
153
|
+
if (!token) return null;
|
|
154
|
+
const tokenBase = path.basename(token).toLowerCase();
|
|
155
|
+
const candidates = new Set([tokenBase]);
|
|
156
|
+
if (process.platform === "win32" && !path.extname(tokenBase)) {
|
|
157
|
+
candidates.add(`${tokenBase}.exe`);
|
|
158
|
+
candidates.add(`${tokenBase}.cmd`);
|
|
159
|
+
candidates.add(`${tokenBase}.bat`);
|
|
160
|
+
}
|
|
161
|
+
for (const entry of collectPluginBinDirs(opts)) {
|
|
162
|
+
for (const candidateName of candidates) {
|
|
163
|
+
const binPath = path.join(entry.dir, candidateName);
|
|
164
|
+
if (!fs.existsSync(binPath)) continue;
|
|
165
|
+
if (path.isAbsolute(token)) {
|
|
166
|
+
try {
|
|
167
|
+
if (path.resolve(token) !== path.resolve(binPath)) continue;
|
|
168
|
+
} catch {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
pluginId: entry.plugin,
|
|
174
|
+
pluginVersion: entry.version || null,
|
|
175
|
+
pluginSource: entry.dir,
|
|
176
|
+
scope: entry.scope || null,
|
|
177
|
+
binPath,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
@@ -122,7 +122,20 @@ export function collectPluginHooks(opts = {}) {
|
|
|
122
122
|
const map = normalizeHookMap(parsed);
|
|
123
123
|
for (const [event, entries] of Object.entries(map)) {
|
|
124
124
|
if (!Array.isArray(entries)) continue;
|
|
125
|
-
|
|
125
|
+
const tagged = entries.map((group) => {
|
|
126
|
+
if (!group || typeof group !== "object" || !Array.isArray(group.hooks)) return group;
|
|
127
|
+
return {
|
|
128
|
+
...group,
|
|
129
|
+
hooks: group.hooks.map((hook) => ({
|
|
130
|
+
...hook,
|
|
131
|
+
origin: "plugin:hook",
|
|
132
|
+
pluginId: p.name,
|
|
133
|
+
pluginVersion: p.version || null,
|
|
134
|
+
pluginSource: p.manifest?.manifestPath || null,
|
|
135
|
+
})),
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
merged[event] = (merged[event] || []).concat(tagged);
|
|
126
139
|
}
|
|
127
140
|
}
|
|
128
141
|
warnHookCapabilityDeniedOnce(denied);
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
discoverPlugins,
|
|
30
30
|
} from "./scopes.js";
|
|
31
31
|
import { verifyPluginManifest } from "../plugin-security.js";
|
|
32
|
-
import { writePluginLock, LOCK_FILENAME } from "./signature.js";
|
|
32
|
+
import { writePluginLock, buildPluginSbom, LOCK_FILENAME } from "./signature.js";
|
|
33
33
|
|
|
34
34
|
export const _deps = {
|
|
35
35
|
existsSync: fs.existsSync,
|
|
@@ -118,6 +118,7 @@ export function installFromDirectory(srcDir, opts = {}) {
|
|
|
118
118
|
signatureVerified: verification.signatureVerified === true,
|
|
119
119
|
signatureBase64: verification.signatureBase64,
|
|
120
120
|
publicKeyPem: verification.publicKeyPem,
|
|
121
|
+
sbom: buildPluginSbom(dest),
|
|
121
122
|
});
|
|
122
123
|
}
|
|
123
124
|
|
|
@@ -91,6 +91,9 @@ export function ensurePluginLspServers(opts = {}) {
|
|
|
91
91
|
args: s.args,
|
|
92
92
|
extensions: s.extensions,
|
|
93
93
|
id: s.id,
|
|
94
|
+
pluginId: p.name,
|
|
95
|
+
pluginVersion: p.version,
|
|
96
|
+
pluginSource: s.absPath || p.manifest.manifestPath,
|
|
94
97
|
});
|
|
95
98
|
registered.push({ plugin: p.name, languageId: s.languageId, id: s.id });
|
|
96
99
|
} catch {
|
|
@@ -119,7 +119,14 @@ export function collectPluginMcpServers(opts = {}) {
|
|
|
119
119
|
for (const [name, cfg] of Object.entries(map)) {
|
|
120
120
|
if (!cfg || typeof cfg !== "object") continue;
|
|
121
121
|
if (name in servers) continue; // first plugin wins on a clash
|
|
122
|
-
servers[name] =
|
|
122
|
+
servers[name] = {
|
|
123
|
+
...cfg,
|
|
124
|
+
origin: "plugin:mcp",
|
|
125
|
+
policy: "allow",
|
|
126
|
+
pluginId: p.name,
|
|
127
|
+
pluginVersion: p.version,
|
|
128
|
+
pluginSource: m.absPath || p.manifest.manifestPath,
|
|
129
|
+
};
|
|
123
130
|
added++;
|
|
124
131
|
}
|
|
125
132
|
if (added > 0 && m.absPath) sources.push(m.absPath);
|
|
@@ -26,12 +26,18 @@ import {
|
|
|
26
26
|
validateOptions,
|
|
27
27
|
redactSensitiveOptions,
|
|
28
28
|
} from "./capabilities.js";
|
|
29
|
+
import {
|
|
30
|
+
createSecretStore,
|
|
31
|
+
isSecretRef,
|
|
32
|
+
secretRef,
|
|
33
|
+
} from "../secret-store.js";
|
|
29
34
|
|
|
30
35
|
export const _deps = {
|
|
31
36
|
existsSync: fs.existsSync,
|
|
32
37
|
readFileSync: fs.readFileSync,
|
|
33
38
|
writeFileSync: fs.writeFileSync,
|
|
34
39
|
mkdirSync: fs.mkdirSync,
|
|
40
|
+
secretStore: () => createSecretStore(),
|
|
35
41
|
userStorePath: () =>
|
|
36
42
|
path.join(getElectronUserDataDir(), "plugin-options.json"),
|
|
37
43
|
projectStorePath: (cwd) =>
|
|
@@ -54,20 +60,70 @@ function writeJsonObject(p, obj) {
|
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
/** Load a plugin's option VALUES at the given scope (`user` | `project`). */
|
|
57
|
-
export function loadPluginOptionValues(name, scope, { cwd } = {}) {
|
|
63
|
+
export function loadPluginOptionValues(name, scope, { cwd, schema, secretStore } = {}) {
|
|
58
64
|
const p =
|
|
59
65
|
scope === "project" ? _deps.projectStorePath(cwd) : _deps.userStorePath();
|
|
60
66
|
const store = readJsonObject(p);
|
|
61
67
|
const v = store[name];
|
|
62
|
-
|
|
68
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return {};
|
|
69
|
+
const out = { ...v };
|
|
70
|
+
const normalized = schema || {};
|
|
71
|
+
for (const [key, desc] of Object.entries(normalized)) {
|
|
72
|
+
if (!desc?.sensitive || !isSecretRef(out[key])) continue;
|
|
73
|
+
try {
|
|
74
|
+
const value = (secretStore || _deps.secretStore)().get(out[key].__cc_secret_ref);
|
|
75
|
+
if (value != null) out[key] = value;
|
|
76
|
+
else delete out[key];
|
|
77
|
+
} catch {
|
|
78
|
+
// Missing/unavailable secret backends fail closed: do not expose a
|
|
79
|
+
// plaintext fallback and let validation keep the option at its default.
|
|
80
|
+
delete out[key];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
63
84
|
}
|
|
64
85
|
|
|
65
86
|
/** Persist a plugin's option VALUES at a scope (replaces the plugin's entry). */
|
|
66
|
-
export function setPluginOptionValues(
|
|
87
|
+
export function setPluginOptionValues(
|
|
88
|
+
name,
|
|
89
|
+
values,
|
|
90
|
+
scope,
|
|
91
|
+
{ cwd, schema, secretStore } = {},
|
|
92
|
+
) {
|
|
67
93
|
const p =
|
|
68
94
|
scope === "project" ? _deps.projectStorePath(cwd) : _deps.userStorePath();
|
|
69
95
|
const store = readJsonObject(p);
|
|
70
|
-
|
|
96
|
+
const input = values && typeof values === "object" ? values : {};
|
|
97
|
+
const persisted = { ...input };
|
|
98
|
+
const normalized = schema || {};
|
|
99
|
+
let secrets = null;
|
|
100
|
+
const getSecrets = () => {
|
|
101
|
+
if (!secrets) secrets = (secretStore || _deps.secretStore)();
|
|
102
|
+
return secrets;
|
|
103
|
+
};
|
|
104
|
+
const rejectedSensitive = [];
|
|
105
|
+
for (const [key, desc] of Object.entries(normalized)) {
|
|
106
|
+
if (!desc?.sensitive || !Object.prototype.hasOwnProperty.call(input, key)) continue;
|
|
107
|
+
// Project files are shareable and must never receive a sensitive value.
|
|
108
|
+
if (scope === "project") {
|
|
109
|
+
delete persisted[key];
|
|
110
|
+
rejectedSensitive.push(key);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (input[key] == null || input[key] === "") {
|
|
114
|
+
delete persisted[key];
|
|
115
|
+
try { getSecrets().delete(`${name}/${key}`); } catch {}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
getSecrets().set(`${name}/${key}`, input[key]);
|
|
119
|
+
persisted[key] = secretRef(`${name}/${key}`);
|
|
120
|
+
}
|
|
121
|
+
if (rejectedSensitive.length > 0) {
|
|
122
|
+
persisted.__cc_rejected_sensitive = [...new Set(rejectedSensitive)].sort();
|
|
123
|
+
} else if (Object.prototype.hasOwnProperty.call(persisted, "__cc_rejected_sensitive")) {
|
|
124
|
+
delete persisted.__cc_rejected_sensitive;
|
|
125
|
+
}
|
|
126
|
+
store[name] = persisted;
|
|
71
127
|
writeJsonObject(p, store);
|
|
72
128
|
return { name, scope, path: p };
|
|
73
129
|
}
|
|
@@ -107,10 +163,21 @@ export function resolvePluginOptions(
|
|
|
107
163
|
|
|
108
164
|
const warnings = [];
|
|
109
165
|
const droppedFromProject = [];
|
|
166
|
+
const projectInput = { ...(projectValues || {}) };
|
|
167
|
+
const rejectedSensitive = Array.isArray(projectInput.__cc_rejected_sensitive)
|
|
168
|
+
? projectInput.__cc_rejected_sensitive
|
|
169
|
+
: [];
|
|
170
|
+
delete projectInput.__cc_rejected_sensitive;
|
|
171
|
+
for (const key of rejectedSensitive) {
|
|
172
|
+
droppedFromProject.push(key);
|
|
173
|
+
warnings.push(
|
|
174
|
+
`project: option "${key}" is sensitive and cannot be set from project config — use user scope / OS keychain`,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
110
177
|
|
|
111
178
|
// Project layer first (lower precedence). validateOptions errors on sensitive/
|
|
112
179
|
// user-only keys at project scope — those are the drops we surface + refuse.
|
|
113
|
-
const proj = acceptedKeys(s,
|
|
180
|
+
const proj = acceptedKeys(s, projectInput, "project");
|
|
114
181
|
for (const err of proj.res.errors) {
|
|
115
182
|
if (/sensitive|user-scoped/.test(err)) {
|
|
116
183
|
const m = err.match(/"([^"]+)"/);
|
|
@@ -145,7 +212,7 @@ export function resolvePluginOptions(
|
|
|
145
212
|
/** Load both scopes' values from disk and resolve against a schema. */
|
|
146
213
|
export function getResolvedPluginOptions(name, schema, { cwd } = {}) {
|
|
147
214
|
return resolvePluginOptions(schema, {
|
|
148
|
-
userValues: loadPluginOptionValues(name, "user", { cwd }),
|
|
149
|
-
projectValues: loadPluginOptionValues(name, "project", { cwd }),
|
|
215
|
+
userValues: loadPluginOptionValues(name, "user", { cwd, schema }),
|
|
216
|
+
projectValues: loadPluginOptionValues(name, "project", { cwd, schema }),
|
|
150
217
|
});
|
|
151
218
|
}
|
|
@@ -30,8 +30,37 @@ export const _deps = {
|
|
|
30
30
|
readFileSync: fs.readFileSync,
|
|
31
31
|
writeFileSync: fs.writeFileSync,
|
|
32
32
|
existsSync: fs.existsSync,
|
|
33
|
+
readdirSync: fs.readdirSync,
|
|
34
|
+
statSync: fs.statSync,
|
|
33
35
|
};
|
|
34
36
|
|
|
37
|
+
/** Build a deterministic file-level SBOM for an installed plugin directory. */
|
|
38
|
+
export function buildPluginSbom(root) {
|
|
39
|
+
const files = [];
|
|
40
|
+
const walk = (dir) => {
|
|
41
|
+
for (const entry of _deps.readdirSync(dir, { withFileTypes: true })) {
|
|
42
|
+
const abs = path.join(dir, entry.name);
|
|
43
|
+
const rel = path.relative(root, abs).replace(/\\/g, "/");
|
|
44
|
+
if (rel === LOCK_FILENAME) continue;
|
|
45
|
+
if (entry.isDirectory()) walk(abs);
|
|
46
|
+
else if (entry.isFile()) {
|
|
47
|
+
const bytes = _deps.readFileSync(abs);
|
|
48
|
+
files.push({
|
|
49
|
+
path: rel,
|
|
50
|
+
bytes: bytes.length,
|
|
51
|
+
sha256: createHash("sha256").update(bytes).digest("hex"),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
walk(path.resolve(root));
|
|
57
|
+
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
58
|
+
const digest = createHash("sha256")
|
|
59
|
+
.update(files.map((file) => `${file.path}\0${file.sha256}\n`).join(""))
|
|
60
|
+
.digest("hex");
|
|
61
|
+
return { version: 1, digest, files };
|
|
62
|
+
}
|
|
63
|
+
|
|
35
64
|
/** Record a verified signature into the version dir. */
|
|
36
65
|
export function writePluginLock(
|
|
37
66
|
versionDir,
|
|
@@ -42,6 +71,7 @@ export function writePluginLock(
|
|
|
42
71
|
signatureVerified,
|
|
43
72
|
signatureBase64,
|
|
44
73
|
publicKeyPem,
|
|
74
|
+
sbom = null,
|
|
45
75
|
},
|
|
46
76
|
) {
|
|
47
77
|
const rel = path.relative(versionDir, manifestFile).replace(/\\/g, "/");
|
|
@@ -55,6 +85,7 @@ export function writePluginLock(
|
|
|
55
85
|
// lock is just self-asserted JSON and counts as unsigned.
|
|
56
86
|
signatureBase64: signatureBase64 || null,
|
|
57
87
|
publicKeyPem: publicKeyPem || null,
|
|
88
|
+
...(sbom ? { sbom } : {}),
|
|
58
89
|
};
|
|
59
90
|
_deps.writeFileSync(
|
|
60
91
|
path.join(versionDir, LOCK_FILENAME),
|
|
@@ -167,6 +198,20 @@ export function verifyInstalledSignature(plugin, opts = {}) {
|
|
|
167
198
|
reason: "recorded signature does not verify over the on-disk manifest",
|
|
168
199
|
};
|
|
169
200
|
}
|
|
201
|
+
if (lock.sbom) {
|
|
202
|
+
let actualSbom;
|
|
203
|
+
try {
|
|
204
|
+
actualSbom = buildPluginSbom(plugin.root);
|
|
205
|
+
} catch {
|
|
206
|
+
return { signed: false, reason: "plugin SBOM cannot be read" };
|
|
207
|
+
}
|
|
208
|
+
if (
|
|
209
|
+
actualSbom.digest !== lock.sbom.digest ||
|
|
210
|
+
JSON.stringify(actualSbom.files) !== JSON.stringify(lock.sbom.files)
|
|
211
|
+
) {
|
|
212
|
+
return { signed: false, reason: "plugin component SBOM mismatch" };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
170
215
|
const trustedKeys = opts.trustedKeys;
|
|
171
216
|
if (trustedKeys && trustedKeys.size > 0) {
|
|
172
217
|
if (!trustedKeys.has(publicKeySha256)) {
|
package/src/lib/pr-create.js
CHANGED
|
@@ -4,8 +4,23 @@
|
|
|
4
4
|
* @module lib/pr-create
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { execSync } from "child_process";
|
|
8
7
|
import { logger } from "./logger.js";
|
|
8
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
9
|
+
|
|
10
|
+
export const _deps = {
|
|
11
|
+
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function git(args, options = {}) {
|
|
15
|
+
return _deps.execFileSync("git", args, {
|
|
16
|
+
encoding: "utf8",
|
|
17
|
+
...options,
|
|
18
|
+
origin: "pr:git",
|
|
19
|
+
policy: "allow",
|
|
20
|
+
scope: "pr",
|
|
21
|
+
shell: false,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
9
24
|
|
|
10
25
|
/**
|
|
11
26
|
* Get current git branch
|
|
@@ -13,9 +28,7 @@ import { logger } from "./logger.js";
|
|
|
13
28
|
*/
|
|
14
29
|
export function getCurrentBranch() {
|
|
15
30
|
try {
|
|
16
|
-
return
|
|
17
|
-
encoding: "utf8",
|
|
18
|
-
}).trim();
|
|
31
|
+
return git(["rev-parse", "--abbrev-ref", "HEAD"]).trim();
|
|
19
32
|
} catch {
|
|
20
33
|
return "main";
|
|
21
34
|
}
|
|
@@ -27,7 +40,7 @@ export function getCurrentBranch() {
|
|
|
27
40
|
*/
|
|
28
41
|
export function getRemoteUrl() {
|
|
29
42
|
try {
|
|
30
|
-
return
|
|
43
|
+
return git(["remote", "get-url", "origin"]).trim();
|
|
31
44
|
} catch {
|
|
32
45
|
return null;
|
|
33
46
|
}
|
|
@@ -58,7 +71,7 @@ export async function preparePullRequest(options = {}) {
|
|
|
58
71
|
const repo = parseGitHubRepo();
|
|
59
72
|
|
|
60
73
|
// Check for uncommitted changes
|
|
61
|
-
const status =
|
|
74
|
+
const status = git(["status", "--porcelain"]);
|
|
62
75
|
const hasChanges = status.trim().length > 0;
|
|
63
76
|
|
|
64
77
|
if (hasChanges && !options.skipStash) {
|
|
@@ -72,13 +85,13 @@ export async function preparePullRequest(options = {}) {
|
|
|
72
85
|
const logRange = `${defaultBase}...${branch}`;
|
|
73
86
|
let commitLog = "";
|
|
74
87
|
try {
|
|
75
|
-
commitLog =
|
|
88
|
+
commitLog = git(["log", "--oneline", "--end-of-options", logRange, "--"]);
|
|
76
89
|
} catch {
|
|
77
90
|
commitLog = "";
|
|
78
91
|
}
|
|
79
92
|
|
|
80
93
|
const prUrl = repo
|
|
81
|
-
? `https://github.com/${repo.owner}/${repo.repo}/compare/${defaultBase}...${branch}?expand=1`
|
|
94
|
+
? `https://github.com/${repo.owner}/${repo.repo}/compare/${encodeURIComponent(defaultBase)}...${encodeURIComponent(branch)}?expand=1`
|
|
82
95
|
: null;
|
|
83
96
|
|
|
84
97
|
logger.info(`Branch: ${branch}`);
|
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
20
|
-
import { execFile } from "node:child_process";
|
|
21
20
|
import { join } from "node:path";
|
|
22
21
|
import { getHomeDir } from "./paths.js";
|
|
22
|
+
import { executionBroker } from "./process-execution-broker/index.js";
|
|
23
23
|
|
|
24
|
-
export const _deps = {
|
|
24
|
+
export const _deps = {
|
|
25
|
+
execFile: (...args) => executionBroker.execFile(...args),
|
|
26
|
+
now: () => Date.now(),
|
|
27
|
+
};
|
|
25
28
|
|
|
26
29
|
const MAX_LINKS_PER_SESSION = 20;
|
|
27
30
|
const MAX_SESSIONS = 500;
|
|
@@ -150,7 +153,16 @@ function ghPrForBranch(cwd, timeoutMs = 3000) {
|
|
|
150
153
|
_deps.execFile(
|
|
151
154
|
file,
|
|
152
155
|
fileArgs,
|
|
153
|
-
{
|
|
156
|
+
{
|
|
157
|
+
cwd,
|
|
158
|
+
encoding: "utf8",
|
|
159
|
+
timeout: timeoutMs,
|
|
160
|
+
windowsHide: true,
|
|
161
|
+
origin: "pr:link-query",
|
|
162
|
+
policy: "allow",
|
|
163
|
+
scope: "pr",
|
|
164
|
+
shell: false,
|
|
165
|
+
},
|
|
154
166
|
(err, stdout) => resolve(err ? null : String(stdout || "").trim()),
|
|
155
167
|
);
|
|
156
168
|
});
|
|
@@ -65,6 +65,11 @@ const ENV_ALLOWLIST = new Set([
|
|
|
65
65
|
"VISUAL",
|
|
66
66
|
"NODE_ENV",
|
|
67
67
|
"NODE_OPTIONS",
|
|
68
|
+
// Correlation identifiers required by ChainlessChain/Claude-compatible
|
|
69
|
+
// child processes. These identify a run; they are not authentication
|
|
70
|
+
// credentials. Other SESSION-named variables remain filtered.
|
|
71
|
+
"CC_SESSION_ID",
|
|
72
|
+
"CLAUDE_CODE_SESSION_ID",
|
|
68
73
|
"npm_config_registry",
|
|
69
74
|
"npm_config_cache",
|
|
70
75
|
"NPM_CONFIG_REGISTRY",
|
|
@@ -208,9 +213,10 @@ class CredentialAgent {
|
|
|
208
213
|
}
|
|
209
214
|
|
|
210
215
|
/**
|
|
211
|
-
* Apply credential filtering
|
|
216
|
+
* Apply credential filtering and return explicit audit metadata. Credential
|
|
217
|
+
* values and proxy reference ids are intentionally kept out of the report.
|
|
212
218
|
*/
|
|
213
|
-
|
|
219
|
+
applyWithReport(spawnOptions) {
|
|
214
220
|
const env = spawnOptions.env || process.env;
|
|
215
221
|
const { safeEnv, redacted: envRedacted } = this.filterEnvironment(env);
|
|
216
222
|
spawnOptions.env = safeEnv;
|
|
@@ -231,7 +237,21 @@ class CredentialAgent {
|
|
|
231
237
|
if (this._accessLog.length > 10000) this._accessLog.shift();
|
|
232
238
|
}
|
|
233
239
|
|
|
234
|
-
return
|
|
240
|
+
return {
|
|
241
|
+
spawnOptions,
|
|
242
|
+
report: {
|
|
243
|
+
envKeys: envRedacted.map((entry) => entry.key),
|
|
244
|
+
argIndexes: argRedacted.map((entry) => entry.index),
|
|
245
|
+
envCount: envRedacted.length,
|
|
246
|
+
argCount: argRedacted.length,
|
|
247
|
+
filtered: envRedacted.length > 0 || argRedacted.length > 0,
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Backward-compatible mutation API for existing integrations. */
|
|
253
|
+
apply(spawnOptions) {
|
|
254
|
+
return this.applyWithReport(spawnOptions).spawnOptions;
|
|
235
255
|
}
|
|
236
256
|
|
|
237
257
|
/**
|