chainlesschain 0.162.149 → 0.162.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +3 -2
- package/src/assets/web-panel/assets/{AIOps-BJif14yR.js → AIOps-DuEOzebi.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CXek6gJY.js → ActionButton-C6GiJa5H.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BgQhdAJi.js → Analytics-BBIiL_pO.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DTYl5NtR.js → AppLayout-CuI2gZRy.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-BzATQAeR.js → Audit-CbUjfr-K.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BzdPEQhL.js → Backup-CsSW9ljf.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BM0KVh8E.js → BaseInput-kM3rLe7F.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D7fHXHkz.js → Chat-kfE51YN3.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Wm34RR-b.js → ChatBubbleRenderer-Bg2FTW6A.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CAiSQ9vO.js → Checkbox-jYb1uj-M.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Df40CrEe.js → Codegen-X9XiD5Lj.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DIT2fNFU.js → Col-BfbHu1xI.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CSTIbW2k.js → Community-c4oJMFS-.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DtqXZZUi.js → Compact-BFmnZpH7.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CUtzw6o7.js → Compliance-s9shVHBS.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CezmlnmU.js → Cowork-C5da--TC.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-P4BITarg.js → Cron-9kNbyNE4.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BRRiYwvq.js → Crosschain-C1k3NJD4.js} +1 -1
- package/src/assets/web-panel/assets/{DID-L5ijB9i4.js → DID-DkheEvNK.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CFxro4ob.js → Dashboard-C3FuSGmJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BmAFCQ71.js → Dropdown-CAV6FMFD.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DJBCEuon.js → EmailListRenderer-Cc-Ulc4l.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-z4oLq6eT.js → FamilyGuardDashboard-8CitHEtv.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DsVCpHMF.js → Federation-DFSZ5KDt.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DP3bP5th.js → FormItemContext-CEWCtnG2.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BAXP2Gc6.js → GenericCardRenderer-CwRzNzmX.js} +1 -1
- package/src/assets/web-panel/assets/{Git-I3g_bAw9.js → Git-0rgDM7cJ.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-jHS5-ioS.js → Governance-CfBKtK9F.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CPL7sfx9.js → Inference-CzcUVvud.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Jf236h4C.js → KnowledgeGraph-Dwc4YL4A.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Cm2tcSKg.js → Logs-DgFPwR2F.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-CZK82rhi.js → Marketplace-DnpPTbGU.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CZCeji7a.js → McpTools-DRxxINyW.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-3l2KVS9k.js → Memory-OhmW_6Z3.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-VYdpoLh6.js → MobileBridge-DkTW-RK5.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CiB9cmm1.js → MobileProjects-DpCGV_lI.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-wCFZbBuL.js → Mtc--vmkL0AS.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-1a3THIyG.js → MtcAudit-DGoFWjD4.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DMzLB2hG.js → Multisig-B4kWgq95.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D9wZbf6l.js → NLProgramming-YQwvommE.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-hrFe2ZM-.js → Notes-CgjtUADJ.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CHGX5Jwm.js → NotificationSettings-6JDrpBG5.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-PM6IlxjO.js +1 -0
- package/src/assets/web-panel/assets/{Organization-By7FkhtY.js → Organization-8McOT_OF.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow--khGSzJn.js → Overflow-DAZpSCGc.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CAG9dH35.js → P2P-B7l2ZWLy.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-B3SQZmK9.js → PdhVaultBrowser-W1Ud-NAL.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D35ec6JA.js → Permissions-Czm_w9u_.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CxBF7hW_.js → PersonalDataHub-B4F0_ZVM.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-s6EtOO1s.js → Pipeline-B37aFiWv.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BbJYmWmO.js → Privacy-94KBnRrD.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-VGQq1jMT.js → ProjectInit-B5h8_dlh.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-B1ew3Teh.js → ProjectSettings-lmeI3Lpm.js} +2 -2
- package/src/assets/web-panel/assets/Projects-D5AYOasl.js +1 -0
- package/src/assets/web-panel/assets/{Providers-mrO47FIK.js → Providers-B3cNWwJg.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-IJF2mHyw.js → QrScannerModal-CHRvOw1R.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CU0wN_Z0.js → QuickAsk-D1JMgFEd.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DhN37R6G.js → Recommend-EYWGR79p.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-D_xOX_hu.js → RemoteSession-BAMC2pJt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-D_Ssv7uH.js → Reputation-X2Hk1XG_.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Kx5dKxX7.js → Row-Eq98LRtU.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BlGwqZkY.js → RssFeed-i76s6z_o.js} +2 -2
- package/src/assets/web-panel/assets/{Search-hLFQzxpb.js → Search-D_Es7CAI.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DMlvsVt4.js → Security-kayD2e94.js} +3 -3
- package/src/assets/web-panel/assets/{Services-Bd0Qsj2m.js → Services-Ctsm6ul8.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DFclq9X3.js → Skeleton-CRNYlfdf.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BNtln2qY.js → Skills-DkZYpF4-.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Dch5H19G.js → Sla-DXkoBcOP.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-2UfQcU1g.js → SpeechSettings-DXi_GI1d.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CD9YQr4i.js → SyncSettings-rNKpfomn.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BNu-7MzI.js → Tasks-XF4uPtG-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D1n9CaIR.js → Templates-i0Hzfeyu.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DenL3iBW.js → Tenant-sMpHAi27.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-BoZvaYAl.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-D87IfukO.js → TimelineRenderer-yuC6K7Rf.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BkiZc8E3.js → Tokens-B8O8i0s6.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BNRSytGN.js → Trigger-Bv6yrlCr.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Bwbd4X2m.js → Trust-C4mW95Ev.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B8O2bs0o.js → UkeySign-DV6yKaHn.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C2fL8zmH.js → VideoEditing-UI479-sD.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BORYDdE1.js → Wallet-M5oV9EVP.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C0V5S2FM.js → WebAuthn-DDyDHPDR.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-2dR0fcHL.js → WorkflowEditor-RoBv4rqk.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BmuAFAn8.js → chat-Cw1mE5LS.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CN3smMcK.js → colors-BFP62Gwf.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DCnxb4kW.js → compact-item-17HL6pyC.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-vlR43pHn.js → createContext-D55X4fZX.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CqbHYuRc.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-D04tHYFd.js → hasIn-D3E5mNsP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbVsQBOH.js → index--44J50mc.js} +1 -1
- package/src/assets/web-panel/assets/{index-TslMTwNy.js → index-ASPYTzMK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTOCnIQ7.js → index-BC6zxOlU.js} +1 -1
- package/src/assets/web-panel/assets/{index-ljuBiQW9.js → index-BEa1RW4c.js} +1 -1
- package/src/assets/web-panel/assets/{index-jzR7Ujuw.js → index-BQmZg5si.js} +1 -1
- package/src/assets/web-panel/assets/{index-BudvKQfG.js → index-BY_xZ2jy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CP9m9Ggr.js → index-BgN5G5vF.js} +3 -3
- package/src/assets/web-panel/assets/{index-Cr-A0FYJ.js → index-BnGpft-Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5LZVZ0L.js → index-Bq83UBDr.js} +1 -1
- package/src/assets/web-panel/assets/{index-ToUh2b1-.js → index-Bzpp2z2S.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbADHwhr.js → index-CFYGn88j.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClhAHDK3.js → index-CGyTos4p.js} +1 -1
- package/src/assets/web-panel/assets/index-CKBI1U5K.js +1 -0
- package/src/assets/web-panel/assets/{index-C-6NO5il.js → index-CLEzsZ8A.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8vwp4qp.js → index-CR9rNUvi.js} +1 -1
- package/src/assets/web-panel/assets/{index-_FIkN3jd.js → index-CW6LLoJO.js} +1 -1
- package/src/assets/web-panel/assets/{index-D65_XseV.js → index-C_MfcrLf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnXebZLL.js → index-Cdvk2_2q.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_n8_vfI.js → index-CjCwi7we.js} +1 -1
- package/src/assets/web-panel/assets/index-CkLp6DTO.js +1 -0
- package/src/assets/web-panel/assets/{index-DDwLgQY9.js → index-CvCFKojj.js} +1 -1
- package/src/assets/web-panel/assets/{index-430S68MN.js → index-D4LHSde4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXRg8GFQ.js → index-DCLu84x-.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTtRscUa.js → index-DD_qGBrt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BasvsWDM.js → index-DIRvdwBX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeGDEXFs.js → index-DOjA8bvj.js} +1 -1
- package/src/assets/web-panel/assets/{index-CsAsCPJ6.js → index-Da27u6j0.js} +1 -1
- package/src/assets/web-panel/assets/{index-D28DeAAB.js → index-DkBVYlE4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CngCC8hC.js → index-DtAnPBWP.js} +1 -1
- package/src/assets/web-panel/assets/{index-B78xL3s2.js → index-DzG7mkgW.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIpY0qM5.js → index-H9_X1Cg_.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5Sxb1sE.js → index-ITeEHb8L.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTPEZTk1.js → index-KtLJXn4s.js} +1 -1
- package/src/assets/web-panel/assets/{index-hpvvtAZ3.js → index-RYZgFIwo.js} +1 -1
- package/src/assets/web-panel/assets/{index-HhNjnCfe.js → index-gAVxDiTZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTWg-18U.js → index-paVubXzn.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqhASEL4.js → index-tUH_6bdJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYAtmqiv.js → index-tVRPgYGr.js} +1 -1
- package/src/assets/web-panel/assets/{index-0DnaZGkC.js → index-uSsiwgZ2.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C3wUb4je.js → initDefaultProps-Ckp7xVZS.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D-jYFUNA.js → motion-DUZgCpn6.js} +1 -1
- package/src/assets/web-panel/assets/{move-tqb8nwJ2.js → move-B2rttglH.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DSOjMJMz.js → mtc-parser-BYWcLTuN.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CJ7VimIW.js → omit-DhHqKeFx.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-qXiG1iT3.js → pickAttrs-ANpJaWMO.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CkGBcy1Z.js → placementArrow-CfZWe7CA.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D3WvTlLO.js → responsiveObserve-D7Xz2y-R.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BEE2ftge.js → slide-DekqCBY9.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CsfBpxiG.js → statusUtils-BET6XU7h.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-xPrIiJPI.js → styleChecker-qHmJjV62.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-C5Yd-SCR.js → useFlexGapSupport-BoMCTNyu.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-D_MDS8HI.js → useFs-TdW-NgFC.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BqJh-usA.js → usePersonalDataHub-Dyox7wCu.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-chm_p-gz.js → vnode-XUn5S8CP.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-3-YDNz0Z.js → zoom-Ls77i8hn.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-manifest.json +8 -1
- package/src/commands/a2a.js +19 -4
- package/src/commands/activitypub.js +20 -3
- package/src/commands/agent.js +27 -5
- package/src/commands/audit.js +40 -24
- package/src/commands/changelog.js +148 -0
- package/src/commands/codeintel.js +68 -0
- package/src/commands/collab.js +15 -2
- package/src/commands/compliance.js +5 -0
- package/src/commands/config.js +4 -1
- package/src/commands/dao.js +86 -14
- package/src/commands/dev.js +2 -0
- package/src/commands/did.js +7 -1
- package/src/commands/dlp.js +23 -1
- package/src/commands/economy.js +29 -3
- package/src/commands/eval.js +7 -0
- package/src/commands/evomap.js +26 -0
- package/src/commands/governance.js +17 -3
- package/src/commands/hardening.js +18 -0
- package/src/commands/incentive.js +5 -0
- package/src/commands/init.js +46 -2
- package/src/commands/kg.js +4 -0
- package/src/commands/loop.js +6 -1
- package/src/commands/lowcode.js +15 -2
- package/src/commands/marketplace.js +40 -6
- package/src/commands/matrix.js +20 -1
- package/src/commands/memory.js +4 -1
- package/src/commands/mtc.js +7 -1
- package/src/commands/nostr.js +31 -4
- package/src/commands/note.js +7 -4
- package/src/commands/plugin.js +125 -5
- package/src/commands/pqc.js +5 -0
- package/src/commands/reputation.js +10 -1
- package/src/commands/scim.js +6 -0
- package/src/commands/session.js +32 -10
- package/src/commands/siem.js +11 -0
- package/src/commands/sla.js +18 -3
- package/src/commands/social.js +38 -5
- package/src/commands/sso.js +10 -2
- package/src/commands/stress.js +23 -4
- package/src/commands/team.js +9 -2
- package/src/commands/tech.js +2 -0
- package/src/commands/tenant.js +10 -1
- package/src/commands/terraform.js +6 -0
- package/src/commands/update.js +1 -1
- package/src/commands/zkp.js +20 -0
- package/src/data/changelog.json +189 -0
- package/src/gateways/ws/message-dispatcher.js +5 -2
- package/src/gateways/ws/remote-session-protocol.js +110 -42
- package/src/harness/jsonl-session-store.js +12 -5
- package/src/harness/plugin-manager.js +16 -4
- package/src/harness/remote-command-ledger.js +46 -15
- package/src/harness/worktree-isolator.js +16 -6
- package/src/index.js +2 -0
- package/src/lib/__tests__/logger.test.js +5 -2
- package/src/lib/a2a-protocol.js +25 -1
- package/src/lib/activitypub-bridge.js +61 -0
- package/src/lib/agent-core.js +2 -0
- package/src/lib/agent-economy.js +262 -29
- package/src/lib/agent-network.js +7 -1
- package/src/lib/agent-team/team-runner.js +25 -9
- package/src/lib/agent-team/team-worktree.js +36 -4
- package/src/lib/async-hook-supervisor.cjs +102 -16
- package/src/lib/audit-logger.js +7 -6
- package/src/lib/autonomous-developer.js +60 -0
- package/src/lib/changelog.js +252 -0
- package/src/lib/chat-core.js +17 -4
- package/src/lib/collaboration-governance.js +56 -0
- package/src/lib/community-governance.js +68 -0
- package/src/lib/compliance-manager.js +63 -0
- package/src/lib/cross-chain.js +5 -0
- package/src/lib/dao-governance.js +151 -2
- package/src/lib/did-manager.js +23 -10
- package/src/lib/dlp-engine.js +70 -0
- package/src/lib/eval/runner.js +89 -1
- package/src/lib/eval/tasks.js +170 -0
- package/src/lib/eval/trend.js +16 -1
- package/src/lib/evolution-system.js +92 -0
- package/src/lib/evomap-federation.js +55 -0
- package/src/lib/evomap-governance.js +94 -0
- package/src/lib/fatal-handler.js +17 -1
- package/src/lib/hardening-manager.js +73 -0
- package/src/lib/hierarchical-memory.js +14 -8
- package/src/lib/knowledge-exporter.js +8 -2
- package/src/lib/knowledge-graph.js +79 -0
- package/src/lib/llm-providers.js +23 -14
- package/src/lib/logger.js +4 -1
- package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +11 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +69 -0
- package/src/lib/lsp/benchmark.js +257 -0
- package/src/lib/lsp/lsp-client.js +30 -9
- package/src/lib/lsp/lsp-manager.js +54 -2
- package/src/lib/lsp/lsp-server-registry.js +15 -4
- package/src/lib/matrix-bridge.js +84 -0
- package/src/lib/memory-manager.js +5 -3
- package/src/lib/nostr-bridge.js +53 -0
- package/src/lib/permission-engine.js +22 -4
- package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
- package/src/lib/plugin-runtime/hooks.js +20 -4
- package/src/lib/plugin-runtime/install.js +9 -1
- package/src/lib/plugin-runtime/monitors.js +20 -4
- package/src/lib/plugin-runtime/policy.js +9 -1
- package/src/lib/plugin-runtime/remote-source.js +240 -0
- package/src/lib/plugin-runtime/signature.js +16 -0
- package/src/lib/pqc-manager.js +64 -0
- package/src/lib/reputation-optimizer.js +101 -0
- package/src/lib/sandbox-egress-proxy.js +195 -59
- package/src/lib/sandbox-fs-policy.js +112 -0
- package/src/lib/sandbox-network-policy.js +44 -5
- package/src/lib/sandbox-v2.js +14 -14
- package/src/lib/scim-manager.js +36 -0
- package/src/lib/session-manager.js +5 -2
- package/src/lib/settings-hooks.cjs +1 -0
- package/src/lib/siem-exporter.js +45 -0
- package/src/lib/skill-loader.js +20 -2
- package/src/lib/skill-marketplace.js +83 -0
- package/src/lib/sla-manager.js +88 -0
- package/src/lib/social-manager.js +74 -0
- package/src/lib/stress-tester.js +65 -0
- package/src/lib/tech-learning-engine.js +75 -0
- package/src/lib/telemetry/span-recorder.js +12 -1
- package/src/lib/tenant-saas.js +107 -0
- package/src/lib/terraform-manager.js +67 -0
- package/src/lib/token-incentive.js +180 -29
- package/src/lib/wallet-manager.js +81 -35
- package/src/lib/zkp-engine.js +87 -0
- package/src/repl/agent-repl.js +17 -2
- package/src/runtime/__tests__/auto-pin.test.js +104 -0
- package/src/runtime/agent-core.js +241 -68
- package/src/runtime/auto-pin.js +117 -0
- package/src/runtime/headless-runner.js +35 -0
- package/src/assets/web-panel/assets/OrderTableRenderer-CRIFE2Tj.js +0 -1
- package/src/assets/web-panel/assets/Projects-CGcNIs_g.js +0 -1
- package/src/assets/web-panel/assets/Terminal-ZzU0Io1Y.js +0 -3
- package/src/assets/web-panel/assets/devWarning-DxwmsL4j.js +0 -1
- package/src/assets/web-panel/assets/index-Cg2ldRfU.js +0 -1
- package/src/assets/web-panel/assets/index-Dwzo-dtJ.js +0 -1
|
@@ -67,6 +67,79 @@ export function ensureHardeningTables(db) {
|
|
|
67
67
|
`);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Rehydrate _baselines/_audits from the persisted performance_baselines/
|
|
72
|
+
* hardening_audits tables. The `cc` CLI runs every command in a fresh process,
|
|
73
|
+
* so without this the Maps start empty and a baseline/audit collected in a
|
|
74
|
+
* prior invocation is invisible (`cc hardening baseline list`/`audit reports`
|
|
75
|
+
* show nothing; `baseline compare`/`audit report <id>` throw "not found"; and —
|
|
76
|
+
* most damagingly — `cc hardening deploy-check` reports "No baseline / No audit"
|
|
77
|
+
* and yields a silently-wrong go/no-go verdict even when the rows exist). Call
|
|
78
|
+
* after ensureHardeningTables(db).
|
|
79
|
+
*/
|
|
80
|
+
export function loadFromDb(db) {
|
|
81
|
+
if (!db) return 0;
|
|
82
|
+
_baselines.clear();
|
|
83
|
+
_audits.clear();
|
|
84
|
+
|
|
85
|
+
const baselineRows = db.prepare(`SELECT * FROM performance_baselines`).all();
|
|
86
|
+
for (const row of baselineRows) {
|
|
87
|
+
let metrics = {};
|
|
88
|
+
let environment = {};
|
|
89
|
+
try {
|
|
90
|
+
metrics = row.metrics ? JSON.parse(row.metrics) : {};
|
|
91
|
+
} catch {
|
|
92
|
+
metrics = {};
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
environment = row.environment ? JSON.parse(row.environment) : {};
|
|
96
|
+
} catch {
|
|
97
|
+
environment = {};
|
|
98
|
+
}
|
|
99
|
+
_baselines.set(row.id, {
|
|
100
|
+
id: row.id,
|
|
101
|
+
name: row.name,
|
|
102
|
+
version: row.version,
|
|
103
|
+
status: row.status,
|
|
104
|
+
metrics,
|
|
105
|
+
environment,
|
|
106
|
+
sampleCount: row.sample_count ?? 0,
|
|
107
|
+
createdAt: row.created_at ?? null,
|
|
108
|
+
completedAt: row.completed_at ?? null,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const auditRows = db.prepare(`SELECT * FROM hardening_audits`).all();
|
|
113
|
+
for (const row of auditRows) {
|
|
114
|
+
let checks = [];
|
|
115
|
+
let recommendations = [];
|
|
116
|
+
try {
|
|
117
|
+
checks = row.checks ? JSON.parse(row.checks) : [];
|
|
118
|
+
} catch {
|
|
119
|
+
checks = [];
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
recommendations = row.recommendations
|
|
123
|
+
? JSON.parse(row.recommendations)
|
|
124
|
+
: [];
|
|
125
|
+
} catch {
|
|
126
|
+
recommendations = [];
|
|
127
|
+
}
|
|
128
|
+
_audits.set(row.id, {
|
|
129
|
+
id: row.id,
|
|
130
|
+
name: row.name,
|
|
131
|
+
checks,
|
|
132
|
+
passed: row.passed ?? 0,
|
|
133
|
+
failed: row.failed ?? 0,
|
|
134
|
+
score: row.score ?? 0,
|
|
135
|
+
recommendations,
|
|
136
|
+
createdAt: row.created_at ?? null,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return _baselines.size + _audits.size;
|
|
141
|
+
}
|
|
142
|
+
|
|
70
143
|
/* ── Baseline Collection ──────────────────────────────────── */
|
|
71
144
|
|
|
72
145
|
export function collectBaseline(db, name, version) {
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* with Ebbinghaus forgetting curve and spacing effect reinforcement.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { escapeLike } from "./sql-like.js";
|
|
9
|
+
|
|
8
10
|
// ─── Configuration ───────────────────────────────────────────────
|
|
9
11
|
export const MEMORY_CONFIG = {
|
|
10
12
|
workingCapacity: 50,
|
|
@@ -292,8 +294,10 @@ export function recallMemory(db, query, options = {}) {
|
|
|
292
294
|
// Search long-term memory (DB)
|
|
293
295
|
ensureMemoryTables(db);
|
|
294
296
|
const ltRows = db
|
|
295
|
-
.prepare(
|
|
296
|
-
|
|
297
|
+
.prepare(
|
|
298
|
+
`SELECT * FROM memory_long_term WHERE content LIKE ? ESCAPE '\\' LIMIT ?`,
|
|
299
|
+
)
|
|
300
|
+
.all(`%${escapeLike(query)}%`, limit);
|
|
297
301
|
for (const row of ltRows) {
|
|
298
302
|
const retention = calcRetention(row.last_accessed);
|
|
299
303
|
if (retention >= MEMORY_CONFIG.recallThreshold) {
|
|
@@ -316,8 +320,10 @@ export function recallMemory(db, query, options = {}) {
|
|
|
316
320
|
|
|
317
321
|
// Search core memory (DB) — core memories don't decay
|
|
318
322
|
const coreRows = db
|
|
319
|
-
.prepare(
|
|
320
|
-
|
|
323
|
+
.prepare(
|
|
324
|
+
`SELECT * FROM memory_core WHERE content LIKE ? ESCAPE '\\' LIMIT ?`,
|
|
325
|
+
)
|
|
326
|
+
.all(`%${escapeLike(query)}%`, limit);
|
|
321
327
|
for (const row of coreRows) {
|
|
322
328
|
db.prepare(
|
|
323
329
|
`UPDATE memory_core SET access_count = access_count + 1, last_accessed = ? WHERE id = ?`,
|
|
@@ -444,9 +450,9 @@ function _searchByType(db, query, type, options = {}) {
|
|
|
444
450
|
ensureMemoryTables(db);
|
|
445
451
|
const ltRows = db
|
|
446
452
|
.prepare(
|
|
447
|
-
`SELECT * FROM memory_long_term WHERE type = ? AND content LIKE ? LIMIT ?`,
|
|
453
|
+
`SELECT * FROM memory_long_term WHERE type = ? AND content LIKE ? ESCAPE '\\' LIMIT ?`,
|
|
448
454
|
)
|
|
449
|
-
.all(type, `%${query}%`, limit);
|
|
455
|
+
.all(type, `%${escapeLike(query)}%`, limit);
|
|
450
456
|
for (const row of ltRows) {
|
|
451
457
|
results.push({
|
|
452
458
|
id: row.id,
|
|
@@ -462,9 +468,9 @@ function _searchByType(db, query, type, options = {}) {
|
|
|
462
468
|
|
|
463
469
|
const coreRows = db
|
|
464
470
|
.prepare(
|
|
465
|
-
`SELECT * FROM memory_core WHERE type = ? AND content LIKE ? LIMIT ?`,
|
|
471
|
+
`SELECT * FROM memory_core WHERE type = ? AND content LIKE ? ESCAPE '\\' LIMIT ?`,
|
|
466
472
|
)
|
|
467
|
-
.all(type, `%${query}%`, limit);
|
|
473
|
+
.all(type, `%${escapeLike(query)}%`, limit);
|
|
468
474
|
for (const row of coreRows) {
|
|
469
475
|
results.push({
|
|
470
476
|
id: row.id,
|
|
@@ -78,7 +78,10 @@ export function sanitizeFilename(name) {
|
|
|
78
78
|
* Convert a note to markdown with YAML frontmatter.
|
|
79
79
|
*/
|
|
80
80
|
export function noteToMarkdown(note) {
|
|
81
|
-
|
|
81
|
+
// safeJsonParse (not bare JSON.parse): exportToMarkdown loops over every note,
|
|
82
|
+
// so one corrupt/hand-edited `tags` cell would otherwise throw and abort the
|
|
83
|
+
// ENTIRE export mid-way. Matches generateIndexHtml, which already guards.
|
|
84
|
+
const tags = safeJsonParse(note.tags, []);
|
|
82
85
|
const lines = [
|
|
83
86
|
"---",
|
|
84
87
|
`title: "${note.title.replace(/"/g, '\\"')}"`,
|
|
@@ -136,7 +139,10 @@ export function exportToMarkdown(db, outputDir, options = {}) {
|
|
|
136
139
|
* Generate a minimal HTML page for a note.
|
|
137
140
|
*/
|
|
138
141
|
export function noteToHtml(note) {
|
|
139
|
-
|
|
142
|
+
// safeJsonParse (not bare JSON.parse): exportToSite loops over every note, so
|
|
143
|
+
// one corrupt `tags` cell would otherwise throw and abort the whole site
|
|
144
|
+
// export — after index.html was already written, leaving dangling links.
|
|
145
|
+
const tags = safeJsonParse(note.tags, []);
|
|
140
146
|
const tagsHtml = tags
|
|
141
147
|
.map((t) => `<span class="tag">${escapeHtml(t)}</span>`)
|
|
142
148
|
.join(" ");
|
|
@@ -95,6 +95,85 @@ export function ensureKnowledgeGraphTables(db) {
|
|
|
95
95
|
);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Hydrate the in-memory graph from the DB. The CLI is one-shot: _entities/
|
|
100
|
+
* _relations/_outEdges/_inEdges start empty every process. Writes dual-write
|
|
101
|
+
* (Map + INSERT), but every read is Map-only and nothing ever SELECTed the
|
|
102
|
+
* tables back — so persisted entities/relations were invisible on the next
|
|
103
|
+
* invocation (list/show/stats/export empty; add-relation threw "Source entity
|
|
104
|
+
* not found"; remove returned false and left the row). Call after
|
|
105
|
+
* ensureKnowledgeGraphTables(db).
|
|
106
|
+
*/
|
|
107
|
+
export function loadFromDb(db) {
|
|
108
|
+
if (!db) return 0;
|
|
109
|
+
ensureKnowledgeGraphTables(db);
|
|
110
|
+
_entities.clear();
|
|
111
|
+
_relations.clear();
|
|
112
|
+
_outEdges.clear();
|
|
113
|
+
_inEdges.clear();
|
|
114
|
+
|
|
115
|
+
const entityRows = db
|
|
116
|
+
.prepare(
|
|
117
|
+
`SELECT id, name, type, properties, tags, created_at, updated_at
|
|
118
|
+
FROM kg_entities ORDER BY created_at ASC`,
|
|
119
|
+
)
|
|
120
|
+
.all();
|
|
121
|
+
for (const r of entityRows) {
|
|
122
|
+
// A single corrupt properties/tags cell must not crash the whole load.
|
|
123
|
+
let properties = null;
|
|
124
|
+
let tags = null;
|
|
125
|
+
try {
|
|
126
|
+
properties = r.properties ? JSON.parse(r.properties) : null;
|
|
127
|
+
} catch {
|
|
128
|
+
properties = null;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
tags = r.tags ? JSON.parse(r.tags) : null;
|
|
132
|
+
} catch {
|
|
133
|
+
tags = null;
|
|
134
|
+
}
|
|
135
|
+
_entities.set(r.id, {
|
|
136
|
+
id: r.id,
|
|
137
|
+
name: r.name,
|
|
138
|
+
type: r.type,
|
|
139
|
+
properties,
|
|
140
|
+
tags,
|
|
141
|
+
createdAt: Number(r.created_at),
|
|
142
|
+
updatedAt: Number(r.updated_at),
|
|
143
|
+
_seq: ++_seq,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const relationRows = db
|
|
148
|
+
.prepare(
|
|
149
|
+
`SELECT id, source_id, target_id, relation_type, weight, properties, created_at
|
|
150
|
+
FROM kg_relationships ORDER BY created_at ASC`,
|
|
151
|
+
)
|
|
152
|
+
.all();
|
|
153
|
+
for (const r of relationRows) {
|
|
154
|
+
let properties = null;
|
|
155
|
+
try {
|
|
156
|
+
properties = r.properties ? JSON.parse(r.properties) : null;
|
|
157
|
+
} catch {
|
|
158
|
+
properties = null;
|
|
159
|
+
}
|
|
160
|
+
const relation = {
|
|
161
|
+
id: r.id,
|
|
162
|
+
sourceId: r.source_id,
|
|
163
|
+
targetId: r.target_id,
|
|
164
|
+
relationType: r.relation_type,
|
|
165
|
+
weight: Number(r.weight),
|
|
166
|
+
properties,
|
|
167
|
+
createdAt: Number(r.created_at),
|
|
168
|
+
_seq: ++_seq,
|
|
169
|
+
};
|
|
170
|
+
_relations.set(r.id, relation);
|
|
171
|
+
_indexRelation(relation);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return _entities.size + _relations.size;
|
|
175
|
+
}
|
|
176
|
+
|
|
98
177
|
/* ── Catalogs ──────────────────────────────────────────────── */
|
|
99
178
|
|
|
100
179
|
export function listEntityTypes() {
|
package/src/lib/llm-providers.js
CHANGED
|
@@ -292,20 +292,29 @@ export class LLMProviderRegistry {
|
|
|
292
292
|
if (!this.providers.has(name)) {
|
|
293
293
|
throw new Error(`Provider "${name}" not found`);
|
|
294
294
|
}
|
|
295
|
-
//
|
|
296
|
-
|
|
297
|
-
//
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
295
|
+
// Clear every active flag then mark the new provider active atomically.
|
|
296
|
+
// Without a transaction, a failure on the second statement leaves NO
|
|
297
|
+
// provider active — which getActive() silently masks as the "ollama"
|
|
298
|
+
// fallback, so a failed switch would quietly lose the current provider.
|
|
299
|
+
const applyWrites = () => {
|
|
300
|
+
this.db.prepare("UPDATE llm_providers SET is_active = 0 WHERE 1=1").run();
|
|
301
|
+
this.db
|
|
302
|
+
.prepare(
|
|
303
|
+
"INSERT OR REPLACE INTO llm_providers (name, display_name, base_url, api_key_env, models, is_active) VALUES (?, ?, ?, ?, ?, 1)",
|
|
304
|
+
)
|
|
305
|
+
.run(
|
|
306
|
+
name,
|
|
307
|
+
this.providers.get(name).displayName,
|
|
308
|
+
this.providers.get(name).baseUrl,
|
|
309
|
+
this.providers.get(name).apiKeyEnv,
|
|
310
|
+
JSON.stringify(this.providers.get(name).models),
|
|
311
|
+
);
|
|
312
|
+
};
|
|
313
|
+
if (this.db && typeof this.db.transaction === "function") {
|
|
314
|
+
this.db.transaction(applyWrites)();
|
|
315
|
+
} else {
|
|
316
|
+
applyWrites();
|
|
317
|
+
}
|
|
309
318
|
return this.providers.get(name);
|
|
310
319
|
}
|
|
311
320
|
|
package/src/lib/logger.js
CHANGED
|
@@ -24,7 +24,10 @@ export function success(message, ...args) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export function warn(message, ...args) {
|
|
27
|
-
|
|
27
|
+
// stderr, not stdout: a warning must never interleave with a command's
|
|
28
|
+
// machine-readable stdout (e.g. `--json` payloads), which `| jq` and other
|
|
29
|
+
// consumers parse. Like error(), warn is never gated by quiet mode.
|
|
30
|
+
console.error(chalk.yellow("⚠"), message, ...args);
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
export function error(message, ...args) {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* benchmark stats tests — the pure percentile/summarize helpers that turn raw
|
|
3
|
+
* latency samples into a report. No spawning; the harness itself is exercised by
|
|
4
|
+
* the live `cc code-intel bench` run.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect } from "vitest";
|
|
8
|
+
import {
|
|
9
|
+
percentile,
|
|
10
|
+
summarize,
|
|
11
|
+
sumSubtreeRss,
|
|
12
|
+
sumSubtreeRssFromWmicCsv,
|
|
13
|
+
} from "../benchmark.js";
|
|
14
|
+
|
|
15
|
+
describe("percentile", () => {
|
|
16
|
+
it("returns the value for a single sample", () => {
|
|
17
|
+
expect(percentile([5], 50)).toBe(5);
|
|
18
|
+
expect(percentile([5], 95)).toBe(5);
|
|
19
|
+
});
|
|
20
|
+
it("computes median and p95 with interpolation", () => {
|
|
21
|
+
const s = [10, 20, 30, 40, 50];
|
|
22
|
+
expect(percentile(s, 50)).toBe(30);
|
|
23
|
+
// p95 of 5 points: rank = 0.95*4 = 3.8 → 40 + (50-40)*0.8 = 48
|
|
24
|
+
expect(percentile(s, 95)).toBeCloseTo(48, 5);
|
|
25
|
+
});
|
|
26
|
+
it("is order-independent (sorts internally)", () => {
|
|
27
|
+
expect(percentile([50, 10, 30, 40, 20], 50)).toBe(30);
|
|
28
|
+
});
|
|
29
|
+
it("returns null for an empty sample", () => {
|
|
30
|
+
expect(percentile([], 50)).toBeNull();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("summarize", () => {
|
|
35
|
+
it("reports n/min/median/p95/max/mean rounded to 0.1ms", () => {
|
|
36
|
+
const s = summarize([12.34, 5.6, 8.9, 20.1, 3.33]);
|
|
37
|
+
expect(s.n).toBe(5);
|
|
38
|
+
expect(s.min).toBe(3.3);
|
|
39
|
+
expect(s.max).toBe(20.1);
|
|
40
|
+
expect(s.median).toBe(8.9);
|
|
41
|
+
expect(s.mean).toBe(10.1); // (12.34+5.6+8.9+20.1+3.33)/5 = 10.054 → 10.1
|
|
42
|
+
});
|
|
43
|
+
it("handles an empty sample", () => {
|
|
44
|
+
expect(summarize([])).toEqual({ n: 0 });
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("sumSubtreeRss", () => {
|
|
49
|
+
// launcher(100) → node server(200) → worker(300); sibling(400) unrelated
|
|
50
|
+
const rows = [
|
|
51
|
+
{ pid: 100, ppid: 1, val: 5 },
|
|
52
|
+
{ pid: 200, ppid: 100, val: 120 },
|
|
53
|
+
{ pid: 300, ppid: 200, val: 40 },
|
|
54
|
+
{ pid: 400, ppid: 1, val: 999 },
|
|
55
|
+
];
|
|
56
|
+
it("sums a pid and all its transitive descendants (not the launcher alone)", () => {
|
|
57
|
+
expect(sumSubtreeRss(rows, 100)).toBe(165); // 5 + 120 + 40
|
|
58
|
+
});
|
|
59
|
+
it("returns just the leaf when it has no children", () => {
|
|
60
|
+
expect(sumSubtreeRss(rows, 300)).toBe(40);
|
|
61
|
+
});
|
|
62
|
+
it("returns null when the root pid is absent", () => {
|
|
63
|
+
expect(sumSubtreeRss(rows, 555)).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
it("does not loop on a cyclic parent relationship", () => {
|
|
66
|
+
const cyclic = [
|
|
67
|
+
{ pid: 1, ppid: 2, val: 10 },
|
|
68
|
+
{ pid: 2, ppid: 1, val: 20 },
|
|
69
|
+
];
|
|
70
|
+
expect(sumSubtreeRss(cyclic, 1)).toBe(30);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe("sumSubtreeRssFromWmicCsv", () => {
|
|
75
|
+
it("parses wmic CSV and sums the subtree in bytes", () => {
|
|
76
|
+
const csv = [
|
|
77
|
+
"Node,ParentProcessId,ProcessId,WorkingSetSize",
|
|
78
|
+
"HOST,1,100,5000",
|
|
79
|
+
"HOST,100,200,120000",
|
|
80
|
+
"HOST,200,300,40000",
|
|
81
|
+
"HOST,1,400,999000",
|
|
82
|
+
].join("\r\n");
|
|
83
|
+
expect(sumSubtreeRssFromWmicCsv(csv, 100)).toBe(165000);
|
|
84
|
+
});
|
|
85
|
+
it("returns null on malformed input", () => {
|
|
86
|
+
expect(sumSubtreeRssFromWmicCsv("garbage\r\n", 100)).toBeNull();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -90,6 +90,17 @@ describe("LSPClient handshake", () => {
|
|
|
90
90
|
expect.objectContaining({ shell: false }),
|
|
91
91
|
);
|
|
92
92
|
});
|
|
93
|
+
|
|
94
|
+
it("kills the spawned server when the initialize handshake times out (no orphan)", async () => {
|
|
95
|
+
const child = new FakeChild({ autoInit: false }); // never answers initialize
|
|
96
|
+
const client = makeClient(child);
|
|
97
|
+
await expect(client.start({ initTimeoutMs: 20 })).rejects.toThrow(
|
|
98
|
+
/timed out/,
|
|
99
|
+
);
|
|
100
|
+
// The spawned process must be torn down, not left running forever.
|
|
101
|
+
expect(child.killed).toBe(true);
|
|
102
|
+
expect(client.running).toBe(false);
|
|
103
|
+
});
|
|
93
104
|
});
|
|
94
105
|
|
|
95
106
|
describe("LSPClient request/response", () => {
|
|
@@ -141,6 +141,38 @@ describe("ensureFor", () => {
|
|
|
141
141
|
await mgr.disposeAll();
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
+
it("spawns only ONE server when two concurrent calls race the same key", async () => {
|
|
145
|
+
// Regression: ensureFor did Map.get(miss)→await start→Map.set with no
|
|
146
|
+
// in-flight dedupe, so two concurrent calls (the read-only agent batch fires
|
|
147
|
+
// several code_intelligence calls at once) both spawned a server; the second
|
|
148
|
+
// set() orphaned the first process. Gate start() so both calls interleave
|
|
149
|
+
// inside the await window, then assert a single spawn.
|
|
150
|
+
let created = 0;
|
|
151
|
+
let releaseStart;
|
|
152
|
+
const gate = new Promise((r) => {
|
|
153
|
+
releaseStart = r;
|
|
154
|
+
});
|
|
155
|
+
_deps.createClient = (opts) => {
|
|
156
|
+
created += 1;
|
|
157
|
+
lastClient = new FakeClient(opts);
|
|
158
|
+
const origStart = lastClient.start.bind(lastClient);
|
|
159
|
+
lastClient.start = async () => {
|
|
160
|
+
await gate; // hold both starts open until released
|
|
161
|
+
return origStart();
|
|
162
|
+
};
|
|
163
|
+
return lastClient;
|
|
164
|
+
};
|
|
165
|
+
const mgr = new LSPManager();
|
|
166
|
+
const p1 = mgr.ensureFor("/proj/src/a.ts");
|
|
167
|
+
const p2 = mgr.ensureFor("/proj/src/b.ts");
|
|
168
|
+
releaseStart();
|
|
169
|
+
const [r1, r2] = await Promise.all([p1, p2]);
|
|
170
|
+
expect(created).toBe(1); // NOT two — the race is deduped
|
|
171
|
+
expect(mgr.activeServerCount).toBe(1);
|
|
172
|
+
expect(r1.client).toBe(r2.client);
|
|
173
|
+
await mgr.disposeAll();
|
|
174
|
+
});
|
|
175
|
+
|
|
144
176
|
it("returns unavailable for an unsupported extension", async () => {
|
|
145
177
|
const mgr = new LSPManager();
|
|
146
178
|
const ready = await mgr.ensureFor("/proj/readme.txt");
|
|
@@ -251,6 +283,43 @@ describe("diagnostics", () => {
|
|
|
251
283
|
expect(diags[0].message).toBe("boom");
|
|
252
284
|
await mgr.disposeAll();
|
|
253
285
|
});
|
|
286
|
+
|
|
287
|
+
it("clears stale diagnostics + readiness state when the server crashes", async () => {
|
|
288
|
+
const { pathToFileUri } = await import("../lsp-client.js");
|
|
289
|
+
const mgr = new LSPManager();
|
|
290
|
+
await mgr.ensureFor("/proj/src/a.ts");
|
|
291
|
+
lastClient.emit("notify:textDocument/publishDiagnostics", {
|
|
292
|
+
uri: pathToFileUri(path.resolve("/proj/src/a.ts")),
|
|
293
|
+
diagnostics: [
|
|
294
|
+
{
|
|
295
|
+
message: "boom",
|
|
296
|
+
severity: 1,
|
|
297
|
+
range: {
|
|
298
|
+
start: { line: 0, character: 0 },
|
|
299
|
+
end: { line: 0, character: 1 },
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
});
|
|
304
|
+
expect(mgr.getDiagnostics("/proj/src/a.ts")).toHaveLength(1);
|
|
305
|
+
|
|
306
|
+
// Server crashes. Its diagnostics + publish bookkeeping must NOT survive —
|
|
307
|
+
// otherwise the readiness waiters resolve on the pre-crash publish and a
|
|
308
|
+
// post-restart query returns these stale results.
|
|
309
|
+
lastClient.running = false;
|
|
310
|
+
lastClient.emit("exit", 1, null);
|
|
311
|
+
expect(mgr.getDiagnostics("/proj/src/a.ts")).toEqual([]);
|
|
312
|
+
|
|
313
|
+
// A fresh query re-spawns the server; before it publishes, waitForDiagnostics
|
|
314
|
+
// must not hand back the stale set (returns empty within the timeout budget).
|
|
315
|
+
await mgr.ensureFor("/proj/src/a.ts");
|
|
316
|
+
const afterRestart = await mgr.waitForDiagnostics("/proj/src/a.ts", {
|
|
317
|
+
timeoutMs: 60,
|
|
318
|
+
settleMs: 20,
|
|
319
|
+
});
|
|
320
|
+
expect(afterRestart).toEqual([]);
|
|
321
|
+
await mgr.disposeAll();
|
|
322
|
+
});
|
|
254
323
|
});
|
|
255
324
|
|
|
256
325
|
describe("disposeAll", () => {
|