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
package/src/commands/mcp.js
CHANGED
|
@@ -44,8 +44,14 @@ import {
|
|
|
44
44
|
MCP_STDIO_LOCAL_CODE_TRUST_REQUIRED_CODE,
|
|
45
45
|
issueMcpStdioExecutionAuthority,
|
|
46
46
|
materializeApprovedMcpStdioInvocation,
|
|
47
|
+
resolveMcpStdioExecutionApproval,
|
|
47
48
|
} from "../lib/mcp-stdio-execution-authority.js";
|
|
48
49
|
import { prepareMcpStdioExecutableIdentity } from "../lib/mcp-stdio-executable-identity.js";
|
|
50
|
+
import {
|
|
51
|
+
materializeMcpStdioNpmPackage,
|
|
52
|
+
parseExactNpmPackageSpec,
|
|
53
|
+
} from "../lib/mcp-stdio-package-materialization.js";
|
|
54
|
+
import { executionBroker } from "../lib/process-execution-broker/index.js";
|
|
49
55
|
import {
|
|
50
56
|
CATALOG as REGISTRY_CATALOG,
|
|
51
57
|
CATEGORIES as REGISTRY_CATEGORIES,
|
|
@@ -807,6 +813,119 @@ export function registerMcpCommand(program) {
|
|
|
807
813
|
}
|
|
808
814
|
});
|
|
809
815
|
|
|
816
|
+
mcp
|
|
817
|
+
.command("materialize-package <name>")
|
|
818
|
+
.description(
|
|
819
|
+
"Replace one exact JavaScript package launcher with a content-addressed, guarded dependency capsule",
|
|
820
|
+
)
|
|
821
|
+
.requiredOption(
|
|
822
|
+
"--package <name@version>",
|
|
823
|
+
"Exact npm registry package version to install (ranges and tags are rejected)",
|
|
824
|
+
)
|
|
825
|
+
.option(
|
|
826
|
+
"--bin <name>",
|
|
827
|
+
"Select one exported bin when the package has several",
|
|
828
|
+
)
|
|
829
|
+
.option(
|
|
830
|
+
"--scope <scope>",
|
|
831
|
+
`Configuration scope: ${MCP_CONFIG_SCOPES.join(" | ")}`,
|
|
832
|
+
)
|
|
833
|
+
.option(
|
|
834
|
+
"--json",
|
|
835
|
+
"Output the materialized generation and closure identity as JSON",
|
|
836
|
+
)
|
|
837
|
+
.action(async (name, options) => {
|
|
838
|
+
try {
|
|
839
|
+
const exact = parseExactNpmPackageSpec(options.package);
|
|
840
|
+
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
841
|
+
if (!ctx.db) throw new Error("Database not available");
|
|
842
|
+
const configStore = new MCPServerConfig(ctx.db.getDatabase());
|
|
843
|
+
const scope = options.scope
|
|
844
|
+
? normalizeMcpConfigScope(options.scope)
|
|
845
|
+
: undefined;
|
|
846
|
+
const rows = await effectiveMcpRows(configStore, { scope });
|
|
847
|
+
const row = rows.find((entry) => entry.name === name);
|
|
848
|
+
if (!row) {
|
|
849
|
+
throw new Error(
|
|
850
|
+
`${notFoundWithSuggestion(
|
|
851
|
+
name,
|
|
852
|
+
rows.map((entry) => entry.name),
|
|
853
|
+
{ noun: "Server" },
|
|
854
|
+
)}. Use 'mcp add' first.`,
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
if (inferTransport(row) !== "stdio") {
|
|
858
|
+
throw new Error(
|
|
859
|
+
`MCP server "${name}" does not use the stdio transport`,
|
|
860
|
+
);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
const authorized = authorizeMcpRowForConnect(row);
|
|
864
|
+
const approval = consumeMcpStdioExecutionAuthority(
|
|
865
|
+
authorized.mcpStdioExecutionAuthority,
|
|
866
|
+
{ serverName: name, config: authorized },
|
|
867
|
+
);
|
|
868
|
+
const invocation = materializeApprovedMcpStdioInvocation(approval);
|
|
869
|
+
const approvalRecord = resolveMcpStdioExecutionApproval(approval);
|
|
870
|
+
const materialized = materializeMcpStdioNpmPackage({
|
|
871
|
+
approvalRecord,
|
|
872
|
+
config: invocation,
|
|
873
|
+
packageSpec: exact.spec,
|
|
874
|
+
...(options.bin ? { binName: options.bin } : {}),
|
|
875
|
+
env: process.env,
|
|
876
|
+
processBrokerRunSync: (command, args, spawnOptions) =>
|
|
877
|
+
executionBroker.spawnSync(command, args, {
|
|
878
|
+
...spawnOptions,
|
|
879
|
+
origin: `mcp:package-materialization:${name}`,
|
|
880
|
+
policy: "allow",
|
|
881
|
+
scope: "mcp",
|
|
882
|
+
shell: false,
|
|
883
|
+
}),
|
|
884
|
+
});
|
|
885
|
+
const prepared = prepareMcpStdioExecutableIdentity({
|
|
886
|
+
serverName: name,
|
|
887
|
+
config: invocation,
|
|
888
|
+
approval,
|
|
889
|
+
cwd: process.cwd(),
|
|
890
|
+
env: process.env,
|
|
891
|
+
retrust: true,
|
|
892
|
+
});
|
|
893
|
+
const result = {
|
|
894
|
+
name,
|
|
895
|
+
package: exact.spec,
|
|
896
|
+
generation: materialized.generation,
|
|
897
|
+
manifestDigest: materialized.manifestDigest,
|
|
898
|
+
identityDigest: prepared.identityDigest,
|
|
899
|
+
closure: materialized.identity,
|
|
900
|
+
command: prepared.identity.command,
|
|
901
|
+
entrypoints: prepared.identity.entrypoints,
|
|
902
|
+
};
|
|
903
|
+
if (options.json) {
|
|
904
|
+
console.log(JSON.stringify(result, null, 2));
|
|
905
|
+
} else {
|
|
906
|
+
logger.log(
|
|
907
|
+
chalk.green(
|
|
908
|
+
`Materialized and trusted ${exact.spec} for MCP server "${name}".`,
|
|
909
|
+
),
|
|
910
|
+
);
|
|
911
|
+
logger.log(
|
|
912
|
+
` ${chalk.gray("Generation:")} ${materialized.generation}`,
|
|
913
|
+
);
|
|
914
|
+
logger.log(
|
|
915
|
+
` ${chalk.gray("Dependency closure:")} sha256:${materialized.identity.closureDigest} (${materialized.identity.fileCount} files, ${materialized.identity.totalBytes} bytes)`,
|
|
916
|
+
);
|
|
917
|
+
logger.log(
|
|
918
|
+
` ${chalk.gray("Execution capsule:")} sha256:${materialized.identity.capsule.sha256} (${materialized.identity.capsule.bytes} bytes, ${materialized.identity.capsule.inputCount} bundled inputs)`,
|
|
919
|
+
);
|
|
920
|
+
}
|
|
921
|
+
await shutdown();
|
|
922
|
+
} catch (err) {
|
|
923
|
+
logger.error(`Failed: ${err.message}`);
|
|
924
|
+
process.exitCode = 1;
|
|
925
|
+
await shutdown();
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
|
|
810
929
|
mcp
|
|
811
930
|
.command("trust-executable <name>")
|
|
812
931
|
.description(
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { numericOption } from "../lib/cli-numeric.js";
|
|
3
|
-
import { feature } from "../lib/feature-flags.js";
|
|
4
3
|
import { logger } from "../lib/logger.js";
|
|
5
4
|
import { getPrLinks } from "../lib/pr-link-store.js";
|
|
6
5
|
import {
|
|
7
6
|
getJsonlSessionMetadata,
|
|
8
7
|
rebuildMessages,
|
|
9
|
-
|
|
10
|
-
sessionHasPersistedEvidence,
|
|
8
|
+
resolveSessionAuthority,
|
|
11
9
|
} from "../harness/jsonl-session-store.js";
|
|
12
10
|
|
|
13
11
|
export function registerSessionShowSubcommand(session, program) {
|
|
@@ -23,14 +21,14 @@ export function registerSessionShowSubcommand(session, program) {
|
|
|
23
21
|
try {
|
|
24
22
|
let sess = null;
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
) {
|
|
24
|
+
// The feature flag controls creation/migration, not authority. Once a
|
|
25
|
+
// canonical namespace witness exists it must fence the legacy DB even
|
|
26
|
+
// if JSONL_SESSION is later disabled.
|
|
27
|
+
const authority = resolveSessionAuthority(id);
|
|
28
|
+
const jsonlId = authority?.readable ? authority.id : null;
|
|
29
|
+
if (authority && !authority.readable) {
|
|
32
30
|
logger.error(
|
|
33
|
-
`Session ${id} has canonical persistence evidence but no readable transcript.`,
|
|
31
|
+
`Session ${authority.id} has canonical persistence evidence but no readable transcript (${authority.presence}).`,
|
|
34
32
|
);
|
|
35
33
|
process.exitCode = 1;
|
|
36
34
|
return;
|
package/src/commands/session.js
CHANGED
|
@@ -47,18 +47,17 @@ import {
|
|
|
47
47
|
getSessionManagerStatsV2,
|
|
48
48
|
} from "../lib/session-manager.js";
|
|
49
49
|
import {
|
|
50
|
-
|
|
50
|
+
listSessionAuthoritySummaries,
|
|
51
|
+
listSessionEvidenceIds,
|
|
51
52
|
rebuildMessages,
|
|
52
53
|
getJsonlSessionMetadata,
|
|
53
|
-
|
|
54
|
-
sessionHasPersistedEvidence,
|
|
54
|
+
resolveSessionAuthority,
|
|
55
55
|
deleteJsonlSession,
|
|
56
56
|
migrateLegacySessions,
|
|
57
57
|
migrateLegacySessionsBatch,
|
|
58
58
|
validateJsonlSession,
|
|
59
59
|
validateAllJsonlSessions,
|
|
60
60
|
} from "../harness/jsonl-session-store.js";
|
|
61
|
-
import { feature } from "../lib/feature-flags.js";
|
|
62
61
|
import {
|
|
63
62
|
listWorkflowSessions,
|
|
64
63
|
readWorkflowSession,
|
|
@@ -234,26 +233,24 @@ export function registerSessionCommand(program) {
|
|
|
234
233
|
const ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
235
234
|
const limit = Math.max(1, parseInt(options.limit) || 20);
|
|
236
235
|
let sessions = [];
|
|
236
|
+
const canonicalIds = new Set(listSessionEvidenceIds());
|
|
237
237
|
|
|
238
238
|
// Merge DB sessions + JSONL sessions
|
|
239
239
|
if (ctx.db) {
|
|
240
240
|
const db = ctx.db.getDatabase();
|
|
241
241
|
sessions.push(
|
|
242
|
-
...listSessions(db, { limit })
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
...listSessions(db, { limit })
|
|
243
|
+
.filter((s) => !canonicalIds.has(s?.id))
|
|
244
|
+
.map((s) => ({
|
|
245
|
+
...s,
|
|
246
|
+
_store: "db",
|
|
247
|
+
})),
|
|
246
248
|
);
|
|
247
249
|
}
|
|
248
250
|
|
|
249
|
-
if
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
...s,
|
|
253
|
-
_store: "jsonl",
|
|
254
|
-
})),
|
|
255
|
-
);
|
|
256
|
-
}
|
|
251
|
+
// Existing canonical sessions remain authoritative even if the
|
|
252
|
+
// creation/migration feature flag is later disabled.
|
|
253
|
+
sessions.push(...listSessionAuthoritySummaries({ limit }));
|
|
257
254
|
|
|
258
255
|
// Deduplicate by id (JSONL takes precedence) and rank by real time.
|
|
259
256
|
sessions = rankSessions(sessions, limit);
|
|
@@ -324,11 +321,14 @@ export function registerSessionCommand(program) {
|
|
|
324
321
|
try {
|
|
325
322
|
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
326
323
|
if (ctx.db) {
|
|
324
|
+
const canonicalIds = new Set(listSessionEvidenceIds());
|
|
327
325
|
local.push(
|
|
328
|
-
...listSessions(ctx.db.getDatabase(), { limit })
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
326
|
+
...listSessions(ctx.db.getDatabase(), { limit })
|
|
327
|
+
.filter((item) => !canonicalIds.has(item?.id))
|
|
328
|
+
.map((item) => ({
|
|
329
|
+
...item,
|
|
330
|
+
_store: "db",
|
|
331
|
+
})),
|
|
332
332
|
);
|
|
333
333
|
}
|
|
334
334
|
} catch (error) {
|
|
@@ -338,12 +338,7 @@ export function registerSessionCommand(program) {
|
|
|
338
338
|
// JSONL is the canonical transcript store and can be read without
|
|
339
339
|
// bootstrapping legacy native DB/config packages (some of which
|
|
340
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
|
-
);
|
|
341
|
+
local.push(...listSessionAuthoritySummaries({ limit }));
|
|
347
342
|
local = rankSessions(local, limit);
|
|
348
343
|
} catch (error) {
|
|
349
344
|
sourceErrors.local = error?.message || String(error);
|
|
@@ -613,15 +608,14 @@ export function registerSessionCommand(program) {
|
|
|
613
608
|
id = picked.id;
|
|
614
609
|
}
|
|
615
610
|
|
|
616
|
-
// Try
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
) {
|
|
611
|
+
// Try the complete canonical namespace first. The feature flag cannot
|
|
612
|
+
// make an existing/damaged canonical generation disappear and thereby
|
|
613
|
+
// authorize a legacy fallback.
|
|
614
|
+
const authority = resolveSessionAuthority(id);
|
|
615
|
+
const jsonlId = authority?.readable ? authority.id : null;
|
|
616
|
+
if (authority && !authority.readable) {
|
|
623
617
|
logger.error(
|
|
624
|
-
`Session ${id} has canonical persistence evidence but no readable transcript.`,
|
|
618
|
+
`Session ${authority.id} has canonical persistence evidence but no readable transcript (${authority.presence}).`,
|
|
625
619
|
);
|
|
626
620
|
logger.error(
|
|
627
621
|
"Refusing legacy fallback. Inspect or explicitly delete the damaged JSONL session before reusing its id.",
|
|
@@ -735,11 +729,14 @@ export function registerSessionCommand(program) {
|
|
|
735
729
|
// Canonical content source: append-only JSONL event log. The legacy DB
|
|
736
730
|
// is consulted only when no matching transcript exists.
|
|
737
731
|
const store = await import("../harness/jsonl-session-store.js");
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
732
|
+
const requestedId = id === "last" ? store.getLastSessionId() : id;
|
|
733
|
+
const authority = requestedId
|
|
734
|
+
? store.resolveSessionAuthority(requestedId)
|
|
735
|
+
: null;
|
|
736
|
+
const sid = authority?.readable ? authority.id : null;
|
|
737
|
+
if (authority && !authority.readable) {
|
|
741
738
|
throw new Error(
|
|
742
|
-
`Session ${id} has canonical persistence evidence but no readable transcript`,
|
|
739
|
+
`Session ${authority.id} has canonical persistence evidence but no readable transcript (${authority.presence})`,
|
|
743
740
|
);
|
|
744
741
|
}
|
|
745
742
|
if (sid) {
|
|
@@ -820,7 +817,10 @@ export function registerSessionCommand(program) {
|
|
|
820
817
|
try {
|
|
821
818
|
const sessionIndex = await import("../harness/session-index.js");
|
|
822
819
|
indexDb = sessionIndex.openIndex();
|
|
823
|
-
sessionIndex.syncIndex(indexDb);
|
|
820
|
+
const sync = sessionIndex.syncIndex(indexDb);
|
|
821
|
+
if (sync.rejected > 0) {
|
|
822
|
+
indexDiagnostic = `${sync.rejected} canonical session(s) were excluded because verification failed`;
|
|
823
|
+
}
|
|
824
824
|
matches = sessionIndex
|
|
825
825
|
.searchSessions(indexDb, query, { limit })
|
|
826
826
|
.map((hit) => ({
|
|
@@ -841,7 +841,7 @@ export function registerSessionCommand(program) {
|
|
|
841
841
|
});
|
|
842
842
|
for (const s of sessions) {
|
|
843
843
|
if (matches.length >= limit) break;
|
|
844
|
-
for (const ev of store.
|
|
844
|
+
for (const ev of store.readVerifiedEvents(s.id)) {
|
|
845
845
|
if (matches.length >= limit) break;
|
|
846
846
|
if (
|
|
847
847
|
ev.type !== "user_message" &&
|
|
@@ -921,8 +921,8 @@ export function registerSessionCommand(program) {
|
|
|
921
921
|
.action(async (id, options) => {
|
|
922
922
|
let ctx = null;
|
|
923
923
|
try {
|
|
924
|
-
const
|
|
925
|
-
|
|
924
|
+
const authority = resolveSessionAuthority(id);
|
|
925
|
+
const jsonlId = authority?.id || null;
|
|
926
926
|
let db = null;
|
|
927
927
|
try {
|
|
928
928
|
ctx = await bootstrap({ verbose: program.opts().verbose });
|
|
@@ -985,10 +985,11 @@ export function registerSessionCommand(program) {
|
|
|
985
985
|
Array.isArray(title) ? title.join(" ") : title,
|
|
986
986
|
).trim();
|
|
987
987
|
if (!normalized) throw new Error("A non-empty title is required");
|
|
988
|
-
const
|
|
989
|
-
|
|
988
|
+
const authority = resolveSessionAuthority(id);
|
|
989
|
+
const jsonlId = authority?.readable ? authority.id : null;
|
|
990
|
+
if (authority && !authority.readable) {
|
|
990
991
|
throw new Error(
|
|
991
|
-
`Session ${id} has canonical persistence evidence but no readable transcript`,
|
|
992
|
+
`Session ${authority.id} has canonical persistence evidence but no readable transcript (${authority.presence})`,
|
|
992
993
|
);
|
|
993
994
|
}
|
|
994
995
|
let result;
|
|
@@ -2175,14 +2176,17 @@ async function mirrorSessions(ids) {
|
|
|
2175
2176
|
|
|
2176
2177
|
const pushed = [];
|
|
2177
2178
|
const errors = [];
|
|
2178
|
-
const { readFileSync, existsSync } = await import("node:fs");
|
|
2179
2179
|
for (const id of ids) {
|
|
2180
2180
|
try {
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
if (!
|
|
2184
|
-
|
|
2185
|
-
|
|
2181
|
+
const authority = store.resolveSessionAuthority(id);
|
|
2182
|
+
if (!authority) throw new Error("session not found");
|
|
2183
|
+
if (!authority.readable) {
|
|
2184
|
+
throw new Error(
|
|
2185
|
+
`canonical session is not readable (${authority.presence})`,
|
|
2186
|
+
);
|
|
2187
|
+
}
|
|
2188
|
+
const bytes = store.readVerifiedTranscriptBytes(authority.id);
|
|
2189
|
+
pushed.push(await mirror.push(authority.id, bytes));
|
|
2186
2190
|
} catch (err) {
|
|
2187
2191
|
errors.push({ id, error: err.message });
|
|
2188
2192
|
}
|
|
@@ -2232,7 +2236,11 @@ async function mirrorPruneSessions() {
|
|
|
2232
2236
|
const { pruneMirror } = await import("../harness/session-mirror.js");
|
|
2233
2237
|
const { mirror } = await loadConfiguredMirror();
|
|
2234
2238
|
if (!mirror) return { target: null, deleted: [], kept: [] };
|
|
2235
|
-
|
|
2239
|
+
// A damaged local generation must not cause automatic deletion of its last
|
|
2240
|
+
// off-box recovery copy. Only an explicit canonical tombstone is prunable.
|
|
2241
|
+
const keep = store
|
|
2242
|
+
.listSessionEvidenceIds()
|
|
2243
|
+
.filter((id) => store.getSessionPresence(id) !== "tombstoned");
|
|
2236
2244
|
const res = await pruneMirror(mirror, { keep });
|
|
2237
2245
|
return { target: mirror.target, ...res };
|
|
2238
2246
|
}
|
package/src/data/changelog.json
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"source": "CHANGELOG.md",
|
|
3
3
|
"releases": [
|
|
4
|
+
{
|
|
5
|
+
"productVersion": null,
|
|
6
|
+
"cliVersion": "0.162.200",
|
|
7
|
+
"cliVersions": ["0.162.198", "0.162.200"],
|
|
8
|
+
"date": "2026-08-07",
|
|
9
|
+
"title": "",
|
|
10
|
+
"sections": [
|
|
11
|
+
{
|
|
12
|
+
"heading": "Fixed — cc CLI 0.162.200: release-gate isolation and carried reliability fixes",
|
|
13
|
+
"body": "> `chainlesschain` **0.162.198 → 0.162.200** (release candidate,\n> 2026-08-07; `0.162.199` failed before npm upload and its tag remains\n> immutable). CLI-only release metadata; `@chainlesschain/personal-data-hub`\n> remains **0.4.57** and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Carries the complete 0.162.199 candidate**: command lifecycle telemetry and\n alias observation policy, canonical session authority, fixed MCP package\n capsules, native update recovery, and portable reliability gates are all\n included because `0.162.199` never reached npm.\n- **Release-gate isolation**: the Agent SDK real-CLI E2E now places its\n rollback-resistant security anchor beside, rather than inside,\n `CHAINLESSCHAIN_HOME`. The fixture therefore matches the production\n fail-closed layout after redirecting `HOME` and no longer hides the `agent`\n command behind compatibility registration.\n- **Pre-release evidence**: implementation SHA `bf6924013d1c` passed the full\n [npm release dry-run](https://github.com/chainlesschain/chainlesschain/actions/runs/31189959290),\n including core packages, Agent SDK real-CLI E2E, Personal Data Hub, Web Panel,\n the complete CLI suite, and credential-free npm package validation. The final\n `0.162.200` version commit must pass the exact-SHA CLI CI and CLI Strict\n Sandbox matrices before tag `v-npm-0-162-200` is created."
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"productVersion": null,
|
|
19
|
+
"cliVersion": "0.162.199",
|
|
20
|
+
"cliVersions": ["0.162.198", "0.162.199"],
|
|
21
|
+
"date": "2026-08-07",
|
|
22
|
+
"title": "",
|
|
23
|
+
"sections": [
|
|
24
|
+
{
|
|
25
|
+
"heading": "Fixed — cc CLI 0.162.199: session authority, MCP capsules, and recovery reliability",
|
|
26
|
+
"body": "> `chainlesschain` **0.162.198 → 0.162.199** (not published, 2026-08-07;\n> the release workflow failed before package creation or npm upload and tag\n> `v-npm-0-162-199` remains immutable). CLI-only release metadata;\n> `@chainlesschain/personal-data-hub` remains **0.4.57** and\n> `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Command lifecycle telemetry**: manifest-driven lifecycle metadata now\n records legacy and replacement routes, aggregates usage without changing\n aliases automatically, and keeps compatibility entries until their stated\n observation window and release-cycle requirements are satisfied.\n- **Canonical session authority**: host leases, transcript witnesses,\n anti-rollback anchors, compare-and-swap persistence, bounded cleanup, and\n descendant retirement harden concurrent resume and long-running session\n behavior across the covered CLI, background, and remote-host paths.\n- **Fixed MCP package execution**: approved JavaScript launchers are resolved\n to exact npm versions and complete transitive closures, then bundled into a\n guarded, content-addressed Node capsule. Runtime execution no longer depends\n on a live dynamic package launcher or mutable `node_modules` entrypoint.\n- **Native update recovery**: Windows and POSIX installer/OTA generations can\n recover interrupted activation, rollback, and rescue state while preserving\n exact lineage, owner-private locks, and Windows path/handle identity under\n Node 22.12 device projection.\n- **Portable reliability gates**: disk/pipe failure injection, process-tree\n cleanup, resource accounting, session stress, and platform path aliases are\n covered by the release matrices. Real hardware, terminal, SSH, and extended\n soak observations remain ongoing evidence rather than compatibility claims.\n- **Candidate evidence**: implementation SHA `7e7ce9182746` passed\n [CLI CI](https://github.com/chainlesschain/chainlesschain/actions/runs/31181229942),\n [CLI Strict Sandbox](https://github.com/chainlesschain/chainlesschain/actions/runs/31181328955),\n [CLI Background Interaction E2E](https://github.com/chainlesschain/chainlesschain/actions/runs/31181258842),\n and [CLI Session Host Consistency](https://github.com/chainlesschain/chainlesschain/actions/runs/31181258424)\n on Ubuntu, Windows, and macOS. Final SHA `23bd2e6e5758` also passed the\n exact-SHA release gates, but the\n [dedicated npm release](https://github.com/chainlesschain/chainlesschain/actions/runs/31187599603)\n stopped before package creation because its Agent SDK fixture placed the\n security anchor inside the redirected CLI home."
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
4
30
|
{
|
|
5
31
|
"productVersion": null,
|
|
6
32
|
"cliVersion": "0.162.198",
|
|
@@ -10,7 +36,7 @@
|
|
|
10
36
|
"sections": [
|
|
11
37
|
{
|
|
12
38
|
"heading": "Fixed — cc CLI 0.162.198: interactive streaming and release portability",
|
|
13
|
-
"body": "> `chainlesschain` **0.162.197 → 0.162.198** (
|
|
39
|
+
"body": "> `chainlesschain` **0.162.197 → 0.162.198** (published, 2026-08-06).\n> CLI-only release metadata; `@chainlesschain/personal-data-hub` remains\n> **0.4.57** and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Interactive output backpressure**: REPL, headless streaming, provider\n pacing, and TTY writers now wait for saturated output streams to drain and\n clean up pending listeners across completion, interruption, and session\n transitions instead of allowing unbounded interactive writes.\n- **Canonical session controls**: the CLI-owned session projection and bounded\n reply routes now support the completed VS Code and JetBrains workbench and\n rewind journeys while preserving CLI authority over persisted mutations.\n- **Portable release gates**: Windows path-alias fixtures, state-path mocks,\n Skill metadata fixtures, POSIX executable-bit setup, and the deprecated\n agent-core shim are aligned with the three-platform CLI CI and Strict\n Sandbox contracts.\n- **Release readback hardening**: public npm verification remains independent\n of undeclared runtime dependencies, retries bounded registry propagation,\n and binds provenance and registry bytes to the immutable publish artifact.\n- **Exact release evidence**: tag `v-npm-0-162-198` points to final release SHA\n [`3c0f62fa17242cfa3123ab502a9bf5d1cbed8481`](https://github.com/chainlesschain/chainlesschain/commit/3c0f62fa17242cfa3123ab502a9bf5d1cbed8481).\n The same SHA passed [CLI CI](https://github.com/chainlesschain/chainlesschain/actions/runs/31078499968)\n and [CLI Strict Sandbox](https://github.com/chainlesschain/chainlesschain/actions/runs/31078499270)\n on Ubuntu, Windows, and macOS. The\n [dedicated npm release](https://github.com/chainlesschain/chainlesschain/actions/runs/31081337370)\n completed the exact-SHA gate, immutable tarball, CycloneDX SBOM, Trusted\n Publishing, signed provenance, registry readback, and npmmirror sync; the\n [independent public readback](https://github.com/chainlesschain/chainlesschain/actions/runs/31082366544)\n re-downloaded the package and matched registry bytes and publishing identity."
|
|
14
40
|
}
|
|
15
41
|
]
|
|
16
42
|
},
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "../../runtime/runtime-events.js";
|
|
7
7
|
import { createSessionRecord } from "../../runtime/contracts/session-record.js";
|
|
8
8
|
import { loadSideEffectLedger } from "../../lib/side-effect-ledger-store.js";
|
|
9
|
+
import { acquireSessionHostLease } from "../../lib/session-host-lease.js";
|
|
9
10
|
import { reconcileSideEffects } from "../../lib/side-effect-ledger.js";
|
|
10
11
|
import {
|
|
11
12
|
formatMcpLedgerRecoveryNotice,
|
|
@@ -532,11 +533,20 @@ async function ensureSessionHandler(server, ws, session) {
|
|
|
532
533
|
});
|
|
533
534
|
} else {
|
|
534
535
|
const { WSAgentHandler } = await import("./ws-agent-handler.js");
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
interaction: session.interaction,
|
|
538
|
-
db: server.sessionManager.db,
|
|
536
|
+
const sessionHostLease = acquireSessionHostLease(session.id, {
|
|
537
|
+
hostKind: "ws",
|
|
539
538
|
});
|
|
539
|
+
try {
|
|
540
|
+
handler = new WSAgentHandler({
|
|
541
|
+
session,
|
|
542
|
+
interaction: session.interaction,
|
|
543
|
+
db: server.sessionManager.db,
|
|
544
|
+
sessionHostLease,
|
|
545
|
+
});
|
|
546
|
+
} catch (error) {
|
|
547
|
+
sessionHostLease.release();
|
|
548
|
+
throw error;
|
|
549
|
+
}
|
|
540
550
|
}
|
|
541
551
|
|
|
542
552
|
server.sessionHandlers.set(session.id, handler);
|
|
@@ -79,6 +79,7 @@ export class WSAgentHandler {
|
|
|
79
79
|
approvalGate,
|
|
80
80
|
agentLoop: runAgentLoop,
|
|
81
81
|
canonicalSessionStore,
|
|
82
|
+
sessionHostLease = null,
|
|
82
83
|
}) {
|
|
83
84
|
this.session = session;
|
|
84
85
|
this.interaction = interaction;
|
|
@@ -86,6 +87,25 @@ export class WSAgentHandler {
|
|
|
86
87
|
this._processing = false;
|
|
87
88
|
this._abortController = null;
|
|
88
89
|
this._activeRequestId = null;
|
|
90
|
+
this._sessionHostLease = sessionHostLease;
|
|
91
|
+
this._onSessionHostLeaseAbort = null;
|
|
92
|
+
if (sessionHostLease?.signal) {
|
|
93
|
+
this._onSessionHostLeaseAbort = () => {
|
|
94
|
+
const reason =
|
|
95
|
+
sessionHostLease.signal.reason ||
|
|
96
|
+
createAbortError("Session host lease was lost");
|
|
97
|
+
if (this._abortController && !this._abortController.signal.aborted) {
|
|
98
|
+
this._abortController.abort(reason);
|
|
99
|
+
}
|
|
100
|
+
this.interaction?.rejectAllPending?.(reason);
|
|
101
|
+
};
|
|
102
|
+
sessionHostLease.signal.addEventListener(
|
|
103
|
+
"abort",
|
|
104
|
+
this._onSessionHostLeaseAbort,
|
|
105
|
+
{ once: true },
|
|
106
|
+
);
|
|
107
|
+
if (sessionHostLease.signal.aborted) this._onSessionHostLeaseAbort();
|
|
108
|
+
}
|
|
89
109
|
// P0-2: monotonic sequence for crash-safe side-effect ledger op ids. The
|
|
90
110
|
// session id + a per-op nonce keep ids unique across turns and processes.
|
|
91
111
|
this._sideEffectSeq = 0;
|
|
@@ -486,6 +506,7 @@ export class WSAgentHandler {
|
|
|
486
506
|
|
|
487
507
|
try {
|
|
488
508
|
const { session } = this;
|
|
509
|
+
this._sessionHostLease?.assert?.();
|
|
489
510
|
|
|
490
511
|
if (session.canonicalJsonlSession === true) {
|
|
491
512
|
canonicalTurn = this._claimCanonicalTurn(userMessage, requestId);
|
|
@@ -648,6 +669,7 @@ export class WSAgentHandler {
|
|
|
648
669
|
})
|
|
649
670
|
.start(opId);
|
|
650
671
|
persistSideEffectLedger(session.id, sideEffectLedger);
|
|
672
|
+
this._sessionHostLease?.assert?.();
|
|
651
673
|
}
|
|
652
674
|
}
|
|
653
675
|
break;
|
|
@@ -884,6 +906,15 @@ export class WSAgentHandler {
|
|
|
884
906
|
reason: "session_closed",
|
|
885
907
|
});
|
|
886
908
|
}
|
|
909
|
+
if (this._sessionHostLease?.signal && this._onSessionHostLeaseAbort) {
|
|
910
|
+
this._sessionHostLease.signal.removeEventListener(
|
|
911
|
+
"abort",
|
|
912
|
+
this._onSessionHostLeaseAbort,
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
this._onSessionHostLeaseAbort = null;
|
|
916
|
+
this._sessionHostLease?.release?.();
|
|
917
|
+
this._sessionHostLease = null;
|
|
887
918
|
}
|
|
888
919
|
|
|
889
920
|
/**
|