chainlesschain 0.162.188 → 0.162.193
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 +61 -11
- package/bin/chainlesschain.js +7 -52
- package/completions/_cc +209 -0
- package/completions/cc.bash +18 -0
- package/completions/cc.fish +13 -0
- package/completions/cc.ps1 +226 -0
- package/package.json +10 -2
- package/src/assets/web-panel/assets/{AIOps-Brr1LVcE.js → AIOps-DBLkaTje.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DQU74DKG.js → ActionButton-BAy-Qebo.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CYp9178y.js → Analytics-Dfb1Mlau.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DW4SCYsW.js → AppLayout-BbFkN8m0.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CYlD_ed1.js → Artifacts-kM4-cEEH.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CWl1rZOi.js → Audit-BSQfYWf3.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BOR-LPsa.js → BackgroundAgents-CWDbI_fG.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DLpG7j1X.js → Backup-BxLPbq_Q.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B35K9wdr.js → BaseInput-DuIbdrp6.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CwUJb9gB.js → Chat-NEmjGahU.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-1v6aMS1m.js → ChatBubbleRenderer-DfJEo-5_.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-pi3-tPNW.js → Checkbox-CaoeG3Ns.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-FyNF35eL.js → Codegen-BFf_g3xY.js} +1 -1
- package/src/assets/web-panel/assets/{Col-tGt_JDEr.js → Col-CNOd8mdQ.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CC7LonQX.js → Community-BhpDqz-i.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BGXrHHjE.js → Compact-CQ42T7Z6.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DSW0TBZ8.js → Compliance-DI5PcLMN.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Bhk7rbvE.js → Cowork-wYYZe0wR.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DxyiQ2NZ.js → Cron-Dlq03DD_.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B2ZkxHok.js → Crosschain-BzqS8PP3.js} +1 -1
- package/src/assets/web-panel/assets/{DID-yOJV99eJ.js → DID-It55Yem7.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CKsttz7D.js → Dashboard-9HkH6oxn.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CVFldXSL.js → Dropdown-00e2YWRB.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Bufv638J.js → EmailListRenderer-By-ugRDL.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-4ncjoIjL.js → FamilyGuardDashboard-C396yu5m.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DsknEDoX.js → Federation-BME5sbZY.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Cqe5jWXA.js → FormItemContext-B4TEZCr-.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-NAJaFKxc.js → GenericCardRenderer-_9CX9ieY.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CszKQpnl.js → Git-BrS6WVSr.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BXGodXi6.js → Governance-BMdCWnKF.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CkoYuG2c.js → Inference-Bcp3vzcA.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DFlEr_T0.js → KnowledgeGraph-DlLuqGY5.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CVaENddA.js → Logs-D-W_6x09.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DElGPxCZ.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CDlLT0fw.js → Marketplace-Dzn2guvI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DdwOyszN.js → McpTools-uPict-KL.js} +6 -6
- package/src/assets/web-panel/assets/{Memory-DKQnkKuG.js → Memory-BCw43kOb.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DGseqlzJ.js → MobileBridge-DmV8Wv7F.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-COBbEOlj.js → MobileProjects-C-HaCmSM.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-O61Vwyli.js → Mtc-C6jxJ34Y.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-Dw2SyasS.js → MtcAudit-Za8ExwhQ.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-hSu_l8kf.js → Multisig-KKDbuEgb.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CX1Epurr.js → NLProgramming-Dj97zbCk.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-R9xX8o8_.js → Notes-DBXvMraU.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-jtSNLCuK.js → NotificationSettings-DOxITLYl.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-7DVjZwMM.js +1 -0
- package/src/assets/web-panel/assets/{Organization-Pu2WO-U3.js → Organization-D1i73mjb.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BjnqUyFp.js → Overflow-kW6Q3rvg.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-jjkvz44c.js → P2P-C-v_8p2v.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-tUbbY64W.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-D4yDpivd.js → Permissions-DkHxEZ58.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-0qsL6iH1.js → PersonalDataHub-DWuMPGrK.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-Cx7Ybrk2.js → Pipeline-30IYXWWm.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-PbfR_M_V.js → Privacy-DZNQ4RrH.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CyV6Gsub.js → ProjectInit-De2MCElf.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C7KZ2Wdk.js → ProjectSettings-5uHk9wsC.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DQDjO-yK.js → Projects-XjDfrFLb.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DyFVBBMX.js → Providers-Bgwj6gcE.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CzB1BC9_.js → QrScannerModal-gKql9umv.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Bk636mC1.js → QuickAsk-BWvmwkh7.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DoWxHIT3.js → Recommend-Uok4hZPd.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-oOVIv9wq.js → RemoteSession-DLJzTk9a.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-BucoReGG.js → Reputation-ZVwIPMSO.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DzmOdJU7.js → Row-CN04HxWR.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C1tK7KGU.js → RssFeed-BdSrEG4g.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CSnInOqk.js → Search-5PwVd0IR.js} +1 -1
- package/src/assets/web-panel/assets/{Security-dlejr15l.js → Security-DdBo4zjN.js} +3 -3
- package/src/assets/web-panel/assets/{Services-BioPZuNh.js → Services-D3letU7M.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DWMibwpC.js → Skeleton--Jb83f1v.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BAAnx1B2.js → Skills-Bg-CulHX.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-jWNp4hNO.js → Sla-7QOa7S-X.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-y5kqKha-.js → SpeechSettings-DQwppjRw.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B9GNsc3e.js → SyncSettings-dNPQGL-s.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BDBYKRen.js → Tasks-Ggs-Z48q.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DRiE5eaN.js → Templates-78TYHgRO.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BGlAvExF.js → Tenant-xHwwv9vO.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B8uzrbNY.js → Terminal-BJXSJfm4.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-Df48iveY.js → TimelineRenderer-fLbjRhJw.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CcmHndN6.js → Tokens-oMSBSBmB.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DPkWxmQ2.js → Trigger-CfnY_wX_.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DTb5a5AV.js → Trust-AdyTgYKO.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CBmg5vch.js → UkeySign-C5K_81dS.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B0mZrz4O.js → VideoEditing-vcGVDqki.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Bxs7_mpd.js → Wallet-hhOc3hlY.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C8x3cMxU.js → WebAuthn-CVloC11s.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-DPrNznrP.js → WorkflowEditor-CYeE32R5.js} +1 -1
- package/src/assets/web-panel/assets/{chat-D3bYWu7S.js → chat-CNROR5bN.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DY-PwMu4.js → colors-Cjx-cnwU.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-LDk10Kw6.js → compact-item-DOIfelvD.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C-2MZnFq.js → createContext-DfA7UZ8u.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BQIBjcnB.js → hasIn-BMSCzcfM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQVb2dWp.js → index-5-HXgOX5.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdXnYMCZ.js → index-AWg-0M1S.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cx6D_dx2.js → index-B4iYzpkL.js} +1 -1
- package/src/assets/web-panel/assets/{index-_HRO_cIu.js → index-B5Udeb_6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlRYqt3S.js → index-B7gf77CJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BrnRO9yE.js → index-BEMwBBHk.js} +1 -1
- package/src/assets/web-panel/assets/{index-VCh5zNJo.js → index-BM1y_9hM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRI3ngNg.js → index-BUonmKSE.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3GNvExG.js → index-BbQ2eQ8H.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSvo_bp0.js → index-BemJ2u_E.js} +1 -1
- package/src/assets/web-panel/assets/{index-L6qixyLc.js → index-BolaOQxx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BI4KgcYC.js → index-BxOk9vkG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CY4KnaO9.js → index-By61ojUx.js} +1 -1
- package/src/assets/web-panel/assets/{index-L3smcoQX.js → index-C2K9SNVX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BX2b9Orc.js → index-C3L5gdiD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cz4b6Z_7.js → index-C7xn0Nub.js} +1 -1
- package/src/assets/web-panel/assets/{index-COG61sRv.js → index-CAnvhwg6.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7FC8cP2.js → index-CEKMcOyU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BN-xdSWZ.js → index-CNC5onm4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DY2FIrmz.js → index-CVL27kXC.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiTvBAr-.js → index-CVm1_i3t.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhRt9cYJ.js → index-CdYBye8B.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5pgtZnY.js → index-ClNMrqEY.js} +1 -1
- package/src/assets/web-panel/assets/{index-7xKu7Fns.js → index-Cs6l7uRu.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4K1weKc.js → index-CshQbilz.js} +1 -1
- package/src/assets/web-panel/assets/{index-k7C_oDCO.js → index-Cyweh0Hy.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3Oq-DLL.js → index-DBpWXFed.js} +3 -3
- package/src/assets/web-panel/assets/{index-DYyLJPlF.js → index-DHtpHZAQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dh-tkpKQ.js → index-DLmn0BoK.js} +1 -1
- package/src/assets/web-panel/assets/{index-8JC9BJa1.js → index-DPAWBrMf.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dd2Km97U.js → index-DjEsxO5h.js} +1 -1
- package/src/assets/web-panel/assets/{index-KFZO_lcx.js → index-FBc_CJBd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTIZpPtG.js → index-Icdoqmzt.js} +1 -1
- package/src/assets/web-panel/assets/index-Q2IajL54.js +1 -0
- package/src/assets/web-panel/assets/index-bRkHgOMc.js +1 -0
- package/src/assets/web-panel/assets/{index-lmm9p-jm.js → index-dCd8cSUq.js} +1 -1
- package/src/assets/web-panel/assets/{index-HasPt4-h.js → index-m2vG9gG_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaslYch6.js → index-mTpHoEzr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbR6ROOa.js → index-ti_lnTWl.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-zQPSHf2C.js → initDefaultProps-Bu8k7H1Y.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CKCStGVk.js → motion-s3iVK41k.js} +1 -1
- package/src/assets/web-panel/assets/{move-BufVDGYF.js → move-B6B-E5Jz.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DcaFxy5D.js → mtc-parser-BiYgTidA.js} +1 -1
- package/src/assets/web-panel/assets/{omit-EScpkGdo.js → omit-pU1RdUDA.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-72hG_qfT.js → pickAttrs-Cdoq_SeM.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CMFWiH20.js → placementArrow-DIuvAn2K.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DKQHS41p.js → responsiveObserve-8w16YR2D.js} +1 -1
- package/src/assets/web-panel/assets/{slide-QVAFHTIQ.js → slide-VZ01cZe3.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DIz38e2G.js → statusUtils-lh8YMN8Z.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-zK5cyLby.js → styleChecker-CmDyreec.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DhZngk62.js → useFlexGapSupport-hiJWMU5y.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BvV2cvkg.js → useFs-Thnu-Iaj.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CRmxb9l3.js → usePersonalDataHub-LBdOxjwY.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CgQIbobP.js → vnode-Cg6lFY_X.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D4XrrO0R.js → zoom-DVfsR1YO.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/cli-help.js +181 -0
- package/src/command-help-index.json +181 -0
- package/src/command-manifest.json +1107 -175
- package/src/command-surface-policy.js +197 -0
- package/src/commands/agent.js +98 -33
- package/src/commands/artifacts.js +400 -2
- package/src/commands/background-session.js +41 -3
- package/src/commands/checkpoint-managed.js +1059 -0
- package/src/commands/checkpoint-restore-recovery.js +1476 -0
- package/src/commands/checkpoint.js +950 -22
- package/src/commands/compact.js +101 -25
- package/src/commands/config.js +506 -20
- package/src/commands/doctor.js +4 -1
- package/src/commands/hub.js +1 -1
- package/src/commands/mcp.js +688 -24
- package/src/commands/pack.js +16 -2
- package/src/commands/plugin.js +20 -12
- package/src/commands/session-mcp-recovery.js +218 -0
- package/src/commands/session.js +470 -110
- package/src/commands/setup.js +36 -10
- package/src/commands/skill.js +181 -110
- package/src/commands/status.js +21 -5
- package/src/commands/team-distributed.js +3324 -0
- package/src/commands/team.js +1130 -74
- package/src/commands/update.js +68 -6
- package/src/constants.js +11 -0
- package/src/data/changelog.json +26 -0
- package/src/gateways/ws/action-protocol.js +10 -0
- package/src/gateways/ws/session-protocol.js +555 -27
- package/src/gateways/ws/ws-agent-handler.js +541 -14
- package/src/gateways/ws/ws-session-gateway.js +129 -22
- package/src/gateways/ws/ws-session-state.js +431 -0
- package/src/harness/background-task-manager.js +233 -36
- package/src/harness/jsonl-session-store.js +2551 -167
- package/src/harness/mcp-client.js +802 -61
- package/src/harness/prompt-compressor.js +227 -27
- package/src/harness/session-index.js +89 -38
- package/src/harness/session-list-index.js +254 -0
- package/src/harness/structured-handoff.js +410 -0
- package/src/lazy-dispatch.js +747 -84
- package/src/lib/__tests__/logger.test.js +50 -2
- package/src/lib/advisor-runtime.js +1047 -0
- package/src/lib/agent-core.js +2 -0
- package/src/lib/agent-sandbox.js +120 -26
- package/src/lib/agent-session-export.js +20 -0
- package/src/lib/agent-team/task-lease.js +271 -3
- package/src/lib/agent-team/team-adjudication.js +1501 -0
- package/src/lib/agent-team/team-budget.js +4 -1
- package/src/lib/agent-team/team-control-store.js +582 -0
- package/src/lib/agent-team/team-distributed-queue.js +5246 -0
- package/src/lib/agent-team/team-process-checkpoint.js +211 -0
- package/src/lib/agent-team/team-runner.js +543 -24
- package/src/lib/agent-team/team-worktree.js +1403 -95
- package/src/lib/artifact-store.js +131 -8
- package/src/lib/background-agent-supervisor.js +185 -13
- package/src/lib/background-interaction-journal.js +37 -9
- package/src/lib/background-launch-profile.js +1058 -0
- package/src/lib/checkpoint-restore-already-completed-controller.js +902 -0
- package/src/lib/checkpoint-restore-orchestrator.js +987 -0
- package/src/lib/checkpoint-restore-partial-rollback-controller.js +1953 -0
- package/src/lib/checkpoint-restore-recovery-controller.js +689 -0
- package/src/lib/checkpoint-restore-recovery.js +884 -0
- package/src/lib/checkpoint-restore-retention.js +126 -0
- package/src/lib/checkpoint-restore-saga.js +5079 -0
- package/src/lib/checkpoint-restore-session-recovery.js +1178 -0
- package/src/lib/checkpoint-restore-workspace-target-verifier.js +270 -0
- package/src/lib/checkpoint-store.js +1688 -97
- package/src/lib/checkpoint-timeline-authority.js +522 -0
- package/src/lib/checkpoint-timeline.js +642 -0
- package/src/lib/config-keys.js +18 -119
- package/src/lib/config-manager.js +446 -27
- package/src/lib/config-redaction.js +57 -0
- package/src/lib/config-schema.js +853 -0
- package/src/lib/cowork-mcp-tools.js +5 -0
- package/src/lib/cowork-task-runner.js +458 -63
- package/src/lib/delivery-coordinator.js +1234 -0
- package/src/lib/delivery-evidence.js +450 -0
- package/src/lib/doctor-checkup.js +199 -14
- package/src/lib/executable-path.js +34 -0
- package/src/lib/fatal-handler.js +16 -0
- package/src/lib/file-checkpoint.js +4909 -186
- package/src/lib/file-lines.js +125 -0
- package/src/lib/headless-config-command.js +16 -5
- package/src/lib/hook-runner.cjs +139 -38
- package/src/lib/hooks-v2-workspace-context.js +10 -0
- package/src/lib/impacted-gate-selector.js +424 -0
- package/src/lib/interaction-adapter.js +62 -0
- package/src/lib/jsonl-session-store.js +1 -35
- package/src/lib/logger.js +66 -14
- package/src/lib/managed-checkpoint-render.js +60 -0
- package/src/lib/managed-tool-checkpoint.js +194 -0
- package/src/lib/mcp-call-ledger-store.js +1069 -0
- package/src/lib/mcp-call-ledger.js +747 -0
- package/src/lib/mcp-client.js +5 -0
- package/src/lib/mcp-conflict-scheduler.js +468 -0
- package/src/lib/mcp-effect-contract.js +102 -0
- package/src/lib/mcp-headers-helper-trust.js +145 -0
- package/src/lib/mcp-headers-helper.js +616 -0
- package/src/lib/mcp-host-recovery-runtime.js +131 -0
- package/src/lib/mcp-ledger-recovery-admission.js +1065 -0
- package/src/lib/mcp-recovery-adjudication.js +443 -0
- package/src/lib/output-context.js +86 -0
- package/src/lib/packer/file-identity.js +170 -0
- package/src/lib/packer/index.js +3 -0
- package/src/lib/packer/native-update-state.js +277 -0
- package/src/lib/packer/pack-update-applier.js +1983 -136
- package/src/lib/packer/pack-update-checker.js +34 -0
- package/src/lib/packer/pack-update-downloader.js +875 -86
- package/src/lib/packer/pack-update-signature.js +86 -0
- package/src/lib/packer/pkg-config-generator.js +6 -0
- package/src/lib/paths.js +65 -10
- package/src/lib/plan-mode.js +831 -14
- package/src/lib/plan-persistence.js +540 -0
- package/src/lib/plugin-runtime/hooks.js +227 -69
- package/src/lib/plugin-runtime/plugin-options.js +189 -44
- package/src/lib/pr-automation-policy.js +146 -8
- package/src/lib/process-execution-broker/credential-agent.js +7 -0
- package/src/lib/process-execution-broker/index.js +491 -13
- package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +28 -1
- package/src/lib/process-execution-broker/linux-generic-bwrap.js +28 -4
- package/src/lib/process-execution-broker/platform-sandbox.js +92 -70
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +284 -19
- package/src/lib/process-execution-broker/workspace-transaction.js +4459 -0
- package/src/lib/project-instructions.js +165 -29
- package/src/lib/project-mcp-trust.js +67 -0
- package/src/lib/public-ide-capability-manifest.js +272 -0
- package/src/lib/public-ide-capability-validation.js +351 -0
- package/src/lib/secret-store.js +267 -43
- package/src/lib/secure-file-identity.js +433 -0
- package/src/lib/secure-fs.js +1089 -0
- package/src/lib/security-audit.js +58 -0
- package/src/lib/service-manager.js +34 -13
- package/src/lib/session-budget-runtime.js +1452 -0
- package/src/lib/session-host-snapshot.js +388 -0
- package/src/lib/session-message-provenance.js +429 -0
- package/src/lib/session-projection.js +804 -0
- package/src/lib/session-resource-budget.js +1495 -0
- package/src/lib/settings-hooks.cjs +138 -22
- package/src/lib/settings-loader.cjs +25 -2
- package/src/lib/side-effect-ledger-store.js +45 -23
- package/src/lib/skill-execution-identity.js +217 -0
- package/src/lib/skill-loader.js +299 -18
- package/src/lib/sub-agent-context.js +236 -28
- package/src/lib/sub-agent-registry.js +5 -0
- package/src/lib/subagent-contract.js +94 -0
- package/src/lib/todo-manager.js +185 -18
- package/src/lib/todo-persistence.js +417 -0
- package/src/lib/turn-binding-store.js +41 -23
- package/src/lib/turn-binding.js +160 -2
- package/src/lib/with-file-lock.js +165 -24
- package/src/lib/ws-chat-handler.js +21 -0
- package/src/program-base.js +18 -0
- package/src/repl/advisor-command.js +103 -0
- package/src/repl/agent-repl.js +2175 -146
- package/src/repl/btw-command.js +93 -10
- package/src/repl/clipboard-image.js +119 -0
- package/src/repl/config-summary.js +64 -108
- package/src/repl/prompt-editor.js +233 -0
- package/src/repl/prompt-interactions.js +344 -0
- package/src/repl/prompt-stash.js +354 -0
- package/src/repl/prompt-suggestions.js +312 -0
- package/src/repl/repl-keybindings.js +227 -0
- package/src/repl/session-recap.js +217 -0
- package/src/repl/slash-command-registry.js +22 -0
- package/src/repl/terminal-layout.js +88 -0
- package/src/runtime/agent-core.js +1630 -447
- package/src/runtime/coding-agent-contract-shared.cjs +13 -1
- package/src/runtime/coding-agent-managed-tool-policy.cjs +7 -2
- package/src/runtime/diagnostics.js +32 -13
- package/src/runtime/headless-runner.js +310 -118
- package/src/runtime/headless-stream.js +356 -95
- package/src/runtime/mcp-config.js +148 -14
- package/src/runtime/policies/agent-policy.js +14 -0
- package/src/runtime/status-diagnostics-lite.js +137 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-7iWGwZ-r.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-BU2Yqq5H.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-69ca_WeR.js +0 -7
- package/src/assets/web-panel/assets/devWarning-B4dXIJqD.js +0 -1
- package/src/assets/web-panel/assets/index-C-C7DaG6.js +0 -1
- package/src/assets/web-panel/assets/index-DkfWzWtd.js +0 -1
|
@@ -11,12 +11,107 @@
|
|
|
11
11
|
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
13
13
|
import { feature, featureVariant } from "../lib/feature-flags.js";
|
|
14
|
+
import {
|
|
15
|
+
DURABLE_SYSTEM_MESSAGE_KINDS,
|
|
16
|
+
markDurableSystemMessage,
|
|
17
|
+
} from "../lib/session-message-provenance.js";
|
|
18
|
+
import {
|
|
19
|
+
buildExtractiveHandoff,
|
|
20
|
+
formatStructuredHandoff,
|
|
21
|
+
parseStructuredHandoff,
|
|
22
|
+
StructuredHandoffValidationError,
|
|
23
|
+
STRUCTURED_HANDOFF_FIELDS,
|
|
24
|
+
} from "./structured-handoff.js";
|
|
25
|
+
|
|
26
|
+
export * from "./structured-handoff.js";
|
|
14
27
|
|
|
15
28
|
// Bounds for the fuzzy near-dup pass in _deduplicate (see there). Generous
|
|
16
29
|
// enough that real near-dups are still caught; small enough that compaction of
|
|
17
30
|
// a long, tool-heavy history stays sub-second instead of O(n²·content).
|
|
18
31
|
const DEDUP_JACCARD_MAX_CHARS = 4000;
|
|
19
32
|
const DEDUP_FUZZY_WINDOW = 100;
|
|
33
|
+
export const SUMMARY_INPUT_DEFAULT_MAX_CHARS = 24000;
|
|
34
|
+
export const SUMMARY_INPUT_HARD_MAX_CHARS = 32000;
|
|
35
|
+
const SUMMARY_INPUT_MIN_CHARS = 1024;
|
|
36
|
+
|
|
37
|
+
function boundedPositiveInteger(value, fallback, minimum, maximum) {
|
|
38
|
+
const number = Math.floor(Number(value));
|
|
39
|
+
if (!Number.isFinite(number) || number <= 0) return fallback;
|
|
40
|
+
return Math.min(Math.max(number, minimum), maximum);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function summaryEntry(message, index) {
|
|
44
|
+
const role = typeof message?.role === "string" ? message.role : "unknown";
|
|
45
|
+
return `[${index}] ${role}: ${getContent(message)
|
|
46
|
+
.replace(/\r\n?/g, "\n")
|
|
47
|
+
.trim()
|
|
48
|
+
.slice(0, 2000)}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Keep the earliest user objective plus as much recent context as fits. */
|
|
52
|
+
function buildBoundedHistory(messages, maxChars) {
|
|
53
|
+
const entries = messages
|
|
54
|
+
.map((message, index) => ({
|
|
55
|
+
index,
|
|
56
|
+
role: message?.role,
|
|
57
|
+
text: summaryEntry(message, index),
|
|
58
|
+
}))
|
|
59
|
+
.filter((entry) => entry.text.trim());
|
|
60
|
+
const all = entries.map((entry) => entry.text).join("\n");
|
|
61
|
+
if (all.length <= maxChars) return all;
|
|
62
|
+
|
|
63
|
+
const firstUser = entries.find((entry) => entry.role === "user");
|
|
64
|
+
const selected = new Map();
|
|
65
|
+
let remaining = maxChars;
|
|
66
|
+
if (firstUser && remaining > 0) {
|
|
67
|
+
const objectiveBudget = Math.min(
|
|
68
|
+
firstUser.text.length,
|
|
69
|
+
Math.max(1, Math.floor(maxChars / 3)),
|
|
70
|
+
);
|
|
71
|
+
selected.set(firstUser.index, firstUser.text.slice(0, objectiveBudget));
|
|
72
|
+
remaining -= objectiveBudget;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (let index = entries.length - 1; index >= 0 && remaining > 0; index--) {
|
|
76
|
+
const entry = entries[index];
|
|
77
|
+
if (selected.has(entry.index)) continue;
|
|
78
|
+
const separator = selected.size > 0 ? 1 : 0;
|
|
79
|
+
if (remaining <= separator) break;
|
|
80
|
+
const text = entry.text.slice(0, remaining - separator);
|
|
81
|
+
if (!text) break;
|
|
82
|
+
selected.set(entry.index, text);
|
|
83
|
+
remaining -= text.length + separator;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return [...selected.entries()]
|
|
87
|
+
.sort(([left], [right]) => left - right)
|
|
88
|
+
.map(([, text]) => text)
|
|
89
|
+
.join("\n")
|
|
90
|
+
.slice(0, maxChars);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function summaryPrompt(messages, maxChars) {
|
|
94
|
+
const schema = `{${STRUCTURED_HANDOFF_FIELDS.map((field) => `"${field}"`).join(",")}}`;
|
|
95
|
+
const instructions = [
|
|
96
|
+
"Create a durable conversation handoff from the history below.",
|
|
97
|
+
`Return exactly one strict JSON object with all keys in this order: ${schema}.`,
|
|
98
|
+
'"objective" must be a string; every other value must be an array of strings.',
|
|
99
|
+
"Preserve constraints, exact file paths, test evidence, unresolved external side effects, blockers, and actionable next steps. Do not use Markdown.",
|
|
100
|
+
"Conversation history:",
|
|
101
|
+
].join("\n");
|
|
102
|
+
const historyBudget = Math.max(0, maxChars - instructions.length - 1);
|
|
103
|
+
const history = buildBoundedHistory(messages, historyBudget);
|
|
104
|
+
return `${instructions}\n${history}`.slice(0, maxChars);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function boundedFailureMessage(error) {
|
|
108
|
+
const message =
|
|
109
|
+
error instanceof Error ? error.message : String(error || "unknown error");
|
|
110
|
+
return message
|
|
111
|
+
.replace(/[\r\n]+/g, " ")
|
|
112
|
+
.trim()
|
|
113
|
+
.slice(0, 240);
|
|
114
|
+
}
|
|
20
115
|
|
|
21
116
|
export function estimateTokens(text) {
|
|
22
117
|
if (!text) return 0;
|
|
@@ -186,7 +281,8 @@ export function sanitizeToolPairs(messages) {
|
|
|
186
281
|
stage1.push({ ...m, tool_calls: kept });
|
|
187
282
|
} else {
|
|
188
283
|
// No surviving calls: keep the assistant text if any, else drop it.
|
|
189
|
-
const
|
|
284
|
+
const rest = { ...m };
|
|
285
|
+
delete rest.tool_calls;
|
|
190
286
|
if (rest.content && String(rest.content).trim()) stage1.push(rest);
|
|
191
287
|
}
|
|
192
288
|
} else {
|
|
@@ -232,6 +328,12 @@ export class PromptCompressor {
|
|
|
232
328
|
}
|
|
233
329
|
this.similarityThreshold = options.similarityThreshold || 0.9;
|
|
234
330
|
this.llmQuery = options.llmQuery || null;
|
|
331
|
+
this.summaryInputMaxChars = boundedPositiveInteger(
|
|
332
|
+
options.summaryInputMaxChars,
|
|
333
|
+
SUMMARY_INPUT_DEFAULT_MAX_CHARS,
|
|
334
|
+
SUMMARY_INPUT_MIN_CHARS,
|
|
335
|
+
SUMMARY_INPUT_HARD_MAX_CHARS,
|
|
336
|
+
);
|
|
235
337
|
}
|
|
236
338
|
|
|
237
339
|
adaptToModel(model, provider) {
|
|
@@ -271,6 +373,7 @@ export class PromptCompressor {
|
|
|
271
373
|
const originalTokens = estimateMessagesTokens(messages);
|
|
272
374
|
let result = [...working];
|
|
273
375
|
const applied = [];
|
|
376
|
+
let summaryStats = null;
|
|
274
377
|
|
|
275
378
|
if (feature("CONTEXT_SNIP")) {
|
|
276
379
|
const before = result.length;
|
|
@@ -290,21 +393,28 @@ export class PromptCompressor {
|
|
|
290
393
|
if (result.length < before) applied.push("collapse");
|
|
291
394
|
}
|
|
292
395
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
|
|
396
|
+
// Semantic handoff must run BEFORE destructive count-based truncation;
|
|
397
|
+
// otherwise long conversations commonly fall under maxTokens only because
|
|
398
|
+
// the facts we needed to summarize were already discarded.
|
|
298
399
|
const currentTokens = estimateMessagesTokens(result);
|
|
299
|
-
if (
|
|
300
|
-
|
|
301
|
-
|
|
400
|
+
if (
|
|
401
|
+
this.llmQuery &&
|
|
402
|
+
(currentTokens > this.maxTokens || result.length > this.maxMessages) &&
|
|
403
|
+
result.length > 4
|
|
404
|
+
) {
|
|
405
|
+
const summarized = await this._summarize(result);
|
|
406
|
+
result = summarized.messages;
|
|
407
|
+
summaryStats = summarized.stats;
|
|
408
|
+
if (summaryStats.summaryMode !== "none") {
|
|
302
409
|
applied.push("summarize");
|
|
303
|
-
} catch (_err) {
|
|
304
|
-
// Summarization failed — continue with what we have
|
|
305
410
|
}
|
|
306
411
|
}
|
|
307
412
|
|
|
413
|
+
if (result.length > this.maxMessages) {
|
|
414
|
+
result = this._truncate(result);
|
|
415
|
+
applied.push("truncate");
|
|
416
|
+
}
|
|
417
|
+
|
|
308
418
|
// Re-insert pinned facts verbatim (order preserved) right after the leading
|
|
309
419
|
// system messages, so they end up as a sticky facts block at the top.
|
|
310
420
|
if (pinned.length) {
|
|
@@ -330,6 +440,7 @@ export class PromptCompressor {
|
|
|
330
440
|
compressedTokens,
|
|
331
441
|
saved: originalTokens - compressedTokens,
|
|
332
442
|
ratio: originalTokens > 0 ? compressedTokens / originalTokens : 1,
|
|
443
|
+
...(summaryStats || {}),
|
|
333
444
|
};
|
|
334
445
|
|
|
335
446
|
const abVariant = getCompressionVariant();
|
|
@@ -417,24 +528,108 @@ export class PromptCompressor {
|
|
|
417
528
|
(m) => m.role !== "system" && m !== last,
|
|
418
529
|
);
|
|
419
530
|
|
|
420
|
-
if (toSummarize.length < 3)
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
531
|
+
if (toSummarize.length < 3) {
|
|
532
|
+
return {
|
|
533
|
+
messages,
|
|
534
|
+
stats: {
|
|
535
|
+
summaryMode: "none",
|
|
536
|
+
degraded: false,
|
|
537
|
+
degradedReason: null,
|
|
538
|
+
summaryInputChars: 0,
|
|
539
|
+
summaryInputLimit: this.summaryInputMaxChars,
|
|
540
|
+
},
|
|
541
|
+
};
|
|
542
|
+
}
|
|
429
543
|
|
|
430
|
-
|
|
544
|
+
const prompt = summaryPrompt(toSummarize, this.summaryInputMaxChars);
|
|
545
|
+
let summary;
|
|
546
|
+
let summaryMode = "llm-structured";
|
|
547
|
+
let degraded = false;
|
|
548
|
+
let degradedReason = null;
|
|
549
|
+
let rawSummary;
|
|
550
|
+
let summaryUsage = null;
|
|
551
|
+
let summaryProvider = null;
|
|
552
|
+
let summaryModel = null;
|
|
553
|
+
try {
|
|
554
|
+
const queryResult = await this.llmQuery(prompt);
|
|
555
|
+
if (
|
|
556
|
+
queryResult &&
|
|
557
|
+
typeof queryResult === "object" &&
|
|
558
|
+
Object.prototype.hasOwnProperty.call(queryResult, "summary")
|
|
559
|
+
) {
|
|
560
|
+
rawSummary = queryResult.summary;
|
|
561
|
+
const usage = queryResult.usage;
|
|
562
|
+
if (usage && typeof usage === "object") {
|
|
563
|
+
summaryUsage = {
|
|
564
|
+
inputTokens: Number(usage.input_tokens ?? usage.prompt_tokens) || 0,
|
|
565
|
+
outputTokens:
|
|
566
|
+
Number(usage.output_tokens ?? usage.completion_tokens) || 0,
|
|
567
|
+
cacheReadTokens:
|
|
568
|
+
Number(
|
|
569
|
+
usage.cache_read_input_tokens ?? usage.cache_read_tokens,
|
|
570
|
+
) || 0,
|
|
571
|
+
cacheCreationTokens:
|
|
572
|
+
Number(
|
|
573
|
+
usage.cache_creation_input_tokens ??
|
|
574
|
+
usage.cache_creation_tokens,
|
|
575
|
+
) || 0,
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
summaryProvider = queryResult.provider || null;
|
|
579
|
+
summaryModel = queryResult.model || null;
|
|
580
|
+
} else {
|
|
581
|
+
rawSummary = queryResult;
|
|
582
|
+
}
|
|
583
|
+
} catch (error) {
|
|
584
|
+
degraded = true;
|
|
585
|
+
summaryMode = "extractive-fallback";
|
|
586
|
+
degradedReason = `llm_query_failed:${boundedFailureMessage(error)}`;
|
|
587
|
+
}
|
|
588
|
+
if (!degraded) {
|
|
589
|
+
try {
|
|
590
|
+
summary = parseStructuredHandoff(rawSummary);
|
|
591
|
+
} catch (error) {
|
|
592
|
+
degraded = true;
|
|
593
|
+
summaryMode = "extractive-fallback";
|
|
594
|
+
degradedReason =
|
|
595
|
+
error instanceof StructuredHandoffValidationError
|
|
596
|
+
? `invalid_llm_summary:${error.code}`
|
|
597
|
+
: `invalid_llm_summary:normalization_error:${boundedFailureMessage(error)}`;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
if (degraded) {
|
|
601
|
+
summary = buildExtractiveHandoff(toSummarize, {
|
|
602
|
+
maxFallbackSourceChars: Math.min(
|
|
603
|
+
this.summaryInputMaxChars,
|
|
604
|
+
SUMMARY_INPUT_DEFAULT_MAX_CHARS,
|
|
605
|
+
),
|
|
606
|
+
});
|
|
607
|
+
}
|
|
431
608
|
|
|
432
609
|
const result = [
|
|
433
610
|
...system,
|
|
434
|
-
|
|
611
|
+
markDurableSystemMessage(
|
|
612
|
+
{
|
|
613
|
+
role: "system",
|
|
614
|
+
content: `[Conversation Summary]\n${formatStructuredHandoff(summary)}`,
|
|
615
|
+
},
|
|
616
|
+
DURABLE_SYSTEM_MESSAGE_KINDS.COMPACT_SUMMARY,
|
|
617
|
+
),
|
|
435
618
|
];
|
|
436
619
|
if (last) result.push(last);
|
|
437
|
-
return
|
|
620
|
+
return {
|
|
621
|
+
messages: result,
|
|
622
|
+
stats: {
|
|
623
|
+
summaryMode,
|
|
624
|
+
degraded,
|
|
625
|
+
degradedReason,
|
|
626
|
+
summaryInputChars: prompt.length,
|
|
627
|
+
summaryInputLimit: this.summaryInputMaxChars,
|
|
628
|
+
...(summaryUsage ? { summaryUsage } : {}),
|
|
629
|
+
...(summaryProvider ? { summaryProvider } : {}),
|
|
630
|
+
...(summaryModel ? { summaryModel } : {}),
|
|
631
|
+
},
|
|
632
|
+
};
|
|
438
633
|
}
|
|
439
634
|
|
|
440
635
|
_snipCompact(messages) {
|
|
@@ -515,10 +710,15 @@ export class PromptCompressor {
|
|
|
515
710
|
.filter(Boolean);
|
|
516
711
|
const uniqueTools = [...new Set(toolNames)];
|
|
517
712
|
|
|
518
|
-
result.push(
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
713
|
+
result.push(
|
|
714
|
+
markDurableSystemMessage(
|
|
715
|
+
{
|
|
716
|
+
role: "system",
|
|
717
|
+
content: `[Collapsed ${toolGroup.length} tool messages: ${uniqueTools.join(", ")}]`,
|
|
718
|
+
},
|
|
719
|
+
DURABLE_SYSTEM_MESSAGE_KINDS.COMPACT_TOOL_COLLAPSE,
|
|
720
|
+
),
|
|
721
|
+
);
|
|
522
722
|
i = j;
|
|
523
723
|
continue;
|
|
524
724
|
}
|
|
@@ -17,18 +17,12 @@
|
|
|
17
17
|
* without touching the user's home dir.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import {
|
|
21
|
-
existsSync,
|
|
22
|
-
mkdirSync,
|
|
23
|
-
readdirSync,
|
|
24
|
-
statSync,
|
|
25
|
-
readFileSync,
|
|
26
|
-
} from "node:fs";
|
|
20
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
27
21
|
import { join, basename } from "node:path";
|
|
28
22
|
import { createRequire } from "node:module";
|
|
29
23
|
import { getHomeDir } from "../lib/paths.js";
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
24
|
+
import { iterateFileLinesSync } from "../lib/file-lines.js";
|
|
25
|
+
import { ensurePrivateDirectory, ensurePrivateFile } from "../lib/secure-fs.js";
|
|
32
26
|
|
|
33
27
|
const requireCjs = createRequire(import.meta.url);
|
|
34
28
|
|
|
@@ -50,7 +44,7 @@ function sessionsDir() {
|
|
|
50
44
|
|
|
51
45
|
function indexPath() {
|
|
52
46
|
const dir = getHomeDir();
|
|
53
|
-
|
|
47
|
+
ensurePrivateDirectory(dir);
|
|
54
48
|
return join(dir, "session-index.db");
|
|
55
49
|
}
|
|
56
50
|
|
|
@@ -82,43 +76,105 @@ CREATE INDEX IF NOT EXISTS idx_sessions_last_ts ON sessions(last_ts DESC);
|
|
|
82
76
|
*/
|
|
83
77
|
export function openIndex({ file } = {}) {
|
|
84
78
|
const Database = _deps.loadDatabase();
|
|
85
|
-
const
|
|
79
|
+
const target = file || indexPath();
|
|
80
|
+
const db = new Database(target);
|
|
86
81
|
db.pragma("journal_mode = WAL");
|
|
87
82
|
db.exec(SCHEMA);
|
|
83
|
+
if (target !== ":memory:") {
|
|
84
|
+
ensurePrivateFile(target);
|
|
85
|
+
ensurePrivateFile(`${target}-wal`);
|
|
86
|
+
ensurePrivateFile(`${target}-shm`);
|
|
87
|
+
}
|
|
88
88
|
return db;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/** Max characters of concatenated message content indexed per session. */
|
|
92
92
|
const CONTENT_CAP = 200_000;
|
|
93
93
|
|
|
94
|
-
function
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
function toIsoSafe(value) {
|
|
95
|
+
const number = Number(value);
|
|
96
|
+
if (!Number.isFinite(number)) return "";
|
|
97
|
+
const date = new Date(number);
|
|
98
|
+
return Number.isNaN(date.getTime()) ? "" : date.toISOString();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function summarizeSessionFile(id, filePath) {
|
|
102
|
+
let startEvent = null;
|
|
103
|
+
let lastEvent = null;
|
|
104
|
+
let renamedTitle = null;
|
|
105
|
+
let messageCount = 0;
|
|
106
|
+
let eventCount = 0;
|
|
107
|
+
let chainHash = "";
|
|
100
108
|
const parts = [];
|
|
101
109
|
let used = 0;
|
|
102
|
-
for (const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
for (const { line } of iterateFileLinesSync(filePath)) {
|
|
111
|
+
let event;
|
|
112
|
+
try {
|
|
113
|
+
event = JSON.parse(line);
|
|
114
|
+
} catch {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
eventCount += 1;
|
|
118
|
+
lastEvent = event;
|
|
119
|
+
if (!startEvent && event.type === "session_start") startEvent = event;
|
|
120
|
+
if (event.type === "session_rename" && event.data?.title) {
|
|
121
|
+
renamedTitle = String(event.data.title);
|
|
122
|
+
}
|
|
123
|
+
if (event.type === "user_message" || event.type === "assistant_message") {
|
|
124
|
+
messageCount += 1;
|
|
125
|
+
if (used < CONTENT_CAP) {
|
|
126
|
+
const content = event.data?.content;
|
|
127
|
+
const text =
|
|
128
|
+
typeof content === "string"
|
|
129
|
+
? content
|
|
130
|
+
: content == null
|
|
131
|
+
? ""
|
|
132
|
+
: JSON.stringify(content);
|
|
133
|
+
if (text) {
|
|
134
|
+
const bounded = text.slice(0, CONTENT_CAP - used);
|
|
135
|
+
parts.push(bounded);
|
|
136
|
+
used += bounded.length;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} else if (
|
|
140
|
+
event.type === "ws_turn" &&
|
|
141
|
+
event.data?.schemaVersion === 1 &&
|
|
142
|
+
event.data?.outcome === "completed" &&
|
|
143
|
+
event.data?.user?.role === "user" &&
|
|
144
|
+
event.data?.assistant?.role === "assistant"
|
|
145
|
+
) {
|
|
146
|
+
messageCount += 2;
|
|
147
|
+
for (const message of [event.data?.user, event.data?.assistant]) {
|
|
148
|
+
if (used >= CONTENT_CAP) break;
|
|
149
|
+
const content = message?.content;
|
|
150
|
+
const text =
|
|
151
|
+
typeof content === "string"
|
|
152
|
+
? content
|
|
153
|
+
: content == null
|
|
154
|
+
? ""
|
|
155
|
+
: JSON.stringify(content);
|
|
156
|
+
if (text) {
|
|
157
|
+
const bounded = text.slice(0, CONTENT_CAP - used);
|
|
158
|
+
parts.push(bounded);
|
|
159
|
+
used += bounded.length;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (typeof event.hash === "string") chainHash = event.hash;
|
|
110
164
|
}
|
|
165
|
+
if (!lastEvent) return null;
|
|
111
166
|
return {
|
|
112
167
|
id,
|
|
113
|
-
title: startEvent?.data?.title || "Untitled",
|
|
168
|
+
title: renamedTitle || startEvent?.data?.title || "Untitled",
|
|
114
169
|
provider: startEvent?.data?.provider || "",
|
|
115
170
|
model: startEvent?.data?.model || "",
|
|
116
171
|
message_count: messageCount,
|
|
117
|
-
event_count:
|
|
172
|
+
event_count: eventCount,
|
|
118
173
|
created_at: toIsoSafe(startEvent?.timestamp),
|
|
119
174
|
updated_at: toIsoSafe(lastEvent?.timestamp),
|
|
120
175
|
last_ts: lastEvent?.timestamp || 0,
|
|
121
176
|
content: parts.join("\n").slice(0, CONTENT_CAP),
|
|
177
|
+
chain_hash: chainHash,
|
|
122
178
|
};
|
|
123
179
|
}
|
|
124
180
|
|
|
@@ -137,16 +193,10 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
137
193
|
* @returns {boolean} true if a row was written.
|
|
138
194
|
*/
|
|
139
195
|
export function indexOneSession(db, id, { mtimeMs = 0, sizeBytes = 0 } = {}) {
|
|
140
|
-
const events = readEvents(id);
|
|
141
|
-
if (events.length === 0) return false;
|
|
142
|
-
const s = summarizeEvents(id, events);
|
|
143
196
|
const filePath = join(sessionsDir(), `${id}.jsonl`);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
} catch {
|
|
148
|
-
/* chain hash is best-effort */
|
|
149
|
-
}
|
|
197
|
+
if (!existsSync(filePath)) return false;
|
|
198
|
+
const s = summarizeSessionFile(id, filePath);
|
|
199
|
+
if (!s) return false;
|
|
150
200
|
db.prepare(UPSERT_SESSION).run({
|
|
151
201
|
id: s.id,
|
|
152
202
|
title: s.title,
|
|
@@ -157,7 +207,7 @@ export function indexOneSession(db, id, { mtimeMs = 0, sizeBytes = 0 } = {}) {
|
|
|
157
207
|
created_at: s.created_at,
|
|
158
208
|
updated_at: s.updated_at,
|
|
159
209
|
last_ts: s.last_ts,
|
|
160
|
-
chain_hash:
|
|
210
|
+
chain_hash: s.chain_hash,
|
|
161
211
|
mtime_ms: Math.floor(mtimeMs),
|
|
162
212
|
size_bytes: sizeBytes,
|
|
163
213
|
});
|
|
@@ -270,7 +320,8 @@ export function searchSessions(db, query, { limit = 20 } = {}) {
|
|
|
270
320
|
.replace(/\s+/g, " ")
|
|
271
321
|
.trim()
|
|
272
322
|
: "";
|
|
273
|
-
const {
|
|
323
|
+
const rest = { ...r };
|
|
324
|
+
delete rest._text;
|
|
274
325
|
return { ...rest, snippet };
|
|
275
326
|
});
|
|
276
327
|
}
|