chainlesschain 0.162.148 → 0.162.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DwpCCp64.js → AIOps-CBLvrjeG.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C9pBYocA.js → ActionButton-DYv2GtE0.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BWAkeXxK.js → Analytics-CL6PZ-Ww.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CivFGH6B.js → AppLayout-xuyHt4uA.js} +3 -3
- package/src/assets/web-panel/assets/{Audit-Cm8hRpZm.js → Audit-DOvSVycq.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DXdFMsE8.js → Backup-DMhfTswr.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-uAwSTeql.js → BaseInput-CQxDdm63.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-KU8eeJJE.js → Chat-BEeNhK2a.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-8nul8eTq.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-C6AMDkjd.js → Checkbox-CL04O-ER.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-t2moDxcO.js → Codegen-C50o-n7x.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DCcsRRhN.js → Col-CH-bDkzs.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DtB-8SAC.js → Community-DqAIMvSe.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CZm8THYA.js → Compact-C43fo_my.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-LiQgC7g1.js → Compliance-BERnMrdP.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CA8SAxht.js → Cowork-Baw3w1gp.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-CtRaF1wD.js → Cron-BEqAHF1-.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-6-br6Hub.js → Crosschain-CvnmKwK4.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Do2EccrL.js → DID-iMPxgVdt.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-wrXcbzGe.js → Dashboard--4SJX3YR.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-p3FsT245.js → Dropdown-BgLV6xgz.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-D95A2L8q.js → EmailListRenderer-Bvb8oUD8.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-cLuJW2zo.js → FamilyGuardDashboard-DpXPjJB5.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Brgq_cbN.js → Federation-BbFfJ1Xi.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DWLCkNgh.js → FormItemContext-DeGq1B-q.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BBqUfQd6.js → GenericCardRenderer-CNW7s9zM.js} +1 -1
- package/src/assets/web-panel/assets/{Git-8F090w4I.js → Git-L1PjW-lT.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CCogEbxb.js → Governance-PK-X58to.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CfLD7v7C.js → Inference-BePWEH-d.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DDuHJewd.js → KnowledgeGraph-LF_sBvdL.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CE8KSEVC.js → Logs-BKkfk9hy.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-DmwpZmhT.js → Marketplace-BNMqUDla.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Bf7AazU8.js → McpTools-w4WPiyz2.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-D0QU_00S.js → Memory-DUKMVGNi.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-yXS9xdhx.js → MobileBridge-BWhiEyTJ.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BuDUoGUP.js → MobileProjects-Ocf5JEkX.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BYyHy28p.js → Mtc-D2B6MMhU.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CK0aqpiZ.js → MtcAudit-DdYjCq1O.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-mNimKYeb.js → Multisig-Cb1hfuUZ.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-AioAJ0YA.js → NLProgramming-CTeImGp7.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CVVNCLHE.js → Notes-BjYNc7eQ.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-C4ABj-TK.js → NotificationSettings-Dn_NtRXQ.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DIp8Xcbd.js → OrderTableRenderer-DVYYIizh.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-uozl_gWK.js → Organization-Be2Kmr5j.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BCZOM2hK.js → Overflow-Cu_-qRlR.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CArcaiaj.js → P2P-DD2HoGzE.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Sgq2Srr8.js → PdhVaultBrowser-BRI7DVth.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BYrQrXnH.js → Permissions-C9Srcs2M.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BzHStAbz.js → PersonalDataHub-CUqcMgo1.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-k7KqxX1M.js → Pipeline-HBrQGLXt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-IumTUWqx.js → Privacy-D-B0vjwh.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BRyImYTf.js → ProjectInit-eTeLIu9e.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BFIqTBFk.js → ProjectSettings-DrRqCsC6.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Dpid9CDg.js → Projects-1G9DNOhI.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CyyFnUPs.js → Providers-RkTZzpxP.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-C82cRx-X.js → QrScannerModal-BSCUgsgC.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DGxDF521.js → QuickAsk-CHgyM3Bz.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Cns-Am1y.js → Recommend-0lry4OZq.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-R7OqAIlg.js → RemoteSession-Cn45UroZ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-D7mgPIYV.js → Reputation-Q-Zjb707.js} +1 -1
- package/src/assets/web-panel/assets/{Row-B3lEURyd.js → Row-BdM70oda.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-9_UVrpBt.js → RssFeed-DmOAKKap.js} +2 -2
- package/src/assets/web-panel/assets/{Search-ClZeO80q.js → Search-Dwavbm07.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BNNJczEp.js → Security-DukXFCnk.js} +3 -3
- package/src/assets/web-panel/assets/{Services-C5SjrWUj.js → Services-BIlRnITu.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Ci_obQ-g.js → Skeleton-YYVQdhhQ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DdebN15P.js → Skills-B8_iYHz2.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-OinZP2vi.js → Sla-BdVrhT31.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CxzbNF51.js → SpeechSettings-CD3ggRx7.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-D06N_66b.js → SyncSettings-Bp02VZFH.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BdEdW0AZ.js → Tasks-DEVmCEsr.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-F1ctKmPa.js → Templates-B6czWc4N.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CVz1Urot.js → Tenant-BCJLv17r.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-CD132d2Y.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-Doitzjmf.js → TimelineRenderer-ZB-CvkZl.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BpyVRpVA.js → Tokens-BnSY0S-s.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-nWhWYTbU.js → Trigger-VZw9Oy2w.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DK_G-wLx.js → Trust-pZq7Hjd2.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B5yBUojO.js → UkeySign-DnQaqk4q.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C5D51qAe.js → VideoEditing-BEUfmvJV.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CLbL9K7v.js → Wallet-CoZKMXJ2.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DZUelI3V.js → WebAuthn-CBOGVx1I.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-8RPxt4KW.js → WorkflowEditor-huSKn7TT.js} +1 -1
- package/src/assets/web-panel/assets/{chat-4N4tOA3d.js → chat-A_3w6FBO.js} +1 -1
- package/src/assets/web-panel/assets/{colors-zbbGVrua.js → colors-D1Bem9Oy.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-D7iMkbnE.js → compact-item-CJYJj0oO.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CBzPJv-w.js → createContext-BkbFiKT4.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-WDr3_M_N.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-bHdrQSqZ.js → hasIn-CKvUafVY.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbE5D0WL.js → index-AjrSPnvv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCr0geV9.js → index-B8i0lViZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiG1IZao.js → index-B9Svn0zc.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1s0Bz9O.js → index-BHdHSX06.js} +1 -1
- package/src/assets/web-panel/assets/{index-QFObYeo1.js → index-BHdailyo.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnBOpqv3.js → index-BJwlEnYo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdmMoYN1.js → index-BOoAQjJz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUyjUkY7.js → index-BSgWxAOG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqdPyWm5.js → index-BdutMsne.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmqlJed-.js → index-BiDWxzbn.js} +1 -1
- package/src/assets/web-panel/assets/{index-S74FpAIn.js → index-By5a0T_W.js} +1 -1
- package/src/assets/web-panel/assets/{index-kmh1TxRa.js → index-C-WIY-FQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTIjjXry.js → index-C37f6iey.js} +1 -1
- package/src/assets/web-panel/assets/{index-BS4_Mwk6.js → index-C9bWmTcO.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBNr77E1.js → index-CBaosWRO.js} +1 -1
- package/src/assets/web-panel/assets/{index-QNAG4JtR.js → index-CBlBVJ_m.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bqmx24kh.js → index-CD62EEGo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQfu1U78.js → index-CUj-l7GM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJ4ZGyW0.js → index-CVS8Ymuq.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ci009ijp.js → index-ChkXUj3f.js} +1 -1
- package/src/assets/web-panel/assets/{index-oDKNgCsP.js → index-Cj0OZ-37.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZb8F8YG.js → index-Co3OFL0t.js} +1 -1
- package/src/assets/web-panel/assets/{index-308gCGh7.js → index-Crp8CbRg.js} +1 -1
- package/src/assets/web-panel/assets/{index-CPxkoKgA.js → index-D22zNXiS.js} +1 -1
- package/src/assets/web-panel/assets/{index-xYCm6W2h.js → index-DTs_D1OL.js} +1 -1
- package/src/assets/web-panel/assets/{index-BtbbdLnf.js → index-DfgCdFrN.js} +3 -3
- package/src/assets/web-panel/assets/{index-BsKehmmS.js → index-DjYrecNb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkxK86vf.js → index-DpW9cf3e.js} +1 -1
- package/src/assets/web-panel/assets/index-Dwix3p4g.js +1 -0
- package/src/assets/web-panel/assets/{index-CvRMA9uT.js → index-F--HuPG1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE9j5YgT.js → index-Fuk6t_3K.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7b1hGry.js → index-JEAGMii9.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1YDh7Wr.js → index-PF-mpv8K.js} +1 -1
- package/src/assets/web-panel/assets/index-SHaoZ0CA.js +1 -0
- package/src/assets/web-panel/assets/{index-CQ6NcfWz.js → index-b-sbVdjQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DyoNgbXl.js → index-pyvMVX8r.js} +1 -1
- package/src/assets/web-panel/assets/{index-DISWAYce.js → index-qNTtOVi_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4XKpj6c.js → index-tgO8iza6.js} +1 -1
- package/src/assets/web-panel/assets/{index-CahryTX0.js → index-ttDQVhZy.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BD55yNBt.js → initDefaultProps-DtrnfsZH.js} +1 -1
- package/src/assets/web-panel/assets/{motion-B5Bbe77U.js → motion-D4zqSaX3.js} +1 -1
- package/src/assets/web-panel/assets/{move-CTvIqHEH.js → move-CGFGOUQj.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BkNyPQKB.js → mtc-parser-DH2HvkJl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BaXJXgHA.js → omit-jJ2at5HX.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Bw6-YTxH.js → pickAttrs-CRyMT1Fv.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BLdbkLqJ.js → placementArrow-DZ_CX0Pt.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-IVYkzntU.js → responsiveObserve-wruHk-h5.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DFMFwwtY.js → slide-BGgx8q67.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CURYRtZ1.js → statusUtils-Do5M7gKm.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Cfz63s1r.js → styleChecker-CRa-GZpX.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-COJL0KE3.js → useFlexGapSupport-BxPcq6pj.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-YLLojQQf.js → useFs-v5O2ZcJm.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BF_21qUC.js → usePersonalDataHub--z2FU0Px.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-9ZpkA7bb.js → vnode-1emidVKd.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DhtAfhl8.js → zoom-CcJaRyHs.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/assets/web-panel/remote-session-sw.js +43 -0
- package/src/command-manifest.json +22 -1
- package/src/commands/a2a.js +19 -4
- package/src/commands/activitypub.js +20 -3
- package/src/commands/agent.js +71 -10
- package/src/commands/audit.js +40 -24
- package/src/commands/codeintel.js +320 -0
- package/src/commands/collab.js +15 -2
- package/src/commands/compliance.js +5 -0
- package/src/commands/config.js +4 -1
- package/src/commands/dao.js +86 -14
- package/src/commands/dev.js +2 -0
- package/src/commands/did.js +7 -1
- package/src/commands/dlp.js +23 -1
- package/src/commands/economy.js +29 -3
- package/src/commands/eval.js +255 -0
- package/src/commands/evomap.js +26 -0
- package/src/commands/governance.js +17 -3
- package/src/commands/hardening.js +18 -0
- package/src/commands/incentive.js +5 -0
- package/src/commands/init.js +46 -2
- package/src/commands/kg.js +4 -0
- package/src/commands/loop.js +6 -1
- package/src/commands/lowcode.js +15 -2
- package/src/commands/marketplace.js +40 -6
- package/src/commands/matrix.js +20 -1
- package/src/commands/memory.js +4 -1
- package/src/commands/mtc.js +7 -1
- package/src/commands/nostr.js +31 -4
- package/src/commands/note.js +7 -4
- package/src/commands/plugin.js +474 -0
- package/src/commands/pqc.js +5 -0
- package/src/commands/reputation.js +10 -1
- package/src/commands/scim.js +6 -0
- package/src/commands/session.js +32 -10
- package/src/commands/siem.js +11 -0
- package/src/commands/sla.js +18 -3
- package/src/commands/social.js +38 -5
- package/src/commands/sso.js +10 -2
- package/src/commands/stress.js +23 -4
- package/src/commands/team.js +463 -0
- package/src/commands/tech.js +2 -0
- package/src/commands/tenant.js +10 -1
- package/src/commands/terraform.js +6 -0
- package/src/commands/update.js +1 -1
- package/src/commands/zkp.js +20 -0
- package/src/gateways/ws/message-dispatcher.js +48 -2
- package/src/gateways/ws/remote-session-protocol.js +140 -42
- package/src/gateways/ws/ws-server.js +1 -1
- package/src/harness/jsonl-session-store.js +12 -5
- package/src/harness/plugin-manager.js +16 -4
- package/src/harness/prompt-compressor.js +27 -1
- package/src/harness/remote-command-ledger.js +189 -0
- package/src/harness/remote-session-push-apns.js +246 -0
- package/src/harness/remote-session-push-errors.js +15 -0
- package/src/harness/remote-session-push-fcm.js +9 -25
- package/src/harness/remote-session-push-huawei.js +174 -0
- package/src/harness/remote-session-push-oppo.js +171 -0
- package/src/harness/remote-session-push-senders.js +42 -0
- package/src/harness/remote-session-push-vivo.js +179 -0
- package/src/harness/remote-session-push-web.js +299 -0
- package/src/harness/remote-session-push-xiaomi.js +99 -0
- package/src/harness/worktree-isolator.js +16 -6
- package/src/index.js +6 -0
- package/src/lib/__tests__/logger.test.js +5 -2
- package/src/lib/a2a-protocol.js +25 -1
- package/src/lib/activitypub-bridge.js +61 -0
- package/src/lib/agent-core.js +4 -0
- package/src/lib/agent-economy.js +262 -29
- package/src/lib/agent-network.js +7 -1
- package/src/lib/agent-sandbox.js +161 -5
- package/src/lib/agent-team/task-lease.js +434 -0
- package/src/lib/agent-team/team-budget.js +165 -0
- package/src/lib/agent-team/team-mailbox.js +106 -0
- package/src/lib/agent-team/team-runner.js +282 -0
- package/src/lib/agent-team/team-worktree.js +236 -0
- package/src/lib/agents.js +18 -0
- package/src/lib/async-hook-supervisor.cjs +391 -0
- package/src/lib/audit-logger.js +7 -6
- package/src/lib/autonomous-developer.js +60 -0
- package/src/lib/chat-core.js +17 -4
- package/src/lib/collaboration-governance.js +56 -0
- package/src/lib/community-governance.js +68 -0
- package/src/lib/compliance-manager.js +63 -0
- package/src/lib/cross-chain.js +5 -0
- package/src/lib/dao-governance.js +151 -2
- package/src/lib/did-manager.js +23 -10
- package/src/lib/dlp-engine.js +70 -0
- package/src/lib/eval/runner.js +251 -0
- package/src/lib/eval/tasks.js +626 -0
- package/src/lib/eval/trend.js +200 -0
- package/src/lib/evolution-system.js +92 -0
- package/src/lib/evomap-federation.js +55 -0
- package/src/lib/evomap-governance.js +94 -0
- package/src/lib/fatal-handler.js +17 -1
- package/src/lib/hardening-manager.js +73 -0
- package/src/lib/hierarchical-memory.js +14 -8
- package/src/lib/knowledge-exporter.js +8 -2
- package/src/lib/knowledge-graph.js +79 -0
- package/src/lib/llm-providers.js +23 -14
- package/src/lib/logger.js +4 -1
- package/src/lib/lsp/__tests__/benchmark.test.js +88 -0
- package/src/lib/lsp/__tests__/code-intelligence.integration.test.js +129 -0
- package/src/lib/lsp/__tests__/code-intelligence.test.js +228 -0
- package/src/lib/lsp/__tests__/jsonrpc-stream.test.js +104 -0
- package/src/lib/lsp/__tests__/lsp-client.test.js +269 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +333 -0
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +128 -0
- package/src/lib/lsp/benchmark.js +257 -0
- package/src/lib/lsp/code-intelligence.js +356 -0
- package/src/lib/lsp/jsonrpc-stream.js +139 -0
- package/src/lib/lsp/lsp-client.js +339 -0
- package/src/lib/lsp/lsp-manager.js +375 -0
- package/src/lib/lsp/lsp-server-registry.js +196 -0
- package/src/lib/matrix-bridge.js +84 -0
- package/src/lib/memory-manager.js +5 -3
- package/src/lib/nostr-bridge.js +53 -0
- package/src/lib/permission-engine.js +22 -4
- package/src/lib/plugin-monitor-supervisor.js +238 -0
- package/src/lib/plugin-runtime/__tests__/remote-source.test.js +256 -0
- package/src/lib/plugin-runtime/agents.js +51 -0
- package/src/lib/plugin-runtime/bin.js +100 -0
- package/src/lib/plugin-runtime/hooks.js +100 -0
- package/src/lib/plugin-runtime/install.js +396 -0
- package/src/lib/plugin-runtime/lsp.js +75 -0
- package/src/lib/plugin-runtime/manifest.js +458 -0
- package/src/lib/plugin-runtime/mcp.js +89 -0
- package/src/lib/plugin-runtime/monitors.js +100 -0
- package/src/lib/plugin-runtime/policy.js +152 -0
- package/src/lib/plugin-runtime/reload.js +79 -0
- package/src/lib/plugin-runtime/remote-source.js +240 -0
- package/src/lib/plugin-runtime/scopes.js +197 -0
- package/src/lib/plugin-runtime/settings.js +119 -0
- package/src/lib/plugin-runtime/signature.js +107 -0
- package/src/lib/plugin-runtime/skills.js +43 -0
- package/src/lib/plugin-runtime/trust.js +140 -0
- package/src/lib/pqc-manager.js +64 -0
- package/src/lib/reputation-optimizer.js +101 -0
- package/src/lib/sandbox-egress-proxy.js +262 -0
- package/src/lib/sandbox-fs-policy.js +112 -0
- package/src/lib/sandbox-network-policy.js +151 -0
- package/src/lib/sandbox-v2.js +24 -18
- package/src/lib/scim-manager.js +36 -0
- package/src/lib/session-manager.js +5 -2
- package/src/lib/settings-hook-events.cjs +78 -6
- package/src/lib/settings-hooks.cjs +30 -3
- package/src/lib/settings-loader.cjs +35 -1
- package/src/lib/siem-exporter.js +45 -0
- package/src/lib/skill-loader.js +38 -2
- package/src/lib/skill-marketplace.js +83 -0
- package/src/lib/sla-manager.js +88 -0
- package/src/lib/social-manager.js +74 -0
- package/src/lib/stress-tester.js +65 -0
- package/src/lib/tech-learning-engine.js +75 -0
- package/src/lib/telemetry/span-recorder.js +237 -0
- package/src/lib/tenant-saas.js +107 -0
- package/src/lib/terraform-manager.js +67 -0
- package/src/lib/token-incentive.js +180 -29
- package/src/lib/wallet-manager.js +81 -35
- package/src/lib/zkp-engine.js +87 -0
- package/src/repl/agent-repl.js +417 -6
- package/src/runtime/__tests__/auto-pin.test.js +104 -0
- package/src/runtime/agent-core.js +771 -104
- package/src/runtime/auto-pin.js +117 -0
- package/src/runtime/coding-agent-contract-shared.cjs +82 -8
- package/src/runtime/coding-agent-policy.cjs +32 -7
- package/src/runtime/fallback-model.js +134 -7
- package/src/runtime/headless-runner.js +388 -108
- package/src/runtime/mcp-config.js +46 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DCNfbdlx.js +0 -1
- package/src/assets/web-panel/assets/Terminal-BvAK_Zel.js +0 -3
- package/src/assets/web-panel/assets/devWarning-C2Z5LRgq.js +0 -1
- package/src/assets/web-panel/assets/index-BGp6Yr-Y.js +0 -1
- package/src/assets/web-panel/assets/index-BXiw9dQf.js +0 -1
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,52 @@ import {
|
|
|
19
19
|
handleRemoteSessionPushRegister,
|
|
20
20
|
handleRemoteSessionRevoke,
|
|
21
21
|
} from "./remote-session-protocol.js";
|
|
22
|
+
import { RemoteCommandLedger } from "../../harness/remote-command-ledger.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Reconnect-safe command execution. When a message carries a stable
|
|
26
|
+
* `commandId`, route it through the server's RemoteCommandLedger so the side
|
|
27
|
+
* effect runs AT MOST ONCE: a client that re-sends the same command after a
|
|
28
|
+
* dropped ACK / reconnect gets a `replayed` ack instead of a second execution
|
|
29
|
+
* (Phase 5 acceptance "断网恢复后不会重复执行工具调用"). Messages WITHOUT a
|
|
30
|
+
* commandId are unchanged — they call `_executeCommand` directly, so existing
|
|
31
|
+
* clients behave exactly as before. A revoked device / stale-seq command is
|
|
32
|
+
* rejected without executing.
|
|
33
|
+
*/
|
|
34
|
+
async function executeWithIdempotency(server, id, ws, message, stream) {
|
|
35
|
+
const commandId = message.commandId;
|
|
36
|
+
if (!commandId) {
|
|
37
|
+
return server._executeCommand(id, ws, message.command, stream);
|
|
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.
|
|
43
|
+
if (!server._commandLedger) {
|
|
44
|
+
server._commandLedger = new RemoteCommandLedger();
|
|
45
|
+
}
|
|
46
|
+
const outcome = await server._commandLedger.apply(
|
|
47
|
+
{ commandId, deviceId: message.deviceId ?? null, seq: message.seq },
|
|
48
|
+
() => server._executeCommand(id, ws, message.command, stream),
|
|
49
|
+
);
|
|
50
|
+
if (outcome.status === "replayed") {
|
|
51
|
+
server._send(ws, {
|
|
52
|
+
id,
|
|
53
|
+
type: "replayed",
|
|
54
|
+
commandId,
|
|
55
|
+
applyIndex: outcome.applyIndex,
|
|
56
|
+
});
|
|
57
|
+
} else if (outcome.status === "rejected") {
|
|
58
|
+
server._send(ws, {
|
|
59
|
+
id,
|
|
60
|
+
type: "error",
|
|
61
|
+
code: "COMMAND_REJECTED",
|
|
62
|
+
commandId,
|
|
63
|
+
message: outcome.reason,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return outcome;
|
|
67
|
+
}
|
|
22
68
|
|
|
23
69
|
export function createWsMessageDispatcher(server) {
|
|
24
70
|
return {
|
|
@@ -52,8 +98,8 @@ export function createWsMessageDispatcher(server) {
|
|
|
52
98
|
auth: () => server._handleAuth(clientId, ws, message),
|
|
53
99
|
ping: () =>
|
|
54
100
|
server._send(ws, { id, type: "pong", serverTime: Date.now() }),
|
|
55
|
-
execute: () => server
|
|
56
|
-
stream: () => server
|
|
101
|
+
execute: () => executeWithIdempotency(server, id, ws, message, false),
|
|
102
|
+
stream: () => executeWithIdempotency(server, id, ws, message, true),
|
|
57
103
|
cancel: () => server._cancelRequest(id, ws),
|
|
58
104
|
"session-create": () => server._handleSessionCreate(id, ws, message),
|
|
59
105
|
"session-resume": () => server._handleSessionResume(id, ws, message),
|
|
@@ -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;
|
|
@@ -341,6 +391,43 @@ export async function handleRemoteSessionPublish(
|
|
|
341
391
|
if (!message.event || typeof message.event.type !== "string") {
|
|
342
392
|
throw new Error("event.type is required");
|
|
343
393
|
}
|
|
394
|
+
// A paired device (incl. relay-only mobiles) refreshing its own vendor push
|
|
395
|
+
// token — e.g. after FCM onNewToken. Self-scoped: authorize proves
|
|
396
|
+
// membership and registerPush keys off the authenticated clientId, so a
|
|
397
|
+
// device can only ever set its OWN token. Omitting the token clears it.
|
|
398
|
+
if (message.event.type === "push.register") {
|
|
399
|
+
server.remoteSessions.authorize(
|
|
400
|
+
message.remoteSessionId,
|
|
401
|
+
clientId,
|
|
402
|
+
"observe",
|
|
403
|
+
);
|
|
404
|
+
const registered = server.remoteSessions.registerPush(
|
|
405
|
+
message.remoteSessionId,
|
|
406
|
+
clientId,
|
|
407
|
+
{
|
|
408
|
+
token: message.event.pushToken,
|
|
409
|
+
provider: message.event.pushProvider,
|
|
410
|
+
},
|
|
411
|
+
);
|
|
412
|
+
audit(server, {
|
|
413
|
+
sessionId: message.remoteSessionId,
|
|
414
|
+
actor: clientId,
|
|
415
|
+
action: "push.registered",
|
|
416
|
+
detail: {
|
|
417
|
+
hasPush: registered.hasPush,
|
|
418
|
+
provider: registered.provider,
|
|
419
|
+
via: "relay",
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
reply(
|
|
423
|
+
server,
|
|
424
|
+
ws,
|
|
425
|
+
message.id,
|
|
426
|
+
"remote-session-push-registered",
|
|
427
|
+
registered,
|
|
428
|
+
);
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
344
431
|
const requiredScope = CLIENT_EVENT_SCOPES[message.event.type];
|
|
345
432
|
const { session } = server.remoteSessions.authorize(
|
|
346
433
|
message.remoteSessionId,
|
|
@@ -358,49 +445,60 @@ export async function handleRemoteSessionPublish(
|
|
|
358
445
|
id: message.id,
|
|
359
446
|
sessionId: session.agentSessionId,
|
|
360
447
|
};
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
audit(server, {
|
|
371
|
-
sessionId: message.remoteSessionId,
|
|
372
|
-
actor: clientId,
|
|
373
|
-
action: "control.prompt",
|
|
374
|
-
detail: { chars: message.event.content.length },
|
|
375
|
-
});
|
|
376
|
-
handleSessionMessage(server, message.id, ws, {
|
|
377
|
-
...controlMessage,
|
|
378
|
-
content: message.event.content,
|
|
379
|
-
});
|
|
380
|
-
} else if (message.event.type === "approval.resolve") {
|
|
381
|
-
audit(server, {
|
|
382
|
-
sessionId: message.remoteSessionId,
|
|
383
|
-
actor: clientId,
|
|
384
|
-
action: "control.approval",
|
|
385
|
-
detail: {
|
|
386
|
-
requestId: message.event.requestId || message.event.approvalId,
|
|
387
|
-
approved: message.event.answer ?? message.event.approved,
|
|
388
|
-
},
|
|
389
|
-
});
|
|
390
|
-
await handleSessionAnswer(server, message.id, ws, {
|
|
391
|
-
...controlMessage,
|
|
392
|
-
requestId: message.event.requestId || message.event.approvalId,
|
|
393
|
-
answer: message.event.answer ?? message.event.approved,
|
|
394
|
-
});
|
|
395
|
-
} else if (message.event.type === "interrupt") {
|
|
396
|
-
audit(server, {
|
|
397
|
-
sessionId: message.remoteSessionId,
|
|
398
|
-
actor: clientId,
|
|
399
|
-
action: "control.interrupt",
|
|
400
|
-
detail: null,
|
|
401
|
-
});
|
|
402
|
-
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");
|
|
403
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
|
+
});
|
|
404
502
|
return;
|
|
405
503
|
}
|
|
406
504
|
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
RemoteSessionPushDispatcher,
|
|
38
38
|
isApprovalRequestEvent,
|
|
39
39
|
} from "../../harness/remote-session-push.js";
|
|
40
|
-
import { createRemoteSessionPushSender } from "../../harness/remote-session-push-
|
|
40
|
+
import { createRemoteSessionPushSender } from "../../harness/remote-session-push-senders.js";
|
|
41
41
|
import { RemoteSessionRelay } from "../remote-session-relay.js";
|
|
42
42
|
import { handleRemoteSessionPublish } from "./remote-session-protocol.js";
|
|
43
43
|
import { handleTaskDetail, handleTaskHistory } from "./task-protocol.js";
|
|
@@ -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 });
|
|
@@ -251,8 +251,25 @@ export class PromptCompressor {
|
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
// Pinned facts — a DETERMINISTIC fact-retention guarantee. A message marked
|
|
255
|
+
// `pinned:true` (or matched by an `options.isPinned` predicate) MUST survive
|
|
256
|
+
// compaction verbatim regardless of any strategy or the non-deterministic LLM
|
|
257
|
+
// summary. Every other retention here is positional (system / recent-N / last
|
|
258
|
+
// user) or summary-dependent, so an important fact that scrolls out of the
|
|
259
|
+
// recent window would otherwise survive only if the summary happens to keep
|
|
260
|
+
// it. We pull pins out BEFORE any strategy runs (so nothing can drop them),
|
|
261
|
+
// then re-insert them as a sticky block right after the system messages.
|
|
262
|
+
const isPinned =
|
|
263
|
+
typeof options.isPinned === "function"
|
|
264
|
+
? options.isPinned
|
|
265
|
+
: (m) => m && (m.pinned === true || m._pin === true);
|
|
266
|
+
const pinned = messages.filter((m) => isPinned(m));
|
|
267
|
+
const working = pinned.length
|
|
268
|
+
? messages.filter((m) => !isPinned(m))
|
|
269
|
+
: messages;
|
|
270
|
+
|
|
254
271
|
const originalTokens = estimateMessagesTokens(messages);
|
|
255
|
-
let result = [...
|
|
272
|
+
let result = [...working];
|
|
256
273
|
const applied = [];
|
|
257
274
|
|
|
258
275
|
if (feature("CONTEXT_SNIP")) {
|
|
@@ -288,6 +305,15 @@ export class PromptCompressor {
|
|
|
288
305
|
}
|
|
289
306
|
}
|
|
290
307
|
|
|
308
|
+
// Re-insert pinned facts verbatim (order preserved) right after the leading
|
|
309
|
+
// system messages, so they end up as a sticky facts block at the top.
|
|
310
|
+
if (pinned.length) {
|
|
311
|
+
const sys = result.filter((m) => m.role === "system");
|
|
312
|
+
const nonSys = result.filter((m) => m.role !== "system");
|
|
313
|
+
result = [...sys, ...pinned, ...nonSys];
|
|
314
|
+
applied.push("pinned");
|
|
315
|
+
}
|
|
316
|
+
|
|
291
317
|
// Tool-pair repair (opt-in) — callers compacting tool-laden histories
|
|
292
318
|
// (e.g. the headless agent loop) pass this so truncation/snip never leaves
|
|
293
319
|
// an orphaned tool result or unanswered tool_call for a strict API.
|