chainlesschain 0.162.149 → 0.162.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +3 -2
- package/src/assets/web-panel/assets/{AIOps-BJif14yR.js → AIOps-DuEOzebi.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CXek6gJY.js → ActionButton-C6GiJa5H.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BgQhdAJi.js → Analytics-BBIiL_pO.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DTYl5NtR.js → AppLayout-CuI2gZRy.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-BzATQAeR.js → Audit-CbUjfr-K.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BzdPEQhL.js → Backup-CsSW9ljf.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BM0KVh8E.js → BaseInput-kM3rLe7F.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D7fHXHkz.js → Chat-kfE51YN3.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Wm34RR-b.js → ChatBubbleRenderer-Bg2FTW6A.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CAiSQ9vO.js → Checkbox-jYb1uj-M.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Df40CrEe.js → Codegen-X9XiD5Lj.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DIT2fNFU.js → Col-BfbHu1xI.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CSTIbW2k.js → Community-c4oJMFS-.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DtqXZZUi.js → Compact-BFmnZpH7.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CUtzw6o7.js → Compliance-s9shVHBS.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CezmlnmU.js → Cowork-C5da--TC.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-P4BITarg.js → Cron-9kNbyNE4.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BRRiYwvq.js → Crosschain-C1k3NJD4.js} +1 -1
- package/src/assets/web-panel/assets/{DID-L5ijB9i4.js → DID-DkheEvNK.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CFxro4ob.js → Dashboard-C3FuSGmJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BmAFCQ71.js → Dropdown-CAV6FMFD.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DJBCEuon.js → EmailListRenderer-Cc-Ulc4l.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-z4oLq6eT.js → FamilyGuardDashboard-8CitHEtv.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DsVCpHMF.js → Federation-DFSZ5KDt.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DP3bP5th.js → FormItemContext-CEWCtnG2.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BAXP2Gc6.js → GenericCardRenderer-CwRzNzmX.js} +1 -1
- package/src/assets/web-panel/assets/{Git-I3g_bAw9.js → Git-0rgDM7cJ.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-jHS5-ioS.js → Governance-CfBKtK9F.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CPL7sfx9.js → Inference-CzcUVvud.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Jf236h4C.js → KnowledgeGraph-Dwc4YL4A.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Cm2tcSKg.js → Logs-DgFPwR2F.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-CZK82rhi.js → Marketplace-DnpPTbGU.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CZCeji7a.js → McpTools-DRxxINyW.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-3l2KVS9k.js → Memory-OhmW_6Z3.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-VYdpoLh6.js → MobileBridge-DkTW-RK5.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CiB9cmm1.js → MobileProjects-DpCGV_lI.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-wCFZbBuL.js → Mtc--vmkL0AS.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-1a3THIyG.js → MtcAudit-DGoFWjD4.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DMzLB2hG.js → Multisig-B4kWgq95.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D9wZbf6l.js → NLProgramming-YQwvommE.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-hrFe2ZM-.js → Notes-CgjtUADJ.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CHGX5Jwm.js → NotificationSettings-6JDrpBG5.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-PM6IlxjO.js +1 -0
- package/src/assets/web-panel/assets/{Organization-By7FkhtY.js → Organization-8McOT_OF.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow--khGSzJn.js → Overflow-DAZpSCGc.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CAG9dH35.js → P2P-B7l2ZWLy.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-B3SQZmK9.js → PdhVaultBrowser-W1Ud-NAL.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-D35ec6JA.js → Permissions-Czm_w9u_.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CxBF7hW_.js → PersonalDataHub-B4F0_ZVM.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-s6EtOO1s.js → Pipeline-B37aFiWv.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BbJYmWmO.js → Privacy-94KBnRrD.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-VGQq1jMT.js → ProjectInit-B5h8_dlh.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-B1ew3Teh.js → ProjectSettings-lmeI3Lpm.js} +2 -2
- package/src/assets/web-panel/assets/Projects-D5AYOasl.js +1 -0
- package/src/assets/web-panel/assets/{Providers-mrO47FIK.js → Providers-B3cNWwJg.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-IJF2mHyw.js → QrScannerModal-CHRvOw1R.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CU0wN_Z0.js → QuickAsk-D1JMgFEd.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DhN37R6G.js → Recommend-EYWGR79p.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-D_xOX_hu.js → RemoteSession-BAMC2pJt.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-D_Ssv7uH.js → Reputation-X2Hk1XG_.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Kx5dKxX7.js → Row-Eq98LRtU.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BlGwqZkY.js → RssFeed-i76s6z_o.js} +2 -2
- package/src/assets/web-panel/assets/{Search-hLFQzxpb.js → Search-D_Es7CAI.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DMlvsVt4.js → Security-kayD2e94.js} +3 -3
- package/src/assets/web-panel/assets/{Services-Bd0Qsj2m.js → Services-Ctsm6ul8.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DFclq9X3.js → Skeleton-CRNYlfdf.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BNtln2qY.js → Skills-DkZYpF4-.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Dch5H19G.js → Sla-DXkoBcOP.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-2UfQcU1g.js → SpeechSettings-DXi_GI1d.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CD9YQr4i.js → SyncSettings-rNKpfomn.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BNu-7MzI.js → Tasks-XF4uPtG-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D1n9CaIR.js → Templates-i0Hzfeyu.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DenL3iBW.js → Tenant-sMpHAi27.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-BoZvaYAl.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-D87IfukO.js → TimelineRenderer-yuC6K7Rf.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BkiZc8E3.js → Tokens-B8O8i0s6.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BNRSytGN.js → Trigger-Bv6yrlCr.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Bwbd4X2m.js → Trust-C4mW95Ev.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B8O2bs0o.js → UkeySign-DV6yKaHn.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C2fL8zmH.js → VideoEditing-UI479-sD.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BORYDdE1.js → Wallet-M5oV9EVP.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C0V5S2FM.js → WebAuthn-DDyDHPDR.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-2dR0fcHL.js → WorkflowEditor-RoBv4rqk.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BmuAFAn8.js → chat-Cw1mE5LS.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CN3smMcK.js → colors-BFP62Gwf.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DCnxb4kW.js → compact-item-17HL6pyC.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-vlR43pHn.js → createContext-D55X4fZX.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CqbHYuRc.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-D04tHYFd.js → hasIn-D3E5mNsP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbVsQBOH.js → index--44J50mc.js} +1 -1
- package/src/assets/web-panel/assets/{index-TslMTwNy.js → index-ASPYTzMK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTOCnIQ7.js → index-BC6zxOlU.js} +1 -1
- package/src/assets/web-panel/assets/{index-ljuBiQW9.js → index-BEa1RW4c.js} +1 -1
- package/src/assets/web-panel/assets/{index-jzR7Ujuw.js → index-BQmZg5si.js} +1 -1
- package/src/assets/web-panel/assets/{index-BudvKQfG.js → index-BY_xZ2jy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CP9m9Ggr.js → index-BgN5G5vF.js} +3 -3
- package/src/assets/web-panel/assets/{index-Cr-A0FYJ.js → index-BnGpft-Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5LZVZ0L.js → index-Bq83UBDr.js} +1 -1
- package/src/assets/web-panel/assets/{index-ToUh2b1-.js → index-Bzpp2z2S.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbADHwhr.js → index-CFYGn88j.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClhAHDK3.js → index-CGyTos4p.js} +1 -1
- package/src/assets/web-panel/assets/index-CKBI1U5K.js +1 -0
- package/src/assets/web-panel/assets/{index-C-6NO5il.js → index-CLEzsZ8A.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8vwp4qp.js → index-CR9rNUvi.js} +1 -1
- package/src/assets/web-panel/assets/{index-_FIkN3jd.js → index-CW6LLoJO.js} +1 -1
- package/src/assets/web-panel/assets/{index-D65_XseV.js → index-C_MfcrLf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnXebZLL.js → index-Cdvk2_2q.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_n8_vfI.js → index-CjCwi7we.js} +1 -1
- package/src/assets/web-panel/assets/index-CkLp6DTO.js +1 -0
- package/src/assets/web-panel/assets/{index-DDwLgQY9.js → index-CvCFKojj.js} +1 -1
- package/src/assets/web-panel/assets/{index-430S68MN.js → index-D4LHSde4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXRg8GFQ.js → index-DCLu84x-.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTtRscUa.js → index-DD_qGBrt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BasvsWDM.js → index-DIRvdwBX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeGDEXFs.js → index-DOjA8bvj.js} +1 -1
- package/src/assets/web-panel/assets/{index-CsAsCPJ6.js → index-Da27u6j0.js} +1 -1
- package/src/assets/web-panel/assets/{index-D28DeAAB.js → index-DkBVYlE4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CngCC8hC.js → index-DtAnPBWP.js} +1 -1
- package/src/assets/web-panel/assets/{index-B78xL3s2.js → index-DzG7mkgW.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIpY0qM5.js → index-H9_X1Cg_.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5Sxb1sE.js → index-ITeEHb8L.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTPEZTk1.js → index-KtLJXn4s.js} +1 -1
- package/src/assets/web-panel/assets/{index-hpvvtAZ3.js → index-RYZgFIwo.js} +1 -1
- package/src/assets/web-panel/assets/{index-HhNjnCfe.js → index-gAVxDiTZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTWg-18U.js → index-paVubXzn.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqhASEL4.js → index-tUH_6bdJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYAtmqiv.js → index-tVRPgYGr.js} +1 -1
- package/src/assets/web-panel/assets/{index-0DnaZGkC.js → index-uSsiwgZ2.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-C3wUb4je.js → initDefaultProps-Ckp7xVZS.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D-jYFUNA.js → motion-DUZgCpn6.js} +1 -1
- package/src/assets/web-panel/assets/{move-tqb8nwJ2.js → move-B2rttglH.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DSOjMJMz.js → mtc-parser-BYWcLTuN.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CJ7VimIW.js → omit-DhHqKeFx.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-qXiG1iT3.js → pickAttrs-ANpJaWMO.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CkGBcy1Z.js → placementArrow-CfZWe7CA.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D3WvTlLO.js → responsiveObserve-D7Xz2y-R.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BEE2ftge.js → slide-DekqCBY9.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CsfBpxiG.js → statusUtils-BET6XU7h.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-xPrIiJPI.js → styleChecker-qHmJjV62.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-C5Yd-SCR.js → useFlexGapSupport-BoMCTNyu.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-D_MDS8HI.js → useFs-TdW-NgFC.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BqJh-usA.js → usePersonalDataHub-Dyox7wCu.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-chm_p-gz.js → vnode-XUn5S8CP.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-3-YDNz0Z.js → zoom-Ls77i8hn.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-manifest.json +8 -1
- package/src/commands/a2a.js +19 -4
- package/src/commands/activitypub.js +20 -3
- package/src/commands/agent.js +27 -5
- package/src/commands/audit.js +40 -24
- package/src/commands/changelog.js +148 -0
- package/src/commands/codeintel.js +68 -0
- package/src/commands/collab.js +15 -2
- package/src/commands/compliance.js +5 -0
- package/src/commands/config.js +4 -1
- package/src/commands/dao.js +86 -14
- package/src/commands/dev.js +2 -0
- package/src/commands/did.js +7 -1
- package/src/commands/dlp.js +23 -1
- package/src/commands/economy.js +29 -3
- package/src/commands/eval.js +7 -0
- package/src/commands/evomap.js +26 -0
- package/src/commands/governance.js +17 -3
- package/src/commands/hardening.js +18 -0
- package/src/commands/incentive.js +5 -0
- package/src/commands/init.js +46 -2
- package/src/commands/kg.js +4 -0
- package/src/commands/loop.js +6 -1
- package/src/commands/lowcode.js +15 -2
- package/src/commands/marketplace.js +40 -6
- package/src/commands/matrix.js +20 -1
- package/src/commands/memory.js +4 -1
- package/src/commands/mtc.js +7 -1
- package/src/commands/nostr.js +31 -4
- package/src/commands/note.js +7 -4
- package/src/commands/plugin.js +125 -5
- package/src/commands/pqc.js +5 -0
- package/src/commands/reputation.js +10 -1
- package/src/commands/scim.js +6 -0
- package/src/commands/session.js +32 -10
- package/src/commands/siem.js +11 -0
- package/src/commands/sla.js +18 -3
- package/src/commands/social.js +38 -5
- package/src/commands/sso.js +10 -2
- package/src/commands/stress.js +23 -4
- package/src/commands/team.js +9 -2
- package/src/commands/tech.js +2 -0
- package/src/commands/tenant.js +10 -1
- package/src/commands/terraform.js +6 -0
- package/src/commands/update.js +1 -1
- package/src/commands/zkp.js +20 -0
- package/src/data/changelog.json +189 -0
- package/src/gateways/ws/message-dispatcher.js +5 -2
- package/src/gateways/ws/remote-session-protocol.js +110 -42
- package/src/harness/jsonl-session-store.js +12 -5
- package/src/harness/plugin-manager.js +16 -4
- package/src/harness/remote-command-ledger.js +46 -15
- package/src/harness/worktree-isolator.js +16 -6
- package/src/index.js +2 -0
- package/src/lib/__tests__/logger.test.js +5 -2
- package/src/lib/a2a-protocol.js +25 -1
- package/src/lib/activitypub-bridge.js +61 -0
- package/src/lib/agent-core.js +2 -0
- package/src/lib/agent-economy.js +262 -29
- package/src/lib/agent-network.js +7 -1
- package/src/lib/agent-team/team-runner.js +25 -9
- package/src/lib/agent-team/team-worktree.js +36 -4
- package/src/lib/async-hook-supervisor.cjs +102 -16
- package/src/lib/audit-logger.js +7 -6
- package/src/lib/autonomous-developer.js +60 -0
- package/src/lib/changelog.js +252 -0
- package/src/lib/chat-core.js +17 -4
- package/src/lib/collaboration-governance.js +56 -0
- package/src/lib/community-governance.js +68 -0
- package/src/lib/compliance-manager.js +63 -0
- package/src/lib/cross-chain.js +5 -0
- package/src/lib/dao-governance.js +151 -2
- package/src/lib/did-manager.js +23 -10
- package/src/lib/dlp-engine.js +70 -0
- package/src/lib/eval/runner.js +89 -1
- package/src/lib/eval/tasks.js +170 -0
- package/src/lib/eval/trend.js +16 -1
- package/src/lib/evolution-system.js +92 -0
- package/src/lib/evomap-federation.js +55 -0
- package/src/lib/evomap-governance.js +94 -0
- package/src/lib/fatal-handler.js +17 -1
- package/src/lib/hardening-manager.js +73 -0
- package/src/lib/hierarchical-memory.js +14 -8
- package/src/lib/knowledge-exporter.js +8 -2
- package/src/lib/knowledge-graph.js +79 -0
- package/src/lib/llm-providers.js +23 -14
- package/src/lib/logger.js +4 -1
- package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +11 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +69 -0
- package/src/lib/lsp/benchmark.js +257 -0
- package/src/lib/lsp/lsp-client.js +30 -9
- package/src/lib/lsp/lsp-manager.js +54 -2
- package/src/lib/lsp/lsp-server-registry.js +15 -4
- package/src/lib/matrix-bridge.js +84 -0
- package/src/lib/memory-manager.js +5 -3
- package/src/lib/nostr-bridge.js +53 -0
- package/src/lib/permission-engine.js +22 -4
- package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
- package/src/lib/plugin-runtime/hooks.js +20 -4
- package/src/lib/plugin-runtime/install.js +9 -1
- package/src/lib/plugin-runtime/monitors.js +20 -4
- package/src/lib/plugin-runtime/policy.js +9 -1
- package/src/lib/plugin-runtime/remote-source.js +240 -0
- package/src/lib/plugin-runtime/signature.js +16 -0
- package/src/lib/pqc-manager.js +64 -0
- package/src/lib/reputation-optimizer.js +101 -0
- package/src/lib/sandbox-egress-proxy.js +195 -59
- package/src/lib/sandbox-fs-policy.js +112 -0
- package/src/lib/sandbox-network-policy.js +44 -5
- package/src/lib/sandbox-v2.js +14 -14
- package/src/lib/scim-manager.js +36 -0
- package/src/lib/session-manager.js +5 -2
- package/src/lib/settings-hooks.cjs +1 -0
- package/src/lib/siem-exporter.js +45 -0
- package/src/lib/skill-loader.js +20 -2
- package/src/lib/skill-marketplace.js +83 -0
- package/src/lib/sla-manager.js +88 -0
- package/src/lib/social-manager.js +74 -0
- package/src/lib/stress-tester.js +65 -0
- package/src/lib/tech-learning-engine.js +75 -0
- package/src/lib/telemetry/span-recorder.js +12 -1
- package/src/lib/tenant-saas.js +107 -0
- package/src/lib/terraform-manager.js +67 -0
- package/src/lib/token-incentive.js +180 -29
- package/src/lib/wallet-manager.js +81 -35
- package/src/lib/zkp-engine.js +87 -0
- package/src/repl/agent-repl.js +17 -2
- package/src/runtime/__tests__/auto-pin.test.js +104 -0
- package/src/runtime/agent-core.js +241 -68
- package/src/runtime/auto-pin.js +117 -0
- package/src/runtime/headless-runner.js +35 -0
- package/src/assets/web-panel/assets/OrderTableRenderer-CRIFE2Tj.js +0 -1
- package/src/assets/web-panel/assets/Projects-CGcNIs_g.js +0 -1
- package/src/assets/web-panel/assets/Terminal-ZzU0Io1Y.js +0 -3
- package/src/assets/web-panel/assets/devWarning-DxwmsL4j.js +0 -1
- package/src/assets/web-panel/assets/index-Cg2ldRfU.js +0 -1
- package/src/assets/web-panel/assets/index-Dwzo-dtJ.js +0 -1
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 = {}) {
|
|
@@ -224,14 +224,15 @@ function _recordTransaction(db, config) {
|
|
|
224
224
|
createdAt: now,
|
|
225
225
|
_seq: ++_seq,
|
|
226
226
|
};
|
|
227
|
-
_transactions.set(id, tx);
|
|
228
|
-
|
|
229
227
|
if (db) {
|
|
230
228
|
db.prepare(
|
|
231
229
|
`INSERT INTO token_transactions (id, from_account, to_account, amount, reason, type, created_at)
|
|
232
230
|
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
233
231
|
).run(id, tx.fromAccount, tx.toAccount, tx.amount, tx.reason, tx.type, now);
|
|
234
232
|
}
|
|
233
|
+
// Register in the in-memory ledger only after the row is persisted, so a
|
|
234
|
+
// failed INSERT (e.g. inside a rolled-back transaction) leaves no phantom.
|
|
235
|
+
_transactions.set(id, tx);
|
|
235
236
|
return tx;
|
|
236
237
|
}
|
|
237
238
|
|
|
@@ -255,6 +256,21 @@ export function transfer(db, config = {}) {
|
|
|
255
256
|
throw new Error(`Insufficient balance: ${fromAccount.balance} < ${amount}`);
|
|
256
257
|
}
|
|
257
258
|
|
|
259
|
+
// The debit, the credit and the ledger row must all land or none of them.
|
|
260
|
+
// Without an enclosing transaction a mid-way failure would persist the debit
|
|
261
|
+
// but not the credit (tokens vanish) or move the balances yet never record
|
|
262
|
+
// the ledger — and the CLI re-hydrates from these tables, so it survives.
|
|
263
|
+
const fromSnap = {
|
|
264
|
+
balance: fromAccount.balance,
|
|
265
|
+
totalSpent: fromAccount.totalSpent,
|
|
266
|
+
updatedAt: fromAccount.updatedAt,
|
|
267
|
+
};
|
|
268
|
+
const toSnap = {
|
|
269
|
+
balance: toAccount.balance,
|
|
270
|
+
totalEarned: toAccount.totalEarned,
|
|
271
|
+
updatedAt: toAccount.updatedAt,
|
|
272
|
+
};
|
|
273
|
+
|
|
258
274
|
fromAccount.balance -= amount;
|
|
259
275
|
fromAccount.totalSpent += amount;
|
|
260
276
|
fromAccount.updatedAt = now;
|
|
@@ -262,17 +278,33 @@ export function transfer(db, config = {}) {
|
|
|
262
278
|
toAccount.totalEarned += amount;
|
|
263
279
|
toAccount.updatedAt = now;
|
|
264
280
|
|
|
265
|
-
|
|
266
|
-
|
|
281
|
+
let tx;
|
|
282
|
+
const applyWrites = () => {
|
|
283
|
+
_persistAccount(db, fromAccount);
|
|
284
|
+
_persistAccount(db, toAccount);
|
|
285
|
+
tx = _recordTransaction(db, {
|
|
286
|
+
from,
|
|
287
|
+
to,
|
|
288
|
+
amount,
|
|
289
|
+
reason: config.reason,
|
|
290
|
+
type: TX_TYPES.TRANSFER,
|
|
291
|
+
now,
|
|
292
|
+
});
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
if (db && typeof db.transaction === "function") {
|
|
297
|
+
db.transaction(applyWrites)();
|
|
298
|
+
} else {
|
|
299
|
+
applyWrites();
|
|
300
|
+
}
|
|
301
|
+
} catch (err) {
|
|
302
|
+
// Roll the in-memory Maps back so they match the rolled-back DB.
|
|
303
|
+
Object.assign(fromAccount, fromSnap);
|
|
304
|
+
Object.assign(toAccount, toSnap);
|
|
305
|
+
throw err;
|
|
306
|
+
}
|
|
267
307
|
|
|
268
|
-
const tx = _recordTransaction(db, {
|
|
269
|
-
from,
|
|
270
|
-
to,
|
|
271
|
-
amount,
|
|
272
|
-
reason: config.reason,
|
|
273
|
-
type: TX_TYPES.TRANSFER,
|
|
274
|
-
now,
|
|
275
|
-
});
|
|
276
308
|
return _strip(tx);
|
|
277
309
|
}
|
|
278
310
|
|
|
@@ -425,28 +457,59 @@ export function rewardContribution(db, contributionId, opts = {}) {
|
|
|
425
457
|
|
|
426
458
|
const now = Number(opts.now ?? Date.now());
|
|
427
459
|
const account = _ensureAccount(db, contribution.userId, now);
|
|
460
|
+
|
|
461
|
+
// Credit the account, record the ledger row and mark the contribution
|
|
462
|
+
// rewarded atomically. A partial failure would otherwise credit the balance
|
|
463
|
+
// without flipping `rewarded`, letting the same contribution be rewarded
|
|
464
|
+
// again after the next re-hydrate (double-reward).
|
|
465
|
+
const acctSnap = {
|
|
466
|
+
balance: account.balance,
|
|
467
|
+
totalEarned: account.totalEarned,
|
|
468
|
+
updatedAt: account.updatedAt,
|
|
469
|
+
};
|
|
470
|
+
const contribSnap = {
|
|
471
|
+
rewarded: contribution.rewarded,
|
|
472
|
+
rewardAmount: contribution.rewardAmount,
|
|
473
|
+
txId: contribution.txId,
|
|
474
|
+
};
|
|
475
|
+
|
|
428
476
|
account.balance += amount;
|
|
429
477
|
account.totalEarned += amount;
|
|
430
478
|
account.updatedAt = now;
|
|
431
|
-
_persistAccount(db, account);
|
|
432
|
-
|
|
433
|
-
const tx = _recordTransaction(db, {
|
|
434
|
-
from: null,
|
|
435
|
-
to: contribution.userId,
|
|
436
|
-
amount,
|
|
437
|
-
reason: `contribution:${contribution.type}:${contributionId.slice(0, 8)}`,
|
|
438
|
-
type: TX_TYPES.REWARD,
|
|
439
|
-
now,
|
|
440
|
-
});
|
|
441
479
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
480
|
+
let tx;
|
|
481
|
+
const applyWrites = () => {
|
|
482
|
+
_persistAccount(db, account);
|
|
483
|
+
tx = _recordTransaction(db, {
|
|
484
|
+
from: null,
|
|
485
|
+
to: contribution.userId,
|
|
486
|
+
amount,
|
|
487
|
+
reason: `contribution:${contribution.type}:${contributionId.slice(0, 8)}`,
|
|
488
|
+
type: TX_TYPES.REWARD,
|
|
489
|
+
now,
|
|
490
|
+
});
|
|
491
|
+
contribution.rewarded = true;
|
|
492
|
+
contribution.rewardAmount = amount;
|
|
493
|
+
contribution.txId = tx.id;
|
|
494
|
+
if (db) {
|
|
495
|
+
db.prepare(
|
|
496
|
+
`UPDATE contributions SET rewarded = ?, reward_amount = ?, tx_id = ? WHERE id = ?`,
|
|
497
|
+
).run(1, amount, tx.id, contributionId);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
445
500
|
|
|
446
|
-
|
|
447
|
-
db.
|
|
448
|
-
|
|
449
|
-
|
|
501
|
+
try {
|
|
502
|
+
if (db && typeof db.transaction === "function") {
|
|
503
|
+
db.transaction(applyWrites)();
|
|
504
|
+
} else {
|
|
505
|
+
applyWrites();
|
|
506
|
+
}
|
|
507
|
+
} catch (err) {
|
|
508
|
+
// Roll the in-memory Maps back to match the rolled-back DB.
|
|
509
|
+
Object.assign(account, acctSnap);
|
|
510
|
+
Object.assign(contribution, contribSnap);
|
|
511
|
+
if (tx) _transactions.delete(tx.id);
|
|
512
|
+
throw err;
|
|
450
513
|
}
|
|
451
514
|
|
|
452
515
|
return { contribution: _strip(contribution), tx: _strip(tx) };
|
|
@@ -512,6 +575,94 @@ export function _resetState() {
|
|
|
512
575
|
_seq = 0;
|
|
513
576
|
}
|
|
514
577
|
|
|
578
|
+
/**
|
|
579
|
+
* Rehydrate the in-memory ledger Maps from the persisted token_* tables. The CLI
|
|
580
|
+
* runs each `cc incentive` subcommand in a fresh node process, so these
|
|
581
|
+
* module-level Maps start empty every invocation. Every write dual-writes (Map +
|
|
582
|
+
* INSERT into token_accounts/token_transactions/contributions) but every read
|
|
583
|
+
* (getBalance/listAccounts/getTransactionHistory/getContributions/
|
|
584
|
+
* getLeaderboard) is Map-only and nothing SELECTed the tables back.
|
|
585
|
+
*
|
|
586
|
+
* This is worse than mere invisibility: `_ensureAccount` does `_accounts.get`
|
|
587
|
+
* (miss on a cold Map) → creates balance 0 → `_persistAccount` INSERT OR REPLACE,
|
|
588
|
+
* so a second process minting/rewarding an existing account CLOBBERS the
|
|
589
|
+
* persisted balance to 0 before applying its delta — balances never accumulate
|
|
590
|
+
* and transfers fail with "Insufficient balance: 0". Call after
|
|
591
|
+
* ensureTokenTables(db).
|
|
592
|
+
*/
|
|
593
|
+
export function loadFromDb(db) {
|
|
594
|
+
if (!db) return 0;
|
|
595
|
+
ensureTokenTables(db);
|
|
596
|
+
_accounts.clear();
|
|
597
|
+
_transactions.clear();
|
|
598
|
+
_contributions.clear();
|
|
599
|
+
|
|
600
|
+
for (const r of db
|
|
601
|
+
.prepare(
|
|
602
|
+
`SELECT id, account_id, balance, total_earned, total_spent, created_at, updated_at
|
|
603
|
+
FROM token_accounts ORDER BY created_at ASC`,
|
|
604
|
+
)
|
|
605
|
+
.all()) {
|
|
606
|
+
_accounts.set(r.account_id, {
|
|
607
|
+
id: r.id,
|
|
608
|
+
accountId: r.account_id,
|
|
609
|
+
balance: Number(r.balance) || 0,
|
|
610
|
+
totalEarned: Number(r.total_earned) || 0,
|
|
611
|
+
totalSpent: Number(r.total_spent) || 0,
|
|
612
|
+
createdAt: Number(r.created_at),
|
|
613
|
+
updatedAt: Number(r.updated_at),
|
|
614
|
+
_seq: ++_seq,
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
for (const r of db
|
|
619
|
+
.prepare(
|
|
620
|
+
`SELECT id, from_account, to_account, amount, reason, type, created_at
|
|
621
|
+
FROM token_transactions ORDER BY created_at ASC`,
|
|
622
|
+
)
|
|
623
|
+
.all()) {
|
|
624
|
+
_transactions.set(r.id, {
|
|
625
|
+
id: r.id,
|
|
626
|
+
fromAccount: r.from_account ?? null,
|
|
627
|
+
toAccount: r.to_account ?? null,
|
|
628
|
+
amount: Number(r.amount),
|
|
629
|
+
reason: r.reason ?? null,
|
|
630
|
+
type: r.type,
|
|
631
|
+
createdAt: Number(r.created_at),
|
|
632
|
+
_seq: ++_seq,
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
for (const r of db
|
|
637
|
+
.prepare(
|
|
638
|
+
`SELECT id, user_id, type, value, metadata, rewarded, reward_amount, tx_id, created_at
|
|
639
|
+
FROM contributions ORDER BY created_at ASC`,
|
|
640
|
+
)
|
|
641
|
+
.all()) {
|
|
642
|
+
// One corrupt metadata cell must not sink the whole ledger load.
|
|
643
|
+
let metadata = null;
|
|
644
|
+
try {
|
|
645
|
+
metadata = r.metadata ? JSON.parse(r.metadata) : null;
|
|
646
|
+
} catch {
|
|
647
|
+
metadata = null;
|
|
648
|
+
}
|
|
649
|
+
_contributions.set(r.id, {
|
|
650
|
+
id: r.id,
|
|
651
|
+
userId: r.user_id,
|
|
652
|
+
type: r.type,
|
|
653
|
+
value: Number(r.value) || 0,
|
|
654
|
+
metadata,
|
|
655
|
+
rewarded: !!r.rewarded,
|
|
656
|
+
rewardAmount: Number(r.reward_amount) || 0,
|
|
657
|
+
txId: r.tx_id ?? null,
|
|
658
|
+
createdAt: Number(r.created_at),
|
|
659
|
+
_seq: ++_seq,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return _accounts.size + _transactions.size + _contributions.size;
|
|
664
|
+
}
|
|
665
|
+
|
|
515
666
|
// ═══════════════════════════════════════════════════════════════
|
|
516
667
|
// Phase 66 V2 — Account + Claim lifecycle, per-user claim cap
|
|
517
668
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -159,10 +159,23 @@ export function setDefaultWallet(db, address) {
|
|
|
159
159
|
const wallet = getWallet(db, address);
|
|
160
160
|
if (!wallet) return false;
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
// Clear the current default(s) then set the new one atomically. Without a
|
|
163
|
+
// transaction, a failure on the second UPDATE leaves every wallet non-default
|
|
164
|
+
// (the default signing/sending wallet silently disappears until re-set),
|
|
165
|
+
// breaking the exactly-one-default invariant.
|
|
166
|
+
const applyWrites = () => {
|
|
167
|
+
db.prepare("UPDATE wallets SET is_default = 0 WHERE address LIKE ?").run(
|
|
168
|
+
"%",
|
|
169
|
+
);
|
|
170
|
+
db.prepare("UPDATE wallets SET is_default = 1 WHERE address = ?").run(
|
|
171
|
+
address,
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
if (db && typeof db.transaction === "function") {
|
|
175
|
+
db.transaction(applyWrites)();
|
|
176
|
+
} else {
|
|
177
|
+
applyWrites();
|
|
178
|
+
}
|
|
166
179
|
return true;
|
|
167
180
|
}
|
|
168
181
|
|
|
@@ -171,21 +184,36 @@ export function setDefaultWallet(db, address) {
|
|
|
171
184
|
*/
|
|
172
185
|
export function deleteWallet(db, address) {
|
|
173
186
|
ensureWalletTables(db);
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
.prepare("
|
|
181
|
-
.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
187
|
+
const wallet = getWallet(db, address);
|
|
188
|
+
if (!wallet) return false;
|
|
189
|
+
const wasDefault = Number(wallet.is_default) === 1;
|
|
190
|
+
|
|
191
|
+
const doDelete = () => {
|
|
192
|
+
const result = db
|
|
193
|
+
.prepare("DELETE FROM wallets WHERE address = ?")
|
|
194
|
+
.run(address);
|
|
195
|
+
// Only promote a new default when the DELETED wallet was the default —
|
|
196
|
+
// otherwise the existing default is untouched and promoting the oldest
|
|
197
|
+
// remaining wallet would leave two defaults. Promote the oldest remaining
|
|
198
|
+
// so exactly one default survives.
|
|
199
|
+
if (result.changes > 0 && wasDefault) {
|
|
200
|
+
const next = db
|
|
201
|
+
.prepare("SELECT address FROM wallets ORDER BY created_at ASC LIMIT 1")
|
|
202
|
+
.get();
|
|
203
|
+
if (next) {
|
|
204
|
+
db.prepare("UPDATE wallets SET is_default = 1 WHERE address = ?").run(
|
|
205
|
+
next.address,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
186
208
|
}
|
|
187
|
-
|
|
188
|
-
|
|
209
|
+
return result.changes;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const changes =
|
|
213
|
+
db && typeof db.transaction === "function"
|
|
214
|
+
? db.transaction(doDelete)()
|
|
215
|
+
: doDelete();
|
|
216
|
+
return changes > 0;
|
|
189
217
|
}
|
|
190
218
|
|
|
191
219
|
/**
|
|
@@ -278,28 +306,46 @@ export function transferAsset(db, assetId, toAddress, amount) {
|
|
|
278
306
|
const asset = getAsset(db, assetId);
|
|
279
307
|
if (!asset) throw new Error(`Asset not found: ${assetId}`);
|
|
280
308
|
|
|
309
|
+
// The destination must be a real local wallet — createAsset enforces the same
|
|
310
|
+
// invariant on the way in. Without this, a transfer to a bogus address moves
|
|
311
|
+
// the asset out of the sender's wallet to an address no wallet owns, so it
|
|
312
|
+
// disappears from every getAssets/getWalletSummary view (permanently orphaned).
|
|
313
|
+
const dest = getWallet(db, toAddress);
|
|
314
|
+
if (!dest) throw new Error(`Destination wallet not found: ${toAddress}`);
|
|
315
|
+
|
|
281
316
|
const txId = `tx-${crypto.randomBytes(8).toString("hex")}`;
|
|
282
317
|
const fromAddress = asset.wallet_address;
|
|
283
318
|
const txAmount = amount || asset.amount;
|
|
284
319
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
320
|
+
// Record the ledger row and move ownership atomically. Without a transaction,
|
|
321
|
+
// a failure on the ownership UPDATE would leave a "confirmed" transactions row
|
|
322
|
+
// for a transfer that never happened (the asset stays with the sender).
|
|
323
|
+
const applyWrites = () => {
|
|
324
|
+
db.prepare(
|
|
325
|
+
`INSERT INTO transactions (id, from_address, to_address, asset_id, amount, tx_type, status)
|
|
326
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
327
|
+
).run(
|
|
328
|
+
txId,
|
|
329
|
+
fromAddress,
|
|
330
|
+
toAddress,
|
|
331
|
+
assetId,
|
|
332
|
+
txAmount,
|
|
333
|
+
"transfer",
|
|
334
|
+
"confirmed",
|
|
335
|
+
);
|
|
297
336
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
337
|
+
// Update asset ownership
|
|
338
|
+
db.prepare("UPDATE digital_assets SET wallet_address = ? WHERE id = ?").run(
|
|
339
|
+
toAddress,
|
|
340
|
+
assetId,
|
|
341
|
+
);
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
if (db && typeof db.transaction === "function") {
|
|
345
|
+
db.transaction(applyWrites)();
|
|
346
|
+
} else {
|
|
347
|
+
applyWrites();
|
|
348
|
+
}
|
|
303
349
|
|
|
304
350
|
return {
|
|
305
351
|
txId,
|
package/src/lib/zkp-engine.js
CHANGED
|
@@ -471,6 +471,93 @@ export function _resetState() {
|
|
|
471
471
|
_proofExpiryMs = ZKP_DEFAULT_PROOF_EXPIRY_MS;
|
|
472
472
|
}
|
|
473
473
|
|
|
474
|
+
/**
|
|
475
|
+
* Rehydrate the in-memory Maps from the persisted zkp_* tables. The CLI runs
|
|
476
|
+
* each `cc zkp` subcommand in a fresh node process, so _circuits/_proofs/
|
|
477
|
+
* _verificationKeys/_credentials start empty every invocation. Every write
|
|
478
|
+
* dual-writes (Map + INSERT into zkp_circuits/zkp_proofs/zkp_credentials) but
|
|
479
|
+
* every read (listCircuits/listProofs/listCredentials/getZKPStats + the
|
|
480
|
+
* generateProof/verifyProof/selectiveDisclose lookups) is Map-only and nothing
|
|
481
|
+
* SELECTed the tables back — so `zkp circuits`/`proofs`/`credentials` were always
|
|
482
|
+
* empty, and `prove`/`verify`/`disclose` threw "not found" for a circuit/proof/
|
|
483
|
+
* credential that genuinely exists on disk. Call after ensureZKPTables(db).
|
|
484
|
+
*/
|
|
485
|
+
export function loadFromDb(db) {
|
|
486
|
+
if (!db) return 0;
|
|
487
|
+
ensureZKPTables(db);
|
|
488
|
+
_circuits.clear();
|
|
489
|
+
_proofs.clear();
|
|
490
|
+
_verificationKeys.clear();
|
|
491
|
+
_credentials.clear();
|
|
492
|
+
|
|
493
|
+
const parse = (v, fallback) => {
|
|
494
|
+
try {
|
|
495
|
+
return v ? JSON.parse(v) : fallback;
|
|
496
|
+
} catch {
|
|
497
|
+
return fallback;
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
for (const r of db
|
|
502
|
+
.prepare(
|
|
503
|
+
`SELECT id, name, definition, compiled, verification_key, status, created_at
|
|
504
|
+
FROM zkp_circuits ORDER BY created_at ASC`,
|
|
505
|
+
)
|
|
506
|
+
.all()) {
|
|
507
|
+
const definition = parse(r.definition, {});
|
|
508
|
+
const constraints = Array.isArray(definition.constraints)
|
|
509
|
+
? definition.constraints
|
|
510
|
+
: [];
|
|
511
|
+
_circuits.set(r.id, {
|
|
512
|
+
id: r.id,
|
|
513
|
+
name: r.name,
|
|
514
|
+
definition,
|
|
515
|
+
compiled: parse(r.compiled, {}),
|
|
516
|
+
constraints: constraints.length || 1,
|
|
517
|
+
inputs: definition.inputs || [],
|
|
518
|
+
outputs: definition.outputs || [],
|
|
519
|
+
verificationKey: r.verification_key,
|
|
520
|
+
status: r.status,
|
|
521
|
+
createdAt: r.created_at,
|
|
522
|
+
});
|
|
523
|
+
if (r.verification_key) _verificationKeys.set(r.id, r.verification_key);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
for (const r of db
|
|
527
|
+
.prepare(
|
|
528
|
+
`SELECT id, circuit_id, proof, public_inputs, verified, scheme, created_at
|
|
529
|
+
FROM zkp_proofs ORDER BY created_at ASC`,
|
|
530
|
+
)
|
|
531
|
+
.all()) {
|
|
532
|
+
_proofs.set(r.id, {
|
|
533
|
+
id: r.id,
|
|
534
|
+
circuitId: r.circuit_id,
|
|
535
|
+
scheme: r.scheme,
|
|
536
|
+
proof: parse(r.proof, {}),
|
|
537
|
+
publicInputs: parse(r.public_inputs, []),
|
|
538
|
+
verified: !!r.verified,
|
|
539
|
+
createdAt: r.created_at,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
for (const r of db
|
|
544
|
+
.prepare(
|
|
545
|
+
`SELECT id, did, claims, merkle_root, created_at
|
|
546
|
+
FROM zkp_credentials ORDER BY created_at ASC`,
|
|
547
|
+
)
|
|
548
|
+
.all()) {
|
|
549
|
+
_credentials.set(r.id, {
|
|
550
|
+
id: r.id,
|
|
551
|
+
did: r.did ?? null,
|
|
552
|
+
claims: parse(r.claims, {}),
|
|
553
|
+
merkleRoot: r.merkle_root,
|
|
554
|
+
createdAt: r.created_at,
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return _circuits.size + _proofs.size + _credentials.size;
|
|
559
|
+
}
|
|
560
|
+
|
|
474
561
|
/* ──────────────────────────────────────────────────────────
|
|
475
562
|
* V2 — Phase 88 surface (strictly additive)
|
|
476
563
|
* ────────────────────────────────────────────────────────── */
|