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
package/src/commands/session.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
listSessions,
|
|
16
16
|
getSession,
|
|
17
17
|
deleteSession,
|
|
18
|
+
updateSession,
|
|
18
19
|
exportSessionMarkdown,
|
|
19
20
|
CONVERSATION_MATURITY_V2,
|
|
20
21
|
TURN_LIFECYCLE_V2,
|
|
@@ -49,7 +50,9 @@ import {
|
|
|
49
50
|
import {
|
|
50
51
|
listJsonlSessions,
|
|
51
52
|
rebuildMessages,
|
|
52
|
-
|
|
53
|
+
getJsonlSessionMetadata,
|
|
54
|
+
resolveSessionId,
|
|
55
|
+
deleteJsonlSession,
|
|
53
56
|
readEvents,
|
|
54
57
|
migrateLegacySessions,
|
|
55
58
|
migrateLegacySessionsBatch,
|
|
@@ -62,11 +65,15 @@ import {
|
|
|
62
65
|
readWorkflowSession,
|
|
63
66
|
} from "../lib/workflow-state-reader.js";
|
|
64
67
|
import { executionBroker } from "../lib/process-execution-broker/index.js";
|
|
68
|
+
import { registerSessionMcpRecoveryCommands } from "./session-mcp-recovery.js";
|
|
65
69
|
|
|
66
70
|
export const _deps = {
|
|
67
71
|
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
68
72
|
};
|
|
69
73
|
|
|
74
|
+
export const PR_STATUS_SCHEMA = "chainlesschain.session-pr-status";
|
|
75
|
+
export const PR_STATUS_VERSION = 1;
|
|
76
|
+
|
|
70
77
|
// DB sessions store `updated_at` as SQLite datetime('now') → "YYYY-MM-DD
|
|
71
78
|
// HH:MM:SS" (UTC, space at index 10); JSONL sessions store toISOString() →
|
|
72
79
|
// "YYYY-MM-DDTHH:MM:SS.sssZ" (UTC, 'T' at index 10). Both are UTC, so normalize
|
|
@@ -90,21 +97,25 @@ function _sessionEpoch(ts) {
|
|
|
90
97
|
*
|
|
91
98
|
* @param {object} signals {branch, prNumber, hasOpenPr, headCommitSha,
|
|
92
99
|
* branchProtectionSatisfied, reviewApproved, pendingApprovals,
|
|
93
|
-
* requiredChecks, checks}
|
|
100
|
+
* requiredChecks, requiredMatrixComplete, checks, ciCommitSha, sideEffects}
|
|
94
101
|
* @param {{enabled?:boolean}} [opts]
|
|
95
102
|
* @returns {{statusBar:string, autoMerge:{allow:boolean,reason:string,unmet:string[]}, lines:string[]}}
|
|
96
103
|
*/
|
|
97
104
|
export async function renderPrStatus(signals = {}, opts = {}) {
|
|
98
|
-
const {
|
|
105
|
+
const { strictAutoMergeDecision, describePrStatusBar } =
|
|
99
106
|
await import("../lib/pr-automation-policy.js");
|
|
100
|
-
const autoMerge =
|
|
107
|
+
const autoMerge = strictAutoMergeDecision({
|
|
101
108
|
enabled: opts.enabled === true,
|
|
102
109
|
hasOpenPr: signals.hasOpenPr,
|
|
103
110
|
branchProtectionSatisfied: signals.branchProtectionSatisfied,
|
|
104
111
|
reviewApproved: signals.reviewApproved,
|
|
105
112
|
pendingApprovals: signals.pendingApprovals,
|
|
106
113
|
requiredChecks: signals.requiredChecks,
|
|
114
|
+
requiredMatrixComplete: signals.requiredMatrixComplete,
|
|
107
115
|
checks: signals.checks,
|
|
116
|
+
headCommitSha: signals.headCommitSha,
|
|
117
|
+
ciCommitSha: signals.ciCommitSha,
|
|
118
|
+
sideEffects: signals.sideEffects,
|
|
108
119
|
});
|
|
109
120
|
const statusBar = describePrStatusBar({
|
|
110
121
|
branch: signals.branch,
|
|
@@ -119,7 +130,15 @@ export async function renderPrStatus(signals = {}, opts = {}) {
|
|
|
119
130
|
} else {
|
|
120
131
|
lines.push(`auto-merge: ✗ blocked (${autoMerge.unmet.join(", ")})`);
|
|
121
132
|
}
|
|
122
|
-
return {
|
|
133
|
+
return {
|
|
134
|
+
schema: PR_STATUS_SCHEMA,
|
|
135
|
+
version: PR_STATUS_VERSION,
|
|
136
|
+
headCommitSha: signals.headCommitSha || null,
|
|
137
|
+
ciCommitSha: signals.ciCommitSha || null,
|
|
138
|
+
statusBar,
|
|
139
|
+
autoMerge,
|
|
140
|
+
lines,
|
|
141
|
+
};
|
|
123
142
|
}
|
|
124
143
|
|
|
125
144
|
/**
|
|
@@ -132,11 +151,16 @@ export function mapGhPrToSignals(gh = {}) {
|
|
|
132
151
|
const rollup = Array.isArray(gh.statusCheckRollup)
|
|
133
152
|
? gh.statusCheckRollup
|
|
134
153
|
: [];
|
|
154
|
+
const headCommitSha = gh.headRefOid || undefined;
|
|
135
155
|
return {
|
|
136
156
|
branch: gh.headRefName || undefined,
|
|
137
157
|
prNumber: gh.number,
|
|
138
158
|
hasOpenPr: String(gh.state || "").toUpperCase() === "OPEN",
|
|
139
|
-
headCommitSha
|
|
159
|
+
headCommitSha,
|
|
160
|
+
// This rollup belongs to the queried headRefOid. The authoritative
|
|
161
|
+
// required-matrix definition is not exposed here, so live auto-merge still
|
|
162
|
+
// fails closed unless another trusted source supplies it.
|
|
163
|
+
ciCommitSha: headCommitSha,
|
|
140
164
|
reviewApproved: gh.reviewDecision === "APPROVED",
|
|
141
165
|
// gh doesn't expose branch-protection satisfaction or pending in-app
|
|
142
166
|
// approvals here; leave them undefined → fail-closed unless a --checks-file
|
|
@@ -145,6 +169,7 @@ export function mapGhPrToSignals(gh = {}) {
|
|
|
145
169
|
name: c.name || c.context,
|
|
146
170
|
// check runs use `conclusion`; legacy statuses use `state`.
|
|
147
171
|
state: c.conclusion || c.state || c.status,
|
|
172
|
+
commitSha: headCommitSha,
|
|
148
173
|
})),
|
|
149
174
|
};
|
|
150
175
|
}
|
|
@@ -196,6 +221,8 @@ export function registerSessionCommand(program) {
|
|
|
196
221
|
.command("session")
|
|
197
222
|
.description("Conversation session management");
|
|
198
223
|
|
|
224
|
+
registerSessionMcpRecoveryCommands(session);
|
|
225
|
+
|
|
199
226
|
// session list
|
|
200
227
|
session
|
|
201
228
|
.command("list", { isDefault: true })
|
|
@@ -258,6 +285,213 @@ export function registerSessionCommand(program) {
|
|
|
258
285
|
}
|
|
259
286
|
});
|
|
260
287
|
|
|
288
|
+
// Canonical IDE/control-plane projection. This is the only Sessions
|
|
289
|
+
// Workbench read contract: IDEs must not merge supervisor/index files on
|
|
290
|
+
// their own because that recreates lifecycle and capability drift.
|
|
291
|
+
session
|
|
292
|
+
.command("projection")
|
|
293
|
+
.description("Emit the canonical versioned session projection for IDEs")
|
|
294
|
+
.option("-n, --limit <n>", "Max local sessions", "100")
|
|
295
|
+
.option("--cwd <path>", "Project root for workflow sessions")
|
|
296
|
+
.option("--json", "Output as JSON")
|
|
297
|
+
.action(async (options) => {
|
|
298
|
+
let ctx = null;
|
|
299
|
+
const stdout = console.log;
|
|
300
|
+
const stdoutWrite = process.stdout.write;
|
|
301
|
+
let jsonPayload = null;
|
|
302
|
+
// Some legacy core packages log initialization directly to stdout. Hold
|
|
303
|
+
// stdout until shutdown so --json remains one parseable document.
|
|
304
|
+
if (options.json) {
|
|
305
|
+
console.log = () => {};
|
|
306
|
+
process.stdout.write = (_chunk, encoding, callback) => {
|
|
307
|
+
const done = typeof encoding === "function" ? encoding : callback;
|
|
308
|
+
if (typeof done === "function") done();
|
|
309
|
+
return true;
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
const limit = Math.max(1, parseInt(options.limit) || 100);
|
|
314
|
+
const projectRoot = path.resolve(options.cwd || process.cwd());
|
|
315
|
+
const sourceErrors = {};
|
|
316
|
+
let local = [];
|
|
317
|
+
let background = [];
|
|
318
|
+
let remote = [];
|
|
319
|
+
let team = [];
|
|
320
|
+
let workflow = [];
|
|
321
|
+
let artifacts = [];
|
|
322
|
+
let prLinks = {};
|
|
323
|
+
|
|
324
|
+
try {
|
|
325
|
+
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
326
|
+
if (ctx.db) {
|
|
327
|
+
local.push(
|
|
328
|
+
...listSessions(ctx.db.getDatabase(), { limit }).map((item) => ({
|
|
329
|
+
...item,
|
|
330
|
+
_store: "db",
|
|
331
|
+
})),
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
} catch (error) {
|
|
335
|
+
sourceErrors.local = error?.message || String(error);
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
// JSONL is the canonical transcript store and can be read without
|
|
339
|
+
// bootstrapping legacy native DB/config packages (some of which
|
|
340
|
+
// write banners directly to stdout and would corrupt --json).
|
|
341
|
+
local.push(
|
|
342
|
+
...listJsonlSessions({ limit }).map((item) => ({
|
|
343
|
+
...item,
|
|
344
|
+
_store: "jsonl",
|
|
345
|
+
})),
|
|
346
|
+
);
|
|
347
|
+
local = rankSessions(local, limit);
|
|
348
|
+
} catch (error) {
|
|
349
|
+
sourceErrors.local = error?.message || String(error);
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
const { listBackgroundAgents } =
|
|
353
|
+
await import("../lib/background-agent-supervisor.js");
|
|
354
|
+
background = listBackgroundAgents({ all: true });
|
|
355
|
+
} catch (error) {
|
|
356
|
+
sourceErrors.background = error?.message || String(error);
|
|
357
|
+
}
|
|
358
|
+
try {
|
|
359
|
+
const { readRemoteControlStates } =
|
|
360
|
+
await import("../lib/remote-control.js");
|
|
361
|
+
remote = readRemoteControlStates();
|
|
362
|
+
} catch (error) {
|
|
363
|
+
sourceErrors.remote = error?.message || String(error);
|
|
364
|
+
}
|
|
365
|
+
try {
|
|
366
|
+
const { listCollaborationRuns } =
|
|
367
|
+
await import("../lib/collaboration-run-store.js");
|
|
368
|
+
team = listCollaborationRuns({ limit }).filter(
|
|
369
|
+
(run) => run?.kind === "team",
|
|
370
|
+
);
|
|
371
|
+
} catch (error) {
|
|
372
|
+
sourceErrors.team = error?.message || String(error);
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
workflow = listWorkflowSessions(projectRoot)
|
|
376
|
+
.slice(0, limit)
|
|
377
|
+
.map((item) => ({
|
|
378
|
+
...item,
|
|
379
|
+
id: item.sessionId,
|
|
380
|
+
cwd: projectRoot,
|
|
381
|
+
checkpointCwd: projectRoot,
|
|
382
|
+
checkpointSessionId: item.sessionId,
|
|
383
|
+
}));
|
|
384
|
+
} catch (error) {
|
|
385
|
+
sourceErrors.workflow = error?.message || String(error);
|
|
386
|
+
}
|
|
387
|
+
try {
|
|
388
|
+
// A file checkpoint is advertised only after the existing CLI git
|
|
389
|
+
// engine proves that the exact worktree is supported. Copy-mode
|
|
390
|
+
// checkpoints need explicit paths and therefore cannot truthfully be
|
|
391
|
+
// offered as a one-click session action.
|
|
392
|
+
const { isCheckpointAvailable } =
|
|
393
|
+
await import("../lib/checkpoint-store.js");
|
|
394
|
+
const capability = new Map();
|
|
395
|
+
const decorate = (items, pathFor, sessionFor) =>
|
|
396
|
+
items.map((item) => {
|
|
397
|
+
const candidate = pathFor(item);
|
|
398
|
+
if (!candidate) return item;
|
|
399
|
+
const checkpointCwd = path.resolve(candidate);
|
|
400
|
+
let available = capability.get(checkpointCwd);
|
|
401
|
+
if (available === undefined) {
|
|
402
|
+
try {
|
|
403
|
+
available = isCheckpointAvailable(checkpointCwd);
|
|
404
|
+
} catch {
|
|
405
|
+
available = false;
|
|
406
|
+
}
|
|
407
|
+
capability.set(checkpointCwd, available);
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
...item,
|
|
411
|
+
checkpointAvailable: available === true,
|
|
412
|
+
checkpointCwd,
|
|
413
|
+
checkpointSessionId: sessionFor(item),
|
|
414
|
+
};
|
|
415
|
+
});
|
|
416
|
+
local = decorate(
|
|
417
|
+
local,
|
|
418
|
+
(item) => item?.workspace || item?.cwd,
|
|
419
|
+
(item) => item?.id,
|
|
420
|
+
);
|
|
421
|
+
background = decorate(
|
|
422
|
+
background,
|
|
423
|
+
(item) => item?.cwd,
|
|
424
|
+
(item) => item?.sessionId || item?.id,
|
|
425
|
+
);
|
|
426
|
+
workflow = decorate(
|
|
427
|
+
workflow,
|
|
428
|
+
(item) => item?.checkpointCwd,
|
|
429
|
+
(item) => item?.checkpointSessionId,
|
|
430
|
+
);
|
|
431
|
+
} catch {
|
|
432
|
+
// Capability detection is additive. Missing git support leaves the
|
|
433
|
+
// checkpoint action unavailable with its explicit reason.
|
|
434
|
+
}
|
|
435
|
+
try {
|
|
436
|
+
const { ArtifactStore } = await import("../lib/artifact-store.js");
|
|
437
|
+
artifacts = new ArtifactStore().list();
|
|
438
|
+
} catch {
|
|
439
|
+
// Summaries are optional; absence never removes a session.
|
|
440
|
+
}
|
|
441
|
+
try {
|
|
442
|
+
const { readPrLinkLedger } = await import("../lib/pr-link-ledger.js");
|
|
443
|
+
prLinks = readPrLinkLedger();
|
|
444
|
+
} catch {
|
|
445
|
+
// Summaries are optional; absence never removes a session.
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const { buildSessionProjection } =
|
|
449
|
+
await import("../lib/session-projection.js");
|
|
450
|
+
const projection = buildSessionProjection({
|
|
451
|
+
local,
|
|
452
|
+
background,
|
|
453
|
+
remote,
|
|
454
|
+
team,
|
|
455
|
+
workflow,
|
|
456
|
+
artifacts,
|
|
457
|
+
prLinks,
|
|
458
|
+
sourceErrors,
|
|
459
|
+
});
|
|
460
|
+
if (options.json) {
|
|
461
|
+
jsonPayload = JSON.stringify(projection, null, 2);
|
|
462
|
+
} else {
|
|
463
|
+
logger.log(
|
|
464
|
+
`${projection.sessions.length} sessions; revision ${projection.revision}`,
|
|
465
|
+
);
|
|
466
|
+
for (const item of projection.sessions) {
|
|
467
|
+
logger.log(
|
|
468
|
+
` ${item.id} ${item.state} [${item.capabilities.join(", ")}]`,
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
} catch (error) {
|
|
473
|
+
const { disconnectedSessionProjection } =
|
|
474
|
+
await import("../lib/session-projection.js");
|
|
475
|
+
if (options.json) {
|
|
476
|
+
jsonPayload = JSON.stringify(
|
|
477
|
+
disconnectedSessionProjection(error?.message || String(error)),
|
|
478
|
+
null,
|
|
479
|
+
2,
|
|
480
|
+
);
|
|
481
|
+
} else {
|
|
482
|
+
logger.error(`Failed: ${error.message}`);
|
|
483
|
+
}
|
|
484
|
+
process.exitCode = 1;
|
|
485
|
+
} finally {
|
|
486
|
+
if (ctx) await shutdown();
|
|
487
|
+
if (options.json) {
|
|
488
|
+
console.log = stdout;
|
|
489
|
+
process.stdout.write = stdoutWrite;
|
|
490
|
+
stdout(jsonPayload || "{}");
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
|
|
261
495
|
// session show
|
|
262
496
|
session
|
|
263
497
|
.command("show")
|
|
@@ -266,35 +500,40 @@ export function registerSessionCommand(program) {
|
|
|
266
500
|
.option("-n, --limit <n>", "Max messages to show")
|
|
267
501
|
.option("--json", "Output as JSON")
|
|
268
502
|
.action(async (id, options) => {
|
|
503
|
+
let ctx = null;
|
|
269
504
|
try {
|
|
270
|
-
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
271
505
|
let sess = null;
|
|
272
506
|
|
|
273
507
|
// Try JSONL first if enabled
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const
|
|
277
|
-
const msgs = rebuildMessages(
|
|
508
|
+
const jsonlId = feature("JSONL_SESSION") ? resolveSessionId(id) : null;
|
|
509
|
+
if (jsonlId) {
|
|
510
|
+
const metadata = getJsonlSessionMetadata(jsonlId);
|
|
511
|
+
const msgs = rebuildMessages(jsonlId);
|
|
278
512
|
sess = {
|
|
279
|
-
id,
|
|
280
|
-
title:
|
|
281
|
-
provider:
|
|
282
|
-
model:
|
|
513
|
+
id: jsonlId,
|
|
514
|
+
title: metadata?.title || "Untitled",
|
|
515
|
+
provider: metadata?.provider || "",
|
|
516
|
+
model: metadata?.model || "",
|
|
283
517
|
message_count: msgs.length,
|
|
284
518
|
messages: msgs,
|
|
285
519
|
_store: "jsonl",
|
|
286
520
|
};
|
|
287
521
|
}
|
|
288
522
|
|
|
289
|
-
//
|
|
290
|
-
|
|
523
|
+
// Version-0 DB adapter is loaded only when the canonical transcript is
|
|
524
|
+
// absent, keeping the JSONL hot path independent from native SQLite.
|
|
525
|
+
if (!sess) {
|
|
526
|
+
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
527
|
+
}
|
|
528
|
+
if (!sess && ctx?.db) {
|
|
291
529
|
const db = ctx.db.getDatabase();
|
|
292
530
|
sess = getSession(db, id);
|
|
293
531
|
}
|
|
294
532
|
|
|
295
533
|
if (!sess) {
|
|
296
534
|
logger.error(`Session not found: ${id}`);
|
|
297
|
-
process.
|
|
535
|
+
process.exitCode = 1;
|
|
536
|
+
return;
|
|
298
537
|
}
|
|
299
538
|
|
|
300
539
|
// PR/session linking: surface PRs this session created/touched.
|
|
@@ -302,7 +541,7 @@ export function registerSessionCommand(program) {
|
|
|
302
541
|
const { getPrLinks } = await import("../lib/pr-link-ledger.js");
|
|
303
542
|
const prLinks = getPrLinks(sess.id);
|
|
304
543
|
if (prLinks.length > 0) sess.prLinks = prLinks;
|
|
305
|
-
} catch
|
|
544
|
+
} catch {
|
|
306
545
|
// PR decoration is cosmetic
|
|
307
546
|
}
|
|
308
547
|
|
|
@@ -346,11 +585,11 @@ export function registerSessionCommand(program) {
|
|
|
346
585
|
logger.log("");
|
|
347
586
|
}
|
|
348
587
|
}
|
|
349
|
-
|
|
350
|
-
await shutdown();
|
|
351
588
|
} catch (err) {
|
|
352
589
|
logger.error(`Failed: ${err.message}`);
|
|
353
|
-
process.
|
|
590
|
+
process.exitCode = 1;
|
|
591
|
+
} finally {
|
|
592
|
+
if (ctx) await shutdown();
|
|
354
593
|
}
|
|
355
594
|
});
|
|
356
595
|
|
|
@@ -366,7 +605,7 @@ export function registerSessionCommand(program) {
|
|
|
366
605
|
.option("--pr <number>", "Which linked PR to assess (default: newest)")
|
|
367
606
|
.option(
|
|
368
607
|
"--checks-file <path>",
|
|
369
|
-
"JSON
|
|
608
|
+
"JSON PR signals including exact head/CI commits, full required matrix, checks and side-effect adjudication — bypasses gh",
|
|
370
609
|
)
|
|
371
610
|
.option("--enable", "Consider auto-merge eligibility (default: off)")
|
|
372
611
|
.option("--json", "Output as machine-readable JSON")
|
|
@@ -452,13 +691,14 @@ export function registerSessionCommand(program) {
|
|
|
452
691
|
"Resume even when the transcript hash chain is broken (context is untrusted)",
|
|
453
692
|
)
|
|
454
693
|
.action(async (id, options) => {
|
|
694
|
+
let ctx = null;
|
|
455
695
|
try {
|
|
456
|
-
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
457
696
|
let sess = null;
|
|
458
697
|
|
|
459
698
|
// No id → shared interactive picker (TTY + >1) or most-recent fallback
|
|
460
699
|
// (single / non-TTY / Ctrl-C). Same helper as `cc agent --resume`.
|
|
461
700
|
if (!id) {
|
|
701
|
+
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
462
702
|
const { pickRecentSession } =
|
|
463
703
|
await import("../lib/session-picker.js");
|
|
464
704
|
const picked = await pickRecentSession(ctx);
|
|
@@ -466,57 +706,64 @@ export function registerSessionCommand(program) {
|
|
|
466
706
|
logger.error(
|
|
467
707
|
"No saved sessions to resume. Use 'chat' or 'agent' to create one.",
|
|
468
708
|
);
|
|
469
|
-
process.
|
|
709
|
+
process.exitCode = 1;
|
|
710
|
+
return;
|
|
470
711
|
}
|
|
471
712
|
id = picked.id;
|
|
472
713
|
}
|
|
473
714
|
|
|
474
715
|
// Try JSONL first
|
|
475
|
-
|
|
716
|
+
const jsonlId = feature("JSONL_SESSION") ? resolveSessionId(id) : null;
|
|
717
|
+
if (jsonlId) {
|
|
476
718
|
// Tamper gate: a broken hash chain means the transcript was edited
|
|
477
719
|
// outside the store — never silently rebuild it as trusted context.
|
|
478
720
|
const { verifySession } =
|
|
479
721
|
await import("../harness/jsonl-session-store.js");
|
|
480
|
-
const trust = verifySession(
|
|
722
|
+
const trust = verifySession(jsonlId);
|
|
481
723
|
if (trust.status === "tampered") {
|
|
482
724
|
if (!options.allowTampered) {
|
|
483
725
|
logger.error(
|
|
484
|
-
`Session ${
|
|
726
|
+
`Session ${jsonlId} transcript failed integrity verification: ${trust.reason}` +
|
|
485
727
|
(trust.firstInvalidLine
|
|
486
728
|
? ` (line ${trust.firstInvalidLine})`
|
|
487
729
|
: ""),
|
|
488
730
|
);
|
|
489
731
|
logger.error(
|
|
490
732
|
"Refusing to resume tampered context. Inspect it read-only with " +
|
|
491
|
-
`'cc session show ${
|
|
733
|
+
`'cc session show ${jsonlId}' / 'cc session verify ${jsonlId}', or pass --allow-tampered to override.`,
|
|
492
734
|
);
|
|
493
|
-
process.
|
|
735
|
+
process.exitCode = 1;
|
|
736
|
+
return;
|
|
494
737
|
}
|
|
495
738
|
logger.warn(
|
|
496
739
|
`⚠ Resuming a TAMPERED transcript (${trust.reason}) — treat restored context as untrusted.`,
|
|
497
740
|
);
|
|
498
741
|
}
|
|
499
|
-
const
|
|
500
|
-
const startEvent = events.find((e) => e.type === "session_start");
|
|
742
|
+
const metadata = getJsonlSessionMetadata(jsonlId);
|
|
501
743
|
sess = {
|
|
502
|
-
id,
|
|
503
|
-
title:
|
|
504
|
-
provider:
|
|
505
|
-
model:
|
|
506
|
-
messages: rebuildMessages(
|
|
744
|
+
id: jsonlId,
|
|
745
|
+
title: metadata?.title || "Untitled",
|
|
746
|
+
provider: metadata?.provider || "",
|
|
747
|
+
model: metadata?.model || "",
|
|
748
|
+
messages: rebuildMessages(jsonlId),
|
|
507
749
|
};
|
|
508
750
|
sess.message_count = sess.messages.length;
|
|
509
751
|
}
|
|
510
752
|
|
|
511
|
-
//
|
|
512
|
-
|
|
753
|
+
// Version-0 DB adapter is loaded only when the canonical transcript is
|
|
754
|
+
// absent (or the picker required the combined legacy view).
|
|
755
|
+
if (!sess && !ctx) {
|
|
756
|
+
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
757
|
+
}
|
|
758
|
+
if (!sess && ctx?.db) {
|
|
513
759
|
const db = ctx.db.getDatabase();
|
|
514
760
|
sess = getSession(db, id);
|
|
515
761
|
}
|
|
516
762
|
|
|
517
763
|
if (!sess) {
|
|
518
764
|
logger.error(`Session not found: ${id}`);
|
|
519
|
-
process.
|
|
765
|
+
process.exitCode = 1;
|
|
766
|
+
return;
|
|
520
767
|
}
|
|
521
768
|
|
|
522
769
|
logger.info(
|
|
@@ -534,7 +781,9 @@ export function registerSessionCommand(program) {
|
|
|
534
781
|
});
|
|
535
782
|
} catch (err) {
|
|
536
783
|
logger.error(`Failed: ${err.message}`);
|
|
537
|
-
process.
|
|
784
|
+
process.exitCode = 1;
|
|
785
|
+
} finally {
|
|
786
|
+
if (ctx) await shutdown();
|
|
538
787
|
}
|
|
539
788
|
});
|
|
540
789
|
|
|
@@ -542,7 +791,7 @@ export function registerSessionCommand(program) {
|
|
|
542
791
|
session
|
|
543
792
|
.command("export")
|
|
544
793
|
.description(
|
|
545
|
-
"Export a session as Markdown (
|
|
794
|
+
"Export a session as Markdown (canonical JSONL transcript, then legacy DB fallback)",
|
|
546
795
|
)
|
|
547
796
|
.argument(
|
|
548
797
|
"<id>",
|
|
@@ -554,12 +803,25 @@ export function registerSessionCommand(program) {
|
|
|
554
803
|
"Do NOT redact detected secrets from the exported transcript (default: redact)",
|
|
555
804
|
)
|
|
556
805
|
.action(async (id, options) => {
|
|
806
|
+
let bootstrapped = false;
|
|
557
807
|
try {
|
|
558
808
|
let markdown = null;
|
|
559
|
-
let bootstrapped = false;
|
|
560
809
|
|
|
561
|
-
//
|
|
562
|
-
|
|
810
|
+
// Canonical content source: append-only JSONL event log. The legacy DB
|
|
811
|
+
// is consulted only when no matching transcript exists.
|
|
812
|
+
const store = await import("../harness/jsonl-session-store.js");
|
|
813
|
+
const sid =
|
|
814
|
+
id === "last" ? store.getLastSessionId() : store.resolveSessionId(id);
|
|
815
|
+
if (sid) {
|
|
816
|
+
const { renderAgentSessionMarkdown } =
|
|
817
|
+
await import("../lib/agent-session-export.js");
|
|
818
|
+
markdown = renderAgentSessionMarkdown(sid, store.readEvents(sid), {
|
|
819
|
+
exportedAt: new Date().toISOString(),
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Version-0 chat DB adapter: read-only migration compatibility.
|
|
824
|
+
if (!markdown && id !== "last") {
|
|
563
825
|
try {
|
|
564
826
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
565
827
|
bootstrapped = true;
|
|
@@ -572,23 +834,10 @@ export function registerSessionCommand(program) {
|
|
|
572
834
|
}
|
|
573
835
|
}
|
|
574
836
|
|
|
575
|
-
// Fallback: JSONL agent sessions (`cc agent --resume` store) —
|
|
576
|
-
// Claude-Code /export parity for agent transcripts.
|
|
577
|
-
if (!markdown) {
|
|
578
|
-
const store = await import("../harness/jsonl-session-store.js");
|
|
579
|
-
const sid = id === "last" ? store.getLastSessionId() : id;
|
|
580
|
-
if (sid && store.sessionExists(sid)) {
|
|
581
|
-
const { renderAgentSessionMarkdown } =
|
|
582
|
-
await import("../lib/agent-session-export.js");
|
|
583
|
-
markdown = renderAgentSessionMarkdown(sid, store.readEvents(sid), {
|
|
584
|
-
exportedAt: new Date().toISOString(),
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
837
|
if (!markdown) {
|
|
590
838
|
logger.error(`Session not found: ${id}`);
|
|
591
|
-
process.
|
|
839
|
+
process.exitCode = 1;
|
|
840
|
+
return;
|
|
592
841
|
}
|
|
593
842
|
|
|
594
843
|
// §8.1 export gate: a transcript can carry provider tokens, JWTs,
|
|
@@ -611,11 +860,11 @@ export function registerSessionCommand(program) {
|
|
|
611
860
|
} else {
|
|
612
861
|
console.log(markdown);
|
|
613
862
|
}
|
|
614
|
-
|
|
615
|
-
if (bootstrapped) await shutdown();
|
|
616
863
|
} catch (err) {
|
|
617
864
|
logger.error(`Failed: ${err.message}`);
|
|
618
|
-
process.
|
|
865
|
+
process.exitCode = 1;
|
|
866
|
+
} finally {
|
|
867
|
+
if (bootstrapped) await shutdown();
|
|
619
868
|
}
|
|
620
869
|
});
|
|
621
870
|
|
|
@@ -634,40 +883,81 @@ export function registerSessionCommand(program) {
|
|
|
634
883
|
const store = await import("../harness/jsonl-session-store.js");
|
|
635
884
|
const q = String(query).toLowerCase();
|
|
636
885
|
const limit = Number(options.limit) || 20;
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
886
|
+
let source = "sqlite-index";
|
|
887
|
+
let indexDiagnostic = null;
|
|
888
|
+
let matches = [];
|
|
889
|
+
let indexDb = null;
|
|
890
|
+
try {
|
|
891
|
+
const sessionIndex = await import("../harness/session-index.js");
|
|
892
|
+
indexDb = sessionIndex.openIndex();
|
|
893
|
+
sessionIndex.syncIndex(indexDb);
|
|
894
|
+
matches = sessionIndex
|
|
895
|
+
.searchSessions(indexDb, query, { limit })
|
|
896
|
+
.map((hit) => ({
|
|
897
|
+
session: hit.id,
|
|
898
|
+
title: hit.title,
|
|
899
|
+
role: "session",
|
|
900
|
+
when: hit.updated_at || "",
|
|
901
|
+
preview: hit.snippet || hit.title || "",
|
|
902
|
+
}));
|
|
903
|
+
} catch (error) {
|
|
904
|
+
// Native SQLite is optional in development/source installs. The
|
|
905
|
+
// bounded streaming fallback preserves functionality and identifies
|
|
906
|
+
// itself in JSON output instead of silently pretending it was indexed.
|
|
907
|
+
source = "stream-fallback";
|
|
908
|
+
indexDiagnostic = error?.message || String(error);
|
|
909
|
+
const sessions = store.listJsonlSessions({
|
|
910
|
+
limit: Number(options.sessions) || 200,
|
|
911
|
+
});
|
|
912
|
+
for (const s of sessions) {
|
|
644
913
|
if (matches.length >= limit) break;
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
.
|
|
664
|
-
.
|
|
665
|
-
|
|
666
|
-
|
|
914
|
+
for (const ev of store.readEvents(s.id)) {
|
|
915
|
+
if (matches.length >= limit) break;
|
|
916
|
+
if (
|
|
917
|
+
ev.type !== "user_message" &&
|
|
918
|
+
ev.type !== "assistant_message"
|
|
919
|
+
) {
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
const text =
|
|
923
|
+
typeof ev.data?.content === "string"
|
|
924
|
+
? ev.data.content
|
|
925
|
+
: JSON.stringify(ev.data?.content || "");
|
|
926
|
+
const at = text.toLowerCase().indexOf(q);
|
|
927
|
+
if (at === -1) continue;
|
|
928
|
+
const from = Math.max(0, at - 30);
|
|
929
|
+
matches.push({
|
|
930
|
+
session: s.id,
|
|
931
|
+
title: s.title,
|
|
932
|
+
role: ev.type === "user_message" ? "user" : "assistant",
|
|
933
|
+
when: store.toIsoSafe(ev.timestamp),
|
|
934
|
+
preview: text
|
|
935
|
+
.slice(from, at + q.length + 50)
|
|
936
|
+
.replace(/\s+/g, " ")
|
|
937
|
+
.trim(),
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
} finally {
|
|
942
|
+
try {
|
|
943
|
+
indexDb?.close();
|
|
944
|
+
} catch {
|
|
945
|
+
/* derived index close is best-effort */
|
|
667
946
|
}
|
|
668
947
|
}
|
|
669
948
|
if (options.json) {
|
|
670
|
-
console.log(
|
|
949
|
+
console.log(
|
|
950
|
+
JSON.stringify(
|
|
951
|
+
{
|
|
952
|
+
query,
|
|
953
|
+
source,
|
|
954
|
+
matches,
|
|
955
|
+
...(indexDiagnostic ? { indexDiagnostic } : {}),
|
|
956
|
+
},
|
|
957
|
+
null,
|
|
958
|
+
2,
|
|
959
|
+
),
|
|
960
|
+
);
|
|
671
961
|
return;
|
|
672
962
|
}
|
|
673
963
|
if (!matches.length) {
|
|
@@ -699,37 +989,53 @@ export function registerSessionCommand(program) {
|
|
|
699
989
|
.argument("<id>", "Session ID")
|
|
700
990
|
.option("--force", "Skip confirmation")
|
|
701
991
|
.action(async (id, options) => {
|
|
992
|
+
let ctx = null;
|
|
702
993
|
try {
|
|
703
|
-
const
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
994
|
+
const jsonlId = resolveSessionId(id);
|
|
995
|
+
let db = null;
|
|
996
|
+
try {
|
|
997
|
+
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
998
|
+
db = ctx.db?.getDatabase() || null;
|
|
999
|
+
} catch (error) {
|
|
1000
|
+
if (!jsonlId) throw error;
|
|
1001
|
+
}
|
|
1002
|
+
const dbSession = !jsonlId && db ? getSession(db, id) : null;
|
|
1003
|
+
const targetId = jsonlId || dbSession?.id || id;
|
|
1004
|
+
|
|
1005
|
+
if (!jsonlId && !dbSession) {
|
|
1006
|
+
logger.error(`Session not found: ${id}`);
|
|
1007
|
+
process.exitCode = 1;
|
|
1008
|
+
return;
|
|
707
1009
|
}
|
|
708
|
-
const db = ctx.db.getDatabase();
|
|
709
1010
|
|
|
710
1011
|
if (!options.force) {
|
|
711
1012
|
const { confirm } = await import("@inquirer/prompts");
|
|
712
1013
|
const ok = await confirm({
|
|
713
|
-
message: `Delete session "${
|
|
1014
|
+
message: `Delete session "${targetId}"?`,
|
|
714
1015
|
});
|
|
715
1016
|
if (!ok) {
|
|
716
1017
|
logger.info("Cancelled");
|
|
717
|
-
await shutdown();
|
|
718
1018
|
return;
|
|
719
1019
|
}
|
|
720
1020
|
}
|
|
721
1021
|
|
|
722
|
-
const
|
|
723
|
-
|
|
1022
|
+
const jsonlDeleted = jsonlId ? deleteJsonlSession(jsonlId) : false;
|
|
1023
|
+
// Remove an exact-id legacy duplicate as part of the same semantic
|
|
1024
|
+
// delete so it cannot reappear after the canonical transcript is gone.
|
|
1025
|
+
const dbDeleted = db
|
|
1026
|
+
? deleteSession(db, jsonlId || dbSession?.id || id)
|
|
1027
|
+
: false;
|
|
1028
|
+
if (jsonlDeleted || dbDeleted) {
|
|
724
1029
|
logger.success("Session deleted");
|
|
725
1030
|
} else {
|
|
726
1031
|
logger.error(`Session not found: ${id}`);
|
|
1032
|
+
process.exitCode = 1;
|
|
727
1033
|
}
|
|
728
|
-
|
|
729
|
-
await shutdown();
|
|
730
1034
|
} catch (err) {
|
|
731
1035
|
logger.error(`Failed: ${err.message}`);
|
|
732
|
-
process.
|
|
1036
|
+
process.exitCode = 1;
|
|
1037
|
+
} finally {
|
|
1038
|
+
if (ctx) await shutdown();
|
|
733
1039
|
}
|
|
734
1040
|
});
|
|
735
1041
|
|
|
@@ -742,13 +1048,26 @@ export function registerSessionCommand(program) {
|
|
|
742
1048
|
.argument("<title...>", "New title")
|
|
743
1049
|
.option("--json", "Output as JSON")
|
|
744
1050
|
.action(async (id, title, options) => {
|
|
1051
|
+
let ctx = null;
|
|
745
1052
|
try {
|
|
746
|
-
const
|
|
747
|
-
await import("../harness/jsonl-session-store.js");
|
|
748
|
-
const result = renameSession(
|
|
749
|
-
id,
|
|
1053
|
+
const normalized = String(
|
|
750
1054
|
Array.isArray(title) ? title.join(" ") : title,
|
|
751
|
-
);
|
|
1055
|
+
).trim();
|
|
1056
|
+
if (!normalized) throw new Error("A non-empty title is required");
|
|
1057
|
+
const jsonlId = resolveSessionId(id);
|
|
1058
|
+
let result;
|
|
1059
|
+
if (jsonlId) {
|
|
1060
|
+
const { renameSession } =
|
|
1061
|
+
await import("../harness/jsonl-session-store.js");
|
|
1062
|
+
result = renameSession(jsonlId, normalized);
|
|
1063
|
+
} else {
|
|
1064
|
+
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
1065
|
+
const db = ctx.db?.getDatabase();
|
|
1066
|
+
const legacy = db ? getSession(db, id) : null;
|
|
1067
|
+
if (!legacy) throw new Error(`Session not found: ${id}`);
|
|
1068
|
+
updateSession(db, legacy.id, { title: normalized.slice(0, 200) });
|
|
1069
|
+
result = { id: legacy.id, title: normalized.slice(0, 200) };
|
|
1070
|
+
}
|
|
752
1071
|
if (options.json) {
|
|
753
1072
|
console.log(JSON.stringify(result, null, 2));
|
|
754
1073
|
return;
|
|
@@ -758,6 +1077,8 @@ export function registerSessionCommand(program) {
|
|
|
758
1077
|
} catch (err) {
|
|
759
1078
|
logger.error(`Failed: ${err.message}`);
|
|
760
1079
|
process.exitCode = 1;
|
|
1080
|
+
} finally {
|
|
1081
|
+
if (ctx) await shutdown();
|
|
761
1082
|
}
|
|
762
1083
|
});
|
|
763
1084
|
|
|
@@ -966,6 +1287,45 @@ export function registerSessionCommand(program) {
|
|
|
966
1287
|
// list/search without scanning every transcript, and can mirror sessions to a
|
|
967
1288
|
// configured off-box target (fs/http). The index is a derived cache: safe to
|
|
968
1289
|
// delete and rebuild from the JSONL at any time.
|
|
1290
|
+
session
|
|
1291
|
+
.command("repair")
|
|
1292
|
+
.description(
|
|
1293
|
+
"Diagnose and repair one crash-partial final transcript record only",
|
|
1294
|
+
)
|
|
1295
|
+
.argument("<id>", "Session ID to repair")
|
|
1296
|
+
.option("--dry-run", "Report the repair without changing the transcript")
|
|
1297
|
+
.option("--json", "Output as JSON")
|
|
1298
|
+
.action(async (id, options) => {
|
|
1299
|
+
try {
|
|
1300
|
+
const store = await import("../harness/jsonl-session-store.js");
|
|
1301
|
+
const result = store.repairSession(id, {
|
|
1302
|
+
dryRun: Boolean(options.dryRun),
|
|
1303
|
+
});
|
|
1304
|
+
if (options.json) {
|
|
1305
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1306
|
+
} else {
|
|
1307
|
+
const label = result.healthy
|
|
1308
|
+
? chalk.green("healthy")
|
|
1309
|
+
: chalk.yellow(options.dryRun ? "repair-needed" : "attention");
|
|
1310
|
+
logger.log(`${label} ${result.sessionId} (${result.status})`);
|
|
1311
|
+
if (result.action && result.action !== "none") {
|
|
1312
|
+
const prefix = options.dryRun ? "would " : "";
|
|
1313
|
+
logger.log(
|
|
1314
|
+
` ${prefix}${result.action}` +
|
|
1315
|
+
(result.discardedBytes
|
|
1316
|
+
? ` (${result.discardedBytes} partial bytes)`
|
|
1317
|
+
: ""),
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
if (result.reason) logger.log(` ${chalk.gray(result.reason)}`);
|
|
1321
|
+
}
|
|
1322
|
+
if (!result.healthy) process.exitCode = 1;
|
|
1323
|
+
} catch (err) {
|
|
1324
|
+
logger.error(`Failed: ${err.message}`);
|
|
1325
|
+
process.exitCode = 1;
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
|
|
969
1329
|
session
|
|
970
1330
|
.command("index")
|
|
971
1331
|
.description(
|