chainlesschain 0.162.197 → 0.162.198
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-D3Gu1a5d.js → AIOps-CSN-D2xb.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DrwAoKaz.js → ActionButton-CBSMlGzv.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C7Q-gd_3.js → Analytics-3yr3Nt2t.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DgBtae-n.js → AppLayout-1b-o3lMH.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-pQ6LcA-W.js → Artifacts-Dr8rJi17.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DK61tocB.js → Audit-2V689HC2.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BOKgDFRh.js → BackgroundAgents-DIxkNrD_.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Bo9G4vTP.js → Backup-Pg6BcwrE.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Do_dE9_v.js → BaseInput-CLUpqyfH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-COVvZzOL.js → Chat-qVS8rD4G.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-ti49X12Q.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Z9MJMolt.js → Checkbox-Bs9AaEay.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BVzWKVbf.js → Codegen-Dvc1mq8q.js} +1 -1
- package/src/assets/web-panel/assets/{Col-C8MnYcbT.js → Col-C4_biO7A.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DQxqw15l.js → Community-al25XQUV.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BAUmrh3y.js → Compact-D-ZDB8M1.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-jPAkQ3zK.js → Compliance-6lIfDz1W.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BBQyxbh8.js → Cowork-DdI48XMJ.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-W5koq8Z5.js → Cron-DF5HZd2g.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BQhnu5hS.js → Crosschain-DuxeSvt3.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DD7PlI18.js → DID-B9yHkUTd.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-w_ILuwKI.js → Dashboard-Z5EuI3IM.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-qiDUAyAo.js → Dropdown-vuRfO3dY.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-PDeBcI5H.js → EmailListRenderer-QFLCc1uL.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-SuArscRM.js → FamilyGuardDashboard-BZ7EXkFJ.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BCovZaUn.js → Federation-DycIEg2s.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DjlFdVFk.js → FormItemContext-Ba0H_7yG.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DoEZ7fcS.js → GenericCardRenderer--JgSTK-C.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CV0-6GPI.js → Git-DEvTbldE.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-B_SFN50w.js → Governance-BJIljy18.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-heI0Eo6k.js → Inference-CVyW3G3q.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Cz5INS5p.js → KnowledgeGraph-v8-borge.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BSFxiHkg.js → Logs-BCdS7gGo.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-CU-JB2Ns.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-0TWTpE7k.js → Marketplace-AN6tGA2B.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CV4-wBLm.js → McpTools-DGViXASN.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-x5bH5rw5.js → Memory-Bpvmx9X4.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DaBmUu9G.js → MobileBridge-CTP-DOTC.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-C8qfktxn.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B_zKEBif.js → Mtc-ndYr0M1s.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BCfKD2yg.js → MtcAudit-Ci0-YK7W.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DgYfj6c_.js → Multisig-BehSTFW7.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Dz09lFUm.js → NLProgramming-B91_YBLv.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Cuj6ugBE.js → Notes-BQlJ0-gq.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DK2WXjhg.js → NotificationSettings-CDgYMjYK.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-D1IAOQoo.js → OrderTableRenderer-BJkSlKeH.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-9fqnPvTw.js → Organization-B-b3cWCp.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-n5xHkhow.js → Overflow-CILUL4nL.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-B5AUWwH-.js → P2P-BTCFBkF0.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CoUDV6dy.js → PdhVaultBrowser-BAR6AUx5.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-DPRmQf_H.js → Permissions-RRf6HbWJ.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-B37bsbEN.js → PersonalDataHub-BGTMiICa.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-CCAuPqu9.js → Pipeline-945qY9YF.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B81msZdv.js → Privacy-DPZwI6lJ.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-B-Py2NbF.js → ProjectInit-BPH2NRKc.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CYsneiRB.js → ProjectSettings-BZCRNCvb.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Y975Mh6R.js → Projects-BTI__tBt.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-uO-10aP1.js → Providers-DDCf_nIw.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Bj_6gJ0l.js → QrScannerModal-N6rbqt1r.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BgpBCMPE.js → QuickAsk-DrwjPS7M.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DhUW3YUA.js → Recommend-Cog9Wd99.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DdeyfbkA.js → RemoteSession-DC9pynjM.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-fxW421xd.js → Reputation-D4th4gKS.js} +1 -1
- package/src/assets/web-panel/assets/{Row-De73w1og.js → Row-ogiWR6v9.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-3US_Q_lj.js → RssFeed-uYlk-2Oj.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DbZ_DU74.js → Search-DYzzwvtM.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DoIU1vMF.js → Security-Da7YOyX6.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DB_RGqpc.js → Services-CLI1VM1X.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DnzLaayC.js → Skeleton-DK77dzDC.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-VzVXHENF.js → Skills-C_z7Lmhl.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DMfvjCAI.js → Sla-D6413Q8L.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DQQOYWbF.js → SpeechSettings-C07ydbj2.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Bmx3FG1P.js → SyncSettings-DGOm2W22.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DOQyfb-2.js → Tasks-Cr_PVyLM.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D6hTRT7c.js → Templates-BhL2mZ0t.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CTPQZAzs.js → Tenant-CPk5oyUr.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B7vII3oH.js → Terminal-ClhqUsqV.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BkiFJeXV.js → TimelineRenderer-BCC7MV5a.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BPPdQMNo.js → Tokens-DD1Jt4oO.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BxG8JAEI.js → Trigger-BCydFvN2.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DHD7nMpM.js → Trust-DDHT1noa.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B4BJpU47.js → UkeySign-CWPZC7oI.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CRiGpFx2.js → VideoEditing-9Ea0nJR0.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BSDSNiem.js → Wallet-BjxhLxTf.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DLTUh5Zv.js → WebAuthn-C6uCye67.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-tW2MwjhD.js → WorkflowEditor-d2g4reYo.js} +1 -1
- package/src/assets/web-panel/assets/{chat-SgsLQ3FC.js → chat-frTc6ScX.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BHjjLIKO.js → colors-B5K6lG3v.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-VceErdKq.js → compact-item-Cdn46r8D.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BZ332MYl.js → createContext-DU1jqVQi.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CP-jEUyw.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CBTjJOjn.js → hasIn-DdNH-aW_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CawpdGTW.js → index-32ajXmTb.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOtvPdHt.js → index-7ehytj1K.js} +1 -1
- package/src/assets/web-panel/assets/{index-vIXOpcjD.js → index-BC4eGkar.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cr4rjlW5.js → index-BVLL-mq_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_SePDWj.js → index-BXKhhx9V.js} +1 -1
- package/src/assets/web-panel/assets/{index-BETEjuNr.js → index-BcGwGIaR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BY1wexYG.js → index-Be4OtL-N.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRWhLbWF.js → index-BoFak7le.js} +1 -1
- package/src/assets/web-panel/assets/{index-29wVzi-k.js → index-BwlIxAmX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeiqkxJG.js → index-CGiwfwB9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQSmZGgs.js → index-CHmkkdfT.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhXZEUAc.js → index-CQorP1Ng.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_B9rFQE.js → index-CUoNAmE8.js} +1 -1
- package/src/assets/web-panel/assets/{index-iYQNU9za.js → index-Cj6P9Nst.js} +1 -1
- package/src/assets/web-panel/assets/{index-DePOeMDM.js → index-CtRPi4YC.js} +1 -1
- package/src/assets/web-panel/assets/index-CzrCHrFy.js +1 -0
- package/src/assets/web-panel/assets/{index-DdefYBSw.js → index-D1qIC4GR.js} +1 -1
- package/src/assets/web-panel/assets/{index-By5jBtkV.js → index-D23xGYjM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMVvxIS8.js → index-D4l82Me1.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLc19alH.js → index-D4miNkWv.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2u26AS3.js → index-DIVyTmZ3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaCCy6lq.js → index-DM5FmPZU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUkVN794.js → index-DRzBBdQ0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPXFLYdW.js → index-Dca_i7H8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpumS98o.js → index-DftZuyA7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CrUgDQkf.js → index-DtBCCkC4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtjLcCNU.js → index-HjCvXHf5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaIS_TNX.js → index-LaivuXyF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BC1xuQgX.js → index-MM4Zz2OE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcUenmCX.js → index-NmEXVjzt.js} +1 -1
- package/src/assets/web-panel/assets/index-OJsGskZw.js +1 -0
- package/src/assets/web-panel/assets/{index-_PHrIO4O.js → index-PjAS0sIZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DgPvuIn2.js → index-VDM2KKo9.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5KAGxNo.js → index-cYaWV4Mq.js} +1 -1
- package/src/assets/web-panel/assets/{index-B40dQn0G.js → index-gg3QPC3i.js} +3 -3
- package/src/assets/web-panel/assets/{index-BTlc-Bve.js → index-kVO_MDm-.js} +1 -1
- package/src/assets/web-panel/assets/{index-FJ3zC9LK.js → index-mgU3Q-lN.js} +1 -1
- package/src/assets/web-panel/assets/{index-1n7xjKDU.js → index-t_OBzIP4.js} +1 -1
- package/src/assets/web-panel/assets/{index-fU7wNHDB.js → index-yZRuZpwK.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-D1oZNz0D.js → initDefaultProps-DwLTRNdo.js} +1 -1
- package/src/assets/web-panel/assets/{motion-C8k6doMO.js → motion-BchZDXnh.js} +1 -1
- package/src/assets/web-panel/assets/{move-DJ4qSbYt.js → move-e8M-zZFl.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CdpJD85j.js → mtc-parser-Ci40fQb3.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B0V4slKA.js → omit-C7110_f2.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Di5NiW1F.js → pickAttrs-skteMgnM.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B5OMHgEM.js → placementArrow-MGZ-lh2B.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C6U9IWql.js → responsiveObserve-N4Sd7uy-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BMyTH3rN.js → slide-C7HDGRaa.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C7d6BG7Z.js → statusUtils-BhRexlgy.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CR50QnQy.js → styleChecker-ChEoQkN2.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DBEeoMb8.js → useFlexGapSupport-CDbG1s2Y.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-3r099cjv.js → useFs-CUIx0tcJ.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-C5IYNdTK.js → usePersonalDataHub-bkO7L7ec.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DmEOLRHf.js → vnode-B_ZvABIG.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DnpUiVCB.js → zoom-D5shjpS8.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +4 -4
- package/src/commands/agent.js +3 -3
- package/src/commands/background-session.js +145 -0
- package/src/commands/mcp.js +125 -7
- package/src/commands/serve.js +1 -1
- package/src/commands/session-show.js +131 -0
- package/src/commands/session.js +50 -106
- package/src/commands/skill.js +87 -50
- package/src/data/changelog.json +14 -1
- package/src/gateways/ws/ws-agent-handler.js +8 -1
- package/src/harness/jsonl-session-store.js +428 -25
- package/src/harness/mcp-client.js +2652 -404
- package/src/harness/session-list-index.js +65 -7
- package/src/lazy-dispatch.js +76 -8
- package/src/lib/abort-utils.js +68 -0
- package/src/lib/agent-core.js +1 -59
- package/src/lib/chat-core.js +24 -6
- package/src/lib/cowork-mcp-tools.js +47 -2
- package/src/lib/cowork-task-runner.js +11 -3
- package/src/lib/doctor-checkup.js +9 -7
- package/src/lib/learning/skill-improver.js +21 -2
- package/src/lib/mcp-call-ledger-store.js +116 -3
- package/src/lib/mcp-call-ledger.js +59 -14
- package/src/lib/mcp-client.js +1 -0
- package/src/lib/mcp-stdio-executable-identity.js +598 -0
- package/src/lib/mcp-stdio-execution-authority.js +363 -0
- package/src/lib/mcp-tool-metadata.js +436 -0
- package/src/lib/mcp-tool-result.js +367 -0
- package/src/lib/observability/index.js +71 -0
- package/src/lib/pr-link-ledger.js +8 -27
- package/src/lib/pr-link-store.js +26 -0
- package/src/lib/process-execution-broker/index.js +14 -0
- package/src/lib/process-tree-termination.js +253 -0
- package/src/lib/session-host-snapshot.js +9 -5
- package/src/lib/session-projection.js +5 -1
- package/src/lib/session-tail.js +31 -1
- package/src/lib/skill-budget.js +222 -0
- package/src/lib/skill-execution-authority.js +381 -0
- package/src/lib/skill-execution-identity.js +39 -2
- package/src/lib/skill-loader.js +322 -86
- package/src/lib/skill-mcp.js +43 -1
- package/src/repl/agent-repl.js +174 -38
- package/src/repl/bg-dashboard.js +81 -28
- package/src/repl/chat-repl.js +77 -12
- package/src/runtime/agent-core.js +340 -108
- package/src/runtime/agent-runtime.js +26 -3
- package/src/runtime/headless-runner.js +150 -23
- package/src/runtime/headless-stream.js +309 -59
- package/src/runtime/mcp-config.js +157 -10
- package/src/runtime/mcp-tool-search.js +0 -0
- package/src/runtime/output-backpressure.js +366 -0
- package/src/runtime/pipe-safety.js +56 -21
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BUUyJ5QO.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-1mNozZ8v.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-DqnoFPgR.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DosMaL-k.js +0 -1
- package/src/assets/web-panel/assets/index-0O5ePnUq.js +0 -1
- package/src/assets/web-panel/assets/index-ChAzPigF.js +0 -1
- package/src/lib/skill-process-broker.js +0 -85
package/src/commands/mcp.js
CHANGED
|
@@ -39,6 +39,13 @@ import {
|
|
|
39
39
|
checkProjectMcpTrust,
|
|
40
40
|
issueProjectMcpWorkspaceAuthority,
|
|
41
41
|
} from "../lib/project-mcp-trust.js";
|
|
42
|
+
import {
|
|
43
|
+
consumeMcpStdioExecutionAuthority,
|
|
44
|
+
MCP_STDIO_LOCAL_CODE_TRUST_REQUIRED_CODE,
|
|
45
|
+
issueMcpStdioExecutionAuthority,
|
|
46
|
+
materializeApprovedMcpStdioInvocation,
|
|
47
|
+
} from "../lib/mcp-stdio-execution-authority.js";
|
|
48
|
+
import { prepareMcpStdioExecutableIdentity } from "../lib/mcp-stdio-executable-identity.js";
|
|
42
49
|
import {
|
|
43
50
|
CATALOG as REGISTRY_CATALOG,
|
|
44
51
|
CATEGORIES as REGISTRY_CATEGORIES,
|
|
@@ -77,6 +84,32 @@ export function isHeadlessEnv(env = process.env, platform = process.platform) {
|
|
|
77
84
|
|
|
78
85
|
// Singleton MCP client for session reuse
|
|
79
86
|
let mcpClient = null;
|
|
87
|
+
const PROJECT_MCP_FILE_TRUST = Symbol("projectMcpFileTrust");
|
|
88
|
+
|
|
89
|
+
export function authorizeMcpRowForConnect(row, overrides = {}) {
|
|
90
|
+
const config = { ...row, ...overrides };
|
|
91
|
+
if (inferTransport(config) !== "stdio") return config;
|
|
92
|
+
if (row?.[PROJECT_MCP_FILE_TRUST] === false) {
|
|
93
|
+
const error = new Error(
|
|
94
|
+
`Project MCP server "${String(row?.name)}" can execute local code; trust the current .mcp.json before connecting`,
|
|
95
|
+
);
|
|
96
|
+
error.code = MCP_STDIO_LOCAL_CODE_TRUST_REQUIRED_CODE;
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
const approvalKind =
|
|
100
|
+
row?.configScope === "managed"
|
|
101
|
+
? "managed-settings"
|
|
102
|
+
: row?.configScope === "project"
|
|
103
|
+
? "project-config"
|
|
104
|
+
: "registered-config";
|
|
105
|
+
config.mcpStdioExecutionAuthority = issueMcpStdioExecutionAuthority({
|
|
106
|
+
serverName: row.name,
|
|
107
|
+
config,
|
|
108
|
+
approvalKind,
|
|
109
|
+
approvalSource: `${row?.configScope || "user"}:${row?.configSource || "database"}:${row.name}`,
|
|
110
|
+
});
|
|
111
|
+
return config;
|
|
112
|
+
}
|
|
80
113
|
|
|
81
114
|
function commandWorkspaceBinding() {
|
|
82
115
|
return registerHostHooksV2Workspace(projectMcpLocation(process.cwd()).root);
|
|
@@ -150,7 +183,7 @@ async function connectForQuery(program, serverName) {
|
|
|
150
183
|
for (const row of rows) {
|
|
151
184
|
if (!row) continue;
|
|
152
185
|
try {
|
|
153
|
-
await client.connect(row.name, row);
|
|
186
|
+
await client.connect(row.name, authorizeMcpRowForConnect(row));
|
|
154
187
|
connected.push(row.name);
|
|
155
188
|
} catch (err) {
|
|
156
189
|
logger.log(
|
|
@@ -339,6 +372,7 @@ export function readProjectMcpRows(cwd = process.cwd()) {
|
|
|
339
372
|
configSource: file,
|
|
340
373
|
projectPath: root,
|
|
341
374
|
};
|
|
375
|
+
Object.defineProperty(row, PROJECT_MCP_FILE_TRUST, { value: trusted });
|
|
342
376
|
if (trusted && row.headersHelper) {
|
|
343
377
|
row.projectMcpWorkspaceAuthority = issueProjectMcpWorkspaceAuthority({
|
|
344
378
|
file,
|
|
@@ -773,6 +807,85 @@ export function registerMcpCommand(program) {
|
|
|
773
807
|
}
|
|
774
808
|
});
|
|
775
809
|
|
|
810
|
+
mcp
|
|
811
|
+
.command("trust-executable <name>")
|
|
812
|
+
.description(
|
|
813
|
+
"Review and trust the current executable and interpreter-entrypoint bytes for one stdio MCP server",
|
|
814
|
+
)
|
|
815
|
+
.option(
|
|
816
|
+
"--scope <scope>",
|
|
817
|
+
`Configuration scope: ${MCP_CONFIG_SCOPES.join(" | ")}`,
|
|
818
|
+
)
|
|
819
|
+
.option("--json", "Output the trusted paths and SHA-256 identities as JSON")
|
|
820
|
+
.action(async (name, options) => {
|
|
821
|
+
try {
|
|
822
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
823
|
+
if (!ctx.db) throw new Error("Database not available");
|
|
824
|
+
const configStore = new MCPServerConfig(ctx.db.getDatabase());
|
|
825
|
+
const scope = options.scope
|
|
826
|
+
? normalizeMcpConfigScope(options.scope)
|
|
827
|
+
: undefined;
|
|
828
|
+
const rows = await effectiveMcpRows(configStore, { scope });
|
|
829
|
+
const row = rows.find((entry) => entry.name === name);
|
|
830
|
+
if (!row) {
|
|
831
|
+
throw new Error(
|
|
832
|
+
`${notFoundWithSuggestion(
|
|
833
|
+
name,
|
|
834
|
+
rows.map((entry) => entry.name),
|
|
835
|
+
{ noun: "Server" },
|
|
836
|
+
)}. Use 'mcp add' first.`,
|
|
837
|
+
);
|
|
838
|
+
}
|
|
839
|
+
if (inferTransport(row) !== "stdio") {
|
|
840
|
+
throw new Error(
|
|
841
|
+
`MCP server "${name}" does not use the stdio transport`,
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
const authorized = authorizeMcpRowForConnect(row);
|
|
846
|
+
const approval = consumeMcpStdioExecutionAuthority(
|
|
847
|
+
authorized.mcpStdioExecutionAuthority,
|
|
848
|
+
{ serverName: name, config: authorized },
|
|
849
|
+
);
|
|
850
|
+
const invocation = materializeApprovedMcpStdioInvocation(approval);
|
|
851
|
+
const prepared = prepareMcpStdioExecutableIdentity({
|
|
852
|
+
serverName: name,
|
|
853
|
+
config: invocation,
|
|
854
|
+
approval,
|
|
855
|
+
cwd: process.cwd(),
|
|
856
|
+
env: process.env,
|
|
857
|
+
retrust: true,
|
|
858
|
+
});
|
|
859
|
+
const result = {
|
|
860
|
+
name,
|
|
861
|
+
status: prepared.trustStatus,
|
|
862
|
+
identityDigest: prepared.identityDigest,
|
|
863
|
+
command: prepared.identity.command,
|
|
864
|
+
entrypoints: prepared.identity.entrypoints,
|
|
865
|
+
};
|
|
866
|
+
if (options.json) {
|
|
867
|
+
console.log(JSON.stringify(result, null, 2));
|
|
868
|
+
} else {
|
|
869
|
+
logger.log(
|
|
870
|
+
chalk.green(`Trusted MCP stdio executable identity for "${name}".`),
|
|
871
|
+
);
|
|
872
|
+
logger.log(
|
|
873
|
+
` ${chalk.gray("Command:")} ${result.command.realPath} sha256:${result.command.sha256}`,
|
|
874
|
+
);
|
|
875
|
+
for (const entrypoint of result.entrypoints) {
|
|
876
|
+
logger.log(
|
|
877
|
+
` ${chalk.gray(`${entrypoint.role}:`)} ${entrypoint.realPath} sha256:${entrypoint.sha256}`,
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
await shutdown();
|
|
882
|
+
} catch (err) {
|
|
883
|
+
logger.error(`Failed: ${err.message}`);
|
|
884
|
+
process.exitCode = 1;
|
|
885
|
+
await shutdown();
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
|
|
776
889
|
// mcp add — add/update a server config
|
|
777
890
|
mcp
|
|
778
891
|
.command("add")
|
|
@@ -1207,11 +1320,13 @@ export function registerMcpCommand(program) {
|
|
|
1207
1320
|
workspaceBinding: commandWorkspaceBinding(),
|
|
1208
1321
|
});
|
|
1209
1322
|
try {
|
|
1210
|
-
const connected = await client.connect(
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1323
|
+
const connected = await client.connect(
|
|
1324
|
+
row.name,
|
|
1325
|
+
authorizeMcpRowForConnect(row, {
|
|
1326
|
+
connectTimeoutMs: timeoutMs,
|
|
1327
|
+
requestTimeoutMs: timeoutMs,
|
|
1328
|
+
}),
|
|
1329
|
+
);
|
|
1215
1330
|
diagnostics.push({
|
|
1216
1331
|
...record,
|
|
1217
1332
|
ok: true,
|
|
@@ -1301,7 +1416,10 @@ export function registerMcpCommand(program) {
|
|
|
1301
1416
|
const spinner = ora(`Connecting to ${name}...`).start();
|
|
1302
1417
|
const client = getClient();
|
|
1303
1418
|
|
|
1304
|
-
const result = await client.connect(
|
|
1419
|
+
const result = await client.connect(
|
|
1420
|
+
name,
|
|
1421
|
+
authorizeMcpRowForConnect(serverConfig),
|
|
1422
|
+
);
|
|
1305
1423
|
spinner.stop();
|
|
1306
1424
|
|
|
1307
1425
|
if (options.json) {
|
package/src/commands/serve.js
CHANGED
|
@@ -41,7 +41,7 @@ export function registerServeCommand(program) {
|
|
|
41
41
|
)
|
|
42
42
|
.option(
|
|
43
43
|
"--bundle <path>",
|
|
44
|
-
"Agent bundle directory
|
|
44
|
+
"Agent bundle directory; may execute local MCP commands from mcp.json",
|
|
45
45
|
)
|
|
46
46
|
.action(async (opts) => {
|
|
47
47
|
try {
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { numericOption } from "../lib/cli-numeric.js";
|
|
3
|
+
import { feature } from "../lib/feature-flags.js";
|
|
4
|
+
import { logger } from "../lib/logger.js";
|
|
5
|
+
import { getPrLinks } from "../lib/pr-link-store.js";
|
|
6
|
+
import {
|
|
7
|
+
getJsonlSessionMetadata,
|
|
8
|
+
rebuildMessages,
|
|
9
|
+
resolveSessionId,
|
|
10
|
+
sessionHasPersistedEvidence,
|
|
11
|
+
} from "../harness/jsonl-session-store.js";
|
|
12
|
+
|
|
13
|
+
export function registerSessionShowSubcommand(session, program) {
|
|
14
|
+
session
|
|
15
|
+
.command("show")
|
|
16
|
+
.description("Show a session's messages")
|
|
17
|
+
.argument("<id>", "Session ID (or prefix)")
|
|
18
|
+
.option("-n, --limit <n>", "Max messages to show")
|
|
19
|
+
.option("--json", "Output as JSON")
|
|
20
|
+
.action(async (id, options) => {
|
|
21
|
+
let ctx = null;
|
|
22
|
+
let shutdown = null;
|
|
23
|
+
try {
|
|
24
|
+
let sess = null;
|
|
25
|
+
|
|
26
|
+
const jsonlId = feature("JSONL_SESSION") ? resolveSessionId(id) : null;
|
|
27
|
+
if (
|
|
28
|
+
!jsonlId &&
|
|
29
|
+
feature("JSONL_SESSION") &&
|
|
30
|
+
sessionHasPersistedEvidence(id)
|
|
31
|
+
) {
|
|
32
|
+
logger.error(
|
|
33
|
+
`Session ${id} has canonical persistence evidence but no readable transcript.`,
|
|
34
|
+
);
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (jsonlId) {
|
|
39
|
+
const metadata = getJsonlSessionMetadata(jsonlId);
|
|
40
|
+
const messages = rebuildMessages(jsonlId);
|
|
41
|
+
sess = {
|
|
42
|
+
id: jsonlId,
|
|
43
|
+
title: metadata?.title || "Untitled",
|
|
44
|
+
provider: metadata?.provider || "",
|
|
45
|
+
model: metadata?.model || "",
|
|
46
|
+
message_count: messages.length,
|
|
47
|
+
messages,
|
|
48
|
+
_store: "jsonl",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Keep SQLite and the application bootstrap outside the canonical
|
|
53
|
+
// JSONL read path. Legacy sessions still retain the original fallback.
|
|
54
|
+
if (!sess) {
|
|
55
|
+
const runtime = await import("../runtime/bootstrap.js");
|
|
56
|
+
const sessionManager = await import("../lib/session-manager.js");
|
|
57
|
+
shutdown = runtime.shutdown;
|
|
58
|
+
ctx = await runtime.bootstrap({ verbose: program.opts().verbose });
|
|
59
|
+
if (ctx?.db) {
|
|
60
|
+
sess = sessionManager.getSession(ctx.db.getDatabase(), id);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!sess) {
|
|
65
|
+
logger.error(`Session not found: ${id}`);
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const prLinks = getPrLinks(sess.id);
|
|
72
|
+
if (prLinks.length > 0) sess.prLinks = prLinks;
|
|
73
|
+
} catch {
|
|
74
|
+
// PR decoration is cosmetic.
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options.json) {
|
|
78
|
+
console.log(JSON.stringify(sess, null, 2));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
logger.log(chalk.bold(sess.title));
|
|
83
|
+
logger.log(
|
|
84
|
+
chalk.gray(
|
|
85
|
+
`ID: ${sess.id} Provider: ${sess.provider} Model: ${sess.model} Messages: ${sess.message_count}`,
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
if (sess.prLinks) {
|
|
89
|
+
for (const pr of sess.prLinks) {
|
|
90
|
+
logger.log(
|
|
91
|
+
chalk.magenta(
|
|
92
|
+
`PR: #${pr.number}${pr.state ? ` ${pr.state}` : ""}${pr.url ? ` ${pr.url}` : ""}`,
|
|
93
|
+
),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
logger.log("");
|
|
98
|
+
|
|
99
|
+
let messages = sess.messages;
|
|
100
|
+
if (options.limit) {
|
|
101
|
+
messages = messages.slice(
|
|
102
|
+
-numericOption(options.limit, {
|
|
103
|
+
name: "--limit",
|
|
104
|
+
integer: true,
|
|
105
|
+
min: 1,
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
for (const message of messages) {
|
|
111
|
+
if (message.role === "system") continue;
|
|
112
|
+
const label =
|
|
113
|
+
message.role === "user" ? chalk.green("you> ") : chalk.blue("ai> ");
|
|
114
|
+
logger.log(`${label}${(message.content || "").substring(0, 500)}`);
|
|
115
|
+
logger.log("");
|
|
116
|
+
}
|
|
117
|
+
} catch (error) {
|
|
118
|
+
logger.error(`Failed: ${error.message}`);
|
|
119
|
+
process.exitCode = 1;
|
|
120
|
+
} finally {
|
|
121
|
+
if (ctx && shutdown) await shutdown();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function registerSessionShowCommand(program) {
|
|
127
|
+
const session = program
|
|
128
|
+
.command("session")
|
|
129
|
+
.description("Conversation session management");
|
|
130
|
+
registerSessionShowSubcommand(session, program);
|
|
131
|
+
}
|
package/src/commands/session.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import fs from "fs";
|
|
7
|
-
import { numericOption } from "../lib/cli-numeric.js";
|
|
8
7
|
import path from "path";
|
|
9
8
|
import chalk from "chalk";
|
|
10
9
|
import { logger } from "../lib/logger.js";
|
|
@@ -52,8 +51,8 @@ import {
|
|
|
52
51
|
rebuildMessages,
|
|
53
52
|
getJsonlSessionMetadata,
|
|
54
53
|
resolveSessionId,
|
|
54
|
+
sessionHasPersistedEvidence,
|
|
55
55
|
deleteJsonlSession,
|
|
56
|
-
readEvents,
|
|
57
56
|
migrateLegacySessions,
|
|
58
57
|
migrateLegacySessionsBatch,
|
|
59
58
|
validateJsonlSession,
|
|
@@ -66,6 +65,7 @@ import {
|
|
|
66
65
|
} from "../lib/workflow-state-reader.js";
|
|
67
66
|
import { executionBroker } from "../lib/process-execution-broker/index.js";
|
|
68
67
|
import { registerSessionMcpRecoveryCommands } from "./session-mcp-recovery.js";
|
|
68
|
+
import { registerSessionShowSubcommand } from "./session-show.js";
|
|
69
69
|
|
|
70
70
|
export const _deps = {
|
|
71
71
|
execFileSync: (...args) => executionBroker.execFileSync(...args),
|
|
@@ -492,106 +492,7 @@ export function registerSessionCommand(program) {
|
|
|
492
492
|
}
|
|
493
493
|
});
|
|
494
494
|
|
|
495
|
-
|
|
496
|
-
session
|
|
497
|
-
.command("show")
|
|
498
|
-
.description("Show a session's messages")
|
|
499
|
-
.argument("<id>", "Session ID (or prefix)")
|
|
500
|
-
.option("-n, --limit <n>", "Max messages to show")
|
|
501
|
-
.option("--json", "Output as JSON")
|
|
502
|
-
.action(async (id, options) => {
|
|
503
|
-
let ctx = null;
|
|
504
|
-
try {
|
|
505
|
-
let sess = null;
|
|
506
|
-
|
|
507
|
-
// Try JSONL first if enabled
|
|
508
|
-
const jsonlId = feature("JSONL_SESSION") ? resolveSessionId(id) : null;
|
|
509
|
-
if (jsonlId) {
|
|
510
|
-
const metadata = getJsonlSessionMetadata(jsonlId);
|
|
511
|
-
const msgs = rebuildMessages(jsonlId);
|
|
512
|
-
sess = {
|
|
513
|
-
id: jsonlId,
|
|
514
|
-
title: metadata?.title || "Untitled",
|
|
515
|
-
provider: metadata?.provider || "",
|
|
516
|
-
model: metadata?.model || "",
|
|
517
|
-
message_count: msgs.length,
|
|
518
|
-
messages: msgs,
|
|
519
|
-
_store: "jsonl",
|
|
520
|
-
};
|
|
521
|
-
}
|
|
522
|
-
|
|
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) {
|
|
529
|
-
const db = ctx.db.getDatabase();
|
|
530
|
-
sess = getSession(db, id);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
if (!sess) {
|
|
534
|
-
logger.error(`Session not found: ${id}`);
|
|
535
|
-
process.exitCode = 1;
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// PR/session linking: surface PRs this session created/touched.
|
|
540
|
-
try {
|
|
541
|
-
const { getPrLinks } = await import("../lib/pr-link-ledger.js");
|
|
542
|
-
const prLinks = getPrLinks(sess.id);
|
|
543
|
-
if (prLinks.length > 0) sess.prLinks = prLinks;
|
|
544
|
-
} catch {
|
|
545
|
-
// PR decoration is cosmetic
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
if (options.json) {
|
|
549
|
-
console.log(JSON.stringify(sess, null, 2));
|
|
550
|
-
} else {
|
|
551
|
-
logger.log(chalk.bold(sess.title));
|
|
552
|
-
logger.log(
|
|
553
|
-
chalk.gray(
|
|
554
|
-
`ID: ${sess.id} Provider: ${sess.provider} Model: ${sess.model} Messages: ${sess.message_count}`,
|
|
555
|
-
),
|
|
556
|
-
);
|
|
557
|
-
if (sess.prLinks) {
|
|
558
|
-
for (const pr of sess.prLinks) {
|
|
559
|
-
logger.log(
|
|
560
|
-
chalk.magenta(
|
|
561
|
-
`PR: #${pr.number}${pr.state ? ` ${pr.state}` : ""}${pr.url ? ` ${pr.url}` : ""}`,
|
|
562
|
-
),
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
logger.log("");
|
|
567
|
-
|
|
568
|
-
let messages = sess.messages;
|
|
569
|
-
if (options.limit) {
|
|
570
|
-
messages = messages.slice(
|
|
571
|
-
-numericOption(options.limit, {
|
|
572
|
-
name: "--limit",
|
|
573
|
-
integer: true,
|
|
574
|
-
min: 1,
|
|
575
|
-
}),
|
|
576
|
-
);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
for (const msg of messages) {
|
|
580
|
-
if (msg.role === "system") continue;
|
|
581
|
-
const label =
|
|
582
|
-
msg.role === "user" ? chalk.green("you> ") : chalk.blue("ai> ");
|
|
583
|
-
const content = (msg.content || "").substring(0, 500);
|
|
584
|
-
logger.log(`${label}${content}`);
|
|
585
|
-
logger.log("");
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
} catch (err) {
|
|
589
|
-
logger.error(`Failed: ${err.message}`);
|
|
590
|
-
process.exitCode = 1;
|
|
591
|
-
} finally {
|
|
592
|
-
if (ctx) await shutdown();
|
|
593
|
-
}
|
|
594
|
-
});
|
|
495
|
+
registerSessionShowSubcommand(session, program);
|
|
595
496
|
|
|
596
497
|
// session pr-status — PR/CI monitor + controlled auto-merge decision (P1-4)
|
|
597
498
|
// for a session's linked PR. Offline-testable via --checks-file; otherwise a
|
|
@@ -714,12 +615,36 @@ export function registerSessionCommand(program) {
|
|
|
714
615
|
|
|
715
616
|
// Try JSONL first
|
|
716
617
|
const jsonlId = feature("JSONL_SESSION") ? resolveSessionId(id) : null;
|
|
618
|
+
if (
|
|
619
|
+
!jsonlId &&
|
|
620
|
+
feature("JSONL_SESSION") &&
|
|
621
|
+
sessionHasPersistedEvidence(id)
|
|
622
|
+
) {
|
|
623
|
+
logger.error(
|
|
624
|
+
`Session ${id} has canonical persistence evidence but no readable transcript.`,
|
|
625
|
+
);
|
|
626
|
+
logger.error(
|
|
627
|
+
"Refusing legacy fallback. Inspect or explicitly delete the damaged JSONL session before reusing its id.",
|
|
628
|
+
);
|
|
629
|
+
process.exitCode = 1;
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
717
632
|
if (jsonlId) {
|
|
718
633
|
// Tamper gate: a broken hash chain means the transcript was edited
|
|
719
634
|
// outside the store — never silently rebuild it as trusted context.
|
|
720
635
|
const { verifySession } =
|
|
721
636
|
await import("../harness/jsonl-session-store.js");
|
|
722
637
|
const trust = verifySession(jsonlId);
|
|
638
|
+
if (["missing", "conflict"].includes(trust.status)) {
|
|
639
|
+
logger.error(
|
|
640
|
+
`Session ${jsonlId} transcript is unavailable: ${trust.reason}`,
|
|
641
|
+
);
|
|
642
|
+
logger.error(
|
|
643
|
+
"Refusing to resume without canonical history. Inspect or explicitly delete the damaged session before reusing its id.",
|
|
644
|
+
);
|
|
645
|
+
process.exitCode = 1;
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
723
648
|
if (trust.status === "tampered") {
|
|
724
649
|
if (!options.allowTampered) {
|
|
725
650
|
logger.error(
|
|
@@ -812,6 +737,11 @@ export function registerSessionCommand(program) {
|
|
|
812
737
|
const store = await import("../harness/jsonl-session-store.js");
|
|
813
738
|
const sid =
|
|
814
739
|
id === "last" ? store.getLastSessionId() : store.resolveSessionId(id);
|
|
740
|
+
if (!sid && id !== "last" && store.sessionHasPersistedEvidence(id)) {
|
|
741
|
+
throw new Error(
|
|
742
|
+
`Session ${id} has canonical persistence evidence but no readable transcript`,
|
|
743
|
+
);
|
|
744
|
+
}
|
|
815
745
|
if (sid) {
|
|
816
746
|
const { renderAgentSessionMarkdown } =
|
|
817
747
|
await import("../lib/agent-session-export.js");
|
|
@@ -991,7 +921,8 @@ export function registerSessionCommand(program) {
|
|
|
991
921
|
.action(async (id, options) => {
|
|
992
922
|
let ctx = null;
|
|
993
923
|
try {
|
|
994
|
-
const jsonlId =
|
|
924
|
+
const jsonlId =
|
|
925
|
+
resolveSessionId(id) || (sessionHasPersistedEvidence(id) ? id : null);
|
|
995
926
|
let db = null;
|
|
996
927
|
try {
|
|
997
928
|
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
@@ -1055,6 +986,11 @@ export function registerSessionCommand(program) {
|
|
|
1055
986
|
).trim();
|
|
1056
987
|
if (!normalized) throw new Error("A non-empty title is required");
|
|
1057
988
|
const jsonlId = resolveSessionId(id);
|
|
989
|
+
if (!jsonlId && sessionHasPersistedEvidence(id)) {
|
|
990
|
+
throw new Error(
|
|
991
|
+
`Session ${id} has canonical persistence evidence but no readable transcript`,
|
|
992
|
+
);
|
|
993
|
+
}
|
|
1058
994
|
let result;
|
|
1059
995
|
if (jsonlId) {
|
|
1060
996
|
const { renameSession } =
|
|
@@ -1273,10 +1209,18 @@ export function registerSessionCommand(program) {
|
|
|
1273
1209
|
}
|
|
1274
1210
|
}
|
|
1275
1211
|
|
|
1276
|
-
const
|
|
1277
|
-
(
|
|
1212
|
+
const hasVerificationFailure = (
|
|
1213
|
+
Array.isArray(result) ? result : [result]
|
|
1214
|
+
).some((item) =>
|
|
1215
|
+
[
|
|
1216
|
+
"tampered",
|
|
1217
|
+
"missing",
|
|
1218
|
+
"conflict",
|
|
1219
|
+
"not-found",
|
|
1220
|
+
"invalid-id",
|
|
1221
|
+
].includes(item.status),
|
|
1278
1222
|
);
|
|
1279
|
-
if (
|
|
1223
|
+
if (hasVerificationFailure) process.exit(1);
|
|
1280
1224
|
} catch (err) {
|
|
1281
1225
|
logger.error(`Failed: ${err.message}`);
|
|
1282
1226
|
process.exit(1);
|