chainlesschain 0.162.149 → 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/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-BJif14yR.js → AIOps-CBLvrjeG.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CXek6gJY.js → ActionButton-DYv2GtE0.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BgQhdAJi.js → Analytics-CL6PZ-Ww.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DTYl5NtR.js → AppLayout-xuyHt4uA.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-BzATQAeR.js → Audit-DOvSVycq.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BzdPEQhL.js → Backup-DMhfTswr.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BM0KVh8E.js → BaseInput-CQxDdm63.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D7fHXHkz.js → Chat-BEeNhK2a.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Wm34RR-b.js → ChatBubbleRenderer-8nul8eTq.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CAiSQ9vO.js → Checkbox-CL04O-ER.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Df40CrEe.js → Codegen-C50o-n7x.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DIT2fNFU.js → Col-CH-bDkzs.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CSTIbW2k.js → Community-DqAIMvSe.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DtqXZZUi.js → Compact-C43fo_my.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CUtzw6o7.js → Compliance-BERnMrdP.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CezmlnmU.js → Cowork-Baw3w1gp.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-P4BITarg.js → Cron-BEqAHF1-.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BRRiYwvq.js → Crosschain-CvnmKwK4.js} +1 -1
- package/src/assets/web-panel/assets/{DID-L5ijB9i4.js → DID-iMPxgVdt.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CFxro4ob.js → Dashboard--4SJX3YR.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BmAFCQ71.js → Dropdown-BgLV6xgz.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DJBCEuon.js → EmailListRenderer-Bvb8oUD8.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-z4oLq6eT.js → FamilyGuardDashboard-DpXPjJB5.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DsVCpHMF.js → Federation-BbFfJ1Xi.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DP3bP5th.js → FormItemContext-DeGq1B-q.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BAXP2Gc6.js → GenericCardRenderer-CNW7s9zM.js} +1 -1
- package/src/assets/web-panel/assets/{Git-I3g_bAw9.js → Git-L1PjW-lT.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-jHS5-ioS.js → Governance-PK-X58to.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CPL7sfx9.js → Inference-BePWEH-d.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Jf236h4C.js → KnowledgeGraph-LF_sBvdL.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Cm2tcSKg.js → Logs-BKkfk9hy.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-CZK82rhi.js → Marketplace-BNMqUDla.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CZCeji7a.js → McpTools-w4WPiyz2.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-3l2KVS9k.js → Memory-DUKMVGNi.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-VYdpoLh6.js → MobileBridge-BWhiEyTJ.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CiB9cmm1.js → MobileProjects-Ocf5JEkX.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-wCFZbBuL.js → Mtc-D2B6MMhU.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-1a3THIyG.js → MtcAudit-DdYjCq1O.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DMzLB2hG.js → Multisig-Cb1hfuUZ.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D9wZbf6l.js → NLProgramming-CTeImGp7.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-hrFe2ZM-.js → Notes-BjYNc7eQ.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-CHGX5Jwm.js → NotificationSettings-Dn_NtRXQ.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-DVYYIizh.js +1 -0
- package/src/assets/web-panel/assets/{Organization-By7FkhtY.js → Organization-Be2Kmr5j.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow--khGSzJn.js → Overflow-Cu_-qRlR.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CAG9dH35.js → P2P-DD2HoGzE.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-B3SQZmK9.js → PdhVaultBrowser-BRI7DVth.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D35ec6JA.js → Permissions-C9Srcs2M.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-CxBF7hW_.js → PersonalDataHub-CUqcMgo1.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-s6EtOO1s.js → Pipeline-HBrQGLXt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BbJYmWmO.js → Privacy-D-B0vjwh.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-VGQq1jMT.js → ProjectInit-eTeLIu9e.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-B1ew3Teh.js → ProjectSettings-DrRqCsC6.js} +2 -2
- package/src/assets/web-panel/assets/Projects-1G9DNOhI.js +1 -0
- package/src/assets/web-panel/assets/{Providers-mrO47FIK.js → Providers-RkTZzpxP.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-IJF2mHyw.js → QrScannerModal-BSCUgsgC.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CU0wN_Z0.js → QuickAsk-CHgyM3Bz.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DhN37R6G.js → Recommend-0lry4OZq.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-D_xOX_hu.js → RemoteSession-Cn45UroZ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-D_Ssv7uH.js → Reputation-Q-Zjb707.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Kx5dKxX7.js → Row-BdM70oda.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BlGwqZkY.js → RssFeed-DmOAKKap.js} +2 -2
- package/src/assets/web-panel/assets/{Search-hLFQzxpb.js → Search-Dwavbm07.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DMlvsVt4.js → Security-DukXFCnk.js} +3 -3
- package/src/assets/web-panel/assets/{Services-Bd0Qsj2m.js → Services-BIlRnITu.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DFclq9X3.js → Skeleton-YYVQdhhQ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BNtln2qY.js → Skills-B8_iYHz2.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Dch5H19G.js → Sla-BdVrhT31.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-2UfQcU1g.js → SpeechSettings-CD3ggRx7.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CD9YQr4i.js → SyncSettings-Bp02VZFH.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BNu-7MzI.js → Tasks-DEVmCEsr.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D1n9CaIR.js → Templates-B6czWc4N.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DenL3iBW.js → Tenant-BCJLv17r.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-ZzU0Io1Y.js → Terminal-CD132d2Y.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D87IfukO.js → TimelineRenderer-ZB-CvkZl.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BkiZc8E3.js → Tokens-BnSY0S-s.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BNRSytGN.js → Trigger-VZw9Oy2w.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Bwbd4X2m.js → Trust-pZq7Hjd2.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B8O2bs0o.js → UkeySign-DnQaqk4q.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C2fL8zmH.js → VideoEditing-BEUfmvJV.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BORYDdE1.js → Wallet-CoZKMXJ2.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C0V5S2FM.js → WebAuthn-CBOGVx1I.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-2dR0fcHL.js → WorkflowEditor-huSKn7TT.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BmuAFAn8.js → chat-A_3w6FBO.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CN3smMcK.js → colors-D1Bem9Oy.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DCnxb4kW.js → compact-item-CJYJj0oO.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-vlR43pHn.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-D04tHYFd.js → hasIn-CKvUafVY.js} +1 -1
- package/src/assets/web-panel/assets/{index-0DnaZGkC.js → index-AjrSPnvv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BudvKQfG.js → index-B8i0lViZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeGDEXFs.js → index-B9Svn0zc.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5LZVZ0L.js → index-BHdHSX06.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTPEZTk1.js → index-BHdailyo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIpY0qM5.js → index-BJwlEnYo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CsAsCPJ6.js → index-BOoAQjJz.js} +1 -1
- package/src/assets/web-panel/assets/{index-ljuBiQW9.js → index-BSgWxAOG.js} +1 -1
- package/src/assets/web-panel/assets/{index-hpvvtAZ3.js → index-BdutMsne.js} +1 -1
- package/src/assets/web-panel/assets/{index-_FIkN3jd.js → index-BiDWxzbn.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-6NO5il.js → index-By5a0T_W.js} +1 -1
- package/src/assets/web-panel/assets/{index-B78xL3s2.js → index-C-WIY-FQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClhAHDK3.js → index-C37f6iey.js} +1 -1
- package/src/assets/web-panel/assets/{index-ToUh2b1-.js → index-C9bWmTcO.js} +1 -1
- package/src/assets/web-panel/assets/{index-D28DeAAB.js → index-CBaosWRO.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8vwp4qp.js → index-CBlBVJ_m.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqhASEL4.js → index-CD62EEGo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDwLgQY9.js → index-CUj-l7GM.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbVsQBOH.js → index-CVS8Ymuq.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cr-A0FYJ.js → index-ChkXUj3f.js} +1 -1
- package/src/assets/web-panel/assets/{index-D65_XseV.js → index-Cj0OZ-37.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXRg8GFQ.js → index-Co3OFL0t.js} +1 -1
- package/src/assets/web-panel/assets/{index-430S68MN.js → index-Crp8CbRg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CngCC8hC.js → index-D22zNXiS.js} +1 -1
- package/src/assets/web-panel/assets/{index-HhNjnCfe.js → index-DTs_D1OL.js} +1 -1
- package/src/assets/web-panel/assets/{index-CP9m9Ggr.js → index-DfgCdFrN.js} +3 -3
- package/src/assets/web-panel/assets/{index-jzR7Ujuw.js → index-DjYrecNb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTOCnIQ7.js → index-DpW9cf3e.js} +1 -1
- package/src/assets/web-panel/assets/index-Dwix3p4g.js +1 -0
- package/src/assets/web-panel/assets/{index-D_n8_vfI.js → index-F--HuPG1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BasvsWDM.js → index-Fuk6t_3K.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnXebZLL.js → index-JEAGMii9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYAtmqiv.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-DTWg-18U.js → index-b-sbVdjQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5Sxb1sE.js → index-pyvMVX8r.js} +1 -1
- package/src/assets/web-panel/assets/{index-TslMTwNy.js → index-qNTtOVi_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTtRscUa.js → index-tgO8iza6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbADHwhr.js → index-ttDQVhZy.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C3wUb4je.js → initDefaultProps-DtrnfsZH.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D-jYFUNA.js → motion-D4zqSaX3.js} +1 -1
- package/src/assets/web-panel/assets/{move-tqb8nwJ2.js → move-CGFGOUQj.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DSOjMJMz.js → mtc-parser-DH2HvkJl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CJ7VimIW.js → omit-jJ2at5HX.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-qXiG1iT3.js → pickAttrs-CRyMT1Fv.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CkGBcy1Z.js → placementArrow-DZ_CX0Pt.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D3WvTlLO.js → responsiveObserve-wruHk-h5.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BEE2ftge.js → slide-BGgx8q67.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CsfBpxiG.js → statusUtils-Do5M7gKm.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-xPrIiJPI.js → styleChecker-CRa-GZpX.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-C5Yd-SCR.js → useFlexGapSupport-BxPcq6pj.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-D_MDS8HI.js → useFs-v5O2ZcJm.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BqJh-usA.js → usePersonalDataHub--z2FU0Px.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-chm_p-gz.js → vnode-1emidVKd.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-3-YDNz0Z.js → zoom-CcJaRyHs.js} +1 -1
- package/src/assets/web-panel/index.html +1 -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/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/gateways/ws/message-dispatcher.js +5 -2
- package/src/gateways/ws/remote-session-protocol.js +103 -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/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/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/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/install.js +9 -1
- package/src/lib/plugin-runtime/policy.js +9 -1
- package/src/lib/plugin-runtime/remote-source.js +240 -0
- package/src/lib/pqc-manager.js +64 -0
- package/src/lib/reputation-optimizer.js +101 -0
- package/src/lib/sandbox-egress-proxy.js +159 -59
- package/src/lib/sandbox-fs-policy.js +112 -0
- package/src/lib/sandbox-network-policy.js +18 -1
- 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/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/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
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
|
@@ -84,6 +84,17 @@ export const LAYER_NAMES = [
|
|
|
84
84
|
* `<group>/<skill>/SKILL.md` layouts (infinite-recursion / deep-tree guard). */
|
|
85
85
|
export const MAX_SKILL_NEST_DEPTH = 5;
|
|
86
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
|
+
|
|
87
98
|
/**
|
|
88
99
|
* Simple YAML frontmatter parser (no dependencies)
|
|
89
100
|
* Shared utility extracted from skill.js
|
|
@@ -165,8 +176,15 @@ export function parseSkillMd(content) {
|
|
|
165
176
|
continue;
|
|
166
177
|
}
|
|
167
178
|
|
|
168
|
-
// Handle booleans and numbers
|
|
169
|
-
|
|
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;
|
|
170
188
|
else if (value === "false") value = false;
|
|
171
189
|
else if (value === "null") value = null;
|
|
172
190
|
else if (/^\d+(\.\d+)?$/.test(value)) value = parseFloat(value);
|
|
@@ -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) {
|
package/src/lib/stress-tester.js
CHANGED
|
@@ -95,6 +95,71 @@ export function ensureStressTables(db) {
|
|
|
95
95
|
`);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Rehydrate _runs/_results from the persisted stress_test_runs/
|
|
100
|
+
* stress_test_results tables. The `cc` CLI runs every command in a fresh
|
|
101
|
+
* process, so without this the Maps start empty and a run recorded in a prior
|
|
102
|
+
* invocation is invisible (`cc stress list` shows "No stress tests recorded.";
|
|
103
|
+
* `cc stress show <id>` throws "Stress test not found"). Call after
|
|
104
|
+
* ensureStressTables(db).
|
|
105
|
+
*/
|
|
106
|
+
export function loadFromDb(db) {
|
|
107
|
+
if (!db) return 0;
|
|
108
|
+
_runs.clear();
|
|
109
|
+
_results.clear();
|
|
110
|
+
|
|
111
|
+
const resultRows = db.prepare(`SELECT * FROM stress_test_results`).all();
|
|
112
|
+
for (const row of resultRows) {
|
|
113
|
+
let bottlenecks = [];
|
|
114
|
+
let capacityRecommendations = [];
|
|
115
|
+
try {
|
|
116
|
+
bottlenecks = row.bottlenecks ? JSON.parse(row.bottlenecks) : [];
|
|
117
|
+
} catch {
|
|
118
|
+
bottlenecks = [];
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
capacityRecommendations = row.capacity_recommendations
|
|
122
|
+
? JSON.parse(row.capacity_recommendations)
|
|
123
|
+
: [];
|
|
124
|
+
} catch {
|
|
125
|
+
capacityRecommendations = [];
|
|
126
|
+
}
|
|
127
|
+
_results.set(row.test_id, {
|
|
128
|
+
resultId: row.result_id,
|
|
129
|
+
testId: row.test_id,
|
|
130
|
+
tps: row.tps,
|
|
131
|
+
avgResponseTime: row.avg_response_time,
|
|
132
|
+
p50ResponseTime: row.p50_response_time,
|
|
133
|
+
p95ResponseTime: row.p95_response_time,
|
|
134
|
+
p99ResponseTime: row.p99_response_time,
|
|
135
|
+
errorRate: row.error_rate,
|
|
136
|
+
bottlenecks,
|
|
137
|
+
capacityRecommendations,
|
|
138
|
+
createdAt: row.created_at,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const runRows = db.prepare(`SELECT * FROM stress_test_runs`).all();
|
|
143
|
+
for (const row of runRows) {
|
|
144
|
+
_runs.set(row.test_id, {
|
|
145
|
+
testId: row.test_id,
|
|
146
|
+
loadLevel: row.load_level,
|
|
147
|
+
concurrency: row.concurrency,
|
|
148
|
+
requestsPerSecond: row.requests_per_second,
|
|
149
|
+
duration: row.duration,
|
|
150
|
+
status: row.status,
|
|
151
|
+
startedAt: row.started_at,
|
|
152
|
+
completedAt: row.completed_at ?? null,
|
|
153
|
+
// _seq is a per-process monotonic tiebreaker; started_at is the primary
|
|
154
|
+
// sort key. Reassign in load order — ties (same ms) are the only case it
|
|
155
|
+
// affects and are cosmetic for history ordering.
|
|
156
|
+
_seq: ++_seq,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return _runs.size + _results.size;
|
|
161
|
+
}
|
|
162
|
+
|
|
98
163
|
/* ── Synthetic metrics ─────────────────────────────────────── */
|
|
99
164
|
|
|
100
165
|
// Deterministic quasi-random: stable across runs for the same inputs. Tests
|
|
@@ -169,6 +169,81 @@ export function ensureTechLearningTables(db) {
|
|
|
169
169
|
);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Rehydrate _profiles/_practices from the persisted tech_stack_profiles/
|
|
174
|
+
* learned_practices tables. The `cc` CLI runs every command in a fresh process,
|
|
175
|
+
* so without this the Maps start empty and a profile/practice recorded in a
|
|
176
|
+
* prior invocation is invisible (`cc tech profile` returns null, `cc tech
|
|
177
|
+
* practices` shows nothing, `cc tech recommend` can't infer the latest stack).
|
|
178
|
+
* Call after ensureTechLearningTables(db). The profile's frameworks/databases/
|
|
179
|
+
* tools/libraries are not stored as columns — they are reconstructed from the
|
|
180
|
+
* classified tech_stack exactly as analyzeTechStack derives them.
|
|
181
|
+
*/
|
|
182
|
+
export function loadFromDb(db) {
|
|
183
|
+
if (!db) return 0;
|
|
184
|
+
_profiles.clear();
|
|
185
|
+
_practices.clear();
|
|
186
|
+
|
|
187
|
+
const profileRows = db.prepare(`SELECT * FROM tech_stack_profiles`).all();
|
|
188
|
+
for (const row of profileRows) {
|
|
189
|
+
let classified = [];
|
|
190
|
+
let deps = [];
|
|
191
|
+
let languages = [];
|
|
192
|
+
try {
|
|
193
|
+
classified = row.tech_stack ? JSON.parse(row.tech_stack) : [];
|
|
194
|
+
} catch {
|
|
195
|
+
classified = [];
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
deps = row.dependencies ? JSON.parse(row.dependencies) : [];
|
|
199
|
+
} catch {
|
|
200
|
+
deps = [];
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
languages = row.languages ? JSON.parse(row.languages) : [];
|
|
204
|
+
} catch {
|
|
205
|
+
languages = [];
|
|
206
|
+
}
|
|
207
|
+
const byType = (t) =>
|
|
208
|
+
classified.filter((d) => d.type === t).map((d) => d.name);
|
|
209
|
+
_profiles.set(row.project_path, {
|
|
210
|
+
profileId: row.profile_id,
|
|
211
|
+
projectPath: row.project_path,
|
|
212
|
+
languages,
|
|
213
|
+
frameworks: byType(TECH_TYPES.FRAMEWORK),
|
|
214
|
+
databases: byType(TECH_TYPES.DATABASE),
|
|
215
|
+
tools: byType(TECH_TYPES.TOOL),
|
|
216
|
+
libraries: byType(TECH_TYPES.LIBRARY),
|
|
217
|
+
totalDependencies: deps.length,
|
|
218
|
+
analysisTimestamp: row.analysis_timestamp,
|
|
219
|
+
createdAt: row.created_at,
|
|
220
|
+
updatedAt: row.updated_at,
|
|
221
|
+
_seq: ++_seq,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const practiceRows = db.prepare(`SELECT * FROM learned_practices`).all();
|
|
226
|
+
for (const row of practiceRows) {
|
|
227
|
+
_practices.set(row.practice_id, {
|
|
228
|
+
practiceId: row.practice_id,
|
|
229
|
+
techType: row.tech_type,
|
|
230
|
+
techName: row.tech_name,
|
|
231
|
+
patternName: row.pattern_name,
|
|
232
|
+
level: row.level,
|
|
233
|
+
description: row.description ?? "",
|
|
234
|
+
codeExample: row.code_example ?? "",
|
|
235
|
+
usageCount: row.usage_count ?? 0,
|
|
236
|
+
score: row.score ?? 0,
|
|
237
|
+
source: row.source,
|
|
238
|
+
learnedAt: row.learned_at,
|
|
239
|
+
updatedAt: row.updated_at,
|
|
240
|
+
_seq: ++_seq,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return _profiles.size + _practices.size;
|
|
245
|
+
}
|
|
246
|
+
|
|
172
247
|
/* ── Parsers for dependency manifests ──────────────────────── */
|
|
173
248
|
|
|
174
249
|
function _readIfExists(filePath) {
|
package/src/lib/tenant-saas.js
CHANGED
|
@@ -830,6 +830,113 @@ export function _resetState() {
|
|
|
830
830
|
_seq = 0;
|
|
831
831
|
}
|
|
832
832
|
|
|
833
|
+
/**
|
|
834
|
+
* Rehydrate the in-memory Maps from the persisted saas_* tables. The CLI runs
|
|
835
|
+
* every subcommand in a fresh node process, so these module-level Maps start
|
|
836
|
+
* empty each invocation. Every write dual-writes (Map + INSERT OR REPLACE) but
|
|
837
|
+
* every read (getTenant/listTenants/getUsage/getActiveSubscription/
|
|
838
|
+
* listSubscriptions/getSaasStats) is Map-only, and nothing SELECTed the tables
|
|
839
|
+
* back — so a tenant created in one invocation was invisible in the next
|
|
840
|
+
* (`No tenants.` / `Tenant not found`), and every follow-up subscribe/record/
|
|
841
|
+
* check-quota/configure/delete threw "Tenant not found". Call after
|
|
842
|
+
* ensureTenantTables(db).
|
|
843
|
+
*/
|
|
844
|
+
export function loadFromDb(db) {
|
|
845
|
+
if (!db) return 0;
|
|
846
|
+
ensureTenantTables(db);
|
|
847
|
+
_tenants.clear();
|
|
848
|
+
_subscriptions.clear();
|
|
849
|
+
_usage.clear();
|
|
850
|
+
_slugIndex.clear();
|
|
851
|
+
_tenantSubs.clear();
|
|
852
|
+
_tenantUsage.clear();
|
|
853
|
+
|
|
854
|
+
for (const r of db
|
|
855
|
+
.prepare(
|
|
856
|
+
`SELECT id, name, slug, config, status, plan, db_path, owner_id,
|
|
857
|
+
created_at, updated_at, deleted_at
|
|
858
|
+
FROM saas_tenants ORDER BY created_at ASC`,
|
|
859
|
+
)
|
|
860
|
+
.all()) {
|
|
861
|
+
// One corrupt config cell must not sink the whole tenant list.
|
|
862
|
+
let config = null;
|
|
863
|
+
try {
|
|
864
|
+
config = r.config ? JSON.parse(r.config) : null;
|
|
865
|
+
} catch {
|
|
866
|
+
config = null;
|
|
867
|
+
}
|
|
868
|
+
_tenants.set(r.id, {
|
|
869
|
+
id: r.id,
|
|
870
|
+
name: r.name,
|
|
871
|
+
slug: r.slug,
|
|
872
|
+
config,
|
|
873
|
+
status: r.status,
|
|
874
|
+
plan: r.plan,
|
|
875
|
+
dbPath: r.db_path || null,
|
|
876
|
+
ownerId: r.owner_id || null,
|
|
877
|
+
createdAt: Number(r.created_at),
|
|
878
|
+
updatedAt: Number(r.updated_at),
|
|
879
|
+
deletedAt: r.deleted_at == null ? null : Number(r.deleted_at),
|
|
880
|
+
_seq: ++_seq,
|
|
881
|
+
});
|
|
882
|
+
if (r.slug) _slugIndex.set(r.slug, r.id);
|
|
883
|
+
_tenantSubs.set(r.id, new Set());
|
|
884
|
+
_tenantUsage.set(r.id, new Set());
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
for (const r of db
|
|
888
|
+
.prepare(
|
|
889
|
+
`SELECT id, tenant_id, metric, value, period, recorded_at
|
|
890
|
+
FROM saas_usage ORDER BY recorded_at ASC`,
|
|
891
|
+
)
|
|
892
|
+
.all()) {
|
|
893
|
+
_usage.set(r.id, {
|
|
894
|
+
id: r.id,
|
|
895
|
+
tenantId: r.tenant_id,
|
|
896
|
+
metric: r.metric,
|
|
897
|
+
value: Number(r.value),
|
|
898
|
+
period: r.period,
|
|
899
|
+
recordedAt: Number(r.recorded_at),
|
|
900
|
+
_seq: ++_seq,
|
|
901
|
+
});
|
|
902
|
+
if (!_tenantUsage.has(r.tenant_id))
|
|
903
|
+
_tenantUsage.set(r.tenant_id, new Set());
|
|
904
|
+
_tenantUsage.get(r.tenant_id).add(r.id);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
for (const r of db
|
|
908
|
+
.prepare(
|
|
909
|
+
`SELECT id, tenant_id, plan, status, started_at, expires_at, cancelled_at,
|
|
910
|
+
payment_method, amount, created_at
|
|
911
|
+
FROM saas_subscriptions ORDER BY created_at ASC`,
|
|
912
|
+
)
|
|
913
|
+
.all()) {
|
|
914
|
+
let paymentMethod = null;
|
|
915
|
+
try {
|
|
916
|
+
paymentMethod = r.payment_method ? JSON.parse(r.payment_method) : null;
|
|
917
|
+
} catch {
|
|
918
|
+
paymentMethod = null;
|
|
919
|
+
}
|
|
920
|
+
_subscriptions.set(r.id, {
|
|
921
|
+
id: r.id,
|
|
922
|
+
tenantId: r.tenant_id,
|
|
923
|
+
plan: r.plan,
|
|
924
|
+
status: r.status,
|
|
925
|
+
startedAt: Number(r.started_at),
|
|
926
|
+
expiresAt: r.expires_at == null ? null : Number(r.expires_at),
|
|
927
|
+
cancelledAt: r.cancelled_at == null ? null : Number(r.cancelled_at),
|
|
928
|
+
paymentMethod,
|
|
929
|
+
amount: r.amount == null ? null : Number(r.amount),
|
|
930
|
+
createdAt: Number(r.created_at),
|
|
931
|
+
_seq: ++_seq,
|
|
932
|
+
});
|
|
933
|
+
if (!_tenantSubs.has(r.tenant_id)) _tenantSubs.set(r.tenant_id, new Set());
|
|
934
|
+
_tenantSubs.get(r.tenant_id).add(r.id);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
return _tenants.size + _usage.size + _subscriptions.size;
|
|
938
|
+
}
|
|
939
|
+
|
|
833
940
|
/* ═══════════════════════════════════════════════════════════════
|
|
834
941
|
* Phase 97 V2 — Tenant Maturity + Subscription Lifecycle
|
|
835
942
|
* Strictly additive. Legacy surface above is preserved.
|
|
@@ -65,6 +65,73 @@ export function ensureTerraformTables(db) {
|
|
|
65
65
|
`);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Rehydrate _workspaces/_runs from the persisted terraform_workspaces/
|
|
70
|
+
* terraform_runs tables. The `cc` CLI runs every command in a fresh process, so
|
|
71
|
+
* without this the Maps start empty and a workspace/run created in a prior
|
|
72
|
+
* invocation is invisible (`cc terraform workspaces`/`runs` show nothing;
|
|
73
|
+
* `cc terraform plan <id>` throws "Workspace not found" for a persisted
|
|
74
|
+
* workspace). Call after ensureTerraformTables(db).
|
|
75
|
+
*/
|
|
76
|
+
export function loadFromDb(db) {
|
|
77
|
+
if (!db) return 0;
|
|
78
|
+
_workspaces.clear();
|
|
79
|
+
_runs.clear();
|
|
80
|
+
|
|
81
|
+
const wsRows = db.prepare(`SELECT * FROM terraform_workspaces`).all();
|
|
82
|
+
for (const row of wsRows) {
|
|
83
|
+
let variables = {};
|
|
84
|
+
let providers = [];
|
|
85
|
+
try {
|
|
86
|
+
variables = row.variables ? JSON.parse(row.variables) : {};
|
|
87
|
+
} catch {
|
|
88
|
+
variables = {};
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
providers = row.providers ? JSON.parse(row.providers) : [];
|
|
92
|
+
} catch {
|
|
93
|
+
providers = [];
|
|
94
|
+
}
|
|
95
|
+
_workspaces.set(row.id, {
|
|
96
|
+
id: row.id,
|
|
97
|
+
name: row.name,
|
|
98
|
+
description: row.description ?? "",
|
|
99
|
+
terraformVersion: row.terraform_version,
|
|
100
|
+
workingDirectory: row.working_directory,
|
|
101
|
+
autoApply: !!row.auto_apply,
|
|
102
|
+
status: row.status,
|
|
103
|
+
lastRunId: row.last_run_id ?? null,
|
|
104
|
+
lastRunAt: row.last_run_at ?? null,
|
|
105
|
+
stateVersion: row.state_version ?? 0,
|
|
106
|
+
variables,
|
|
107
|
+
providers,
|
|
108
|
+
createdAt: row.created_at ?? null,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const runRows = db.prepare(`SELECT * FROM terraform_runs`).all();
|
|
113
|
+
for (const row of runRows) {
|
|
114
|
+
_runs.set(row.id, {
|
|
115
|
+
id: row.id,
|
|
116
|
+
workspaceId: row.workspace_id,
|
|
117
|
+
runType: row.run_type,
|
|
118
|
+
status: row.status,
|
|
119
|
+
planOutput: row.plan_output ?? null,
|
|
120
|
+
applyOutput: row.apply_output ?? null,
|
|
121
|
+
resourcesAdded: row.resources_added ?? 0,
|
|
122
|
+
resourcesChanged: row.resources_changed ?? 0,
|
|
123
|
+
resourcesDestroyed: row.resources_destroyed ?? 0,
|
|
124
|
+
triggeredBy: row.triggered_by ?? null,
|
|
125
|
+
startedAt: row.started_at ?? null,
|
|
126
|
+
completedAt: row.completed_at ?? null,
|
|
127
|
+
errorMessage: row.error_message ?? null,
|
|
128
|
+
createdAt: row.created_at ?? null,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return _workspaces.size + _runs.size;
|
|
133
|
+
}
|
|
134
|
+
|
|
68
135
|
/* ── Workspace Management ─────────────────────────────────── */
|
|
69
136
|
|
|
70
137
|
export function listWorkspaces(filter = {}) {
|