chainlesschain 0.162.148 → 0.162.150
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 +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DwpCCp64.js → AIOps-CBLvrjeG.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C9pBYocA.js → ActionButton-DYv2GtE0.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BWAkeXxK.js → Analytics-CL6PZ-Ww.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CivFGH6B.js → AppLayout-xuyHt4uA.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-Cm8hRpZm.js → Audit-DOvSVycq.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DXdFMsE8.js → Backup-DMhfTswr.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-uAwSTeql.js → BaseInput-CQxDdm63.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-KU8eeJJE.js → Chat-BEeNhK2a.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-8nul8eTq.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-C6AMDkjd.js → Checkbox-CL04O-ER.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-t2moDxcO.js → Codegen-C50o-n7x.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DCcsRRhN.js → Col-CH-bDkzs.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DtB-8SAC.js → Community-DqAIMvSe.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CZm8THYA.js → Compact-C43fo_my.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-LiQgC7g1.js → Compliance-BERnMrdP.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CA8SAxht.js → Cowork-Baw3w1gp.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-CtRaF1wD.js → Cron-BEqAHF1-.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-6-br6Hub.js → Crosschain-CvnmKwK4.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Do2EccrL.js → DID-iMPxgVdt.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-wrXcbzGe.js → Dashboard--4SJX3YR.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-p3FsT245.js → Dropdown-BgLV6xgz.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-D95A2L8q.js → EmailListRenderer-Bvb8oUD8.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-cLuJW2zo.js → FamilyGuardDashboard-DpXPjJB5.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Brgq_cbN.js → Federation-BbFfJ1Xi.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DWLCkNgh.js → FormItemContext-DeGq1B-q.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BBqUfQd6.js → GenericCardRenderer-CNW7s9zM.js} +1 -1
- package/src/assets/web-panel/assets/{Git-8F090w4I.js → Git-L1PjW-lT.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CCogEbxb.js → Governance-PK-X58to.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CfLD7v7C.js → Inference-BePWEH-d.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DDuHJewd.js → KnowledgeGraph-LF_sBvdL.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CE8KSEVC.js → Logs-BKkfk9hy.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-DmwpZmhT.js → Marketplace-BNMqUDla.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Bf7AazU8.js → McpTools-w4WPiyz2.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-D0QU_00S.js → Memory-DUKMVGNi.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-yXS9xdhx.js → MobileBridge-BWhiEyTJ.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BuDUoGUP.js → MobileProjects-Ocf5JEkX.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BYyHy28p.js → Mtc-D2B6MMhU.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CK0aqpiZ.js → MtcAudit-DdYjCq1O.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-mNimKYeb.js → Multisig-Cb1hfuUZ.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-AioAJ0YA.js → NLProgramming-CTeImGp7.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CVVNCLHE.js → Notes-BjYNc7eQ.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-C4ABj-TK.js → NotificationSettings-Dn_NtRXQ.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DIp8Xcbd.js → OrderTableRenderer-DVYYIizh.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-uozl_gWK.js → Organization-Be2Kmr5j.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BCZOM2hK.js → Overflow-Cu_-qRlR.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CArcaiaj.js → P2P-DD2HoGzE.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Sgq2Srr8.js → PdhVaultBrowser-BRI7DVth.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BYrQrXnH.js → Permissions-C9Srcs2M.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BzHStAbz.js → PersonalDataHub-CUqcMgo1.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-k7KqxX1M.js → Pipeline-HBrQGLXt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-IumTUWqx.js → Privacy-D-B0vjwh.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BRyImYTf.js → ProjectInit-eTeLIu9e.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BFIqTBFk.js → ProjectSettings-DrRqCsC6.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Dpid9CDg.js → Projects-1G9DNOhI.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CyyFnUPs.js → Providers-RkTZzpxP.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-C82cRx-X.js → QrScannerModal-BSCUgsgC.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DGxDF521.js → QuickAsk-CHgyM3Bz.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Cns-Am1y.js → Recommend-0lry4OZq.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-R7OqAIlg.js → RemoteSession-Cn45UroZ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-D7mgPIYV.js → Reputation-Q-Zjb707.js} +1 -1
- package/src/assets/web-panel/assets/{Row-B3lEURyd.js → Row-BdM70oda.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-9_UVrpBt.js → RssFeed-DmOAKKap.js} +2 -2
- package/src/assets/web-panel/assets/{Search-ClZeO80q.js → Search-Dwavbm07.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BNNJczEp.js → Security-DukXFCnk.js} +3 -3
- package/src/assets/web-panel/assets/{Services-C5SjrWUj.js → Services-BIlRnITu.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Ci_obQ-g.js → Skeleton-YYVQdhhQ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DdebN15P.js → Skills-B8_iYHz2.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-OinZP2vi.js → Sla-BdVrhT31.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CxzbNF51.js → SpeechSettings-CD3ggRx7.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-D06N_66b.js → SyncSettings-Bp02VZFH.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BdEdW0AZ.js → Tasks-DEVmCEsr.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-F1ctKmPa.js → Templates-B6czWc4N.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CVz1Urot.js → Tenant-BCJLv17r.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-CD132d2Y.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-Doitzjmf.js → TimelineRenderer-ZB-CvkZl.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BpyVRpVA.js → Tokens-BnSY0S-s.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-nWhWYTbU.js → Trigger-VZw9Oy2w.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DK_G-wLx.js → Trust-pZq7Hjd2.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B5yBUojO.js → UkeySign-DnQaqk4q.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C5D51qAe.js → VideoEditing-BEUfmvJV.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CLbL9K7v.js → Wallet-CoZKMXJ2.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DZUelI3V.js → WebAuthn-CBOGVx1I.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-8RPxt4KW.js → WorkflowEditor-huSKn7TT.js} +1 -1
- package/src/assets/web-panel/assets/{chat-4N4tOA3d.js → chat-A_3w6FBO.js} +1 -1
- package/src/assets/web-panel/assets/{colors-zbbGVrua.js → colors-D1Bem9Oy.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-D7iMkbnE.js → compact-item-CJYJj0oO.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CBzPJv-w.js → createContext-BkbFiKT4.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-bHdrQSqZ.js → hasIn-CKvUafVY.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbE5D0WL.js → index-AjrSPnvv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCr0geV9.js → index-B8i0lViZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiG1IZao.js → index-B9Svn0zc.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1s0Bz9O.js → index-BHdHSX06.js} +1 -1
- package/src/assets/web-panel/assets/{index-QFObYeo1.js → index-BHdailyo.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnBOpqv3.js → index-BJwlEnYo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdmMoYN1.js → index-BOoAQjJz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUyjUkY7.js → index-BSgWxAOG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqdPyWm5.js → index-BdutMsne.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmqlJed-.js → index-BiDWxzbn.js} +1 -1
- package/src/assets/web-panel/assets/{index-S74FpAIn.js → index-By5a0T_W.js} +1 -1
- package/src/assets/web-panel/assets/{index-kmh1TxRa.js → index-C-WIY-FQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTIjjXry.js → index-C37f6iey.js} +1 -1
- package/src/assets/web-panel/assets/{index-BS4_Mwk6.js → index-C9bWmTcO.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBNr77E1.js → index-CBaosWRO.js} +1 -1
- package/src/assets/web-panel/assets/{index-QNAG4JtR.js → index-CBlBVJ_m.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bqmx24kh.js → index-CD62EEGo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQfu1U78.js → index-CUj-l7GM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJ4ZGyW0.js → index-CVS8Ymuq.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ci009ijp.js → index-ChkXUj3f.js} +1 -1
- package/src/assets/web-panel/assets/{index-oDKNgCsP.js → index-Cj0OZ-37.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZb8F8YG.js → index-Co3OFL0t.js} +1 -1
- package/src/assets/web-panel/assets/{index-308gCGh7.js → index-Crp8CbRg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CPxkoKgA.js → index-D22zNXiS.js} +1 -1
- package/src/assets/web-panel/assets/{index-xYCm6W2h.js → index-DTs_D1OL.js} +1 -1
- package/src/assets/web-panel/assets/{index-BtbbdLnf.js → index-DfgCdFrN.js} +3 -3
- package/src/assets/web-panel/assets/{index-BsKehmmS.js → index-DjYrecNb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkxK86vf.js → index-DpW9cf3e.js} +1 -1
- package/src/assets/web-panel/assets/index-Dwix3p4g.js +1 -0
- package/src/assets/web-panel/assets/{index-CvRMA9uT.js → index-F--HuPG1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE9j5YgT.js → index-Fuk6t_3K.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7b1hGry.js → index-JEAGMii9.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1YDh7Wr.js → index-PF-mpv8K.js} +1 -1
- package/src/assets/web-panel/assets/index-SHaoZ0CA.js +1 -0
- package/src/assets/web-panel/assets/{index-CQ6NcfWz.js → index-b-sbVdjQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DyoNgbXl.js → index-pyvMVX8r.js} +1 -1
- package/src/assets/web-panel/assets/{index-DISWAYce.js → index-qNTtOVi_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4XKpj6c.js → index-tgO8iza6.js} +1 -1
- package/src/assets/web-panel/assets/{index-CahryTX0.js → index-ttDQVhZy.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BD55yNBt.js → initDefaultProps-DtrnfsZH.js} +1 -1
- package/src/assets/web-panel/assets/{motion-B5Bbe77U.js → motion-D4zqSaX3.js} +1 -1
- package/src/assets/web-panel/assets/{move-CTvIqHEH.js → move-CGFGOUQj.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BkNyPQKB.js → mtc-parser-DH2HvkJl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BaXJXgHA.js → omit-jJ2at5HX.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Bw6-YTxH.js → pickAttrs-CRyMT1Fv.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BLdbkLqJ.js → placementArrow-DZ_CX0Pt.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-IVYkzntU.js → responsiveObserve-wruHk-h5.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DFMFwwtY.js → slide-BGgx8q67.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CURYRtZ1.js → statusUtils-Do5M7gKm.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Cfz63s1r.js → styleChecker-CRa-GZpX.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-COJL0KE3.js → useFlexGapSupport-BxPcq6pj.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-YLLojQQf.js → useFs-v5O2ZcJm.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BF_21qUC.js → usePersonalDataHub--z2FU0Px.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-9ZpkA7bb.js → vnode-1emidVKd.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DhtAfhl8.js → zoom-CcJaRyHs.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/assets/web-panel/remote-session-sw.js +43 -0
- package/src/command-manifest.json +22 -1
- package/src/commands/a2a.js +19 -4
- package/src/commands/activitypub.js +20 -3
- package/src/commands/agent.js +71 -10
- package/src/commands/audit.js +40 -24
- package/src/commands/codeintel.js +320 -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 +255 -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 +474 -0
- 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 +463 -0
- 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/gateways/ws/message-dispatcher.js +48 -2
- package/src/gateways/ws/remote-session-protocol.js +140 -42
- package/src/gateways/ws/ws-server.js +1 -1
- package/src/harness/jsonl-session-store.js +12 -5
- package/src/harness/plugin-manager.js +16 -4
- package/src/harness/prompt-compressor.js +27 -1
- package/src/harness/remote-command-ledger.js +189 -0
- package/src/harness/remote-session-push-apns.js +246 -0
- package/src/harness/remote-session-push-errors.js +15 -0
- package/src/harness/remote-session-push-fcm.js +9 -25
- package/src/harness/remote-session-push-huawei.js +174 -0
- package/src/harness/remote-session-push-oppo.js +171 -0
- package/src/harness/remote-session-push-senders.js +42 -0
- package/src/harness/remote-session-push-vivo.js +179 -0
- package/src/harness/remote-session-push-web.js +299 -0
- package/src/harness/remote-session-push-xiaomi.js +99 -0
- package/src/harness/worktree-isolator.js +16 -6
- package/src/index.js +6 -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 +4 -0
- package/src/lib/agent-economy.js +262 -29
- package/src/lib/agent-network.js +7 -1
- package/src/lib/agent-sandbox.js +161 -5
- package/src/lib/agent-team/task-lease.js +434 -0
- package/src/lib/agent-team/team-budget.js +165 -0
- package/src/lib/agent-team/team-mailbox.js +106 -0
- package/src/lib/agent-team/team-runner.js +282 -0
- package/src/lib/agent-team/team-worktree.js +236 -0
- package/src/lib/agents.js +18 -0
- package/src/lib/async-hook-supervisor.cjs +391 -0
- package/src/lib/audit-logger.js +7 -6
- package/src/lib/autonomous-developer.js +60 -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 +251 -0
- package/src/lib/eval/tasks.js +626 -0
- package/src/lib/eval/trend.js +200 -0
- 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__/code-intelligence.integration.test.js +129 -0
- package/src/lib/lsp/__tests__/code-intelligence.test.js +228 -0
- package/src/lib/lsp/__tests__/jsonrpc-stream.test.js +104 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +269 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +333 -0
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +128 -0
- package/src/lib/lsp/benchmark.js +257 -0
- package/src/lib/lsp/code-intelligence.js +356 -0
- package/src/lib/lsp/jsonrpc-stream.js +139 -0
- package/src/lib/lsp/lsp-client.js +339 -0
- package/src/lib/lsp/lsp-manager.js +375 -0
- package/src/lib/lsp/lsp-server-registry.js +196 -0
- 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-monitor-supervisor.js +238 -0
- package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
- package/src/lib/plugin-runtime/agents.js +51 -0
- package/src/lib/plugin-runtime/bin.js +100 -0
- package/src/lib/plugin-runtime/hooks.js +100 -0
- package/src/lib/plugin-runtime/install.js +396 -0
- package/src/lib/plugin-runtime/lsp.js +75 -0
- package/src/lib/plugin-runtime/manifest.js +458 -0
- package/src/lib/plugin-runtime/mcp.js +89 -0
- package/src/lib/plugin-runtime/monitors.js +100 -0
- package/src/lib/plugin-runtime/policy.js +152 -0
- package/src/lib/plugin-runtime/reload.js +79 -0
- package/src/lib/plugin-runtime/remote-source.js +240 -0
- package/src/lib/plugin-runtime/scopes.js +197 -0
- package/src/lib/plugin-runtime/settings.js +119 -0
- package/src/lib/plugin-runtime/signature.js +107 -0
- package/src/lib/plugin-runtime/skills.js +43 -0
- package/src/lib/plugin-runtime/trust.js +140 -0
- package/src/lib/pqc-manager.js +64 -0
- package/src/lib/reputation-optimizer.js +101 -0
- package/src/lib/sandbox-egress-proxy.js +262 -0
- package/src/lib/sandbox-fs-policy.js +112 -0
- package/src/lib/sandbox-network-policy.js +151 -0
- package/src/lib/sandbox-v2.js +24 -18
- package/src/lib/scim-manager.js +36 -0
- package/src/lib/session-manager.js +5 -2
- package/src/lib/settings-hook-events.cjs +78 -6
- package/src/lib/settings-hooks.cjs +30 -3
- package/src/lib/settings-loader.cjs +35 -1
- package/src/lib/siem-exporter.js +45 -0
- package/src/lib/skill-loader.js +38 -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 +237 -0
- 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 +417 -6
- package/src/runtime/__tests__/auto-pin.test.js +104 -0
- package/src/runtime/agent-core.js +771 -104
- package/src/runtime/auto-pin.js +117 -0
- package/src/runtime/coding-agent-contract-shared.cjs +82 -8
- package/src/runtime/coding-agent-policy.cjs +32 -7
- package/src/runtime/fallback-model.js +134 -7
- package/src/runtime/headless-runner.js +388 -108
- package/src/runtime/mcp-config.js +46 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DCNfbdlx.js +0 -1
- package/src/assets/web-panel/assets/Terminal-BvAK_Zel.js +0 -3
- package/src/assets/web-panel/assets/devWarning-C2Z5LRgq.js +0 -1
- package/src/assets/web-panel/assets/index-BGp6Yr-Y.js +0 -1
- package/src/assets/web-panel/assets/index-BXiw9dQf.js +0 -1
|
@@ -19,6 +19,24 @@
|
|
|
19
19
|
const { collectHooks } = require("./settings-hooks.cjs");
|
|
20
20
|
const { runHooks } = require("./hook-runner.cjs");
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Split collected hooks into the blocking (sync) set and the fire-and-forget
|
|
24
|
+
* (`async: true`) set. Only NON-decision events should dispatch async hooks —
|
|
25
|
+
* an async hook can't gate a turn it no longer blocks, so a UserPromptSubmit
|
|
26
|
+
* hook that must be able to `block` should stay sync. The caller decides which
|
|
27
|
+
* events are eligible; this is just the partition.
|
|
28
|
+
* @returns {{ sync: Array, async: Array }}
|
|
29
|
+
*/
|
|
30
|
+
function partitionAsyncHooks(hooks) {
|
|
31
|
+
const sync = [];
|
|
32
|
+
const asyncHooks = [];
|
|
33
|
+
for (const h of hooks || []) {
|
|
34
|
+
if (h && h.async === true) asyncHooks.push(h);
|
|
35
|
+
else sync.push(h);
|
|
36
|
+
}
|
|
37
|
+
return { sync, async: asyncHooks };
|
|
38
|
+
}
|
|
39
|
+
|
|
22
40
|
/** Join the context emitted by the hooks that ran (additionalContext / plain stdout). */
|
|
23
41
|
function aggregateContext(results) {
|
|
24
42
|
const parts = [];
|
|
@@ -36,19 +54,32 @@ function aggregateContext(results) {
|
|
|
36
54
|
/**
|
|
37
55
|
* UserPromptSubmit settings hooks. A `block`/`ask` decision aborts the turn;
|
|
38
56
|
* otherwise any emitted context is returned for the caller to inject.
|
|
57
|
+
*
|
|
58
|
+
* `async: true` hooks are EXCLUDED from this blocking run — they can't gate a
|
|
59
|
+
* turn they no longer block, so a fire-and-forget hook is dispatched separately
|
|
60
|
+
* (see dispatchAsyncHooks). This keeps the sync/decision path unchanged while a
|
|
61
|
+
* long-running check runs alongside the turn.
|
|
39
62
|
* @returns {{ blocked:boolean, reason?:string, hook?:string, additionalContext:string|null }}
|
|
40
63
|
*/
|
|
41
|
-
function runUserPromptSubmitHooks(
|
|
64
|
+
function runUserPromptSubmitHooks(
|
|
65
|
+
settingsHooks,
|
|
66
|
+
{ prompt, cwd, sessionId } = {},
|
|
67
|
+
) {
|
|
42
68
|
if (!settingsHooks) return { blocked: false, additionalContext: null };
|
|
43
69
|
const matched = collectHooks(settingsHooks, "UserPromptSubmit", "");
|
|
44
70
|
if (matched.length === 0) return { blocked: false, additionalContext: null };
|
|
71
|
+
const { sync } = partitionAsyncHooks(matched);
|
|
72
|
+
if (sync.length === 0) return { blocked: false, additionalContext: null };
|
|
45
73
|
const payload = {
|
|
46
74
|
hook_event_name: "UserPromptSubmit",
|
|
47
75
|
prompt: String(prompt || ""),
|
|
48
76
|
cwd,
|
|
49
77
|
session_id: sessionId || null,
|
|
50
78
|
};
|
|
51
|
-
const outcome = runHooks(
|
|
79
|
+
const outcome = runHooks(sync, payload, {
|
|
80
|
+
cwd,
|
|
81
|
+
event: "UserPromptSubmit",
|
|
82
|
+
});
|
|
52
83
|
if (outcome.decision === "block" || outcome.decision === "ask") {
|
|
53
84
|
return {
|
|
54
85
|
blocked: true,
|
|
@@ -57,7 +88,36 @@ function runUserPromptSubmitHooks(settingsHooks, { prompt, cwd, sessionId } = {}
|
|
|
57
88
|
additionalContext: null,
|
|
58
89
|
};
|
|
59
90
|
}
|
|
60
|
-
return {
|
|
91
|
+
return {
|
|
92
|
+
blocked: false,
|
|
93
|
+
additionalContext: aggregateContext(outcome.results),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Dispatch the `async: true` hooks for an event fire-and-forget onto the given
|
|
99
|
+
* supervisor (see async-hook-supervisor). Sync hooks are ignored here — they run
|
|
100
|
+
* on the blocking path. No-op (returns []) without a supervisor or async hooks,
|
|
101
|
+
* so callers can wire it unconditionally.
|
|
102
|
+
*
|
|
103
|
+
* @param {object} settingsHooks merged hooks block
|
|
104
|
+
* @param {string} event UserPromptSubmit / PostToolUse / Stop / …
|
|
105
|
+
* @param {object} payload extra fields merged into the hook stdin JSON
|
|
106
|
+
* @param {object} opts { cwd, matchTarget, supervisor }
|
|
107
|
+
* @returns {Array<{command:string, dispatched:boolean, reason?:string}>}
|
|
108
|
+
*/
|
|
109
|
+
function dispatchAsyncHooks(settingsHooks, event, payload = {}, opts = {}) {
|
|
110
|
+
const supervisor = opts.supervisor;
|
|
111
|
+
if (!settingsHooks || !supervisor) return [];
|
|
112
|
+
const matched = collectHooks(settingsHooks, event, opts.matchTarget || "");
|
|
113
|
+
if (matched.length === 0) return [];
|
|
114
|
+
const { async: asyncHooks } = partitionAsyncHooks(matched);
|
|
115
|
+
if (asyncHooks.length === 0) return [];
|
|
116
|
+
return supervisor.dispatch(
|
|
117
|
+
asyncHooks,
|
|
118
|
+
{ hook_event_name: event, cwd: opts.cwd, ...payload },
|
|
119
|
+
{ cwd: opts.cwd },
|
|
120
|
+
);
|
|
61
121
|
}
|
|
62
122
|
|
|
63
123
|
/**
|
|
@@ -82,13 +142,23 @@ function runSessionStartHooks(settingsHooks, { source, cwd, sessionId } = {}) {
|
|
|
82
142
|
/**
|
|
83
143
|
* Generic observe-only fire (SessionEnd / Stop / PreCompact). Returns the raw
|
|
84
144
|
* runHooks outcome so callers can read a block reason; never gates flow here.
|
|
145
|
+
*
|
|
146
|
+
* `async: true` hooks are EXCLUDED from this synchronous run — they are always
|
|
147
|
+
* fire-and-forget and are dispatched separately (dispatchAsyncHooks), so running
|
|
148
|
+
* them here too would double-execute them.
|
|
85
149
|
*/
|
|
86
|
-
function runObserveHooks(
|
|
150
|
+
function runObserveHooks(
|
|
151
|
+
settingsHooks,
|
|
152
|
+
event,
|
|
153
|
+
payload = {},
|
|
154
|
+
{ cwd, matchTarget } = {},
|
|
155
|
+
) {
|
|
87
156
|
if (!settingsHooks) return { decision: "continue", results: [] };
|
|
88
157
|
const matched = collectHooks(settingsHooks, event, matchTarget || "");
|
|
89
|
-
|
|
158
|
+
const { sync } = partitionAsyncHooks(matched);
|
|
159
|
+
if (sync.length === 0) return { decision: "continue", results: [] };
|
|
90
160
|
return runHooks(
|
|
91
|
-
|
|
161
|
+
sync,
|
|
92
162
|
{ hook_event_name: event, cwd, ...payload },
|
|
93
163
|
{ cwd, event },
|
|
94
164
|
);
|
|
@@ -99,4 +169,6 @@ module.exports = {
|
|
|
99
169
|
runSessionStartHooks,
|
|
100
170
|
runObserveHooks,
|
|
101
171
|
aggregateContext,
|
|
172
|
+
partitionAsyncHooks,
|
|
173
|
+
dispatchAsyncHooks,
|
|
102
174
|
};
|
|
@@ -39,11 +39,16 @@ const HOOK_EVENTS = Object.freeze([
|
|
|
39
39
|
"PostToolUse",
|
|
40
40
|
"UserPromptSubmit",
|
|
41
41
|
"Stop",
|
|
42
|
+
"SubagentStart",
|
|
42
43
|
"SubagentStop",
|
|
43
44
|
"SessionStart",
|
|
45
|
+
"SessionResume",
|
|
46
|
+
"SessionPause",
|
|
44
47
|
"SessionEnd",
|
|
48
|
+
"ConfigChange",
|
|
45
49
|
"PreCompact",
|
|
46
50
|
"Notification",
|
|
51
|
+
"PermissionRequest",
|
|
47
52
|
]);
|
|
48
53
|
|
|
49
54
|
/**
|
|
@@ -210,18 +215,40 @@ function umbrellaFor(tool) {
|
|
|
210
215
|
* matcher is tested against BOTH the CC umbrella (`Bash`) and the raw tool
|
|
211
216
|
* name (`run_shell`), so settings written either way fire.
|
|
212
217
|
*
|
|
213
|
-
*
|
|
218
|
+
* `async`/`asyncRewake` are carried through (default false) so the caller can
|
|
219
|
+
* split fire-and-forget hooks off the blocking path (see async-hook-supervisor).
|
|
220
|
+
* `event` is stamped on each hook so a supervisor can key runs by (event+cmd).
|
|
221
|
+
*
|
|
222
|
+
* @returns {Array<{command:string, timeout?:number, event:string,
|
|
223
|
+
* async:boolean, asyncRewake:boolean}>}
|
|
214
224
|
*/
|
|
215
225
|
function collectHooks(hooksBlock, event, toolName) {
|
|
216
226
|
const groups = (hooksBlock && hooksBlock[event]) || [];
|
|
217
227
|
const umbrella = umbrellaFor(toolName);
|
|
218
228
|
const raw = String(toolName || "");
|
|
229
|
+
// Claude-Code MCP parity: a bare server-prefix matcher (`mcp__github`) fires
|
|
230
|
+
// for EVERY tool from that server (`mcp__github__create_issue`, …). Our
|
|
231
|
+
// matcher is anchored (`^…$`), so the server prefix alone would never match a
|
|
232
|
+
// full `mcp__server__tool` name without also testing the prefix explicitly.
|
|
233
|
+
// (Users can still target one tool with the full name, or all of a server's
|
|
234
|
+
// tools with a `mcp__server*` wildcard / `/mcp__server__/` regex.)
|
|
235
|
+
let mcpServer = null;
|
|
236
|
+
if (raw.startsWith("mcp__")) {
|
|
237
|
+
const parts = raw.split("__");
|
|
238
|
+
if (parts.length >= 3) mcpServer = `${parts[0]}__${parts[1]}`;
|
|
239
|
+
}
|
|
219
240
|
const out = [];
|
|
220
241
|
for (const g of groups) {
|
|
221
242
|
const fn = compileMatcher(g.matcher);
|
|
222
|
-
if (fn(umbrella) || (raw && fn(raw))) {
|
|
243
|
+
if (fn(umbrella) || (raw && fn(raw)) || (mcpServer && fn(mcpServer))) {
|
|
223
244
|
for (const h of g.hooks)
|
|
224
|
-
out.push({
|
|
245
|
+
out.push({
|
|
246
|
+
command: h.command,
|
|
247
|
+
timeout: h.timeout,
|
|
248
|
+
event,
|
|
249
|
+
async: h.async === true,
|
|
250
|
+
asyncRewake: h.asyncRewake === true,
|
|
251
|
+
});
|
|
225
252
|
}
|
|
226
253
|
}
|
|
227
254
|
return out;
|
|
@@ -300,6 +300,7 @@ function loadSettingsConfig(opts = {}) {
|
|
|
300
300
|
const cwd = opts.cwd || process.cwd();
|
|
301
301
|
let model = null;
|
|
302
302
|
const env = {};
|
|
303
|
+
let sandbox = null;
|
|
303
304
|
const files = [];
|
|
304
305
|
for (const file of settingsPaths(cwd, opts.settingsFile)) {
|
|
305
306
|
const data = readSettingsFile(file, { onWarn: opts.onWarn });
|
|
@@ -317,6 +318,14 @@ function loadSettingsConfig(opts = {}) {
|
|
|
317
318
|
}
|
|
318
319
|
}
|
|
319
320
|
}
|
|
321
|
+
if (
|
|
322
|
+
data.sandbox &&
|
|
323
|
+
typeof data.sandbox === "object" &&
|
|
324
|
+
!Array.isArray(data.sandbox)
|
|
325
|
+
) {
|
|
326
|
+
sandbox = mergeSandboxSettings(sandbox, data.sandbox);
|
|
327
|
+
contributed = true;
|
|
328
|
+
}
|
|
320
329
|
if (contributed) files.push(file);
|
|
321
330
|
}
|
|
322
331
|
const managed = loadManagedSettings(opts);
|
|
@@ -335,9 +344,33 @@ function loadSettingsConfig(opts = {}) {
|
|
|
335
344
|
}
|
|
336
345
|
}
|
|
337
346
|
}
|
|
347
|
+
if (
|
|
348
|
+
data.sandbox &&
|
|
349
|
+
typeof data.sandbox === "object" &&
|
|
350
|
+
!Array.isArray(data.sandbox)
|
|
351
|
+
) {
|
|
352
|
+
sandbox = mergeSandboxSettings(sandbox, data.sandbox);
|
|
353
|
+
contributed = true;
|
|
354
|
+
}
|
|
338
355
|
if (contributed) files.push(managed.file);
|
|
339
356
|
}
|
|
340
|
-
return { model, env, files };
|
|
357
|
+
return { model, env, sandbox, files };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function mergeSandboxSettings(base, overlay) {
|
|
361
|
+
const out =
|
|
362
|
+
base && typeof base === "object" ? JSON.parse(JSON.stringify(base)) : {};
|
|
363
|
+
for (const [key, value] of Object.entries(overlay || {})) {
|
|
364
|
+
if (Array.isArray(value)) {
|
|
365
|
+
const previous = Array.isArray(out[key]) ? out[key] : [];
|
|
366
|
+
out[key] = [...new Set([...previous, ...value].map(String))];
|
|
367
|
+
} else if (value && typeof value === "object") {
|
|
368
|
+
out[key] = mergeSandboxSettings(out[key], value);
|
|
369
|
+
} else if (["string", "boolean", "number"].includes(typeof value)) {
|
|
370
|
+
out[key] = value;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return out;
|
|
341
374
|
}
|
|
342
375
|
|
|
343
376
|
/**
|
|
@@ -393,6 +426,7 @@ module.exports = {
|
|
|
393
426
|
applyManagedPermissionPolicy,
|
|
394
427
|
assertManagedPermissionMode,
|
|
395
428
|
parseEnvList,
|
|
429
|
+
mergeSandboxSettings,
|
|
396
430
|
ruleSource,
|
|
397
431
|
addRule,
|
|
398
432
|
scopeFile,
|
package/src/lib/siem-exporter.js
CHANGED
|
@@ -136,6 +136,51 @@ export function _resetState() {
|
|
|
136
136
|
_exports.length = 0;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Rehydrate the in-memory _targets Map from the persisted siem_exports table.
|
|
141
|
+
* The CLI runs each `cc siem` subcommand in a fresh node process, so _targets
|
|
142
|
+
* starts empty every invocation. addTarget dual-writes (Map + INSERT INTO
|
|
143
|
+
* siem_exports) but every read (listTargets/exportLogs/getSIEMStats/
|
|
144
|
+
* removeTarget/setTargetStatus/listTargetsByStatus) is Map-only and nothing
|
|
145
|
+
* SELECTed the table back — so a target added in one invocation was invisible in
|
|
146
|
+
* the next (`No SIEM targets configured.`) and `siem export <id>` hard-crashed
|
|
147
|
+
* with `Target not found` for a target that genuinely exists on disk. Call after
|
|
148
|
+
* ensureSIEMTables(db).
|
|
149
|
+
*/
|
|
150
|
+
export function loadFromDb(db) {
|
|
151
|
+
if (!db) return 0;
|
|
152
|
+
ensureSIEMTables(db);
|
|
153
|
+
_targets.clear();
|
|
154
|
+
for (const r of db
|
|
155
|
+
.prepare(
|
|
156
|
+
`SELECT id, target_type, target_url, format, last_exported_log_id,
|
|
157
|
+
exported_count, last_export_at, status, config, created_at
|
|
158
|
+
FROM siem_exports ORDER BY created_at ASC`,
|
|
159
|
+
)
|
|
160
|
+
.all()) {
|
|
161
|
+
// One corrupt config cell must not sink the whole target load.
|
|
162
|
+
let config = {};
|
|
163
|
+
try {
|
|
164
|
+
config = r.config ? JSON.parse(r.config) : {};
|
|
165
|
+
} catch {
|
|
166
|
+
config = {};
|
|
167
|
+
}
|
|
168
|
+
_targets.set(r.id, {
|
|
169
|
+
id: r.id,
|
|
170
|
+
type: r.target_type,
|
|
171
|
+
url: r.target_url,
|
|
172
|
+
format: r.format,
|
|
173
|
+
exportedCount: Number(r.exported_count) || 0,
|
|
174
|
+
lastExportAt: r.last_export_at ?? null,
|
|
175
|
+
lastExportedLogId: r.last_exported_log_id ?? null,
|
|
176
|
+
status: r.status,
|
|
177
|
+
config,
|
|
178
|
+
createdAt: r.created_at,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return _targets.size;
|
|
182
|
+
}
|
|
183
|
+
|
|
139
184
|
// ═══════════════════════════════════════════════════════════════
|
|
140
185
|
// V2 Canonical Surface (Phase 51)
|
|
141
186
|
// ═══════════════════════════════════════════════════════════════
|
package/src/lib/skill-loader.js
CHANGED
|
@@ -28,6 +28,7 @@ import { getElectronUserDataDir } from "./paths.js";
|
|
|
28
28
|
import { findProjectRoot } from "./project-detector.js";
|
|
29
29
|
import { findProjectRoot as findGitRoot } from "./project-instructions.js";
|
|
30
30
|
import { parseSkillMcpServers } from "./skill-mcp.js";
|
|
31
|
+
import { discoverPluginSkillLayers } from "./plugin-runtime/skills.js";
|
|
31
32
|
import settingsLoader from "./settings-loader.cjs";
|
|
32
33
|
|
|
33
34
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -72,6 +73,7 @@ export const LAYER_NAMES = [
|
|
|
72
73
|
"bundled",
|
|
73
74
|
"cli-bundled",
|
|
74
75
|
"marketplace",
|
|
76
|
+
"plugin",
|
|
75
77
|
"managed",
|
|
76
78
|
"claude-user",
|
|
77
79
|
"claude-project",
|
|
@@ -82,6 +84,17 @@ export const LAYER_NAMES = [
|
|
|
82
84
|
* `<group>/<skill>/SKILL.md` layouts (infinite-recursion / deep-tree guard). */
|
|
83
85
|
export const MAX_SKILL_NEST_DEPTH = 5;
|
|
84
86
|
|
|
87
|
+
// Frontmatter keys (camelCased) that are semantically strings and are consumed
|
|
88
|
+
// with string methods; they must never be number/boolean-coerced. `version` is
|
|
89
|
+
// deliberately excluded — it is only string-interpolated and existing behavior
|
|
90
|
+
// coerces it to a number.
|
|
91
|
+
const STRING_SCALAR_FIELDS = new Set([
|
|
92
|
+
"name",
|
|
93
|
+
"displayName",
|
|
94
|
+
"description",
|
|
95
|
+
"category",
|
|
96
|
+
]);
|
|
97
|
+
|
|
85
98
|
/**
|
|
86
99
|
* Simple YAML frontmatter parser (no dependencies)
|
|
87
100
|
* Shared utility extracted from skill.js
|
|
@@ -163,8 +176,15 @@ export function parseSkillMd(content) {
|
|
|
163
176
|
continue;
|
|
164
177
|
}
|
|
165
178
|
|
|
166
|
-
// Handle booleans and numbers
|
|
167
|
-
|
|
179
|
+
// Handle booleans and numbers. These fields are string-semantic and get
|
|
180
|
+
// used with string methods downstream (skill.id.includes(),
|
|
181
|
+
// description.substring(), category/displayName.toLowerCase()); coercing a
|
|
182
|
+
// bare numeric ("2024") or boolean value to Number/Boolean makes those
|
|
183
|
+
// throw and aborts the whole `cc skill list/search/run` command on a
|
|
184
|
+
// single such skill — so never coerce them. (version stays coercible.)
|
|
185
|
+
if (STRING_SCALAR_FIELDS.has(camelKey))
|
|
186
|
+
value = value.replace(/^['"]|['"]$/g, "");
|
|
187
|
+
else if (value === "true") value = true;
|
|
168
188
|
else if (value === "false") value = false;
|
|
169
189
|
else if (value === "null") value = null;
|
|
170
190
|
else if (/^\d+(\.\d+)?$/.test(value)) value = parseFloat(value);
|
|
@@ -312,6 +332,22 @@ export class CLISkillLoader {
|
|
|
312
332
|
exists: fs.existsSync(marketplacePath),
|
|
313
333
|
});
|
|
314
334
|
|
|
335
|
+
// Layer 1b: plugin — each installed plugin's skills/ dir (Phase 3). Sits
|
|
336
|
+
// just above marketplace so a user's managed/workspace/project skills still
|
|
337
|
+
// override a plugin's on a name collision. One entry per plugin.
|
|
338
|
+
try {
|
|
339
|
+
for (const p of discoverPluginSkillLayers({ cwd: process.cwd() })) {
|
|
340
|
+
layers.push({
|
|
341
|
+
layer: "plugin",
|
|
342
|
+
path: p.path,
|
|
343
|
+
exists: fs.existsSync(p.path),
|
|
344
|
+
plugin: p.name,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
} catch {
|
|
348
|
+
/* plugin skill discovery is best-effort — never break skill loading */
|
|
349
|
+
}
|
|
350
|
+
|
|
315
351
|
// Layer 2: managed — <userData>/skills/
|
|
316
352
|
const managedPath = path.join(userData, "skills");
|
|
317
353
|
layers.push({
|
|
@@ -109,6 +109,89 @@ export function ensureMarketplaceTables(db) {
|
|
|
109
109
|
);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Hydrate the in-memory _services/_invocations Maps from the DB. The CLI is
|
|
114
|
+
* one-shot: both start empty each process. Writes dual-write (Map + INSERT) but
|
|
115
|
+
* every read (getService/listServices/listInvocations/getInvocationStats/
|
|
116
|
+
* getMarketplaceStatsV2) and _mustGetService (record/status/invoke) is Map-only
|
|
117
|
+
* and nothing SELECTed the tables back — so a published service was invisible on
|
|
118
|
+
* the next invocation, and record/show/status threw "Service not found". Call
|
|
119
|
+
* after ensureMarketplaceTables(db).
|
|
120
|
+
*
|
|
121
|
+
* V2 timing fields (startedAt/completedAt) are not persisted → default null.
|
|
122
|
+
*/
|
|
123
|
+
export function loadFromDb(db) {
|
|
124
|
+
if (!db) return 0;
|
|
125
|
+
ensureMarketplaceTables(db);
|
|
126
|
+
_services.clear();
|
|
127
|
+
_invocations.clear();
|
|
128
|
+
|
|
129
|
+
for (const r of db
|
|
130
|
+
.prepare(
|
|
131
|
+
`SELECT id, name, version, description, endpoint, pricing, status, owner, invocation_count, created_at, updated_at
|
|
132
|
+
FROM skill_services ORDER BY created_at ASC`,
|
|
133
|
+
)
|
|
134
|
+
.all()) {
|
|
135
|
+
// One corrupt pricing cell must not crash the whole service load.
|
|
136
|
+
let pricing = null;
|
|
137
|
+
try {
|
|
138
|
+
pricing = r.pricing ? JSON.parse(r.pricing) : null;
|
|
139
|
+
} catch {
|
|
140
|
+
pricing = null;
|
|
141
|
+
}
|
|
142
|
+
_services.set(r.id, {
|
|
143
|
+
id: r.id,
|
|
144
|
+
name: r.name,
|
|
145
|
+
version: r.version,
|
|
146
|
+
description: r.description || "",
|
|
147
|
+
endpoint: r.endpoint,
|
|
148
|
+
pricing,
|
|
149
|
+
status: r.status,
|
|
150
|
+
owner: r.owner,
|
|
151
|
+
invocationCount: Number(r.invocation_count) || 0,
|
|
152
|
+
createdAt: Number(r.created_at),
|
|
153
|
+
updatedAt: Number(r.updated_at),
|
|
154
|
+
_seq: ++_seq,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
for (const r of db
|
|
159
|
+
.prepare(
|
|
160
|
+
`SELECT id, service_id, caller_id, input, output, status, duration_ms, error, created_at
|
|
161
|
+
FROM skill_invocations ORDER BY created_at ASC`,
|
|
162
|
+
)
|
|
163
|
+
.all()) {
|
|
164
|
+
let input = null;
|
|
165
|
+
let output = null;
|
|
166
|
+
try {
|
|
167
|
+
input = r.input == null ? null : JSON.parse(r.input);
|
|
168
|
+
} catch {
|
|
169
|
+
input = r.input;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
output = r.output == null ? null : JSON.parse(r.output);
|
|
173
|
+
} catch {
|
|
174
|
+
output = r.output;
|
|
175
|
+
}
|
|
176
|
+
_invocations.set(r.id, {
|
|
177
|
+
id: r.id,
|
|
178
|
+
serviceId: r.service_id,
|
|
179
|
+
callerId: r.caller_id,
|
|
180
|
+
input,
|
|
181
|
+
output,
|
|
182
|
+
status: r.status,
|
|
183
|
+
durationMs: r.duration_ms == null ? null : Number(r.duration_ms),
|
|
184
|
+
error: r.error,
|
|
185
|
+
createdAt: Number(r.created_at),
|
|
186
|
+
startedAt: null,
|
|
187
|
+
completedAt: null,
|
|
188
|
+
_seq: ++_seq,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return _services.size + _invocations.size;
|
|
193
|
+
}
|
|
194
|
+
|
|
112
195
|
/* ── Catalogs ──────────────────────────────────────────────── */
|
|
113
196
|
|
|
114
197
|
export function listServiceStatus() {
|
package/src/lib/sla-manager.js
CHANGED
|
@@ -484,6 +484,94 @@ export function _resetState() {
|
|
|
484
484
|
_maxActiveSlasPerOrg = DEFAULT_MAX_ACTIVE_SLAS_PER_ORG;
|
|
485
485
|
}
|
|
486
486
|
|
|
487
|
+
/**
|
|
488
|
+
* Rehydrate the in-memory Maps from the persisted sla_* tables. The CLI runs
|
|
489
|
+
* each `cc sla` subcommand in a fresh node process, so _contracts/_metrics/
|
|
490
|
+
* _violations start empty every invocation. Every write dual-writes (Map +
|
|
491
|
+
* INSERT into sla_contracts/sla_metrics/sla_violations) but every read (listSLAs/
|
|
492
|
+
* getSLA/getSLAMetrics/checkViolations/listViolations/calculateCompensation/
|
|
493
|
+
* generateReport) is Map-only and nothing SELECTed the tables back — so `sla
|
|
494
|
+
* list` reported none, and `show`/`record`/`metrics`/`report` threw "SLA not
|
|
495
|
+
* found" for a contract that genuinely exists on disk. Call after
|
|
496
|
+
* ensureSlaTables(db).
|
|
497
|
+
*/
|
|
498
|
+
export function loadFromDb(db) {
|
|
499
|
+
if (!db) return 0;
|
|
500
|
+
ensureSlaTables(db);
|
|
501
|
+
_contracts.clear();
|
|
502
|
+
_metrics.clear();
|
|
503
|
+
_violations.clear();
|
|
504
|
+
|
|
505
|
+
for (const r of db
|
|
506
|
+
.prepare(
|
|
507
|
+
`SELECT sla_id, org_id, tier, terms, monthly_fee, start_date, end_date, status, created_at, updated_at
|
|
508
|
+
FROM sla_contracts ORDER BY created_at ASC`,
|
|
509
|
+
)
|
|
510
|
+
.all()) {
|
|
511
|
+
// One corrupt terms cell must not sink the whole contract list.
|
|
512
|
+
let terms = {};
|
|
513
|
+
try {
|
|
514
|
+
terms = r.terms ? JSON.parse(r.terms) : {};
|
|
515
|
+
} catch {
|
|
516
|
+
terms = {};
|
|
517
|
+
}
|
|
518
|
+
_contracts.set(r.sla_id, {
|
|
519
|
+
slaId: r.sla_id,
|
|
520
|
+
orgId: r.org_id,
|
|
521
|
+
tier: r.tier,
|
|
522
|
+
terms,
|
|
523
|
+
monthlyFee: Number(r.monthly_fee) || 0,
|
|
524
|
+
startDate: Number(r.start_date),
|
|
525
|
+
endDate: Number(r.end_date),
|
|
526
|
+
status: r.status,
|
|
527
|
+
createdAt: Number(r.created_at),
|
|
528
|
+
updatedAt: Number(r.updated_at),
|
|
529
|
+
_seq: ++_seq,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
for (const r of db
|
|
534
|
+
.prepare(
|
|
535
|
+
`SELECT metric_id, sla_id, term, value, recorded_at
|
|
536
|
+
FROM sla_metrics ORDER BY recorded_at ASC`,
|
|
537
|
+
)
|
|
538
|
+
.all()) {
|
|
539
|
+
if (!_metrics.has(r.sla_id)) _metrics.set(r.sla_id, []);
|
|
540
|
+
_metrics.get(r.sla_id).push({
|
|
541
|
+
metricId: r.metric_id,
|
|
542
|
+
slaId: r.sla_id,
|
|
543
|
+
term: r.term,
|
|
544
|
+
value: Number(r.value),
|
|
545
|
+
recordedAt: Number(r.recorded_at),
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
for (const r of db
|
|
550
|
+
.prepare(
|
|
551
|
+
`SELECT violation_id, sla_id, term, severity, expected_value, actual_value,
|
|
552
|
+
deviation_percent, compensation_amount, occurred_at, resolved_at
|
|
553
|
+
FROM sla_violations ORDER BY occurred_at ASC`,
|
|
554
|
+
)
|
|
555
|
+
.all()) {
|
|
556
|
+
_violations.set(r.violation_id, {
|
|
557
|
+
violationId: r.violation_id,
|
|
558
|
+
slaId: r.sla_id,
|
|
559
|
+
term: r.term,
|
|
560
|
+
severity: r.severity,
|
|
561
|
+
expectedValue: Number(r.expected_value),
|
|
562
|
+
actualValue: Number(r.actual_value),
|
|
563
|
+
deviationPercent:
|
|
564
|
+
r.deviation_percent == null ? null : Number(r.deviation_percent),
|
|
565
|
+
compensationAmount:
|
|
566
|
+
r.compensation_amount == null ? null : Number(r.compensation_amount),
|
|
567
|
+
occurredAt: Number(r.occurred_at),
|
|
568
|
+
resolvedAt: r.resolved_at == null ? null : Number(r.resolved_at),
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return _contracts.size + _metrics.size + _violations.size;
|
|
573
|
+
}
|
|
574
|
+
|
|
487
575
|
/* ═══════════════════════════════════════════════════════════════
|
|
488
576
|
* V2 (Phase 61) — Frozen enums + contract/violation state
|
|
489
577
|
* machines + active-per-org cap + auto-expire + stats-v2.
|
|
@@ -54,6 +54,80 @@ export function ensureSocialTables(db) {
|
|
|
54
54
|
`);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Hydrate the in-memory stores from the DB. The CLI is one-shot: every command
|
|
59
|
+
* runs in a fresh process, so the module-level Maps start empty. Write paths
|
|
60
|
+
* dual-write (Map + DB), but the read paths (listContacts/listFriends/listPosts/
|
|
61
|
+
* getChatMessages/getChatThreads/getSocialStats) read the Maps ONLY — so without
|
|
62
|
+
* this, a user's persisted contacts/friends/posts/messages are invisible on the
|
|
63
|
+
* next invocation. Mirrors social-graph.loadFromDb (the asymmetry tell: graph
|
|
64
|
+
* commands hydrate, social commands didn't). Call after ensureSocialTables(db).
|
|
65
|
+
*/
|
|
66
|
+
export function loadFromDb(db) {
|
|
67
|
+
if (!db) return 0;
|
|
68
|
+
_contacts.clear();
|
|
69
|
+
_friends.clear();
|
|
70
|
+
_posts.clear();
|
|
71
|
+
_messages.clear();
|
|
72
|
+
|
|
73
|
+
for (const r of db
|
|
74
|
+
.prepare(
|
|
75
|
+
`SELECT id, name, did, email, notes, created_at FROM social_contacts`,
|
|
76
|
+
)
|
|
77
|
+
.all()) {
|
|
78
|
+
_contacts.set(r.id, {
|
|
79
|
+
id: r.id,
|
|
80
|
+
name: r.name,
|
|
81
|
+
did: r.did || null,
|
|
82
|
+
email: r.email || null,
|
|
83
|
+
notes: r.notes || "",
|
|
84
|
+
createdAt: r.created_at,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (const r of db
|
|
89
|
+
.prepare(`SELECT id, contact_id, status, created_at FROM social_friends`)
|
|
90
|
+
.all()) {
|
|
91
|
+
// Keyed by contact_id to match addFriend's _friends.set(contactId, ...).
|
|
92
|
+
_friends.set(r.contact_id, {
|
|
93
|
+
id: r.id,
|
|
94
|
+
contactId: r.contact_id,
|
|
95
|
+
status: r.status,
|
|
96
|
+
createdAt: r.created_at,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for (const r of db
|
|
101
|
+
.prepare(`SELECT id, author, content, likes, created_at FROM social_posts`)
|
|
102
|
+
.all()) {
|
|
103
|
+
_posts.set(r.id, {
|
|
104
|
+
id: r.id,
|
|
105
|
+
author: r.author,
|
|
106
|
+
content: r.content,
|
|
107
|
+
likes: r.likes,
|
|
108
|
+
createdAt: r.created_at,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const r of db
|
|
113
|
+
.prepare(
|
|
114
|
+
`SELECT id, thread_id, sender, recipient, content, read, created_at FROM social_messages`,
|
|
115
|
+
)
|
|
116
|
+
.all()) {
|
|
117
|
+
_messages.set(r.id, {
|
|
118
|
+
id: r.id,
|
|
119
|
+
threadId: r.thread_id,
|
|
120
|
+
sender: r.sender,
|
|
121
|
+
recipient: r.recipient,
|
|
122
|
+
content: r.content,
|
|
123
|
+
read: !!r.read,
|
|
124
|
+
createdAt: r.created_at,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return _contacts.size + _friends.size + _posts.size + _messages.size;
|
|
129
|
+
}
|
|
130
|
+
|
|
57
131
|
/* ── Contacts ──────────────────────────────────────────────── */
|
|
58
132
|
|
|
59
133
|
export function addContact(db, name, did, email, notes) {
|