chainlesschain 0.162.198 → 0.162.200
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/bin/chainlesschain.js +14 -6
- package/package.json +4 -1
- package/scripts/command-lifecycle-report.mjs +94 -0
- package/src/assets/web-panel/assets/{AIOps-CSN-D2xb.js → AIOps-DcQ0bWKy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CBSMlGzv.js → ActionButton-GecwfFPt.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-3yr3Nt2t.js → Analytics-CD6iSt9v.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-1b-o3lMH.js → AppLayout-CDEtuEYf.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-Dr8rJi17.js → Artifacts-DS3jAjeW.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-2V689HC2.js → Audit-CcSJA048.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DIxkNrD_.js → BackgroundAgents-DRo9Morb.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Pg6BcwrE.js → Backup-Vw5MrWft.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CLUpqyfH.js → BaseInput-DNHIu823.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-qVS8rD4G.js → Chat-DvAsO8-b.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-ti49X12Q.js → ChatBubbleRenderer-9aDuObay.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-Bs9AaEay.js → Checkbox-CKCa7tvn.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Dvc1mq8q.js → Codegen-CIFvZdaT.js} +1 -1
- package/src/assets/web-panel/assets/{Col-C4_biO7A.js → Col-C79yz7bK.js} +1 -1
- package/src/assets/web-panel/assets/{Community-al25XQUV.js → Community-DVvZskLJ.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-D-ZDB8M1.js → Compact-oaew61hV.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-6lIfDz1W.js → Compliance-DqA7wmRx.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DdI48XMJ.js → Cowork-B-qGadxa.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DF5HZd2g.js → Cron-CUlCl4sS.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DuxeSvt3.js → Crosschain-CNOlr9DU.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B9yHkUTd.js → DID-DJqFCT_3.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Z5EuI3IM.js → Dashboard-CznGpphf.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-vuRfO3dY.js → Dropdown-_cJw218E.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-QFLCc1uL.js → EmailListRenderer-Dr-1BZ9C.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BZ7EXkFJ.js → FamilyGuardDashboard-Dxf4xtSk.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DycIEg2s.js → Federation-DOiG3i_1.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Ba0H_7yG.js → FormItemContext-BzbMcFB9.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer--JgSTK-C.js → GenericCardRenderer-VbBrYttP.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DEvTbldE.js → Git-CLG8E6ED.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BJIljy18.js → Governance-LGJQfk_q.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CVyW3G3q.js → Inference-DlQKx9lF.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-v8-borge.js → KnowledgeGraph-DU8vEouV.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BCdS7gGo.js → Logs-FZIQOdln.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BJNWIrbw.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-AN6tGA2B.js → Marketplace-C_xd-zZI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DGViXASN.js → McpTools-q-YktphS.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-Bpvmx9X4.js → Memory-Cq9OhDin.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CTP-DOTC.js → MobileBridge-B03_R98T.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-C8qfktxn.js → MobileProjects-DZrk-qmF.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-ndYr0M1s.js → Mtc-BidCKW28.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Ci0-YK7W.js → MtcAudit-r-iaMVM7.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-BehSTFW7.js → Multisig-CgTUFvff.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-B91_YBLv.js → NLProgramming-B7NvzfAV.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BQlJ0-gq.js → Notes-80CWNqJI.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CDgYMjYK.js → NotificationSettings-0H6xdiY3.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BJkSlKeH.js → OrderTableRenderer-CKP4AFWy.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-B-b3cWCp.js → Organization-B8sxCV_h.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CILUL4nL.js → Overflow-CW9JBBhQ.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BTCFBkF0.js → P2P-bdSQV7oZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BAR6AUx5.js → PdhVaultBrowser-DQad42nW.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-RRf6HbWJ.js → Permissions-CueexxTR.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BGTMiICa.js → PersonalDataHub-fqxflhR8.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-945qY9YF.js → Pipeline-KFwwnIMC.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DPZwI6lJ.js → Privacy-ClnD9buY.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BPH2NRKc.js → ProjectInit-CZEz6sm3.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BZCRNCvb.js → ProjectSettings-B6NzpmOI.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BTI__tBt.js → Projects-DYyuwPCs.js} +1 -1
- package/src/assets/web-panel/assets/Providers-C3tz_jdh.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-N6rbqt1r.js → QrScannerModal-BzuOBbqB.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DrwjPS7M.js → QuickAsk-CmNO9qSj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Cog9Wd99.js → Recommend-VJNj3_NF.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DC9pynjM.js → RemoteSession-CrbdbSBF.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-D4th4gKS.js → Reputation-DTyMd45j.js} +1 -1
- package/src/assets/web-panel/assets/{Row-ogiWR6v9.js → Row-DHrQ-Icz.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-uYlk-2Oj.js → RssFeed-DqWxY9c5.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DYzzwvtM.js → Search-ctF1Ks3J.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Da7YOyX6.js → Security-BrQz8uo5.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CLI1VM1X.js → Services-D4scVFar.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DK77dzDC.js → Skeleton-oUScaOjv.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-C_z7Lmhl.js → Skills-CL-y0eLt.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-D6413Q8L.js → Sla-DQExhwXj.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-C07ydbj2.js → SpeechSettings-iNp_I7kN.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DGOm2W22.js → SyncSettings-CTDlMo0A.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Cr_PVyLM.js → Tasks-4kb8l3sc.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BhL2mZ0t.js → Templates-BXcL9oXW.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CPk5oyUr.js → Tenant-DLE8eS0D.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-ClhqUsqV.js → Terminal-DGpUZPPK.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BCC7MV5a.js → TimelineRenderer-C1pWXGPC.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DD1Jt4oO.js → Tokens-BYfbfqhZ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BCydFvN2.js → Trigger-K9YfLOCw.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DDHT1noa.js → Trust-Ctkq77Hy.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CWPZC7oI.js → UkeySign-C6_CSe9J.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-9Ea0nJR0.js → VideoEditing-Be3rpOWs.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BjxhLxTf.js → Wallet-D0UIplxk.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C6uCye67.js → WebAuthn-CF9bM9I3.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-d2g4reYo.js → WorkflowEditor-D0H1XVPY.js} +1 -1
- package/src/assets/web-panel/assets/{chat-frTc6ScX.js → chat-Cgzzbe0o.js} +1 -1
- package/src/assets/web-panel/assets/{colors-B5K6lG3v.js → colors-BwNxEVS0.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cdn46r8D.js → compact-item-D60Z4Hhs.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DU1jqVQi.js → createContext-MFk58XB0.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BJiw369i.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DdNH-aW_.js → hasIn-CRj2SvGO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DM5FmPZU.js → index--s45_1cb.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4l82Me1.js → index--tquQ2ZG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQorP1Ng.js → index-1T1rhokn.js} +1 -1
- package/src/assets/web-panel/assets/{index-CHmkkdfT.js → index-B-M82_rx.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGiwfwB9.js → index-BE_el1Zs.js} +1 -1
- package/src/assets/web-panel/assets/{index-BwlIxAmX.js → index-BhRkR7IO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cj6P9Nst.js → index-Bo0y96-K.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoFak7le.js → index-CJgu5JUK.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dca_i7H8.js → index-CLWwdebO.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVLL-mq_.js → index-CNAK5QG_.js} +1 -1
- package/src/assets/web-panel/assets/{index-LaivuXyF.js → index-CQjJjPRD.js} +1 -1
- package/src/assets/web-panel/assets/{index-t_OBzIP4.js → index-CTDbAfae.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcGwGIaR.js → index-CVI_9sRK.js} +1 -1
- package/src/assets/web-panel/assets/{index-D23xGYjM.js → index-CY14oMQK.js} +1 -1
- package/src/assets/web-panel/assets/{index-VDM2KKo9.js → index-CbiTJkZf.js} +1 -1
- package/src/assets/web-panel/assets/index-CiMouosn.js +1 -0
- package/src/assets/web-panel/assets/{index-32ajXmTb.js → index-CqWpxMqx.js} +1 -1
- package/src/assets/web-panel/assets/{index-PjAS0sIZ.js → index-CvB8lYUR.js} +1 -1
- package/src/assets/web-panel/assets/{index-7ehytj1K.js → index-D51XwtCY.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtBCCkC4.js → index-D6HvK_1O.js} +1 -1
- package/src/assets/web-panel/assets/{index-Be4OtL-N.js → index-D9jVIwLJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUoNAmE8.js → index-DA4tE98u.js} +1 -1
- package/src/assets/web-panel/assets/{index-cYaWV4Mq.js → index-DBwOtXw0.js} +1 -1
- package/src/assets/web-panel/assets/{index-MM4Zz2OE.js → index-DKdNzTIb.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIVyTmZ3.js → index-DRySdmvN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtRPi4YC.js → index-DWzyTev7.js} +1 -1
- package/src/assets/web-panel/assets/index-DXcKlwy7.js +1 -0
- package/src/assets/web-panel/assets/{index-kVO_MDm-.js → index-DYjs7jAP.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4miNkWv.js → index-DbROzMBp.js} +1 -1
- package/src/assets/web-panel/assets/{index-yZRuZpwK.js → index-DhFtk5PR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXKhhx9V.js → index-Di2AbMLg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BC4eGkar.js → index-DvmocQsM.js} +1 -1
- package/src/assets/web-panel/assets/{index-NmEXVjzt.js → index-Dw-o0zEF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRzBBdQ0.js → index-DysPoP38.js} +1 -1
- package/src/assets/web-panel/assets/{index-HjCvXHf5.js → index-LX9pJxm_.js} +1 -1
- package/src/assets/web-panel/assets/{index-gg3QPC3i.js → index-OI_fXWx0.js} +3 -3
- package/src/assets/web-panel/assets/{index-mgU3Q-lN.js → index-eDTOX8Xj.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1qIC4GR.js → index-gWKDsTzF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DftZuyA7.js → index-q_GDUVAA.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DwLTRNdo.js → initDefaultProps-C61kZqEd.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BchZDXnh.js → motion-DZnT5U1L.js} +1 -1
- package/src/assets/web-panel/assets/{move-e8M-zZFl.js → move-L8wzwbel.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-Ci40fQb3.js → mtc-parser-DLdYSejc.js} +1 -1
- package/src/assets/web-panel/assets/{omit-C7110_f2.js → omit-D53cbS59.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-skteMgnM.js → pickAttrs-Bbc5HPtu.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-MGZ-lh2B.js → placementArrow-BkvmO860.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-N4Sd7uy-.js → responsiveObserve-u2y1ryS1.js} +1 -1
- package/src/assets/web-panel/assets/{slide-C7HDGRaa.js → slide-BBqj7svU.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BhRexlgy.js → statusUtils-GN0mqu2d.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-ChEoQkN2.js → styleChecker-BvwPKoBT.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CDbG1s2Y.js → useFlexGapSupport-CCt8tnfY.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CUIx0tcJ.js → useFs-DXAxl2SV.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-bkO7L7ec.js → usePersonalDataHub-DihlR2dj.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-B_ZvABIG.js → vnode-D7BOX2gi.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D5shjpS8.js → zoom-CVbO-nL7.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/mcp.js +119 -0
- package/src/commands/session-show.js +8 -10
- package/src/commands/session.js +60 -52
- package/src/data/changelog.json +27 -1
- package/src/gateways/ws/session-protocol.js +14 -4
- package/src/gateways/ws/ws-agent-handler.js +31 -0
- package/src/harness/jsonl-session-store.js +1147 -130
- package/src/harness/mcp-client.js +44 -11
- package/src/harness/session-index.js +80 -80
- package/src/harness/session-list-index.js +147 -2
- package/src/lib/background-interaction-journal.js +2 -2
- package/src/lib/command-lifecycle-report.js +516 -0
- package/src/lib/mcp-stdio-environment.js +48 -0
- package/src/lib/mcp-stdio-executable-identity.js +552 -17
- package/src/lib/mcp-stdio-package-materialization.js +1424 -0
- package/src/lib/packer/native-update-state.js +979 -1
- package/src/lib/packer/pack-update-applier.js +1050 -125
- package/src/lib/packer/pkg-config-generator.js +1 -0
- package/src/lib/paths.js +53 -0
- package/src/lib/process-execution-broker/index.js +180 -37
- package/src/lib/process-execution-broker/platform-sandbox.js +291 -24
- package/src/lib/recent-session.js +17 -17
- package/src/lib/secure-file-identity.js +47 -0
- package/src/lib/secure-fs.js +21 -2
- package/src/lib/session-anti-rollback-anchor.js +766 -0
- package/src/lib/session-host-lease.js +492 -0
- package/src/lib/session-persistence-failure.js +109 -0
- package/src/lib/session-picker.js +26 -3
- package/src/lib/session-search.js +25 -11
- package/src/lib/side-effect-ledger-store.js +2 -2
- package/src/lib/skill-execution-authority.js +13 -9
- package/src/lib/turn-binding-store.js +2 -2
- package/src/repl/agent-repl.js +309 -39
- package/src/runtime/agent-core.js +88 -5
- package/src/runtime/cleanup-deadline.js +143 -0
- package/src/runtime/headless-runner.js +357 -139
- package/src/runtime/headless-stream.js +207 -28
- package/src/runtime/output-backpressure.js +53 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-CU-JB2Ns.js +0 -1
- package/src/assets/web-panel/assets/Providers-DDCf_nIw.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CP-jEUyw.js +0 -1
- package/src/assets/web-panel/assets/index-CzrCHrFy.js +0 -1
- package/src/assets/web-panel/assets/index-OJsGskZw.js +0 -1
|
@@ -34,7 +34,10 @@ import {
|
|
|
34
34
|
materializeApprovedMcpStdioInvocation,
|
|
35
35
|
renewMcpStdioExecutionAuthority,
|
|
36
36
|
} from "../lib/mcp-stdio-execution-authority.js";
|
|
37
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
MCP_STDIO_CAPSULE_CODE_SNAPSHOT_BOUNDARY,
|
|
39
|
+
prepareMcpStdioExecutableIdentity,
|
|
40
|
+
} from "../lib/mcp-stdio-executable-identity.js";
|
|
38
41
|
|
|
39
42
|
/**
|
|
40
43
|
* Injectable dependencies — overridable from tests.
|
|
@@ -1856,6 +1859,10 @@ export class MCPClient extends EventEmitter {
|
|
|
1856
1859
|
let pluginWorkspaceRoot = null;
|
|
1857
1860
|
let stdioExecutableIdentity = null;
|
|
1858
1861
|
let stdioExecutableIdentityAuthority = null;
|
|
1862
|
+
let stdioExecutableEnvironment = null;
|
|
1863
|
+
let stdioExecutableWorkingDirectory = null;
|
|
1864
|
+
let stdioExecutableIdentityDigest = null;
|
|
1865
|
+
let stdioCapsuleSandboxExecutionContract = null;
|
|
1859
1866
|
let runtimeConfig = sourceConfig;
|
|
1860
1867
|
if (transportKind === "stdio") {
|
|
1861
1868
|
const isPlugin = sourceConfig.origin === "plugin:mcp";
|
|
@@ -1884,7 +1891,7 @@ export class MCPClient extends EventEmitter {
|
|
|
1884
1891
|
config: sourceConfig,
|
|
1885
1892
|
approval: stdioExecutionApproval,
|
|
1886
1893
|
cwd: pluginWorkspaceRoot || process.cwd(),
|
|
1887
|
-
env: process.env,
|
|
1894
|
+
env: { ...process.env, ...this._agentIdentityEnv() },
|
|
1888
1895
|
});
|
|
1889
1896
|
runtimeConfig = {
|
|
1890
1897
|
...sourceConfig,
|
|
@@ -1893,6 +1900,11 @@ export class MCPClient extends EventEmitter {
|
|
|
1893
1900
|
};
|
|
1894
1901
|
stdioExecutableIdentity = prepared.identity;
|
|
1895
1902
|
stdioExecutableIdentityAuthority = prepared.authority;
|
|
1903
|
+
stdioExecutableEnvironment = prepared.env;
|
|
1904
|
+
stdioExecutableWorkingDirectory = prepared.workingDirectory;
|
|
1905
|
+
stdioExecutableIdentityDigest = prepared.identityDigest;
|
|
1906
|
+
stdioCapsuleSandboxExecutionContract =
|
|
1907
|
+
prepared.sandboxExecutionContract || null;
|
|
1896
1908
|
}
|
|
1897
1909
|
const connectionHeaders = await this._connectionHeaders(
|
|
1898
1910
|
name,
|
|
@@ -2292,11 +2304,14 @@ export class MCPClient extends EventEmitter {
|
|
|
2292
2304
|
}
|
|
2293
2305
|
const isPlugin = config.origin === "plugin:mcp";
|
|
2294
2306
|
const spawnOptions = {
|
|
2295
|
-
cwd:
|
|
2307
|
+
cwd:
|
|
2308
|
+
stdioExecutableWorkingDirectory ||
|
|
2309
|
+
pluginWorkspaceRoot ||
|
|
2310
|
+
process.cwd(),
|
|
2296
2311
|
stdio: ["pipe", "pipe", "pipe"],
|
|
2297
2312
|
// process.env < agent identity (CLAUDECODE / session id) < the
|
|
2298
2313
|
// server's own config.env, so an explicit per-server override wins.
|
|
2299
|
-
env: {
|
|
2314
|
+
env: stdioExecutableEnvironment || {
|
|
2300
2315
|
...process.env,
|
|
2301
2316
|
...this._agentIdentityEnv(),
|
|
2302
2317
|
...(config.env || {}),
|
|
@@ -2310,8 +2325,16 @@ export class MCPClient extends EventEmitter {
|
|
|
2310
2325
|
// Broker's Job Object boundary so an unexpectedly exiting MCP root
|
|
2311
2326
|
// cannot orphan grandchildren before taskkill can enumerate them.
|
|
2312
2327
|
detached: process.platform !== "win32",
|
|
2313
|
-
...(process.platform === "win32"
|
|
2314
|
-
|
|
2328
|
+
...(process.platform === "win32" ||
|
|
2329
|
+
stdioCapsuleSandboxExecutionContract
|
|
2330
|
+
? {
|
|
2331
|
+
requiredBoundaries: [
|
|
2332
|
+
...(process.platform === "win32" ? ["process-tree"] : []),
|
|
2333
|
+
...(stdioCapsuleSandboxExecutionContract
|
|
2334
|
+
? [MCP_STDIO_CAPSULE_CODE_SNAPSHOT_BOUNDARY]
|
|
2335
|
+
: []),
|
|
2336
|
+
],
|
|
2337
|
+
}
|
|
2315
2338
|
: {}),
|
|
2316
2339
|
pluginId: config.pluginId,
|
|
2317
2340
|
pluginVersion: config.pluginVersion,
|
|
@@ -2320,19 +2343,29 @@ export class MCPClient extends EventEmitter {
|
|
|
2320
2343
|
? { sandboxPolicy: config.sandboxPolicy }
|
|
2321
2344
|
: {}),
|
|
2322
2345
|
mcpStdioExecutableIdentityAuthority: stdioExecutableIdentityAuthority,
|
|
2346
|
+
mcpStdioExecutableIdentityDigest: stdioExecutableIdentityDigest,
|
|
2323
2347
|
};
|
|
2324
2348
|
const sandboxExecutionContract =
|
|
2325
|
-
|
|
2349
|
+
stdioCapsuleSandboxExecutionContract ||
|
|
2350
|
+
(!isPlugin || pluginWorkspaceRoot
|
|
2326
2351
|
? executionBroker.issueLinuxWorkspaceSandboxExecutionContract(
|
|
2327
2352
|
config.command,
|
|
2328
2353
|
config.args || [],
|
|
2329
2354
|
{ ...spawnOptions, detached: false },
|
|
2330
|
-
|
|
2355
|
+
stdioExecutableWorkingDirectory ||
|
|
2356
|
+
pluginWorkspaceRoot ||
|
|
2357
|
+
process.cwd(),
|
|
2331
2358
|
)
|
|
2332
|
-
: null;
|
|
2359
|
+
: null);
|
|
2360
|
+
const capsuleUsesPosixProcessGroup =
|
|
2361
|
+
Boolean(stdioCapsuleSandboxExecutionContract) &&
|
|
2362
|
+
process.platform !== "win32";
|
|
2333
2363
|
const launchOptions = {
|
|
2334
2364
|
...spawnOptions,
|
|
2335
|
-
detached:
|
|
2365
|
+
detached:
|
|
2366
|
+
sandboxExecutionContract && !capsuleUsesPosixProcessGroup
|
|
2367
|
+
? false
|
|
2368
|
+
: spawnOptions.detached,
|
|
2336
2369
|
...(sandboxExecutionContract ? { sandboxExecutionContract } : {}),
|
|
2337
2370
|
};
|
|
2338
2371
|
const proc = _deps.spawn(config.command, config.args || [], {
|
|
@@ -2341,7 +2374,7 @@ export class MCPClient extends EventEmitter {
|
|
|
2341
2374
|
|
|
2342
2375
|
entry.process = proc;
|
|
2343
2376
|
entry._stdioTreeMode =
|
|
2344
|
-
sandboxExecutionContract ||
|
|
2377
|
+
(sandboxExecutionContract && !capsuleUsesPosixProcessGroup) ||
|
|
2345
2378
|
(process.platform === "win32" && proc?.sandboxReady?.then)
|
|
2346
2379
|
? "sandbox"
|
|
2347
2380
|
: process.platform === "win32"
|
|
@@ -21,8 +21,8 @@ import { existsSync, readdirSync, statSync } from "node:fs";
|
|
|
21
21
|
import { join, basename } from "node:path";
|
|
22
22
|
import { createRequire } from "node:module";
|
|
23
23
|
import { getHomeDir } from "../lib/paths.js";
|
|
24
|
-
import { iterateFileLinesSync } from "../lib/file-lines.js";
|
|
25
24
|
import { ensurePrivateDirectory, ensurePrivateFile } from "../lib/secure-fs.js";
|
|
25
|
+
import { readVerifiedProjection } from "./jsonl-session-store.js";
|
|
26
26
|
|
|
27
27
|
const requireCjs = createRequire(import.meta.url);
|
|
28
28
|
|
|
@@ -98,84 +98,74 @@ function toIsoSafe(value) {
|
|
|
98
98
|
return Number.isNaN(date.getTime()) ? "" : date.toISOString();
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
? ""
|
|
132
|
-
: JSON.stringify(content);
|
|
133
|
-
if (text) {
|
|
134
|
-
const bounded = text.slice(0, CONTENT_CAP - used);
|
|
135
|
-
parts.push(bounded);
|
|
136
|
-
used += bounded.length;
|
|
101
|
+
function summarizeVerifiedSession(id) {
|
|
102
|
+
return readVerifiedProjection(id, () => {
|
|
103
|
+
let startEvent = null;
|
|
104
|
+
let lastEvent = null;
|
|
105
|
+
let renamedTitle = null;
|
|
106
|
+
let messageCount = 0;
|
|
107
|
+
let eventCount = 0;
|
|
108
|
+
let chainHash = "";
|
|
109
|
+
const parts = [];
|
|
110
|
+
let used = 0;
|
|
111
|
+
const acceptContent = (content) => {
|
|
112
|
+
if (used >= CONTENT_CAP) return;
|
|
113
|
+
const text =
|
|
114
|
+
typeof content === "string"
|
|
115
|
+
? content
|
|
116
|
+
: content == null
|
|
117
|
+
? ""
|
|
118
|
+
: JSON.stringify(content);
|
|
119
|
+
if (!text) return;
|
|
120
|
+
const bounded = text.slice(0, CONTENT_CAP - used);
|
|
121
|
+
parts.push(bounded);
|
|
122
|
+
used += bounded.length;
|
|
123
|
+
};
|
|
124
|
+
return {
|
|
125
|
+
accept(event) {
|
|
126
|
+
eventCount += 1;
|
|
127
|
+
lastEvent = event;
|
|
128
|
+
if (!startEvent && event.type === "session_start") startEvent = event;
|
|
129
|
+
if (event.type === "session_rename" && event.data?.title) {
|
|
130
|
+
renamedTitle = String(event.data.title);
|
|
137
131
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
? ""
|
|
155
|
-
: JSON.stringify(content);
|
|
156
|
-
if (text) {
|
|
157
|
-
const bounded = text.slice(0, CONTENT_CAP - used);
|
|
158
|
-
parts.push(bounded);
|
|
159
|
-
used += bounded.length;
|
|
132
|
+
if (
|
|
133
|
+
event.type === "user_message" ||
|
|
134
|
+
event.type === "assistant_message"
|
|
135
|
+
) {
|
|
136
|
+
messageCount += 1;
|
|
137
|
+
acceptContent(event.data?.content);
|
|
138
|
+
} else if (
|
|
139
|
+
event.type === "ws_turn" &&
|
|
140
|
+
event.data?.schemaVersion === 1 &&
|
|
141
|
+
event.data?.outcome === "completed" &&
|
|
142
|
+
event.data?.user?.role === "user" &&
|
|
143
|
+
event.data?.assistant?.role === "assistant"
|
|
144
|
+
) {
|
|
145
|
+
messageCount += 2;
|
|
146
|
+
acceptContent(event.data.user.content);
|
|
147
|
+
acceptContent(event.data.assistant.content);
|
|
160
148
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
149
|
+
if (typeof event.hash === "string") chainHash = event.hash;
|
|
150
|
+
},
|
|
151
|
+
finish() {
|
|
152
|
+
if (!lastEvent) return null;
|
|
153
|
+
return {
|
|
154
|
+
id,
|
|
155
|
+
title: renamedTitle || startEvent?.data?.title || "Untitled",
|
|
156
|
+
provider: startEvent?.data?.provider || "",
|
|
157
|
+
model: startEvent?.data?.model || "",
|
|
158
|
+
message_count: messageCount,
|
|
159
|
+
event_count: eventCount,
|
|
160
|
+
created_at: toIsoSafe(startEvent?.timestamp),
|
|
161
|
+
updated_at: toIsoSafe(lastEvent?.timestamp),
|
|
162
|
+
last_ts: lastEvent?.timestamp || 0,
|
|
163
|
+
content: parts.join("\n").slice(0, CONTENT_CAP),
|
|
164
|
+
chain_hash: chainHash,
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
});
|
|
179
169
|
}
|
|
180
170
|
|
|
181
171
|
const UPSERT_SESSION = `
|
|
@@ -195,7 +185,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
195
185
|
export function indexOneSession(db, id, { mtimeMs = 0, sizeBytes = 0 } = {}) {
|
|
196
186
|
const filePath = join(sessionsDir(), `${id}.jsonl`);
|
|
197
187
|
if (!existsSync(filePath)) return false;
|
|
198
|
-
const s =
|
|
188
|
+
const s = summarizeVerifiedSession(id);
|
|
199
189
|
if (!s) return false;
|
|
200
190
|
db.prepare(UPSERT_SESSION).run({
|
|
201
191
|
id: s.id,
|
|
@@ -228,6 +218,7 @@ export function syncIndex(db, { force = false } = {}) {
|
|
|
228
218
|
let scanned = 0;
|
|
229
219
|
let updated = 0;
|
|
230
220
|
let removed = 0;
|
|
221
|
+
let rejected = 0;
|
|
231
222
|
const seen = new Set();
|
|
232
223
|
|
|
233
224
|
if (existsSync(dir)) {
|
|
@@ -251,7 +242,16 @@ export function syncIndex(db, { force = false } = {}) {
|
|
|
251
242
|
) {
|
|
252
243
|
continue; // unchanged
|
|
253
244
|
}
|
|
254
|
-
|
|
245
|
+
try {
|
|
246
|
+
if (indexOneSession(db, id, { mtimeMs, sizeBytes: size })) updated++;
|
|
247
|
+
} catch {
|
|
248
|
+
// The index is disposable. A damaged canonical source invalidates any
|
|
249
|
+
// older cached content immediately and is reported without exposing
|
|
250
|
+
// transcript text or local paths.
|
|
251
|
+
db.prepare("DELETE FROM sessions WHERE id=?").run(id);
|
|
252
|
+
db.prepare("DELETE FROM session_content WHERE id=?").run(id);
|
|
253
|
+
rejected++;
|
|
254
|
+
}
|
|
255
255
|
}
|
|
256
256
|
});
|
|
257
257
|
const entries = [];
|
|
@@ -278,7 +278,7 @@ export function syncIndex(db, { force = false } = {}) {
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
const total = db.prepare("SELECT COUNT(*) c FROM sessions").get().c;
|
|
281
|
-
return { scanned, updated, removed, total };
|
|
281
|
+
return { scanned, updated, removed, rejected, total };
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
const LIST_COLUMNS =
|
|
@@ -21,6 +21,11 @@ import { ensurePrivateFile } from "../lib/secure-fs.js";
|
|
|
21
21
|
export const SESSION_INDEX_SCHEMA = 2;
|
|
22
22
|
export const SESSION_INDEX_FILE = ".sessions-index-v2.ndjson";
|
|
23
23
|
export const SESSION_TOMBSTONE_MARKER_SUFFIX = ".tombstone";
|
|
24
|
+
export const SESSION_TOMBSTONE_MARKER_SCHEMA =
|
|
25
|
+
"chainlesschain.session-tombstone/v1";
|
|
26
|
+
export const SESSION_GENERATION_AUTHORITY_FIELD = "_sessionGeneration";
|
|
27
|
+
export const SESSION_GENERATION_AUTHORITY_SCHEMA =
|
|
28
|
+
"chainlesschain.session-generation-authority/v1";
|
|
24
29
|
|
|
25
30
|
// Used only by an opted-in child in the independent session-scale crash gate.
|
|
26
31
|
// Keeping the injection immediately around the production sidecar/journal
|
|
@@ -59,10 +64,67 @@ export function emptySessionMeta(sessionId) {
|
|
|
59
64
|
created_at_ms: 0,
|
|
60
65
|
updated_at_ms: 0,
|
|
61
66
|
last_hash: null,
|
|
67
|
+
transcript: null,
|
|
68
|
+
generation: null,
|
|
69
|
+
deleted_at_ms: null,
|
|
62
70
|
deleted: false,
|
|
63
71
|
};
|
|
64
72
|
}
|
|
65
73
|
|
|
74
|
+
export function normalizeSessionGenerationAuthority(value) {
|
|
75
|
+
if (
|
|
76
|
+
!value ||
|
|
77
|
+
typeof value !== "object" ||
|
|
78
|
+
Array.isArray(value) ||
|
|
79
|
+
value.schema !== SESSION_GENERATION_AUTHORITY_SCHEMA ||
|
|
80
|
+
typeof value.sessionId !== "string" ||
|
|
81
|
+
value.sessionId.length === 0 ||
|
|
82
|
+
typeof value.generationId !== "string" ||
|
|
83
|
+
!/^generation-[0-9a-f-]{32,36}$/.test(value.generationId) ||
|
|
84
|
+
!Number.isSafeInteger(value.ordinal) ||
|
|
85
|
+
value.ordinal < 1
|
|
86
|
+
) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
let predecessor = null;
|
|
90
|
+
if (value.predecessor !== null) {
|
|
91
|
+
const previous = value.predecessor;
|
|
92
|
+
if (
|
|
93
|
+
!previous ||
|
|
94
|
+
typeof previous !== "object" ||
|
|
95
|
+
Array.isArray(previous) ||
|
|
96
|
+
!["tombstone", "legacy-tombstone"].includes(previous.kind) ||
|
|
97
|
+
(previous.generationId !== null &&
|
|
98
|
+
(typeof previous.generationId !== "string" ||
|
|
99
|
+
!/^generation-[0-9a-f-]{32,36}$/.test(previous.generationId))) ||
|
|
100
|
+
(previous.headHash !== null &&
|
|
101
|
+
(typeof previous.headHash !== "string" ||
|
|
102
|
+
!/^[0-9a-f]{64}$/.test(previous.headHash))) ||
|
|
103
|
+
!Number.isSafeInteger(previous.eventCount) ||
|
|
104
|
+
previous.eventCount < 0 ||
|
|
105
|
+
(previous.tombstonedAtMs !== null &&
|
|
106
|
+
(!Number.isSafeInteger(previous.tombstonedAtMs) ||
|
|
107
|
+
previous.tombstonedAtMs < 0))
|
|
108
|
+
) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
predecessor = {
|
|
112
|
+
kind: previous.kind,
|
|
113
|
+
generationId: previous.generationId,
|
|
114
|
+
headHash: previous.headHash,
|
|
115
|
+
eventCount: previous.eventCount,
|
|
116
|
+
tombstonedAtMs: previous.tombstonedAtMs,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
schema: SESSION_GENERATION_AUTHORITY_SCHEMA,
|
|
121
|
+
sessionId: value.sessionId,
|
|
122
|
+
generationId: value.generationId,
|
|
123
|
+
ordinal: value.ordinal,
|
|
124
|
+
predecessor,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
66
128
|
export function readSessionMeta(dir, sessionId) {
|
|
67
129
|
const filePath = sessionMetaPath(dir, sessionId);
|
|
68
130
|
if (!existsSync(filePath)) return null;
|
|
@@ -108,6 +170,11 @@ export function applyEventToSessionMeta(meta, event, lastHash) {
|
|
|
108
170
|
) {
|
|
109
171
|
next.message_count = Math.max(0, Number(next.message_count) || 0) + 2;
|
|
110
172
|
}
|
|
173
|
+
const generation = normalizeSessionGenerationAuthority(
|
|
174
|
+
event?.data?.[SESSION_GENERATION_AUTHORITY_FIELD],
|
|
175
|
+
);
|
|
176
|
+
if (generation?.sessionId === next.id) next.generation = generation;
|
|
177
|
+
next.deleted_at_ms = null;
|
|
111
178
|
next.last_hash = typeof lastHash === "string" ? lastHash : null;
|
|
112
179
|
return next;
|
|
113
180
|
}
|
|
@@ -123,7 +190,26 @@ function writeMetaSnapshot(dir, meta) {
|
|
|
123
190
|
// commits, so crashes can cause an extra candidate read but never hide a
|
|
124
191
|
// successfully committed tombstone.
|
|
125
192
|
if (meta.deleted === true) {
|
|
126
|
-
|
|
193
|
+
const generation = normalizeSessionGenerationAuthority(meta.generation);
|
|
194
|
+
const marker = {
|
|
195
|
+
schema: SESSION_TOMBSTONE_MARKER_SCHEMA,
|
|
196
|
+
id: meta.id,
|
|
197
|
+
generation: generation?.sessionId === meta.id ? generation : null,
|
|
198
|
+
last_hash:
|
|
199
|
+
typeof meta.last_hash === "string" &&
|
|
200
|
+
/^[0-9a-f]{64}$/.test(meta.last_hash)
|
|
201
|
+
? meta.last_hash
|
|
202
|
+
: null,
|
|
203
|
+
event_count: Math.max(0, Number(meta.event_count) || 0),
|
|
204
|
+
deleted_at_ms: Math.max(
|
|
205
|
+
0,
|
|
206
|
+
Number(meta.deleted_at_ms || meta.updated_at_ms) || 0,
|
|
207
|
+
),
|
|
208
|
+
};
|
|
209
|
+
writeFileSync(tombstoneMarker, `${JSON.stringify(marker)}\n`, {
|
|
210
|
+
encoding: "utf8",
|
|
211
|
+
mode: 0o600,
|
|
212
|
+
});
|
|
127
213
|
ensurePrivateFile(tombstoneMarker);
|
|
128
214
|
}
|
|
129
215
|
// The owning transcript lock serializes this derived snapshot. It need not
|
|
@@ -137,6 +223,39 @@ function writeMetaSnapshot(dir, meta) {
|
|
|
137
223
|
if (meta.deleted !== true) rmSync(tombstoneMarker, { force: true });
|
|
138
224
|
}
|
|
139
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Read the durable namespace marker. Legacy empty/invalid markers still count
|
|
228
|
+
* as deletion evidence, but deliberately expose no predecessor authority.
|
|
229
|
+
*/
|
|
230
|
+
export function readSessionTombstoneMarker(dir, sessionId) {
|
|
231
|
+
const filePath = sessionTombstoneMarkerPath(dir, sessionId);
|
|
232
|
+
if (!existsSync(filePath)) return null;
|
|
233
|
+
try {
|
|
234
|
+
const value = JSON.parse(readFileSync(filePath, "utf8"));
|
|
235
|
+
if (
|
|
236
|
+
value?.schema !== SESSION_TOMBSTONE_MARKER_SCHEMA ||
|
|
237
|
+
value?.id !== sessionId
|
|
238
|
+
) {
|
|
239
|
+
return { id: sessionId, legacy: true };
|
|
240
|
+
}
|
|
241
|
+
const generation = normalizeSessionGenerationAuthority(value.generation);
|
|
242
|
+
return {
|
|
243
|
+
schema: SESSION_TOMBSTONE_MARKER_SCHEMA,
|
|
244
|
+
id: sessionId,
|
|
245
|
+
generation: generation?.sessionId === sessionId ? generation : null,
|
|
246
|
+
last_hash:
|
|
247
|
+
typeof value.last_hash === "string" &&
|
|
248
|
+
/^[0-9a-f]{64}$/.test(value.last_hash)
|
|
249
|
+
? value.last_hash
|
|
250
|
+
: null,
|
|
251
|
+
event_count: Math.max(0, Number(value.event_count) || 0),
|
|
252
|
+
deleted_at_ms: Math.max(0, Number(value.deleted_at_ms) || 0),
|
|
253
|
+
};
|
|
254
|
+
} catch {
|
|
255
|
+
return { id: sessionId, legacy: true };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
140
259
|
function appendActivity(dir, meta) {
|
|
141
260
|
const filePath = sessionIndexPath(dir);
|
|
142
261
|
// One compact line is emitted through one O_APPEND write. The journal is a
|
|
@@ -159,7 +278,7 @@ export function recordSessionEvent(
|
|
|
159
278
|
sessionId,
|
|
160
279
|
event,
|
|
161
280
|
lastHash,
|
|
162
|
-
{ resetGeneration = false } = {},
|
|
281
|
+
{ resetGeneration = false, transcriptState = null } = {},
|
|
163
282
|
) {
|
|
164
283
|
const existing = readSessionMeta(dir, sessionId);
|
|
165
284
|
// Only the transcript writer may authorize a new generation after checking
|
|
@@ -170,6 +289,30 @@ export function recordSessionEvent(
|
|
|
170
289
|
: existing || emptySessionMeta(sessionId);
|
|
171
290
|
current.id = sessionId;
|
|
172
291
|
const next = applyEventToSessionMeta(current, event, lastHash);
|
|
292
|
+
next.transcript = transcriptState
|
|
293
|
+
? {
|
|
294
|
+
dev: String(transcriptState.dev),
|
|
295
|
+
ino: String(transcriptState.ino),
|
|
296
|
+
size: Number(transcriptState.size),
|
|
297
|
+
mtimeMs: Number(transcriptState.mtimeMs),
|
|
298
|
+
ctimeMs: Number(transcriptState.ctimeMs),
|
|
299
|
+
...(transcriptState.devExact != null
|
|
300
|
+
? { devExact: String(transcriptState.devExact) }
|
|
301
|
+
: {}),
|
|
302
|
+
...(transcriptState.inoExact != null
|
|
303
|
+
? { inoExact: String(transcriptState.inoExact) }
|
|
304
|
+
: {}),
|
|
305
|
+
...(transcriptState.sizeExact != null
|
|
306
|
+
? { sizeExact: String(transcriptState.sizeExact) }
|
|
307
|
+
: {}),
|
|
308
|
+
...(transcriptState.mtimeNs != null
|
|
309
|
+
? { mtimeNs: String(transcriptState.mtimeNs) }
|
|
310
|
+
: {}),
|
|
311
|
+
...(transcriptState.ctimeNs != null
|
|
312
|
+
? { ctimeNs: String(transcriptState.ctimeNs) }
|
|
313
|
+
: {}),
|
|
314
|
+
}
|
|
315
|
+
: null;
|
|
173
316
|
writeMetaSnapshot(dir, next);
|
|
174
317
|
runSessionScaleFaultHook("afterMetaSnapshot", {
|
|
175
318
|
dir,
|
|
@@ -201,7 +344,9 @@ export function recordSessionDeleted(dir, sessionId, timestamp = Date.now()) {
|
|
|
201
344
|
const tombstone = {
|
|
202
345
|
...current,
|
|
203
346
|
updated_at_ms: timestamp,
|
|
347
|
+
deleted_at_ms: timestamp,
|
|
204
348
|
deleted: true,
|
|
349
|
+
transcript: null,
|
|
205
350
|
};
|
|
206
351
|
writeMetaSnapshot(dir, tombstone);
|
|
207
352
|
appendActivity(dir, tombstone);
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
appendAuthorityEvent as storeAppendAuthorityEvent,
|
|
13
13
|
readEvents as storeReadEvents,
|
|
14
14
|
findLatestEvent as storeFindLatestEvent,
|
|
15
15
|
} from "../harness/jsonl-session-store.js";
|
|
@@ -26,7 +26,7 @@ export const MAX_BACKGROUND_INTERACTION_RECORDS = 256;
|
|
|
26
26
|
const TERMINAL_STATUSES = new Set(["resolved", "rejected", "cancelled"]);
|
|
27
27
|
|
|
28
28
|
export const _deps = {
|
|
29
|
-
appendEvent:
|
|
29
|
+
appendEvent: storeAppendAuthorityEvent,
|
|
30
30
|
readEvents: storeReadEvents,
|
|
31
31
|
findLatestEvent: storeFindLatestEvent,
|
|
32
32
|
};
|