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/commands/stress.js
CHANGED
|
@@ -9,6 +9,7 @@ import { logger } from "../lib/logger.js";
|
|
|
9
9
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
10
10
|
import {
|
|
11
11
|
ensureStressTables,
|
|
12
|
+
loadFromDb,
|
|
12
13
|
startStressTest,
|
|
13
14
|
stopStressTest,
|
|
14
15
|
getTestResults,
|
|
@@ -41,6 +42,7 @@ function _dbFromCtx(ctx) {
|
|
|
41
42
|
}
|
|
42
43
|
const db = ctx.db.getDatabase();
|
|
43
44
|
ensureStressTables(db);
|
|
45
|
+
loadFromDb(db);
|
|
44
46
|
return db;
|
|
45
47
|
}
|
|
46
48
|
|
|
@@ -59,9 +61,17 @@ export function registerStressCommand(program) {
|
|
|
59
61
|
"Load level (light|medium|heavy|extreme)",
|
|
60
62
|
"medium",
|
|
61
63
|
)
|
|
62
|
-
.option(
|
|
64
|
+
.option(
|
|
65
|
+
"-c, --concurrency <n>",
|
|
66
|
+
"Override concurrency",
|
|
67
|
+
intArg("--concurrency"),
|
|
68
|
+
)
|
|
63
69
|
.option("-r, --rps <n>", "Override requests per second", intArg("--rps"))
|
|
64
|
-
.option(
|
|
70
|
+
.option(
|
|
71
|
+
"-d, --duration <ms>",
|
|
72
|
+
"Override duration in ms",
|
|
73
|
+
intArg("--duration"),
|
|
74
|
+
)
|
|
65
75
|
.option("--json", "Output as JSON")
|
|
66
76
|
.action(async (options) => {
|
|
67
77
|
try {
|
|
@@ -277,6 +287,7 @@ export function registerStressCommand(program) {
|
|
|
277
287
|
try {
|
|
278
288
|
const db = ctx.db.getDatabase();
|
|
279
289
|
ensureStressTables(db);
|
|
290
|
+
loadFromDb(db);
|
|
280
291
|
return await fn(db);
|
|
281
292
|
} finally {
|
|
282
293
|
await shutdown();
|
|
@@ -355,9 +366,17 @@ export function registerStressCommand(program) {
|
|
|
355
366
|
"Load level (light|medium|heavy|extreme)",
|
|
356
367
|
"medium",
|
|
357
368
|
)
|
|
358
|
-
.option(
|
|
369
|
+
.option(
|
|
370
|
+
"-c, --concurrency <n>",
|
|
371
|
+
"Override concurrency",
|
|
372
|
+
intArg("--concurrency"),
|
|
373
|
+
)
|
|
359
374
|
.option("-r, --rps <n>", "Override requests per second", intArg("--rps"))
|
|
360
|
-
.option(
|
|
375
|
+
.option(
|
|
376
|
+
"-d, --duration <ms>",
|
|
377
|
+
"Override duration in ms",
|
|
378
|
+
intArg("--duration"),
|
|
379
|
+
)
|
|
361
380
|
.option("--json", "Output as JSON")
|
|
362
381
|
.action(async (options) => {
|
|
363
382
|
try {
|
package/src/commands/team.js
CHANGED
|
@@ -345,8 +345,15 @@ export function registerTeamCommand(program, { logger } = {}) {
|
|
|
345
345
|
} else {
|
|
346
346
|
runTask = coord.makeRunTask();
|
|
347
347
|
}
|
|
348
|
-
} else if (options.exec)
|
|
349
|
-
|
|
348
|
+
} else if (options.exec) {
|
|
349
|
+
// --exec runs each task's `command` verbatim through a shell. A shared
|
|
350
|
+
// or downloaded plan file is untrusted input — surface that before we
|
|
351
|
+
// start executing it, so it's not silently treated as safe.
|
|
352
|
+
log.warn(
|
|
353
|
+
"⚠ --exec executes each task's shell `command` from the plan file. Only run plans you trust.",
|
|
354
|
+
);
|
|
355
|
+
runTask = makeShellRunTask(log);
|
|
356
|
+
} else if (options.agent)
|
|
350
357
|
runTask = makeAgentRunTask({ model: options.model });
|
|
351
358
|
else runTask = async () => ({ dryRun: true });
|
|
352
359
|
|
package/src/commands/tech.js
CHANGED
|
@@ -8,6 +8,7 @@ import { logger } from "../lib/logger.js";
|
|
|
8
8
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
9
9
|
import {
|
|
10
10
|
ensureTechLearningTables,
|
|
11
|
+
loadFromDb,
|
|
11
12
|
analyzeTechStack,
|
|
12
13
|
getProfile,
|
|
13
14
|
detectAntiPatterns,
|
|
@@ -57,6 +58,7 @@ function _dbFromCtx(ctx) {
|
|
|
57
58
|
}
|
|
58
59
|
const db = ctx.db.getDatabase();
|
|
59
60
|
ensureTechLearningTables(db);
|
|
61
|
+
loadFromDb(db);
|
|
60
62
|
return db;
|
|
61
63
|
}
|
|
62
64
|
|
package/src/commands/tenant.js
CHANGED
|
@@ -13,6 +13,7 @@ import { parseJsonOption } from "../lib/parse-json-option.js";
|
|
|
13
13
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
14
14
|
import {
|
|
15
15
|
ensureTenantTables,
|
|
16
|
+
loadFromDb as loadTenantsFromDb,
|
|
16
17
|
listPlans,
|
|
17
18
|
listMetrics,
|
|
18
19
|
createTenant,
|
|
@@ -73,6 +74,10 @@ function _dbFromCtx(ctx) {
|
|
|
73
74
|
}
|
|
74
75
|
const db = ctx.db.getDatabase();
|
|
75
76
|
ensureTenantTables(db);
|
|
77
|
+
// Rehydrate the in-memory Maps from the persisted saas_* tables — without this
|
|
78
|
+
// every read is Map-only-empty in the fresh CLI process and a tenant created
|
|
79
|
+
// in a prior invocation is invisible (No tenants. / Tenant not found).
|
|
80
|
+
loadTenantsFromDb(db);
|
|
76
81
|
return db;
|
|
77
82
|
}
|
|
78
83
|
|
|
@@ -382,7 +387,11 @@ export function registerTenantCommand(program) {
|
|
|
382
387
|
.description("Start a new subscription (cancels any prior active one)")
|
|
383
388
|
.requiredOption("-p, --plan <plan>", "Plan id")
|
|
384
389
|
.option("-a, --amount <n>", "Override amount", floatArg("--amount"))
|
|
385
|
-
.option(
|
|
390
|
+
.option(
|
|
391
|
+
"-d, --duration-ms <ms>",
|
|
392
|
+
"Duration in ms (default 30d)",
|
|
393
|
+
intArg("--duration-ms"),
|
|
394
|
+
)
|
|
386
395
|
.option("--json", "Output as JSON")
|
|
387
396
|
.action(async (tenantId, options) => {
|
|
388
397
|
try {
|
|
@@ -8,6 +8,7 @@ import { logger } from "../lib/logger.js";
|
|
|
8
8
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
9
9
|
import {
|
|
10
10
|
ensureTerraformTables,
|
|
11
|
+
loadFromDb,
|
|
11
12
|
listWorkspaces,
|
|
12
13
|
createWorkspace,
|
|
13
14
|
planRun,
|
|
@@ -49,6 +50,7 @@ export function registerTerraformCommand(program) {
|
|
|
49
50
|
}
|
|
50
51
|
const db = ctx.db.getDatabase();
|
|
51
52
|
ensureTerraformTables(db);
|
|
53
|
+
loadFromDb(db);
|
|
52
54
|
|
|
53
55
|
const workspaces = listWorkspaces({ status: options.status });
|
|
54
56
|
if (options.json) {
|
|
@@ -84,6 +86,7 @@ export function registerTerraformCommand(program) {
|
|
|
84
86
|
}
|
|
85
87
|
const db = ctx.db.getDatabase();
|
|
86
88
|
ensureTerraformTables(db);
|
|
89
|
+
loadFromDb(db);
|
|
87
90
|
|
|
88
91
|
const ws = createWorkspace(db, name, {
|
|
89
92
|
description: options.description,
|
|
@@ -114,6 +117,7 @@ export function registerTerraformCommand(program) {
|
|
|
114
117
|
}
|
|
115
118
|
const db = ctx.db.getDatabase();
|
|
116
119
|
ensureTerraformTables(db);
|
|
120
|
+
loadFromDb(db);
|
|
117
121
|
|
|
118
122
|
const run = planRun(db, workspaceId, { runType: options.type });
|
|
119
123
|
logger.success(`Run completed: ${run.planOutput}`);
|
|
@@ -142,6 +146,7 @@ export function registerTerraformCommand(program) {
|
|
|
142
146
|
}
|
|
143
147
|
const db = ctx.db.getDatabase();
|
|
144
148
|
ensureTerraformTables(db);
|
|
149
|
+
loadFromDb(db);
|
|
145
150
|
|
|
146
151
|
const runs = listRuns({ workspaceId: options.workspace });
|
|
147
152
|
if (options.json) {
|
|
@@ -173,6 +178,7 @@ export function registerTerraformCommand(program) {
|
|
|
173
178
|
try {
|
|
174
179
|
const db = ctx.db.getDatabase();
|
|
175
180
|
ensureTerraformTables(db);
|
|
181
|
+
loadFromDb(db);
|
|
176
182
|
return await fn(db);
|
|
177
183
|
} finally {
|
|
178
184
|
await shutdown();
|
package/src/commands/update.js
CHANGED
|
@@ -155,7 +155,7 @@ export function registerUpdateCommand(program) {
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
await downloadRelease(result.latestVersion, { force: options.force });
|
|
158
|
-
logger.success(
|
|
158
|
+
logger.success(`Downloaded v${result.latestVersion}`);
|
|
159
159
|
|
|
160
160
|
// Self-update the CLI npm package
|
|
161
161
|
const cliUpdated = await selfUpdateCli(result.latestVersion);
|
package/src/commands/zkp.js
CHANGED
|
@@ -9,6 +9,7 @@ import { parseJsonOption } from "../lib/parse-json-option.js";
|
|
|
9
9
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
10
10
|
import {
|
|
11
11
|
ensureZKPTables,
|
|
12
|
+
loadFromDb as loadZkpFromDb,
|
|
12
13
|
compileCircuit,
|
|
13
14
|
generateProof,
|
|
14
15
|
verifyProof,
|
|
@@ -64,6 +65,7 @@ export function registerZkpCommand(program) {
|
|
|
64
65
|
}
|
|
65
66
|
const db = ctx.db.getDatabase();
|
|
66
67
|
ensureZKPTables(db);
|
|
68
|
+
loadZkpFromDb(db);
|
|
67
69
|
|
|
68
70
|
const def = options.definition || "{}";
|
|
69
71
|
const circuit = compileCircuit(db, name, def);
|
|
@@ -100,6 +102,7 @@ export function registerZkpCommand(program) {
|
|
|
100
102
|
}
|
|
101
103
|
const db = ctx.db.getDatabase();
|
|
102
104
|
ensureZKPTables(db);
|
|
105
|
+
loadZkpFromDb(db);
|
|
103
106
|
|
|
104
107
|
const privateInputs = parseJsonOption(options.private, "--private", {});
|
|
105
108
|
const publicInputs = parseJsonOption(options.public, "--public", []);
|
|
@@ -142,6 +145,7 @@ export function registerZkpCommand(program) {
|
|
|
142
145
|
}
|
|
143
146
|
const db = ctx.db.getDatabase();
|
|
144
147
|
ensureZKPTables(db);
|
|
148
|
+
loadZkpFromDb(db);
|
|
145
149
|
|
|
146
150
|
const result = verifyProof(db, proofId);
|
|
147
151
|
if (options.json) {
|
|
@@ -212,6 +216,7 @@ export function registerZkpCommand(program) {
|
|
|
212
216
|
}
|
|
213
217
|
const db = ctx.db.getDatabase();
|
|
214
218
|
ensureZKPTables(db);
|
|
219
|
+
loadZkpFromDb(db);
|
|
215
220
|
|
|
216
221
|
const stats = getZKPStats();
|
|
217
222
|
if (options.json) {
|
|
@@ -266,6 +271,7 @@ export function registerZkpCommand(program) {
|
|
|
266
271
|
}
|
|
267
272
|
const db = ctx.db.getDatabase();
|
|
268
273
|
ensureZKPTables(db);
|
|
274
|
+
loadZkpFromDb(db);
|
|
269
275
|
|
|
270
276
|
const circuits = listCircuits(db);
|
|
271
277
|
if (options.json) {
|
|
@@ -304,6 +310,7 @@ export function registerZkpCommand(program) {
|
|
|
304
310
|
}
|
|
305
311
|
const db = ctx.db.getDatabase();
|
|
306
312
|
ensureZKPTables(db);
|
|
313
|
+
loadZkpFromDb(db);
|
|
307
314
|
|
|
308
315
|
const proofs = listProofs(db, { circuitId: options.circuit });
|
|
309
316
|
if (options.json) {
|
|
@@ -373,6 +380,7 @@ export function registerZkpCommand(program) {
|
|
|
373
380
|
}
|
|
374
381
|
const db = ctx.db.getDatabase();
|
|
375
382
|
ensureZKPTables(db);
|
|
383
|
+
loadZkpFromDb(db);
|
|
376
384
|
|
|
377
385
|
const result = setCircuitStatus(db, circuitId, status);
|
|
378
386
|
logger.success(
|
|
@@ -402,6 +410,7 @@ export function registerZkpCommand(program) {
|
|
|
402
410
|
}
|
|
403
411
|
const db = ctx.db.getDatabase();
|
|
404
412
|
ensureZKPTables(db);
|
|
413
|
+
loadZkpFromDb(db);
|
|
405
414
|
|
|
406
415
|
const claims = parseJsonOption(options.claims, "--claims", {});
|
|
407
416
|
const cred = registerCredential(db, {
|
|
@@ -444,6 +453,7 @@ export function registerZkpCommand(program) {
|
|
|
444
453
|
}
|
|
445
454
|
const db = ctx.db.getDatabase();
|
|
446
455
|
ensureZKPTables(db);
|
|
456
|
+
loadZkpFromDb(db);
|
|
447
457
|
|
|
448
458
|
const disclosed = fields
|
|
449
459
|
.split(",")
|
|
@@ -497,6 +507,7 @@ export function registerZkpCommand(program) {
|
|
|
497
507
|
}
|
|
498
508
|
const db = ctx.db.getDatabase();
|
|
499
509
|
ensureZKPTables(db);
|
|
510
|
+
loadZkpFromDb(db);
|
|
500
511
|
|
|
501
512
|
const creds = listCredentials(db, { did: options.did });
|
|
502
513
|
if (options.json) {
|
|
@@ -621,6 +632,7 @@ export function registerZkpCommand(program) {
|
|
|
621
632
|
}
|
|
622
633
|
const db = ctx.db.getDatabase();
|
|
623
634
|
ensureZKPTables(db);
|
|
635
|
+
loadZkpFromDb(db);
|
|
624
636
|
const def = parseJsonOption(options.definition, "--definition", {});
|
|
625
637
|
const circuit = compileCircuitV2(db, {
|
|
626
638
|
name,
|
|
@@ -648,6 +660,7 @@ export function registerZkpCommand(program) {
|
|
|
648
660
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
649
661
|
const db = ctx.db.getDatabase();
|
|
650
662
|
ensureZKPTables(db);
|
|
663
|
+
loadZkpFromDb(db);
|
|
651
664
|
const patch = {};
|
|
652
665
|
if (options.errorMessage !== undefined) {
|
|
653
666
|
patch.errorMessage = options.errorMessage;
|
|
@@ -672,6 +685,7 @@ export function registerZkpCommand(program) {
|
|
|
672
685
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
673
686
|
const db = ctx.db.getDatabase();
|
|
674
687
|
ensureZKPTables(db);
|
|
688
|
+
loadZkpFromDb(db);
|
|
675
689
|
const proof = generateProofV2(db, {
|
|
676
690
|
circuitId,
|
|
677
691
|
privateInputs: parseJsonOption(options.private, "--private"),
|
|
@@ -699,6 +713,7 @@ export function registerZkpCommand(program) {
|
|
|
699
713
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
700
714
|
const db = ctx.db.getDatabase();
|
|
701
715
|
ensureZKPTables(db);
|
|
716
|
+
loadZkpFromDb(db);
|
|
702
717
|
const result = verifyProofV2(db, proofId);
|
|
703
718
|
if (result.valid) {
|
|
704
719
|
logger.success(`Proof ${proofId} VERIFIED`);
|
|
@@ -723,6 +738,7 @@ export function registerZkpCommand(program) {
|
|
|
723
738
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
724
739
|
const db = ctx.db.getDatabase();
|
|
725
740
|
ensureZKPTables(db);
|
|
741
|
+
loadZkpFromDb(db);
|
|
726
742
|
failProof(db, proofId, { reason: options.reason });
|
|
727
743
|
logger.success(`Proof ${proofId} → invalid`);
|
|
728
744
|
await shutdown();
|
|
@@ -741,6 +757,7 @@ export function registerZkpCommand(program) {
|
|
|
741
757
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
742
758
|
const db = ctx.db.getDatabase();
|
|
743
759
|
ensureZKPTables(db);
|
|
760
|
+
loadZkpFromDb(db);
|
|
744
761
|
const patch = {};
|
|
745
762
|
if (options.errorMessage !== undefined) {
|
|
746
763
|
patch.errorMessage = options.errorMessage;
|
|
@@ -762,6 +779,7 @@ export function registerZkpCommand(program) {
|
|
|
762
779
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
763
780
|
const db = ctx.db.getDatabase();
|
|
764
781
|
ensureZKPTables(db);
|
|
782
|
+
loadZkpFromDb(db);
|
|
765
783
|
const expired = autoExpireProofs(db);
|
|
766
784
|
logger.success(`Expired ${expired.length} proofs`);
|
|
767
785
|
await shutdown();
|
|
@@ -792,6 +810,7 @@ export function registerZkpCommand(program) {
|
|
|
792
810
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
793
811
|
const db = ctx.db.getDatabase();
|
|
794
812
|
ensureZKPTables(db);
|
|
813
|
+
loadZkpFromDb(db);
|
|
795
814
|
const disclosedFields = options.disclosed
|
|
796
815
|
? options.disclosed
|
|
797
816
|
.split(",")
|
|
@@ -826,6 +845,7 @@ export function registerZkpCommand(program) {
|
|
|
826
845
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
827
846
|
const db = ctx.db.getDatabase();
|
|
828
847
|
ensureZKPTables(db);
|
|
848
|
+
loadZkpFromDb(db);
|
|
829
849
|
const stats = getZKPStatsV2();
|
|
830
850
|
console.log(JSON.stringify(stats, null, 2));
|
|
831
851
|
await shutdown();
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
handleRemoteSessionPushRegister,
|
|
20
20
|
handleRemoteSessionRevoke,
|
|
21
21
|
} from "./remote-session-protocol.js";
|
|
22
|
+
import { RemoteCommandLedger } from "../../harness/remote-command-ledger.js";
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Reconnect-safe command execution. When a message carries a stable
|
|
@@ -35,9 +36,11 @@ async function executeWithIdempotency(server, id, ws, message, stream) {
|
|
|
35
36
|
if (!commandId) {
|
|
36
37
|
return server._executeCommand(id, ws, message.command, stream);
|
|
37
38
|
}
|
|
39
|
+
// Create the ledger SYNCHRONOUSLY (no await between the check and the assign)
|
|
40
|
+
// so two concurrent re-deliveries of the same commandId share ONE ledger and
|
|
41
|
+
// coalesce; a lazy `await import()` here would let each build its own ledger
|
|
42
|
+
// and both would execute — the exact double-exec this guards against.
|
|
38
43
|
if (!server._commandLedger) {
|
|
39
|
-
const { RemoteCommandLedger } =
|
|
40
|
-
await import("../../harness/remote-command-ledger.js");
|
|
41
44
|
server._commandLedger = new RemoteCommandLedger();
|
|
42
45
|
}
|
|
43
46
|
const outcome = await server._commandLedger.apply(
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
RemoteSessionCryptoContext,
|
|
8
8
|
createRemotePairingUri,
|
|
9
9
|
} from "../../harness/remote-session-crypto.js";
|
|
10
|
+
import { RemoteCommandLedger } from "../../harness/remote-command-ledger.js";
|
|
10
11
|
|
|
11
12
|
const CLIENT_EVENT_SCOPES = Object.freeze({
|
|
12
13
|
prompt: "prompt",
|
|
@@ -22,6 +23,55 @@ function audit(server, entry) {
|
|
|
22
23
|
server.remoteSessionAudit?.record(entry);
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Apply a remote-client control event (prompt / approval.resolve / interrupt)
|
|
28
|
+
* idempotently when it carries a stable `commandId`. This is the ACTUAL takeover
|
|
29
|
+
* path — a paired mobile/web device driving the host agent — and it does NOT
|
|
30
|
+
* flow through message-dispatcher's execute/stream ledger, so without this a
|
|
31
|
+
* prompt re-sent after a dropped connection would run the agent turn a SECOND
|
|
32
|
+
* time (Phase 5 acceptance "断网恢复后不会重复执行工具调用"). The side effect
|
|
33
|
+
* (audit + dispatch into the host session) runs AT MOST ONCE per commandId; a
|
|
34
|
+
* re-delivery gets a `replayed` ack instead. Byte-identical when the event
|
|
35
|
+
* carries no `commandId` (existing clients unchanged). deviceId is the
|
|
36
|
+
* AUTHENTICATED clientId, so a device can never spoof another's idempotency /
|
|
37
|
+
* ordering stream. A revoked device / stale seq is rejected without forwarding.
|
|
38
|
+
* Uses a ledger SEPARATE from the execute/stream one (`_commandLedger`) so the
|
|
39
|
+
* two paths keep independent per-device sequence spaces.
|
|
40
|
+
*/
|
|
41
|
+
async function applyControlIdempotent(server, clientId, ws, message, forward) {
|
|
42
|
+
const commandId = message.commandId;
|
|
43
|
+
if (!commandId) return forward();
|
|
44
|
+
// Create the ledger SYNCHRONOUSLY (no await between the check and the assign)
|
|
45
|
+
// so two concurrent re-deliveries of the same commandId share ONE ledger and
|
|
46
|
+
// coalesce — a lazy `await import()` here would let each build its own ledger
|
|
47
|
+
// and both would execute, defeating the whole guarantee.
|
|
48
|
+
if (!server._remoteControlLedger) {
|
|
49
|
+
server._remoteControlLedger = new RemoteCommandLedger();
|
|
50
|
+
}
|
|
51
|
+
const outcome = await server._remoteControlLedger.apply(
|
|
52
|
+
{ commandId, deviceId: clientId, seq: message.seq },
|
|
53
|
+
async () => {
|
|
54
|
+
await forward();
|
|
55
|
+
return true;
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
if (outcome.status === "replayed") {
|
|
59
|
+
reply(server, ws, message.id, "remote-session-published", {
|
|
60
|
+
delivered: 0,
|
|
61
|
+
replayed: true,
|
|
62
|
+
commandId,
|
|
63
|
+
applyIndex: outcome.applyIndex,
|
|
64
|
+
});
|
|
65
|
+
} else if (outcome.status === "rejected") {
|
|
66
|
+
reply(server, ws, message.id, "error", {
|
|
67
|
+
code: "COMMAND_REJECTED",
|
|
68
|
+
commandId,
|
|
69
|
+
message: outcome.reason,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return outcome;
|
|
73
|
+
}
|
|
74
|
+
|
|
25
75
|
function attachPairingUri(server, result) {
|
|
26
76
|
const relayUrl = server.remoteSessionRelayUrl;
|
|
27
77
|
const hostPeerId = server.remoteSessionPeerId;
|
|
@@ -395,49 +445,60 @@ export async function handleRemoteSessionPublish(
|
|
|
395
445
|
id: message.id,
|
|
396
446
|
sessionId: session.agentSessionId,
|
|
397
447
|
};
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
audit(server, {
|
|
408
|
-
sessionId: message.remoteSessionId,
|
|
409
|
-
actor: clientId,
|
|
410
|
-
action: "control.prompt",
|
|
411
|
-
detail: { chars: message.event.content.length },
|
|
412
|
-
});
|
|
413
|
-
handleSessionMessage(server, message.id, ws, {
|
|
414
|
-
...controlMessage,
|
|
415
|
-
content: message.event.content,
|
|
416
|
-
});
|
|
417
|
-
} else if (message.event.type === "approval.resolve") {
|
|
418
|
-
audit(server, {
|
|
419
|
-
sessionId: message.remoteSessionId,
|
|
420
|
-
actor: clientId,
|
|
421
|
-
action: "control.approval",
|
|
422
|
-
detail: {
|
|
423
|
-
requestId: message.event.requestId || message.event.approvalId,
|
|
424
|
-
approved: message.event.answer ?? message.event.approved,
|
|
425
|
-
},
|
|
426
|
-
});
|
|
427
|
-
await handleSessionAnswer(server, message.id, ws, {
|
|
428
|
-
...controlMessage,
|
|
429
|
-
requestId: message.event.requestId || message.event.approvalId,
|
|
430
|
-
answer: message.event.answer ?? message.event.approved,
|
|
431
|
-
});
|
|
432
|
-
} else if (message.event.type === "interrupt") {
|
|
433
|
-
audit(server, {
|
|
434
|
-
sessionId: message.remoteSessionId,
|
|
435
|
-
actor: clientId,
|
|
436
|
-
action: "control.interrupt",
|
|
437
|
-
detail: null,
|
|
438
|
-
});
|
|
439
|
-
await handleSessionInterrupt(server, message.id, ws, controlMessage);
|
|
448
|
+
// Validate up-front so a malformed control event errors identically
|
|
449
|
+
// whether or not it carries a commandId — idempotency must never change
|
|
450
|
+
// validation semantics (a bad prompt must not consume a commandId slot).
|
|
451
|
+
if (
|
|
452
|
+
message.event.type === "prompt" &&
|
|
453
|
+
(typeof message.event.content !== "string" ||
|
|
454
|
+
!message.event.content.trim())
|
|
455
|
+
) {
|
|
456
|
+
throw new Error("prompt content is required");
|
|
440
457
|
}
|
|
458
|
+
// Idempotent forward: a control event with a stable commandId runs its
|
|
459
|
+
// side effect (audit + dispatch into the host agent) AT MOST ONCE, so a
|
|
460
|
+
// reconnecting device re-sending the same prompt/approval/interrupt gets a
|
|
461
|
+
// `replayed` ack instead of a second agent turn. No commandId → forwarded
|
|
462
|
+
// directly, byte-identical to before.
|
|
463
|
+
await applyControlIdempotent(server, clientId, ws, message, async () => {
|
|
464
|
+
if (message.event.type === "prompt") {
|
|
465
|
+
// Record the shape, not the content — the audit trail must stay
|
|
466
|
+
// useful without hoarding potentially sensitive session prompts.
|
|
467
|
+
audit(server, {
|
|
468
|
+
sessionId: message.remoteSessionId,
|
|
469
|
+
actor: clientId,
|
|
470
|
+
action: "control.prompt",
|
|
471
|
+
detail: { chars: message.event.content.length },
|
|
472
|
+
});
|
|
473
|
+
handleSessionMessage(server, message.id, ws, {
|
|
474
|
+
...controlMessage,
|
|
475
|
+
content: message.event.content,
|
|
476
|
+
});
|
|
477
|
+
} else if (message.event.type === "approval.resolve") {
|
|
478
|
+
audit(server, {
|
|
479
|
+
sessionId: message.remoteSessionId,
|
|
480
|
+
actor: clientId,
|
|
481
|
+
action: "control.approval",
|
|
482
|
+
detail: {
|
|
483
|
+
requestId: message.event.requestId || message.event.approvalId,
|
|
484
|
+
approved: message.event.answer ?? message.event.approved,
|
|
485
|
+
},
|
|
486
|
+
});
|
|
487
|
+
await handleSessionAnswer(server, message.id, ws, {
|
|
488
|
+
...controlMessage,
|
|
489
|
+
requestId: message.event.requestId || message.event.approvalId,
|
|
490
|
+
answer: message.event.answer ?? message.event.approved,
|
|
491
|
+
});
|
|
492
|
+
} else if (message.event.type === "interrupt") {
|
|
493
|
+
audit(server, {
|
|
494
|
+
sessionId: message.remoteSessionId,
|
|
495
|
+
actor: clientId,
|
|
496
|
+
action: "control.interrupt",
|
|
497
|
+
detail: null,
|
|
498
|
+
});
|
|
499
|
+
await handleSessionInterrupt(server, message.id, ws, controlMessage);
|
|
500
|
+
}
|
|
501
|
+
});
|
|
441
502
|
return;
|
|
442
503
|
}
|
|
443
504
|
|
|
@@ -438,12 +438,19 @@ function performLegacySessionMigration(sourcePath, options) {
|
|
|
438
438
|
}
|
|
439
439
|
|
|
440
440
|
const validation = validateJsonlSession(sessionId);
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
)
|
|
441
|
+
// Verify EVERY legacy message persisted, by event count — NOT by
|
|
442
|
+
// `messageCount`, which counts only user_message/assistant_message events.
|
|
443
|
+
// A legacy `system` message becomes a `system` event and a `tool` message a
|
|
444
|
+
// `tool_result` event (see appendLegacyMessage); neither is a "message" by
|
|
445
|
+
// that count, so comparing messageCount to legacy.messages.length wrongly
|
|
446
|
+
// FAILED migration for any session with a system prompt or tool call.
|
|
447
|
+
// appendLegacyMessage writes exactly one event per message, plus the leading
|
|
448
|
+
// session_start and an optional trailing summary event.
|
|
449
|
+
const expectedEvents =
|
|
450
|
+
1 + legacy.messages.length + (legacy.summary ? 1 : 0);
|
|
451
|
+
if (!validation.valid || validation.eventCount !== expectedEvents) {
|
|
445
452
|
throw new Error(
|
|
446
|
-
`post-migration validation failed for ${sessionId} (${validation.
|
|
453
|
+
`post-migration validation failed for ${sessionId} (${validation.eventCount}/${expectedEvents} events)`,
|
|
447
454
|
);
|
|
448
455
|
}
|
|
449
456
|
|
|
@@ -11,6 +11,7 @@ import crypto from "crypto";
|
|
|
11
11
|
import fs from "fs";
|
|
12
12
|
import path from "path";
|
|
13
13
|
import { getElectronUserDataDir } from "../lib/paths.js";
|
|
14
|
+
import { escapeLike } from "../lib/sql-like.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Ensure plugin tables exist.
|
|
@@ -288,11 +289,15 @@ export function registerInMarketplace(db, pluginInfo) {
|
|
|
288
289
|
*/
|
|
289
290
|
export function searchRegistry(db, query) {
|
|
290
291
|
ensurePluginTables(db);
|
|
292
|
+
// Escape LIKE metacharacters so a query containing % or _ is matched
|
|
293
|
+
// literally — otherwise `cc plugin search "%"` (or any term with _) is treated
|
|
294
|
+
// as a wildcard and matches EVERY registry row instead of the intended text.
|
|
295
|
+
const pattern = `%${escapeLike(query)}%`;
|
|
291
296
|
return db
|
|
292
297
|
.prepare(
|
|
293
|
-
"SELECT * FROM plugin_registry WHERE name LIKE ? OR description LIKE ? ORDER BY downloads DESC",
|
|
298
|
+
"SELECT * FROM plugin_registry WHERE name LIKE ? ESCAPE '\\' OR description LIKE ? ESCAPE '\\' ORDER BY downloads DESC",
|
|
294
299
|
)
|
|
295
|
-
.all(
|
|
300
|
+
.all(pattern, pattern);
|
|
296
301
|
}
|
|
297
302
|
|
|
298
303
|
/**
|
|
@@ -352,7 +357,11 @@ export function installPluginSkills(db, pluginName, pluginPath, skills) {
|
|
|
352
357
|
const installed = [];
|
|
353
358
|
|
|
354
359
|
for (const skill of skills) {
|
|
355
|
-
if (
|
|
360
|
+
if (
|
|
361
|
+
!skill ||
|
|
362
|
+
typeof skill.name !== "string" ||
|
|
363
|
+
typeof skill.path !== "string"
|
|
364
|
+
) {
|
|
356
365
|
continue;
|
|
357
366
|
}
|
|
358
367
|
const srcDir = path.resolve(pluginPath, skill.path);
|
|
@@ -363,7 +372,10 @@ export function installPluginSkills(db, pluginName, pluginPath, skills) {
|
|
|
363
372
|
if (!fs.existsSync(srcDir)) continue;
|
|
364
373
|
|
|
365
374
|
const destDir = path.join(marketplaceDir, skill.name);
|
|
366
|
-
if (
|
|
375
|
+
if (
|
|
376
|
+
!_isWithin(marketplaceDir, destDir) ||
|
|
377
|
+
path.resolve(destDir) === path.resolve(marketplaceDir)
|
|
378
|
+
) {
|
|
367
379
|
continue;
|
|
368
380
|
}
|
|
369
381
|
fs.mkdirSync(destDir, { recursive: true });
|