chainlesschain 0.162.174 → 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-Dcl-X1Hw.js → AIOps-BDLu5Elz.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-ClMh9HzT.js → ActionButton-DH5us-CK.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DPj0rSQ5.js → Analytics-BZ0u8IFG.js} +3 -3
- package/src/assets/web-panel/assets/AppLayout-Duu8xR14.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-L8781rE8.js → Artifacts-Br2YBbh_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CffB6WIP.js → Audit-C3C6a482.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BkLhayyY.js → BackgroundAgents-CzHvebcj.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BQnwFI78.js → Backup-DZNHYDFd.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-xuUGHQch.js → BaseInput-VRiC4fIx.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-feQXwWrg.js → Chat-Cm08WWAD.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CGHYrugQ.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-DVaIiUGW.js → Checkbox-DtByk7d7.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-D2kEnzeU.js → Codegen-CphXXOfD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-azDoyusS.js → Col-Hz86TnLR.js} +1 -1
- package/src/assets/web-panel/assets/{Community-OZdnPWM5.js → Community-HP03ltpD.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-VDMvBN-C.js → Compact-B_N1mqQz.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CPJ_zgQ1.js → Compliance-CVztRpi8.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-iRBwcsOA.js → Cowork-wUVOyZih.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-DrxrspUz.js → Cron-DW5TLJKw.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-D-rkAZXF.js → Crosschain-CrAFGhWH.js} +1 -1
- package/src/assets/web-panel/assets/{DID-5Pp1Xnmr.js → DID-pA-oD8ke.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-CXrd5gAw.js +3 -0
- package/src/assets/web-panel/assets/{Dropdown-BWj_E0Ie.js → Dropdown-EweJcsek.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BT-wgSEh.js → EmailListRenderer-C9xVLPG4.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-1PzH23pa.js → FamilyGuardDashboard-CDcEEqlu.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BxMIXGC6.js → Federation-DtZda9A_.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CyJobBln.js → FormItemContext-CiYdcVz3.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-YkjFuQTN.js → GenericCardRenderer-DA13uwA0.js} +1 -1
- package/src/assets/web-panel/assets/{Git-C2a98Wp_.js → Git-DzRhZD1O.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DKL3Fl84.js → Governance-D5RMgOSb.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BJ2cQC_3.js → Inference-BgrPfSNk.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DBAsOngt.js → KnowledgeGraph-DzjnD571.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-COt8g9LO.js → Logs-BhWzVDtN.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-3Lfht1Fd.js → MarkdownRenderer-BDape9cx.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-C9Zk9Pb2.js → Marketplace-DJtL5GV7.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DDWDFWPO.js → McpTools-CZcQygI7.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-BRmVye_o.js → Memory-DUWSDUUu.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CppBbWpD.js → MobileBridge-BTwq2WKY.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-NZvvfDME.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-CcWpeGa6.js → Mtc-BiGugEQm.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-BcllEq0K.js → MtcAudit-DY7a6gUe.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BFD1CarL.js → Multisig-BQbDu_w7.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-QNXXYvjz.js → NLProgramming-CM2wXTLv.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-07YwgQVy.js → Notes-DI6gGs1v.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-bOccEInE.js → NotificationSettings-BsZOLWAB.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DlRi29WL.js → OrderTableRenderer-C48mu09U.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CBaezzEr.js → Organization-Cds0_tXr.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Bl5NohFO.js → Overflow-WunYMD87.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CLMal9Aw.js → P2P-Bo6j4DDv.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CGO0NITk.js → PdhVaultBrowser-Bh2XPD5f.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CPSw48E2.js → Permissions-EMvMMC8N.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-CDM5n134.js → PersonalDataHub-AX3ypUDV.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-BdsqG7WV.js → Pipeline-BOx8HOgL.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B6L4E-M7.js → Privacy-tBeTVQVM.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DXPyZKRs.js → ProjectInit-CVYg1W4M.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BrCC3xYT.js → ProjectSettings-Dvt5I7y1.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BYmuHC2q.js → Projects-Cc7FC9-e.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CbCe2eUl.js → Providers-Ct8xqY-E.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DkukgCrR.js → QrScannerModal-Cni8Ooja.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D-htOrV8.js → QuickAsk-BJVLKdxr.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Bm7SIfzu.js → Recommend-DPG8Rbbm.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C9rP-iMc.js → RemoteSession-DsdR7dCt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-kGlUgbsl.js → Reputation-Csg1YM-b.js} +1 -1
- package/src/assets/web-panel/assets/{Row-PBupbbUA.js → Row-D9DoFoEf.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-njlwKUGK.js → RssFeed-BsvKrXMS.js} +2 -2
- package/src/assets/web-panel/assets/{Search-DLdEmgBw.js → Search-DFUStfgQ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-SXGPSHdu.js → Security-ILg1zxdK.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CuFGnNsb.js → Services-Dd41PCaY.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CtUC0mDa.js → Skeleton-Bzo1cN80.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-P1qgOVFn.js → Skills-BDHh17P0.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CsppE8YV.js → Sla-jl7UTiRY.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Cq1oG56m.js → SpeechSettings-BePa-RF6.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DdKW6V-C.js → SyncSettings-DiqqDKGZ.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BCc9san5.js → Tasks-DYQ_6lxj.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CcHC1dMA.js → Templates-JiDeI06L.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CA4PqU22.js → Tenant-hhgI6zwS.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-CjTZPa37.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-DHWTSvOy.js → TimelineRenderer-B8uB5Llk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Ddz-P_yh.js → Tokens-C3b_6r2z.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-ePmrmLZ1.js → Trigger-tIP7HKVe.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DmuK1CCE.js → Trust-vjoc11vJ.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CqqBuRrT.js → UkeySign-DUPBnGuH.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BGlR3uWM.js → VideoEditing-CBvhUY5T.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Ba_Qx6Ga.js → Wallet-DUaQ0uA5.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-29neXKt2.js → WebAuthn-DllSivjE.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-lD0lR0UQ.js → WorkflowEditor-xc8D3uO6.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B3stH01u.js → chat-BVicU7oA.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Czly56MN.js → colors-DJzLmhLm.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C0TkbkAJ.js → compact-item-BvYRfThE.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BJmpSlf1.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-D1q-zw7u.js → hasIn-SBDJB1y4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DV-twjNO.js → index-1SdDS6lR.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-kTvMq7.js → index-9gdI7uUW.js} +1 -1
- package/src/assets/web-panel/assets/index-B7nuIywP.js +1 -0
- package/src/assets/web-panel/assets/{index-Bm_-RKal.js → index-BJZf9DhV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQftlZn-.js → index-BO1itZaY.js} +3 -3
- package/src/assets/web-panel/assets/{index-Dw3L_smW.js → index-BTrBGBJs.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7sFKQ53.js → index-BYqz4Wrr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlvsSuBC.js → index-Bf-ctERC.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChESIe5r.js → index-CKyEivf8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaqEHaCg.js → index-CdGY9P8a.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZeoKL6t.js → index-Cf-O_g_8.js} +1 -1
- package/src/assets/web-panel/assets/{index-XWV8JWMc.js → index-CloCgBUR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpMIdPJ0.js → index-CoJAO1Lm.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgS8XUBU.js → index-Crk5NTb0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmUta2lw.js → index-Cs2rmLFt.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dpz_7sf-.js → index-CtwqO5qo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRcQsPez.js → index-D7HimK0M.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEt2-3x5.js → index-DCdRAgjy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHvPlzWJ.js → index-DCqRS6da.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDHXx65P.js → index-DHVLJ8q0.js} +1 -1
- package/src/assets/web-panel/assets/{index-K4YaPDOn.js → index-DKrvvWm4.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1pOqU7D.js → index-DMarmfrv.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAhrn9EJ.js → index-DRfiXB_p.js} +1 -1
- package/src/assets/web-panel/assets/{index-cPjWjvmW.js → index-Dm_77jgR.js} +1 -1
- package/src/assets/web-panel/assets/{index-C27TnOoT.js → index-DnjPdvR6.js} +1 -1
- package/src/assets/web-panel/assets/{index-upY9rkGZ.js → index-DonCnfMr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbvNJUwu.js → index-DvUTDYXX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVwJ3jht.js → index-FxZzRyE1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIF6XHIi.js → index-MjC4G09d.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8KqsomG.js → index-VMfwIH5G.js} +1 -1
- package/src/assets/web-panel/assets/{index-8GKykbS4.js → index-YJkzy8ZF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpGs96FC.js → index-d5BVd-cL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DO8xOwxi.js → index-e4fXH_WO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cu_4HaUS.js → index-hxTODbM1.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf7Gr3NG.js → index-lpaGoTH3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBqAm8es.js → index-wcCL-miV.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZDUhX41Z.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-z8ATo2aQ.js → index-z1ZylsLq.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-QWEXi6-t.js → initDefaultProps-C1zO1KnY.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BfrQwvV1.js → motion-CWLtEGmC.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dn7x0H9t.js → move-DzD_C3Vm.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-F61D_TgE.js → mtc-parser-D880PYJl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-4SQZ39PF.js → omit-CFR_z2ov.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-C7DTe126.js → pickAttrs-srIhgrSC.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-40NeyzDK.js → placementArrow-C1rXpibP.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BiUJ6qWs.js → responsiveObserve-C30gRcSS.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CacJTM3f.js → slide-CvtKiMfV.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-K812HB-k.js → statusUtils-DNHO7ITG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CKeHA2eM.js → styleChecker-Dt_Sl-g4.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CKl4FqXF.js → useFlexGapSupport-Cjev42Gh.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DPoiJjSZ.js → useFs-Baxglj2V.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-aHwBspmt.js → usePersonalDataHub-B4NkcLaP.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DrA-GuCT.js → vnode-mIRkdT7o.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-G3LMswgy.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 +45 -3
- package/src/commands/background-session.js +103 -0
- 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/esm-bridge.js +3 -0
- 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 +92 -4
- package/src/harness/jsonl-session-store.js +13 -6
- package/src/harness/mcp-client.js +200 -1
- package/src/index.js +123 -55
- package/src/lazy-dispatch.js +86 -85
- 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 +26 -4
- package/src/lib/background-interaction-resolver.js +71 -0
- package/src/lib/background-session-transport.js +59 -1
- 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/crash-reporter.js +6 -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 +34 -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/ipc-attach-protocol.js +98 -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 +295 -0
- package/src/lib/process-execution-broker/index.js +440 -14
- package/src/lib/process-execution-broker/patch-child-process.js +2 -3
- package/src/lib/process-execution-broker/platform-sandbox.js +351 -0
- package/src/lib/process-manager.js +18 -3
- package/src/lib/provenance-api.js +6 -0
- package/src/lib/proxy-bootstrap.js +19 -0
- package/src/lib/publish-workspace.js +14 -6
- package/src/lib/repl-rewind.js +9 -4
- package/src/lib/secret-store.js +159 -0
- package/src/lib/service-manager.js +64 -29
- package/src/lib/session-hooks.js +328 -473
- package/src/lib/session-telemetry-middleware.js +6 -0
- 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/trace-api.js +6 -0
- package/src/lib/turn-context.js +14 -8
- package/src/lib/unattended-action-policy.js +83 -0
- package/src/lib/update-notice.js +9 -45
- package/src/lib/with-file-lock.js +7 -0
- package/src/lib/ws-server.js +1 -0
- package/src/repl/agent-repl.js +71 -13
- 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/workers/background-agent-worker.js +80 -1
- package/src/assets/web-panel/assets/AppLayout-7iSKDmlI.js +0 -9
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DcbUHeGW.js +0 -1
- package/src/assets/web-panel/assets/Dashboard-BAKYNavw.js +0 -3
- package/src/assets/web-panel/assets/MobileProjects-C4GKn1dH.js +0 -1
- package/src/assets/web-panel/assets/Terminal-Fj7ea0In.js +0 -3
- package/src/assets/web-panel/assets/devWarning-CDI8Sbaj.js +0 -1
- package/src/assets/web-panel/assets/index-96LBR96V.js +0 -1
- package/src/assets/web-panel/assets/index-DyQkiW24.js +0 -1
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
LEGACY_TO_UNIFIED_TYPE,
|
|
15
15
|
} from "../runtime/runtime-events.js";
|
|
16
16
|
import { createAbortError } from "./abort-utils.js";
|
|
17
|
+
import { emitHooksV2Event } from "./hooks-v2-producers.js";
|
|
17
18
|
import { verifyApprovalBinding } from "./agent-authority.js";
|
|
18
19
|
import { createEnvelope } from "@chainlesschain/session-core";
|
|
19
20
|
|
|
@@ -245,6 +246,44 @@ export class WebSocketInteractionAdapter extends InteractionAdapter {
|
|
|
245
246
|
this._resolvePending(requestId, answer, "question", binding);
|
|
246
247
|
}
|
|
247
248
|
|
|
249
|
+
/**
|
|
250
|
+
* Ask an MCP server elicitation over the same question/answer channel.
|
|
251
|
+
* The schema is carried as metadata so capable IDE clients can render a
|
|
252
|
+
* native form; older clients still receive a bounded, ordinary question.
|
|
253
|
+
*/
|
|
254
|
+
async askElicitation({
|
|
255
|
+
server,
|
|
256
|
+
requestId: mcpRequestId,
|
|
257
|
+
message = "MCP server requests input",
|
|
258
|
+
requestedSchema = null,
|
|
259
|
+
timeoutMs,
|
|
260
|
+
} = {}) {
|
|
261
|
+
emitHooksV2Event("MCPElicitation", {
|
|
262
|
+
server: server || null,
|
|
263
|
+
request_id: mcpRequestId ?? null,
|
|
264
|
+
message: String(message),
|
|
265
|
+
requested_schema: requestedSchema || null,
|
|
266
|
+
});
|
|
267
|
+
return this._request(
|
|
268
|
+
{
|
|
269
|
+
type: "question",
|
|
270
|
+
questionType: "elicitation",
|
|
271
|
+
question: String(message),
|
|
272
|
+
...(requestedSchema ? { requestedSchema } : {}),
|
|
273
|
+
metadata: {
|
|
274
|
+
kind: "mcp_elicitation",
|
|
275
|
+
server: server || null,
|
|
276
|
+
requestId: mcpRequestId ?? null,
|
|
277
|
+
requestedSchema: requestedSchema || null,
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
kind: "question",
|
|
282
|
+
...(Number(timeoutMs) > 0 ? { timeoutMs: Number(timeoutMs) } : {}),
|
|
283
|
+
},
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
248
287
|
async requestHostTool(toolName, args = {}, extra = {}) {
|
|
249
288
|
return this._request(
|
|
250
289
|
{
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPC Attach Protocol — stdio 双向消息协议
|
|
3
|
+
*
|
|
4
|
+
* 用于 `cc cowork background attach <id>` 与 Background Agent Worker 子进程之间
|
|
5
|
+
* 传递结构化消息(提问/回答/取消/恢复),与普通 stdout/stderr 输出互不干扰。
|
|
6
|
+
*
|
|
7
|
+
* 协议格式:每一行以 `__IPC__:` 开头,后接 JSON 编码的消息体
|
|
8
|
+
* 换行安全:JSON 内的换行符被转义为 \x1f,回车符被转义为 \x1e
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const IPC_PREFIX = "__IPC__:";
|
|
12
|
+
const NL = "\n";
|
|
13
|
+
const CR = "\r";
|
|
14
|
+
const NL_SUBST = "\x1f";
|
|
15
|
+
const CR_SUBST = "\x1e";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 编码一条 IPC 消息
|
|
19
|
+
* @param {string} type - 消息类型 (HELLO/QUESTION/ANSWER/RESUME/CANCEL/...)
|
|
20
|
+
* @param {object} [payload={}] - 消息负载
|
|
21
|
+
* @returns {string} 可直接写入 stdin/stdout 的带前缀字符串(含末尾换行)
|
|
22
|
+
*/
|
|
23
|
+
function encodeIpcMessage(type, payload = {}) {
|
|
24
|
+
const json = JSON.stringify({ type, ...payload });
|
|
25
|
+
const safe = json.split(CR).join(CR_SUBST).split(NL).join(NL_SUBST);
|
|
26
|
+
return IPC_PREFIX + safe + NL;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 尝试从一行文本解析 IPC 消息
|
|
31
|
+
* @param {string} line - 单行文本(不含末尾换行)
|
|
32
|
+
* @returns {object|null} 解析出的消息对象,非 IPC 消息返回 null
|
|
33
|
+
*/
|
|
34
|
+
function decodeIpcLine(line) {
|
|
35
|
+
if (!line || !line.startsWith(IPC_PREFIX)) return null;
|
|
36
|
+
const raw = line
|
|
37
|
+
.slice(IPC_PREFIX.length)
|
|
38
|
+
.split(CR_SUBST)
|
|
39
|
+
.join(CR)
|
|
40
|
+
.split(NL_SUBST)
|
|
41
|
+
.join(NL);
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(raw);
|
|
44
|
+
} catch (_err) {
|
|
45
|
+
return { type: "PARSE_ERROR", raw };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 从文本流中提取所有完整 IPC 消息,并返回剩余的未完成片段
|
|
51
|
+
* @param {string} buffer - 累积的文本缓冲区
|
|
52
|
+
* @returns {{ messages: Array<object>, rest: string }}
|
|
53
|
+
*/
|
|
54
|
+
function parseIpcBuffer(buffer) {
|
|
55
|
+
const messages = [];
|
|
56
|
+
const lines = buffer.split(NL);
|
|
57
|
+
const rest = lines.pop() || "";
|
|
58
|
+
for (const line of lines) {
|
|
59
|
+
const msg = decodeIpcLine(line);
|
|
60
|
+
if (msg) messages.push(msg);
|
|
61
|
+
}
|
|
62
|
+
return { messages, rest };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 将答案值标准化为字符串(兼容文本/对象/选项序号)
|
|
67
|
+
* @param {*} value - 用户输入的原始答案
|
|
68
|
+
* @param {object} [question] - 原问题对象(用于解析选项序号)
|
|
69
|
+
* @returns {string}
|
|
70
|
+
*/
|
|
71
|
+
function normalizeAnswer(value, question = null) {
|
|
72
|
+
if (value === null || value === undefined) return "";
|
|
73
|
+
if (typeof value === "string") {
|
|
74
|
+
const s = value.trim();
|
|
75
|
+
if (
|
|
76
|
+
question &&
|
|
77
|
+
Array.isArray(question.options) &&
|
|
78
|
+
question.options.length > 0
|
|
79
|
+
) {
|
|
80
|
+
const num = Number(s);
|
|
81
|
+
if (Number.isInteger(num) && num >= 1 && num <= question.options.length) {
|
|
82
|
+
return String(
|
|
83
|
+
question.options[num - 1].value ?? question.options[num - 1],
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return s;
|
|
88
|
+
}
|
|
89
|
+
return JSON.stringify(value);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export {
|
|
93
|
+
IPC_PREFIX,
|
|
94
|
+
encodeIpcMessage,
|
|
95
|
+
decodeIpcLine,
|
|
96
|
+
parseIpcBuffer,
|
|
97
|
+
normalizeAnswer,
|
|
98
|
+
};
|
|
@@ -173,9 +173,7 @@ export function computeSchemaDigest(schema) {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
/** Resolve a local `#/...` JSON Pointer $ref within `root`; null if unresolved. */
|
|
176
|
-
function
|
|
177
|
-
if (typeof ref !== "string" || !ref.startsWith("#")) return null;
|
|
178
|
-
const frag = ref.slice(1);
|
|
176
|
+
function resolvePointer(root, frag) {
|
|
179
177
|
if (frag === "" || frag === "/") return root;
|
|
180
178
|
const parts = frag
|
|
181
179
|
.replace(/^\//, "")
|
|
@@ -189,15 +187,56 @@ function resolveRef(root, ref) {
|
|
|
189
187
|
return cur === undefined ? null : cur;
|
|
190
188
|
}
|
|
191
189
|
|
|
190
|
+
function findAnchor(root, anchor, seen = new Set()) {
|
|
191
|
+
if (!root || typeof root !== "object" || seen.has(root)) return null;
|
|
192
|
+
seen.add(root);
|
|
193
|
+
if (root.$anchor === anchor || root.$dynamicAnchor === anchor) return root;
|
|
194
|
+
for (const value of Object.values(root)) {
|
|
195
|
+
const found = findAnchor(value, anchor, seen);
|
|
196
|
+
if (found) return found;
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** Resolve local refs or a caller-provided external document registry. */
|
|
202
|
+
function resolveRef(root, ref, externalSchemas = {}) {
|
|
203
|
+
if (typeof ref !== "string") return null;
|
|
204
|
+
if (ref.startsWith("#")) {
|
|
205
|
+
const fragment = ref.slice(1);
|
|
206
|
+
if (fragment === "" || fragment.startsWith("/")) {
|
|
207
|
+
return resolvePointer(root, fragment);
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
return findAnchor(root, decodeURIComponent(fragment), new Set());
|
|
211
|
+
} catch {
|
|
212
|
+
return findAnchor(root, fragment, new Set());
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const hash = ref.indexOf("#");
|
|
216
|
+
const uri = hash >= 0 ? ref.slice(0, hash) : ref;
|
|
217
|
+
const document = externalSchemas?.[ref] ?? externalSchemas?.[uri];
|
|
218
|
+
if (document === undefined) return null;
|
|
219
|
+
if (hash < 0) return document;
|
|
220
|
+
const fragment = ref.slice(hash + 1);
|
|
221
|
+
if (fragment === "" || fragment.startsWith("/")) {
|
|
222
|
+
return resolvePointer(document, fragment);
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
return findAnchor(document, decodeURIComponent(fragment), new Set());
|
|
226
|
+
} catch {
|
|
227
|
+
return findAnchor(document, fragment, new Set());
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
192
231
|
// ─── instance validation ─────────────────────────────────────────────────────
|
|
193
232
|
|
|
194
233
|
/**
|
|
195
234
|
* Validate `value` against `schema`.
|
|
196
235
|
* @returns {{valid:boolean, errors:Array<{code,keyword,instancePath,schemaPath,message}>}}
|
|
197
236
|
*/
|
|
198
|
-
export function validate(value, schema) {
|
|
237
|
+
export function validate(value, schema, { externalSchemas = {} } = {}) {
|
|
199
238
|
const errors = [];
|
|
200
|
-
_validate(value, schema, [], [], schema, errors, 0);
|
|
239
|
+
_validate(value, schema, [], [], schema, errors, 0, externalSchemas);
|
|
201
240
|
return { valid: errors.length === 0, errors };
|
|
202
241
|
}
|
|
203
242
|
|
|
@@ -211,7 +250,7 @@ function _err(errors, keyword, instSegs, schemaSegs, message) {
|
|
|
211
250
|
});
|
|
212
251
|
}
|
|
213
252
|
|
|
214
|
-
function _validate(value, schema, inst, sch, root, errors, depth) {
|
|
253
|
+
function _validate(value, schema, inst, sch, root, errors, depth, externalSchemas) {
|
|
215
254
|
if (schema === true || schema === undefined) return;
|
|
216
255
|
if (schema === false) {
|
|
217
256
|
_err(errors, "false", inst, sch, "schema is `false` — no value is valid");
|
|
@@ -220,19 +259,25 @@ function _validate(value, schema, inst, sch, root, errors, depth) {
|
|
|
220
259
|
if (!schema || typeof schema !== "object") return;
|
|
221
260
|
if (depth > MAX_REF_DEPTH) return; // cyclic $ref guard
|
|
222
261
|
|
|
223
|
-
// $ref —
|
|
224
|
-
|
|
225
|
-
|
|
262
|
+
// $ref/$dynamicRef — local pointer/anchor or explicit external registry.
|
|
263
|
+
const refKeyword =
|
|
264
|
+
typeof schema.$ref === "string"
|
|
265
|
+
? "$ref"
|
|
266
|
+
: typeof schema.$dynamicRef === "string"
|
|
267
|
+
? "$dynamicRef"
|
|
268
|
+
: null;
|
|
269
|
+
if (refKeyword) {
|
|
270
|
+
const target = resolveRef(root, schema[refKeyword], externalSchemas);
|
|
226
271
|
if (target == null) {
|
|
227
272
|
_err(
|
|
228
273
|
errors,
|
|
229
|
-
|
|
274
|
+
refKeyword,
|
|
230
275
|
inst,
|
|
231
|
-
[...sch,
|
|
232
|
-
`cannot resolve $
|
|
276
|
+
[...sch, refKeyword],
|
|
277
|
+
`cannot resolve ${refKeyword} "${schema[refKeyword]}"`,
|
|
233
278
|
);
|
|
234
279
|
} else {
|
|
235
|
-
_validate(value, target, inst, [...sch,
|
|
280
|
+
_validate(value, target, inst, [...sch, refKeyword], root, errors, depth + 1, externalSchemas);
|
|
236
281
|
}
|
|
237
282
|
// sibling keywords still apply in 2020-12; fall through.
|
|
238
283
|
}
|
|
@@ -282,12 +327,12 @@ function _validate(value, schema, inst, sch, root, errors, depth) {
|
|
|
282
327
|
if (t === "number" || t === "integer")
|
|
283
328
|
_validateNumber(value, schema, inst, sch, errors);
|
|
284
329
|
if (t === "array")
|
|
285
|
-
_validateArray(value, schema, inst, sch, root, errors, depth);
|
|
330
|
+
_validateArray(value, schema, inst, sch, root, errors, depth, externalSchemas);
|
|
286
331
|
if (t === "object")
|
|
287
|
-
_validateObject(value, schema, inst, sch, root, errors, depth);
|
|
332
|
+
_validateObject(value, schema, inst, sch, root, errors, depth, externalSchemas);
|
|
288
333
|
|
|
289
|
-
_validateCombinators(value, schema, inst, sch, root, errors, depth);
|
|
290
|
-
_validateConditional(value, schema, inst, sch, root, errors, depth);
|
|
334
|
+
_validateCombinators(value, schema, inst, sch, root, errors, depth, externalSchemas);
|
|
335
|
+
_validateConditional(value, schema, inst, sch, root, errors, depth, externalSchemas);
|
|
291
336
|
}
|
|
292
337
|
|
|
293
338
|
/**
|
|
@@ -295,9 +340,9 @@ function _validate(value, schema, inst, sch, root, errors, depth) {
|
|
|
295
340
|
* own errors are never reported; if the value matches `if`, `then` applies,
|
|
296
341
|
* otherwise `else` applies. No `if` keyword ⇒ then/else are inert.
|
|
297
342
|
*/
|
|
298
|
-
function _validateConditional(value, schema, inst, sch, root, errors, depth) {
|
|
343
|
+
function _validateConditional(value, schema, inst, sch, root, errors, depth, externalSchemas) {
|
|
299
344
|
if (schema.if === undefined) return;
|
|
300
|
-
const matched = _branchValid(value, schema.if, root, depth);
|
|
345
|
+
const matched = _branchValid(value, schema.if, root, depth, externalSchemas);
|
|
301
346
|
if (matched) {
|
|
302
347
|
if (schema.then !== undefined) {
|
|
303
348
|
_validate(
|
|
@@ -308,10 +353,11 @@ function _validateConditional(value, schema, inst, sch, root, errors, depth) {
|
|
|
308
353
|
root,
|
|
309
354
|
errors,
|
|
310
355
|
depth,
|
|
356
|
+
externalSchemas,
|
|
311
357
|
);
|
|
312
358
|
}
|
|
313
359
|
} else if (schema.else !== undefined) {
|
|
314
|
-
_validate(value, schema.else, inst, [...sch, "else"], root, errors, depth);
|
|
360
|
+
_validate(value, schema.else, inst, [...sch, "else"], root, errors, depth, externalSchemas);
|
|
315
361
|
}
|
|
316
362
|
}
|
|
317
363
|
|
|
@@ -423,7 +469,7 @@ function _validateNumber(value, schema, inst, sch, errors) {
|
|
|
423
469
|
}
|
|
424
470
|
}
|
|
425
471
|
|
|
426
|
-
function _validateArray(value, schema, inst, sch, root, errors, depth) {
|
|
472
|
+
function _validateArray(value, schema, inst, sch, root, errors, depth, externalSchemas) {
|
|
427
473
|
if (Number.isFinite(schema.minItems) && value.length < schema.minItems) {
|
|
428
474
|
_err(
|
|
429
475
|
errors,
|
|
@@ -460,6 +506,24 @@ function _validateArray(value, schema, inst, sch, root, errors, depth) {
|
|
|
460
506
|
}
|
|
461
507
|
}
|
|
462
508
|
const prefix = Array.isArray(schema.prefixItems) ? schema.prefixItems : [];
|
|
509
|
+
if (schema.contains !== undefined) {
|
|
510
|
+
const matches = value.reduce(
|
|
511
|
+
(count, item, i) =>
|
|
512
|
+
count + (_branchValid(item, schema.contains, root, depth, externalSchemas) ? 1 : 0),
|
|
513
|
+
0,
|
|
514
|
+
);
|
|
515
|
+
const min = Number.isFinite(schema.minContains) ? schema.minContains : 1;
|
|
516
|
+
const max = Number.isFinite(schema.maxContains) ? schema.maxContains : Infinity;
|
|
517
|
+
if (matches < min || matches > max) {
|
|
518
|
+
_err(
|
|
519
|
+
errors,
|
|
520
|
+
"contains",
|
|
521
|
+
inst,
|
|
522
|
+
[...sch, "contains"],
|
|
523
|
+
`array contains ${matches} matching item(s), expected ${min}${max === Infinity ? "+" : `..${max}`}`,
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
463
527
|
value.forEach((item, i) => {
|
|
464
528
|
if (i < prefix.length) {
|
|
465
529
|
_validate(
|
|
@@ -470,6 +534,7 @@ function _validateArray(value, schema, inst, sch, root, errors, depth) {
|
|
|
470
534
|
root,
|
|
471
535
|
errors,
|
|
472
536
|
depth,
|
|
537
|
+
externalSchemas,
|
|
473
538
|
);
|
|
474
539
|
} else if (schema.items !== undefined) {
|
|
475
540
|
_validate(
|
|
@@ -480,12 +545,13 @@ function _validateArray(value, schema, inst, sch, root, errors, depth) {
|
|
|
480
545
|
root,
|
|
481
546
|
errors,
|
|
482
547
|
depth,
|
|
548
|
+
externalSchemas,
|
|
483
549
|
);
|
|
484
550
|
}
|
|
485
551
|
});
|
|
486
552
|
}
|
|
487
553
|
|
|
488
|
-
function _validateObject(value, schema, inst, sch, root, errors, depth) {
|
|
554
|
+
function _validateObject(value, schema, inst, sch, root, errors, depth, externalSchemas) {
|
|
489
555
|
const keys = Object.keys(value);
|
|
490
556
|
if (
|
|
491
557
|
Number.isFinite(schema.minProperties) &&
|
|
@@ -523,6 +589,10 @@ function _validateObject(value, schema, inst, sch, root, errors, depth) {
|
|
|
523
589
|
}
|
|
524
590
|
}
|
|
525
591
|
const props = schema.properties || {};
|
|
592
|
+
const patterns = schema.patternProperties || {};
|
|
593
|
+
const patternEntries = Object.entries(patterns).map(([pattern, sub]) => {
|
|
594
|
+
try { return [new RegExp(pattern), pattern, sub]; } catch { return [null, pattern, sub]; }
|
|
595
|
+
});
|
|
526
596
|
for (const [k, v] of Object.entries(value)) {
|
|
527
597
|
if (Object.prototype.hasOwnProperty.call(props, k)) {
|
|
528
598
|
_validate(
|
|
@@ -533,19 +603,25 @@ function _validateObject(value, schema, inst, sch, root, errors, depth) {
|
|
|
533
603
|
root,
|
|
534
604
|
errors,
|
|
535
605
|
depth,
|
|
606
|
+
externalSchemas,
|
|
536
607
|
);
|
|
537
|
-
} else
|
|
608
|
+
} else {
|
|
609
|
+
const matches = patternEntries.filter(([re]) => re && re.test(k));
|
|
610
|
+
if (matches.length > 0) {
|
|
611
|
+
for (const [, pattern, sub] of matches) {
|
|
612
|
+
_validate(v, sub, [...inst, k], [...sch, "patternProperties", pattern], root, errors, depth, externalSchemas);
|
|
613
|
+
}
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
if (schema.additionalProperties === false || schema.unevaluatedProperties === false) {
|
|
538
617
|
_err(
|
|
539
618
|
errors,
|
|
540
|
-
"additionalProperties",
|
|
619
|
+
schema.additionalProperties === false ? "additionalProperties" : "unevaluatedProperties",
|
|
541
620
|
[...inst, k],
|
|
542
|
-
[...sch, "additionalProperties"],
|
|
621
|
+
[...sch, schema.additionalProperties === false ? "additionalProperties" : "unevaluatedProperties"],
|
|
543
622
|
`unexpected property "${k}"`,
|
|
544
623
|
);
|
|
545
|
-
|
|
546
|
-
schema.additionalProperties &&
|
|
547
|
-
typeof schema.additionalProperties === "object"
|
|
548
|
-
) {
|
|
624
|
+
} else if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
|
|
549
625
|
_validate(
|
|
550
626
|
v,
|
|
551
627
|
schema.additionalProperties,
|
|
@@ -554,25 +630,49 @@ function _validateObject(value, schema, inst, sch, root, errors, depth) {
|
|
|
554
630
|
root,
|
|
555
631
|
errors,
|
|
556
632
|
depth,
|
|
633
|
+
externalSchemas,
|
|
557
634
|
);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
if (schema.propertyNames !== undefined) {
|
|
639
|
+
for (const key of keys) {
|
|
640
|
+
_validate(key, schema.propertyNames, [...inst, key], [...sch, "propertyNames"], root, errors, depth, externalSchemas);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
if (schema.dependentRequired && typeof schema.dependentRequired === "object") {
|
|
644
|
+
for (const [key, required] of Object.entries(schema.dependentRequired)) {
|
|
645
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
646
|
+
for (const dep of Array.isArray(required) ? required : []) {
|
|
647
|
+
if (!Object.prototype.hasOwnProperty.call(value, dep)) {
|
|
648
|
+
_err(errors, "dependentRequired", inst, [...sch, "dependentRequired", key], `property "${key}" requires property "${dep}"`);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
if (schema.dependentSchemas && typeof schema.dependentSchemas === "object") {
|
|
654
|
+
for (const [key, sub] of Object.entries(schema.dependentSchemas)) {
|
|
655
|
+
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
|
656
|
+
_validate(value, sub, inst, [...sch, "dependentSchemas", key], root, errors, depth, externalSchemas);
|
|
657
|
+
}
|
|
558
658
|
}
|
|
559
659
|
}
|
|
560
660
|
}
|
|
561
661
|
|
|
562
|
-
function _branchValid(value, subschema, root, depth) {
|
|
662
|
+
function _branchValid(value, subschema, root, depth, externalSchemas) {
|
|
563
663
|
const errs = [];
|
|
564
|
-
_validate(value, subschema, [], [], root, errs, depth + 1);
|
|
664
|
+
_validate(value, subschema, [], [], root, errs, depth + 1, externalSchemas);
|
|
565
665
|
return errs.length === 0;
|
|
566
666
|
}
|
|
567
667
|
|
|
568
|
-
function _validateCombinators(value, schema, inst, sch, root, errors, depth) {
|
|
668
|
+
function _validateCombinators(value, schema, inst, sch, root, errors, depth, externalSchemas) {
|
|
569
669
|
if (Array.isArray(schema.allOf)) {
|
|
570
670
|
schema.allOf.forEach((s, i) => {
|
|
571
|
-
_validate(value, s, inst, [...sch, "allOf", i], root, errors, depth);
|
|
671
|
+
_validate(value, s, inst, [...sch, "allOf", i], root, errors, depth, externalSchemas);
|
|
572
672
|
});
|
|
573
673
|
}
|
|
574
674
|
if (Array.isArray(schema.anyOf)) {
|
|
575
|
-
const ok = schema.anyOf.some((s) => _branchValid(value, s, root, depth));
|
|
675
|
+
const ok = schema.anyOf.some((s) => _branchValid(value, s, root, depth, externalSchemas));
|
|
576
676
|
if (!ok)
|
|
577
677
|
_err(
|
|
578
678
|
errors,
|
|
@@ -584,7 +684,7 @@ function _validateCombinators(value, schema, inst, sch, root, errors, depth) {
|
|
|
584
684
|
}
|
|
585
685
|
if (Array.isArray(schema.oneOf)) {
|
|
586
686
|
const matches = schema.oneOf.filter((s) =>
|
|
587
|
-
_branchValid(value, s, root, depth),
|
|
687
|
+
_branchValid(value, s, root, depth, externalSchemas),
|
|
588
688
|
).length;
|
|
589
689
|
if (matches !== 1) {
|
|
590
690
|
_err(
|
|
@@ -598,7 +698,7 @@ function _validateCombinators(value, schema, inst, sch, root, errors, depth) {
|
|
|
598
698
|
}
|
|
599
699
|
if (
|
|
600
700
|
schema.not !== undefined &&
|
|
601
|
-
_branchValid(value, schema.not, root, depth)
|
|
701
|
+
_branchValid(value, schema.not, root, depth, externalSchemas)
|
|
602
702
|
) {
|
|
603
703
|
_err(
|
|
604
704
|
errors,
|
|
@@ -692,6 +792,8 @@ function _metaValidate(schema, segs, errors, depth) {
|
|
|
692
792
|
"maxItems",
|
|
693
793
|
"minProperties",
|
|
694
794
|
"maxProperties",
|
|
795
|
+
"minContains",
|
|
796
|
+
"maxContains",
|
|
695
797
|
]) {
|
|
696
798
|
if (
|
|
697
799
|
schema[k] !== undefined &&
|
|
@@ -724,6 +826,28 @@ function _metaValidate(schema, segs, errors, depth) {
|
|
|
724
826
|
if (schema.$ref !== undefined && typeof schema.$ref !== "string") {
|
|
725
827
|
_metaErr(errors, "$ref", [...segs, "$ref"], "$ref must be a string");
|
|
726
828
|
}
|
|
829
|
+
for (const k of ["$id", "$schema", "$anchor", "$dynamicAnchor", "$dynamicRef", "$comment"]) {
|
|
830
|
+
if (schema[k] !== undefined && typeof schema[k] !== "string") {
|
|
831
|
+
_metaErr(errors, k, [...segs, k], `${k} must be a string`);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
if (schema.$anchor !== undefined && typeof schema.$anchor === "string" && !/^[A-Za-z][A-Za-z0-9:_-]*$/.test(schema.$anchor)) {
|
|
835
|
+
_metaErr(errors, "$anchor", [...segs, "$anchor"], "$anchor must match the anchor-name syntax");
|
|
836
|
+
}
|
|
837
|
+
if (schema.$dynamicAnchor !== undefined && typeof schema.$dynamicAnchor === "string" && !/^[A-Za-z][A-Za-z0-9:_-]*$/.test(schema.$dynamicAnchor)) {
|
|
838
|
+
_metaErr(errors, "$dynamicAnchor", [...segs, "$dynamicAnchor"], "$dynamicAnchor must match the anchor-name syntax");
|
|
839
|
+
}
|
|
840
|
+
if (schema.$vocabulary !== undefined) {
|
|
841
|
+
if (!schema.$vocabulary || typeof schema.$vocabulary !== "object" || Array.isArray(schema.$vocabulary)) {
|
|
842
|
+
_metaErr(errors, "$vocabulary", [...segs, "$vocabulary"], "$vocabulary must be an object");
|
|
843
|
+
} else {
|
|
844
|
+
for (const [uri, required] of Object.entries(schema.$vocabulary)) {
|
|
845
|
+
if (typeof required !== "boolean") {
|
|
846
|
+
_metaErr(errors, "$vocabulary", [...segs, "$vocabulary", uri], "vocabulary values must be boolean");
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
727
851
|
if (schema.properties !== undefined) {
|
|
728
852
|
if (
|
|
729
853
|
typeof schema.properties !== "object" ||
|
|
@@ -741,6 +865,36 @@ function _metaValidate(schema, segs, errors, depth) {
|
|
|
741
865
|
}
|
|
742
866
|
}
|
|
743
867
|
}
|
|
868
|
+
for (const k of ["patternProperties", "dependentSchemas"]) {
|
|
869
|
+
if (schema[k] === undefined) continue;
|
|
870
|
+
if (typeof schema[k] !== "object" || Array.isArray(schema[k])) {
|
|
871
|
+
_metaErr(errors, k, [...segs, k], `${k} must be an object`);
|
|
872
|
+
} else {
|
|
873
|
+
for (const [name, sub] of Object.entries(schema[k])) {
|
|
874
|
+
if (k === "patternProperties") {
|
|
875
|
+
try { new RegExp(name); } catch (e) { _metaErr(errors, k, [...segs, k, name], `invalid regex: ${e.message}`); }
|
|
876
|
+
}
|
|
877
|
+
_metaValidate(sub, [...segs, k, name], errors, depth + 1);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
if (schema.propertyNames !== undefined) {
|
|
882
|
+
_metaValidate(schema.propertyNames, [...segs, "propertyNames"], errors, depth + 1);
|
|
883
|
+
}
|
|
884
|
+
if (schema.dependentRequired !== undefined) {
|
|
885
|
+
if (typeof schema.dependentRequired !== "object" || Array.isArray(schema.dependentRequired)) {
|
|
886
|
+
_metaErr(errors, "dependentRequired", [...segs, "dependentRequired"], "dependentRequired must be an object");
|
|
887
|
+
} else {
|
|
888
|
+
for (const [key, required] of Object.entries(schema.dependentRequired)) {
|
|
889
|
+
if (!Array.isArray(required) || required.some((v) => typeof v !== "string")) {
|
|
890
|
+
_metaErr(errors, "dependentRequired", [...segs, "dependentRequired", key], "dependentRequired values must be arrays of strings");
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
if (schema.contains !== undefined) {
|
|
896
|
+
_metaValidate(schema.contains, [...segs, "contains"], errors, depth + 1);
|
|
897
|
+
}
|
|
744
898
|
if (
|
|
745
899
|
schema.additionalProperties !== undefined &&
|
|
746
900
|
typeof schema.additionalProperties === "object"
|
|
@@ -21,8 +21,12 @@
|
|
|
21
21
|
|
|
22
22
|
import os from "node:os";
|
|
23
23
|
import fs from "node:fs";
|
|
24
|
-
import { execSync } from "node:child_process";
|
|
25
24
|
import dgram from "node:dgram";
|
|
25
|
+
import executionBroker from "./process-execution-broker/index.js";
|
|
26
|
+
|
|
27
|
+
export const _deps = {
|
|
28
|
+
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
29
|
+
};
|
|
26
30
|
|
|
27
31
|
const MDNS_PORT = 5353;
|
|
28
32
|
const MDNS_GROUP = "224.0.0.251";
|
|
@@ -313,7 +317,14 @@ function which(cmd) {
|
|
|
313
317
|
try {
|
|
314
318
|
const platform = os.platform();
|
|
315
319
|
const probe = platform === "win32" ? "where" : "which";
|
|
316
|
-
|
|
320
|
+
_deps.execFileSync(probe, [cmd], {
|
|
321
|
+
origin: "lan-pairing:firewall-probe",
|
|
322
|
+
scope: "network-diagnostics",
|
|
323
|
+
policy: "allow",
|
|
324
|
+
shell: false,
|
|
325
|
+
stdio: "pipe",
|
|
326
|
+
windowsHide: true,
|
|
327
|
+
});
|
|
317
328
|
return true;
|
|
318
329
|
} catch (_err) {
|
|
319
330
|
return false;
|
|
@@ -109,6 +109,24 @@ describe("plugin server registration", () => {
|
|
|
109
109
|
expect(s).toMatchObject({ id: "zls" });
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
it("returns plugin provenance for Broker-enforced servers", () => {
|
|
113
|
+
registerLanguageServer({
|
|
114
|
+
languageId: "kotlin",
|
|
115
|
+
command: "kotlin-lsp",
|
|
116
|
+
pluginId: "p-kotlin",
|
|
117
|
+
pluginVersion: "1.2.3",
|
|
118
|
+
pluginSource: "/plugins/kotlin/.lsp.json",
|
|
119
|
+
});
|
|
120
|
+
const isWin = process.platform === "win32";
|
|
121
|
+
existsFor([path.join("/proj", "node_modules", ".bin", isWin ? "kotlin-lsp.cmd" : "kotlin-lsp")]);
|
|
122
|
+
expect(resolveServer("kotlin", "/proj")).toMatchObject({
|
|
123
|
+
origin: "plugin:lsp",
|
|
124
|
+
pluginId: "p-kotlin",
|
|
125
|
+
pluginVersion: "1.2.3",
|
|
126
|
+
pluginSource: "/plugins/kotlin/.lsp.json",
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
112
130
|
it("rejects an incomplete registration", () => {
|
|
113
131
|
expect(() => registerLanguageServer({ languageId: "x" })).toThrow(
|
|
114
132
|
/requires/,
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { spawn as nodeSpawn } from "child_process";
|
|
17
17
|
import { EventEmitter } from "events";
|
|
18
18
|
import { encodeMessage, MessageBuffer } from "./jsonrpc-stream.js";
|
|
19
|
+
import { executionBroker } from "../process-execution-broker/index.js";
|
|
19
20
|
|
|
20
21
|
const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
|
|
21
22
|
const DEFAULT_INIT_TIMEOUT_MS = 30_000;
|
|
@@ -41,6 +42,10 @@ export class LSPClient extends EventEmitter {
|
|
|
41
42
|
this.env = opts.env || {};
|
|
42
43
|
this.requestTimeoutMs = opts.requestTimeoutMs || DEFAULT_REQUEST_TIMEOUT_MS;
|
|
43
44
|
this.capabilitiesOverride = opts.capabilities || null;
|
|
45
|
+
this.origin = opts.origin || null;
|
|
46
|
+
this.pluginId = opts.pluginId || null;
|
|
47
|
+
this.pluginVersion = opts.pluginVersion || null;
|
|
48
|
+
this.pluginSource = opts.pluginSource || null;
|
|
44
49
|
|
|
45
50
|
this._child = null;
|
|
46
51
|
this._buffer = new MessageBuffer();
|
|
@@ -73,13 +78,25 @@ export class LSPClient extends EventEmitter {
|
|
|
73
78
|
// fix, so buildSpawnCommand rewrites them to an explicit `cmd.exe /d /s /c`
|
|
74
79
|
// invocation with verbatim args — still no shell, still injection-safe.
|
|
75
80
|
const spawnSpec = buildSpawnCommand(this.command, this.args);
|
|
76
|
-
|
|
81
|
+
const spawnFn = String(this.origin || "").startsWith("plugin:")
|
|
82
|
+
? executionBroker.spawn.bind(executionBroker)
|
|
83
|
+
: _deps.spawn;
|
|
84
|
+
this._child = spawnFn(spawnSpec.file, spawnSpec.args, {
|
|
77
85
|
cwd: this.rootPath,
|
|
78
86
|
env: { ...process.env, ...this.env },
|
|
79
87
|
stdio: ["pipe", "pipe", "pipe"],
|
|
80
88
|
shell: false,
|
|
81
89
|
windowsHide: true,
|
|
82
90
|
windowsVerbatimArguments: spawnSpec.windowsVerbatimArguments,
|
|
91
|
+
...(this.origin
|
|
92
|
+
? {
|
|
93
|
+
origin: this.origin,
|
|
94
|
+
policy: "allow",
|
|
95
|
+
pluginId: this.pluginId,
|
|
96
|
+
pluginVersion: this.pluginVersion,
|
|
97
|
+
pluginSource: this.pluginSource,
|
|
98
|
+
}
|
|
99
|
+
: {}),
|
|
83
100
|
});
|
|
84
101
|
|
|
85
102
|
this._child.on("error", (err) => {
|
|
@@ -239,6 +239,10 @@ export class LSPManager {
|
|
|
239
239
|
command: resolved.command,
|
|
240
240
|
args: resolved.args,
|
|
241
241
|
rootPath: projectRoot,
|
|
242
|
+
origin: resolved.origin,
|
|
243
|
+
pluginId: resolved.pluginId,
|
|
244
|
+
pluginVersion: resolved.pluginVersion,
|
|
245
|
+
pluginSource: resolved.pluginSource,
|
|
242
246
|
});
|
|
243
247
|
// Collect pushed diagnostics keyed by document, tracking publish count/time
|
|
244
248
|
// so callers can wait for the project to load (first publish) and settle
|
|
@@ -95,6 +95,9 @@ export function registerLanguageServer(def) {
|
|
|
95
95
|
bins: [def.command],
|
|
96
96
|
argsFor: () => (Array.isArray(def.args) ? def.args : []),
|
|
97
97
|
fromPlugin: true,
|
|
98
|
+
pluginId: def.pluginId || null,
|
|
99
|
+
pluginVersion: def.pluginVersion || null,
|
|
100
|
+
pluginSource: def.pluginSource || null,
|
|
98
101
|
};
|
|
99
102
|
const existing = pluginServers.get(def.languageId) || [];
|
|
100
103
|
// De-dupe by server id so re-registering the same server (e.g. a reload)
|
|
@@ -147,6 +150,14 @@ export function resolveServer(languageId, projectRoot) {
|
|
|
147
150
|
id: def.id,
|
|
148
151
|
command,
|
|
149
152
|
args: def.argsFor(bin),
|
|
153
|
+
...(def.fromPlugin
|
|
154
|
+
? {
|
|
155
|
+
origin: "plugin:lsp",
|
|
156
|
+
pluginId: def.pluginId,
|
|
157
|
+
pluginVersion: def.pluginVersion,
|
|
158
|
+
pluginSource: def.pluginSource,
|
|
159
|
+
}
|
|
160
|
+
: {}),
|
|
150
161
|
};
|
|
151
162
|
}
|
|
152
163
|
}
|