chainlesschain 0.165.5 → 0.165.6
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-CEeYTeDB.js → AIOps-vfoDb6HZ.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BeRUQ3V2.js → ActionButton-Cm5f7p93.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DrV718XF.js → Analytics-yRuvgWxa.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Cd2Frt7Q.js → AppLayout-BROsC4h1.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CUJMlORU.js → Artifacts-CimHApb1.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CXJcfT6p.js → Audit-DI8kr8zI.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DOv6Z7H9.js → BackgroundAgents-DSLzKy-n.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BwdDyBI0.js → Backup-DkH_n2r1.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BmLn4kYH.js → BaseInput-CKSrUoRA.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-COg8pAW2.js → Chat-ClwfMXUS.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CjMaqfL7.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-BCP4uoU8.js → Checkbox-BYTehcQG.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-pRt6Y9JI.js → Codegen-B8AMcp6J.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DLaprKhS.js → Col-BNSogPo3.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DyATsz5f.js → Community-JxPvGb8O.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BXAaupZK.js → Compact-DF7bFAgE.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DpcJBELr.js → Compliance-Bvhqnwrq.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DG4EFWyd.js → Cowork-BDS0CJvM.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-F6Oy5n2P.js → Cron-DqvRfxoQ.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BOdgtalX.js → Crosschain-CDcIvnqS.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DT1dSkjH.js → DID-D7jaUxU3.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-NBUIqWzC.js → Dashboard-B5A18wEV.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CSpHeMYB.js → Dropdown-_6IVkGag.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CEG0xISr.js → EmailListRenderer-C9PeiKCG.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BTZ0BZna.js → FamilyGuardDashboard-DXjuEHrX.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BuuCTn2V.js → Federation-B4IAR9zv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-KAVceevk.js → FormItemContext-CxQeSNx1.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DnHpcQvW.js → GenericCardRenderer-B8GS-Y3N.js} +1 -1
- package/src/assets/web-panel/assets/{Git-C_B_0HwB.js → Git-BS8SouUX.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DPSZuzuu.js → Governance-Dq9aYb5Q.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BV-06V7q.js → Inference-BrCEe9AJ.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-wpDuupn6.js → KnowledgeGraph-DybOpiY2.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Bseca1_I.js → Logs-DBpzbRfx.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-CFyt8iUd.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-d3kM4DDL.js → Marketplace-Cc7CCSCu.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DQ_xZ23i.js → McpTools-DFaIhOfu.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-CRIeYO4L.js → Memory-KCqlp9ol.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BsllIa9l.js → MobileBridge-Bys84ySN.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BUuQy30X.js → MobileProjects-B-6qU-je.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BOFDIzrC.js → Mtc-BgY-fvCq.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-BQg-vyvG.js → MtcAudit-B8pCmqQJ.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-Bo1jrPdN.js → Multisig-BbOmYutA.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Bmod8alw.js → NLProgramming-BocLQz_M.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CGGFL8w-.js → Notes-CSwbxEop.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BsZvCJxC.js → NotificationSettings-CqFNSYG3.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C1-Quo_h.js → OrderTableRenderer-C6gMfAk7.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BjOeDYOi.js → Organization-QrDXVdMJ.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DwVV3l5A.js → Overflow-Cxntotjt.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Cu3DQT9W.js → P2P-CIdBOwNq.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Cg0gR7dH.js → PdhVaultBrowser-CT5aP8rD.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-CsAXxRN5.js → Permissions-DH7OM8XU.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C-nNmnYp.js → PersonalDataHub-CnJqbWce.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-BOnW7nNc.js → Pipeline-5C3HG1kH.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-ClLSyGKt.js → Privacy-B4yIp7xK.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DuLvjjq7.js → ProjectInit-BMvt-2M0.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DQYYbDD9.js → ProjectSettings-CvSTEMRG.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Drw8MBGK.js → Projects-BKBJxEek.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-ckqHQe6K.js → Providers-BdwUqFWN.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-DW5BXk-G.js → QrScannerModal-DtnCKlTm.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DDLnhNTp.js → QuickAsk-sTbgwyNr.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-PJQ2C91U.js → Recommend-Bzr14gSb.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-s6wmda34.js → RemoteSession-C_TF5IaJ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DC2sb-I3.js → Reputation-GCAM4H2K.js} +1 -1
- package/src/assets/web-panel/assets/{Row-hPGk1eGj.js → Row-Dir0r6OQ.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-RIvfZql0.js → RssFeed-CpGnlecX.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DFg1G1eR.js → Search-DMMamC6u.js} +1 -1
- package/src/assets/web-panel/assets/{Security-D6H5p8Dp.js → Security-yqay5yG-.js} +4 -4
- package/src/assets/web-panel/assets/{Services-nxYiFV_w.js → Services-C5i2wh9G.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BmgFNAdB.js → Skeleton-vUqk35yj.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CsaaD2av.js → Skills-DzcSkhot.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-yM5y9yvK.js → Sla-CB6qbYNr.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DPy1XMYh.js → SpeechSettings-BHUI7cox.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CFVhEyyr.js → SyncSettings-D-RrsxTJ.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DdO02Inn.js → Tasks-DFxdOJiq.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Eo2d8Llu.js → Templates-SKAob_Aq.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-ChESOXgy.js → Tenant-BPfsfHQ-.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BJ7oDxTI.js → Terminal-8iw7FpUf.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-hWX0fUvz.js → TimelineRenderer-C4Gjj5Su.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DVBZQnd-.js → Tokens-COYhN18e.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-D89cQfVq.js → Trigger-B-JzXcf6.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BIVSb4-V.js → Trust-BJ5bg0nI.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B58gWopl.js → UkeySign-BG_ByRMf.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DhHI7bmG.js → VideoEditing-B3kOnSiU.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-C4FheWS_.js → Wallet-CcoGFnK7.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-DnPRq-Bx.js → WebAuthn-DdT8vRC_.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BerRPjpJ.js → WorkflowEditor-CZu3M9N8.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BzZ52iKr.js → chat-DxJt3Qba.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BI_E4BAn.js → colors-DdYfwJaB.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-d50mr3yk.js → compact-item-BG3SUzwj.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C6FsQ1IH.js → createContext-By51z2-1.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DorRZcI9.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DLZEMgLP.js → hasIn-B0apZ3KJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoNZlzhQ.js → index-3jWkIu5j.js} +1 -1
- package/src/assets/web-panel/assets/{index-AHr7ryWf.js → index-B3rWuPMW.js} +1 -1
- package/src/assets/web-panel/assets/{index-KNGgO4Wm.js → index-B5rLiEo0.js} +1 -1
- package/src/assets/web-panel/assets/{index-IPkwSAW_.js → index-BBPf3TpM.js} +1 -1
- package/src/assets/web-panel/assets/index-BETiL0a3.js +1 -0
- package/src/assets/web-panel/assets/{index-Dec0Kf_Z.js → index-BIrJfqO4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTpIOTfR.js → index-BLIbGOLX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcSUl9fA.js → index-BP94CrBV.js} +1 -1
- package/src/assets/web-panel/assets/{index-B81mo1Et.js → index-BWF8_mkx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoFtCVZ7.js → index-BYINoRLK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DY4j5zkF.js → index-BZ_0qm4g.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVzuawCX.js → index-BewKYrX9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE0V6cp-.js → index-BfWYsB9t.js} +1 -1
- package/src/assets/web-panel/assets/index-BhAVHuW8.js +1 -0
- package/src/assets/web-panel/assets/{index-BRGx3w6T.js → index-Bissefox.js} +3 -3
- package/src/assets/web-panel/assets/{index-CjuKZBqJ.js → index-BkvcEo4p.js} +1 -1
- package/src/assets/web-panel/assets/{index-9H_M2jju.js → index-Bos5_aMV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqkbHHg8.js → index-C1C9i79A.js} +1 -1
- package/src/assets/web-panel/assets/{index-Y2-q7QLm.js → index-CAhHirVH.js} +1 -1
- package/src/assets/web-panel/assets/{index-Q5Tn735s.js → index-CNIxXMmN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CO8DAF7U.js → index-CW93tZDv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZjjdQ62.js → index-CWEuZWCK.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3k8kevG.js → index-Cp6e-hGw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUaEHfQ0.js → index-CpjZhgNd.js} +1 -1
- package/src/assets/web-panel/assets/{index-GXE0D8Nx.js → index-CzmQElZy.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bmr_vxXD.js → index-DCn8IcxV.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-aBumtY.js → index-DE76D-kA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeM4hfht.js → index-DaIz0NAW.js} +1 -1
- package/src/assets/web-panel/assets/{index-Pvf30m8Q.js → index-Da_WBdLX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAE3hwev.js → index-Dz49VOyQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdKt9fOd.js → index-Q2SCX-MI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRN5TRTQ.js → index-RD6O-0C6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsscwxPE.js → index-SQqOlR3d.js} +1 -1
- package/src/assets/web-panel/assets/{index-TWG-_D1M.js → index-ZFbps9po.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLoTQr0W.js → index-ZxtP8jG7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BB9SqVSt.js → index-bP_VlDb4.js} +1 -1
- package/src/assets/web-panel/assets/{index-A5CDWP7y.js → index-kf57LJ93.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgkoH3_g.js → index-oxRrmFO9.js} +1 -1
- package/src/assets/web-panel/assets/{index-Co7s9LsB.js → index-p1_8SbI1.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-D-4Hzgej.js → initDefaultProps-BWJktcg8.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D4Wl4xU7.js → motion-BEXBzUFV.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cd5eQvL0.js → move-BUKwn2sx.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-B4ilslCW.js → mtc-parser-FTI7btqQ.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Ckarx-tf.js → omit-CsLtSPH3.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-QJ0bpCmc.js → pickAttrs-DWZxsT_S.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CKHm-tq8.js → placementArrow-Bcfs43CX.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CV6a_w_Y.js → responsiveObserve-a9bcC1p-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-mHpeQFgk.js → slide-BDTzgOXN.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DIaQNQWA.js → statusUtils-Iq1j_HUg.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-PJpzavV8.js → styleChecker-DAZEYxeh.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BH7zTw8S.js → useFlexGapSupport-DVkjyDrh.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BDNG3JDd.js → useFs-wXTpNTHt.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CY2VWdUg.js → usePersonalDataHub-CtQM_aZr.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D0kw9jhz.js → vnode-hjEoG85v.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-B5g7TN7r.js → zoom-BHVpyKg_.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +2 -2
- package/src/commands/agent.js +14 -2
- package/src/commands/background-session.js +100 -10
- package/src/commands/mcp.js +5 -0
- package/src/commands/plugin.js +145 -29
- package/src/commands/remote-control.js +295 -110
- package/src/commands/session-message.js +171 -0
- package/src/commands/session.js +11 -0
- package/src/data/changelog.json +15 -2
- package/src/harness/mcp-client.js +141 -10
- package/src/lib/background-session-transport.js +153 -27
- package/src/lib/mcp-client.js +2 -0
- package/src/lib/mcp-headers-helper.js +47 -5
- package/src/lib/mcp-oauth.js +55 -6
- package/src/lib/mcp-tls.js +230 -0
- package/src/lib/output-styles.js +12 -0
- package/src/lib/plugin-runtime/install.js +614 -71
- package/src/lib/plugin-runtime/marketplace-archive-source.js +331 -0
- package/src/lib/plugin-runtime/marketplace-catalog.js +52 -6
- package/src/lib/plugin-runtime/marketplace-remote-artifacts.js +1 -0
- package/src/lib/plugin-runtime/marketplace-source-adapter.js +163 -0
- package/src/lib/plugin-runtime/marketplace-source-cache.js +11 -1
- package/src/lib/plugin-runtime/remote-source.js +435 -55
- package/src/lib/plugin-security.js +393 -41
- package/src/lib/plugin-source-identity.js +850 -0
- package/src/lib/remote-approval-bridge.js +136 -46
- package/src/lib/remote-control.js +217 -31
- package/src/lib/session-message-fabric.js +1105 -0
- package/src/lib/session-projection.js +45 -2
- package/src/lib/session-runtime-retention.js +155 -0
- package/src/lib/settings-loader.cjs +29 -0
- package/src/repl/agent-repl.js +51 -14
- package/src/repl/permission-prompt.js +31 -8
- package/src/repl/repl-keybindings.js +55 -0
- package/src/runtime/agent-core.js +51 -2
- package/src/runtime/headless-runner.js +47 -66
- package/src/runtime/headless-stream.js +18 -24
- package/src/runtime/mcp-config.js +2 -0
- package/src/runtime/policies/agent-policy.js +2 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-4gGkdGgA.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-B4RLp2zs.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CagEcIex.js +0 -1
- package/src/assets/web-panel/assets/index-pzT9PpOU.js +0 -1
- package/src/assets/web-panel/assets/index-z1kFadaX.js +0 -1
|
@@ -615,6 +615,37 @@ function approvalSummary(source, state) {
|
|
|
615
615
|
};
|
|
616
616
|
}
|
|
617
617
|
|
|
618
|
+
function messagingSummary(sessionIds, fabric) {
|
|
619
|
+
const linked = new Set(
|
|
620
|
+
(Array.isArray(sessionIds) ? sessionIds : [sessionIds]).filter(Boolean),
|
|
621
|
+
);
|
|
622
|
+
const endpoints = Array.isArray(fabric?.endpoints)
|
|
623
|
+
? fabric.endpoints
|
|
624
|
+
.filter((endpoint) => linked.has(endpoint?.sessionId))
|
|
625
|
+
.map((endpoint) => ({
|
|
626
|
+
name: asText(endpoint?.name),
|
|
627
|
+
address: asText(endpoint?.address),
|
|
628
|
+
policy: ["accept", "hold", "refuse"].includes(endpoint?.policy)
|
|
629
|
+
? endpoint.policy
|
|
630
|
+
: "refuse",
|
|
631
|
+
online: endpoint?.online === true,
|
|
632
|
+
idle: endpoint?.idle === true,
|
|
633
|
+
unread: asCount(endpoint?.unread),
|
|
634
|
+
held: asCount(endpoint?.held),
|
|
635
|
+
}))
|
|
636
|
+
.filter((endpoint) => endpoint.name && endpoint.address)
|
|
637
|
+
.sort((left, right) => left.name.localeCompare(right.name))
|
|
638
|
+
: [];
|
|
639
|
+
return {
|
|
640
|
+
authority: "cli",
|
|
641
|
+
registered: endpoints.length > 0,
|
|
642
|
+
revision: Number.isSafeInteger(fabric?.revision) ? fabric.revision : 0,
|
|
643
|
+
unread: endpoints.reduce((total, endpoint) => total + endpoint.unread, 0),
|
|
644
|
+
held: endpoints.reduce((total, endpoint) => total + endpoint.held, 0),
|
|
645
|
+
endpoints,
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
618
649
|
function lastEventFor(source, state) {
|
|
619
650
|
const at =
|
|
620
651
|
toIso(source?.lastEvent?.at) ||
|
|
@@ -629,7 +660,11 @@ function lastEventFor(source, state) {
|
|
|
629
660
|
};
|
|
630
661
|
}
|
|
631
662
|
|
|
632
|
-
function projectOne(
|
|
663
|
+
function projectOne(
|
|
664
|
+
kind,
|
|
665
|
+
source,
|
|
666
|
+
{ artifacts, prLinks, sessionMessageFabric },
|
|
667
|
+
) {
|
|
633
668
|
let sourceId;
|
|
634
669
|
if (kind === "remote") {
|
|
635
670
|
const stateFile = asText(source?.stateFile);
|
|
@@ -701,6 +736,7 @@ function projectOne(kind, source, { artifacts, prLinks }) {
|
|
|
701
736
|
? { count: asCount(source?.artifacts?.count), latest: null }
|
|
702
737
|
: artifactSummary(linkedSessionIds, artifacts),
|
|
703
738
|
approval: approvalSummary(source, state),
|
|
739
|
+
messaging: messagingSummary(linkedSessionIds, sessionMessageFabric),
|
|
704
740
|
pr: prSummary(linkedSessionIds, prLinks),
|
|
705
741
|
workflow: dynamicWorkflowSummary(source),
|
|
706
742
|
lastEvent: lastEventFor(source, state),
|
|
@@ -726,10 +762,11 @@ export function buildSessionProjection({
|
|
|
726
762
|
dynamicWorkflow = [],
|
|
727
763
|
artifacts = [],
|
|
728
764
|
prLinks = {},
|
|
765
|
+
sessionMessageFabric = null,
|
|
729
766
|
sourceErrors = {},
|
|
730
767
|
generatedAt = new Date().toISOString(),
|
|
731
768
|
} = {}) {
|
|
732
|
-
const context = { artifacts, prLinks };
|
|
769
|
+
const context = { artifacts, prLinks, sessionMessageFabric };
|
|
733
770
|
const sessions = [
|
|
734
771
|
...(Array.isArray(local) ? local : []).map((source) =>
|
|
735
772
|
projectOne("local", source, context),
|
|
@@ -785,6 +822,12 @@ export function buildSessionProjection({
|
|
|
785
822
|
Array.isArray(dynamicWorkflow) ? dynamicWorkflow.length : 0,
|
|
786
823
|
sourceErrors.dynamicWorkflow,
|
|
787
824
|
),
|
|
825
|
+
sessionMessageFabric: sourceStatus(
|
|
826
|
+
Array.isArray(sessionMessageFabric?.endpoints)
|
|
827
|
+
? sessionMessageFabric.endpoints.length
|
|
828
|
+
: 0,
|
|
829
|
+
sourceErrors.sessionMessageFabric,
|
|
830
|
+
),
|
|
788
831
|
};
|
|
789
832
|
const revision = projectionRevision({
|
|
790
833
|
schema: SESSION_PROJECTION_SCHEMA,
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/** Bounded live-state retention for long-running agent conversations. */
|
|
2
|
+
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
|
|
5
|
+
export const SESSION_RUNTIME_RETENTION_LIMITS = Object.freeze({
|
|
6
|
+
recentResults: 32,
|
|
7
|
+
retainedResultChars: 512,
|
|
8
|
+
markerHeadChars: 128,
|
|
9
|
+
markerTailChars: 128,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const SESSION_RUNTIME_RELEASE_MARKER = "…[live result released:";
|
|
13
|
+
const BACKGROUND_RESULT_PREFIX = '[Background sub-agent "';
|
|
14
|
+
|
|
15
|
+
function normalizedLimit(value, fallback, minimum = 0) {
|
|
16
|
+
return Number.isFinite(value)
|
|
17
|
+
? Math.max(minimum, Math.floor(value))
|
|
18
|
+
: fallback;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function resultContent(message) {
|
|
22
|
+
if (!message || typeof message.content !== "string") return null;
|
|
23
|
+
if (message.role === "tool") return message.content;
|
|
24
|
+
if (
|
|
25
|
+
message.role === "user" &&
|
|
26
|
+
message.content.startsWith(BACKGROUND_RESULT_PREFIX)
|
|
27
|
+
) {
|
|
28
|
+
return message.content;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// V8 may represent `slice()` as a view that keeps the entire source string's
|
|
34
|
+
// backing store alive. Joining individual UTF-16 code units forces a small,
|
|
35
|
+
// independent flat string while preserving even unpaired surrogate units.
|
|
36
|
+
function detachedSlice(content, start, end) {
|
|
37
|
+
const length = Math.max(0, end - start);
|
|
38
|
+
const units = new Array(length);
|
|
39
|
+
for (let index = 0; index < length; index += 1) {
|
|
40
|
+
units[index] = content.charAt(start + index);
|
|
41
|
+
}
|
|
42
|
+
return units.join("");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function releaseProjection(content, options) {
|
|
46
|
+
const digest = createHash("sha256").update(content, "utf8").digest("hex");
|
|
47
|
+
const marker =
|
|
48
|
+
`${SESSION_RUNTIME_RELEASE_MARKER} ${content.length} chars; sha256:${digest}; ` +
|
|
49
|
+
"full evidence remains in the durable transcript]";
|
|
50
|
+
const maxChars = options.retainedResultChars;
|
|
51
|
+
if (marker.length >= maxChars) {
|
|
52
|
+
return { content: marker.slice(0, maxChars), digest };
|
|
53
|
+
}
|
|
54
|
+
const remaining = maxChars - marker.length - 2;
|
|
55
|
+
const headChars = Math.min(
|
|
56
|
+
options.markerHeadChars,
|
|
57
|
+
Math.max(0, Math.floor(remaining / 2)),
|
|
58
|
+
);
|
|
59
|
+
const tailChars = Math.min(
|
|
60
|
+
options.markerTailChars,
|
|
61
|
+
Math.max(0, remaining - headChars),
|
|
62
|
+
);
|
|
63
|
+
const head = detachedSlice(content, 0, headChars);
|
|
64
|
+
const tail =
|
|
65
|
+
tailChars > 0
|
|
66
|
+
? detachedSlice(content, content.length - tailChars, content.length)
|
|
67
|
+
: "";
|
|
68
|
+
return {
|
|
69
|
+
content: `${head}\n${marker}\n${tail}`.slice(0, maxChars),
|
|
70
|
+
digest,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Replace old live tool/subagent result bodies with a bounded head/tail,
|
|
76
|
+
* digest, and durable-transcript locator. The message and pairing structure is
|
|
77
|
+
* retained; only old result content is released. The returned array is new and
|
|
78
|
+
* the input is never mutated.
|
|
79
|
+
*/
|
|
80
|
+
export function releaseOldLiveSessionResults(messages, configured = {}) {
|
|
81
|
+
if (!Array.isArray(messages)) {
|
|
82
|
+
return {
|
|
83
|
+
messages,
|
|
84
|
+
stats: {
|
|
85
|
+
strategy: "session-runtime-retention",
|
|
86
|
+
released: 0,
|
|
87
|
+
savedChars: 0,
|
|
88
|
+
recentResults: 0,
|
|
89
|
+
durableReferences: [],
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const options = {
|
|
94
|
+
recentResults: normalizedLimit(
|
|
95
|
+
configured.recentResults,
|
|
96
|
+
SESSION_RUNTIME_RETENTION_LIMITS.recentResults,
|
|
97
|
+
),
|
|
98
|
+
retainedResultChars: normalizedLimit(
|
|
99
|
+
configured.retainedResultChars,
|
|
100
|
+
SESSION_RUNTIME_RETENTION_LIMITS.retainedResultChars,
|
|
101
|
+
256,
|
|
102
|
+
),
|
|
103
|
+
markerHeadChars: normalizedLimit(
|
|
104
|
+
configured.markerHeadChars,
|
|
105
|
+
SESSION_RUNTIME_RETENTION_LIMITS.markerHeadChars,
|
|
106
|
+
),
|
|
107
|
+
markerTailChars: normalizedLimit(
|
|
108
|
+
configured.markerTailChars,
|
|
109
|
+
SESSION_RUNTIME_RETENTION_LIMITS.markerTailChars,
|
|
110
|
+
),
|
|
111
|
+
};
|
|
112
|
+
const resultIndexes = [];
|
|
113
|
+
for (let index = 0; index < messages.length; index += 1) {
|
|
114
|
+
if (resultContent(messages[index]) != null) resultIndexes.push(index);
|
|
115
|
+
}
|
|
116
|
+
const releaseCount = Math.max(
|
|
117
|
+
0,
|
|
118
|
+
resultIndexes.length - options.recentResults,
|
|
119
|
+
);
|
|
120
|
+
const releaseIndexes = new Set(resultIndexes.slice(0, releaseCount));
|
|
121
|
+
let released = 0;
|
|
122
|
+
let savedChars = 0;
|
|
123
|
+
const durableReferences = [];
|
|
124
|
+
const output = messages.map((message, index) => {
|
|
125
|
+
if (!releaseIndexes.has(index)) return message;
|
|
126
|
+
const content = resultContent(message);
|
|
127
|
+
if (content.length <= options.retainedResultChars) {
|
|
128
|
+
return message;
|
|
129
|
+
}
|
|
130
|
+
const projection = releaseProjection(content, options);
|
|
131
|
+
released += 1;
|
|
132
|
+
savedChars += content.length - projection.content.length;
|
|
133
|
+
durableReferences.push({
|
|
134
|
+
messageIndex: index,
|
|
135
|
+
digest: `sha256:${projection.digest}`,
|
|
136
|
+
originalChars: content.length,
|
|
137
|
+
retainedChars: projection.content.length,
|
|
138
|
+
});
|
|
139
|
+
return { ...message, content: projection.content };
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
messages: output,
|
|
143
|
+
stats: {
|
|
144
|
+
strategy: "session-runtime-retention",
|
|
145
|
+
released,
|
|
146
|
+
savedChars,
|
|
147
|
+
saved: savedChars,
|
|
148
|
+
recentResults: Math.min(options.recentResults, resultIndexes.length),
|
|
149
|
+
retainedResultChars: options.retainedResultChars,
|
|
150
|
+
originalMessages: messages.length,
|
|
151
|
+
compressedMessages: output.length,
|
|
152
|
+
durableReferences,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -438,6 +438,34 @@ function readBooleanSetting(key, opts = {}) {
|
|
|
438
438
|
return value;
|
|
439
439
|
}
|
|
440
440
|
|
|
441
|
+
/**
|
|
442
|
+
* Read a string setting across the layered `.claude/settings.json` files.
|
|
443
|
+
* The closest layer wins and managed settings remain authoritative. Blank and
|
|
444
|
+
* non-string values are ignored so they cannot erase a valid lower layer.
|
|
445
|
+
*
|
|
446
|
+
* @param {string} key settings key or dotted path
|
|
447
|
+
* @param {object} [opts]
|
|
448
|
+
* @returns {string|undefined}
|
|
449
|
+
*/
|
|
450
|
+
function readStringSetting(key, opts = {}) {
|
|
451
|
+
const cwd = opts.cwd || process.cwd();
|
|
452
|
+
const parts = String(key).split(".");
|
|
453
|
+
let value;
|
|
454
|
+
const absorb = (data) => {
|
|
455
|
+
let node = data;
|
|
456
|
+
for (const part of parts) {
|
|
457
|
+
node = node && typeof node === "object" ? node[part] : undefined;
|
|
458
|
+
}
|
|
459
|
+
if (typeof node === "string" && node.trim()) value = node.trim();
|
|
460
|
+
};
|
|
461
|
+
for (const file of settingsPaths(cwd, opts.settingsFile)) {
|
|
462
|
+
absorb(readSettingsFile(file, { onWarn: opts.onWarn }));
|
|
463
|
+
}
|
|
464
|
+
const managed = loadManagedSettings(opts);
|
|
465
|
+
if (managed.settings) absorb(managed.settings);
|
|
466
|
+
return value;
|
|
467
|
+
}
|
|
468
|
+
|
|
441
469
|
/**
|
|
442
470
|
* Read a string-array setting across the layered `.claude/settings.json` files
|
|
443
471
|
* plus managed settings. Unlike {@link readBooleanSetting} (last-layer wins),
|
|
@@ -484,6 +512,7 @@ module.exports = {
|
|
|
484
512
|
loadSettingsConfig,
|
|
485
513
|
readSettingsFile,
|
|
486
514
|
readBooleanSetting,
|
|
515
|
+
readStringSetting,
|
|
487
516
|
readStringArraySetting,
|
|
488
517
|
settingsPaths,
|
|
489
518
|
managedSettingsPath,
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -185,6 +185,11 @@ import {
|
|
|
185
185
|
createPromptInteractionSurface,
|
|
186
186
|
mergeClipboardImageChips,
|
|
187
187
|
} from "./prompt-interactions.js";
|
|
188
|
+
import {
|
|
189
|
+
isReadlineWordRuboutKey,
|
|
190
|
+
readlineWordRubout,
|
|
191
|
+
resolveReplKeybindingFlavor,
|
|
192
|
+
} from "./repl-keybindings.js";
|
|
188
193
|
import { createSystemClipboardImageBinding } from "./clipboard-image.js";
|
|
189
194
|
import {
|
|
190
195
|
buildPermissionPrompt,
|
|
@@ -2760,15 +2765,11 @@ export async function runReplStartupBoundary(options, startupDependencies) {
|
|
|
2760
2765
|
"CC_REPL_STARTUP_DEPENDENCY_INVALID",
|
|
2761
2766
|
);
|
|
2762
2767
|
}
|
|
2763
|
-
const root = openBudgetRoot(
|
|
2764
|
-
|
|
2765
|
-
options.
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
signal: combineReplSignals(options.signal, leaseScope.lease.signal),
|
|
2769
|
-
table: options.sessionBudgetRoot.table,
|
|
2770
|
-
},
|
|
2771
|
-
);
|
|
2768
|
+
const root = openBudgetRoot(leaseSessionId, options.sessionBudgetRoot, {
|
|
2769
|
+
persist: true,
|
|
2770
|
+
signal: combineReplSignals(options.signal, leaseScope.lease.signal),
|
|
2771
|
+
table: options.sessionBudgetRoot.table,
|
|
2772
|
+
});
|
|
2772
2773
|
if (
|
|
2773
2774
|
root?.enabled !== true ||
|
|
2774
2775
|
!root.budget ||
|
|
@@ -2824,10 +2825,7 @@ export function startReplJsonlSession(
|
|
|
2824
2825
|
...meta,
|
|
2825
2826
|
...(observabilityScope != null ? { observabilityScope } : {}),
|
|
2826
2827
|
});
|
|
2827
|
-
if (
|
|
2828
|
-
requireDurable &&
|
|
2829
|
-
(typeof sessionId !== "string" || !sessionId)
|
|
2830
|
-
) {
|
|
2828
|
+
if (requireDurable && (typeof sessionId !== "string" || !sessionId)) {
|
|
2831
2829
|
throw new Error("JSONL session creation returned no durable session id");
|
|
2832
2830
|
}
|
|
2833
2831
|
return sessionId || null;
|
|
@@ -3187,6 +3185,7 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
3187
3185
|
let _visionModel;
|
|
3188
3186
|
let _promptInteractionConfig = {};
|
|
3189
3187
|
let _persistPromptSuggestionsEnabled = null;
|
|
3188
|
+
let _keybindingFlavor = "classic";
|
|
3190
3189
|
// Hard stream inactivity timeout override (config.llm.streamStallTimeoutMs,
|
|
3191
3190
|
// ms): a stream silent that long is aborted + retried instead of hanging.
|
|
3192
3191
|
// Unset → agent-core's 180s default (matches cc chat/ask). Set to 0 to
|
|
@@ -3218,6 +3217,23 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
3218
3217
|
} catch {
|
|
3219
3218
|
/* optional — resolveVisionLlm falls back to DEFAULT_VISION_MODEL */
|
|
3220
3219
|
}
|
|
3220
|
+
try {
|
|
3221
|
+
const { readStringSetting } = await import("../lib/settings-loader.cjs");
|
|
3222
|
+
const configuredFlavor = readStringSetting("keybindingFlavor", {
|
|
3223
|
+
cwd: process.cwd(),
|
|
3224
|
+
settingsFile: options.settingsFile || null,
|
|
3225
|
+
managedSettingsFile: options.managedSettingsFile || null,
|
|
3226
|
+
onWarn: (message) => logger.warn(message),
|
|
3227
|
+
});
|
|
3228
|
+
const resolvedFlavor = resolveReplKeybindingFlavor(configuredFlavor);
|
|
3229
|
+
_keybindingFlavor = resolvedFlavor.flavor;
|
|
3230
|
+
if (resolvedFlavor.error) {
|
|
3231
|
+
logger.warn(`settings: ${resolvedFlavor.error}; using classic`);
|
|
3232
|
+
}
|
|
3233
|
+
} catch (error) {
|
|
3234
|
+
if (error?.code === "CC_MANAGED_SETTINGS_INVALID") throw error;
|
|
3235
|
+
logger.warn(`settings: could not load keybindingFlavor (${error.message})`);
|
|
3236
|
+
}
|
|
3221
3237
|
// Extra workspace roots (--add-dir): advertised in the system prompt and
|
|
3222
3238
|
// spanned by search_files.
|
|
3223
3239
|
const additionalDirectories = Array.isArray(options.additionalDirectories)
|
|
@@ -3815,6 +3831,8 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
3815
3831
|
agentSessionId:
|
|
3816
3832
|
sessionId || `repl-${process.pid}-${Date.now().toString(36)}`,
|
|
3817
3833
|
isText: false, // the REPL prints its own pairing lines below
|
|
3834
|
+
allowLan: options.remoteControlAllowLan === true,
|
|
3835
|
+
env: process.env,
|
|
3818
3836
|
});
|
|
3819
3837
|
_remoteApproval = {
|
|
3820
3838
|
bridge: started.bridge,
|
|
@@ -5201,6 +5219,25 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
5201
5219
|
return;
|
|
5202
5220
|
}
|
|
5203
5221
|
|
|
5222
|
+
// 1.875) The opt-in readline flavor makes Ctrl+W a whitespace-delimited
|
|
5223
|
+
// unix-word-rubout. Classic stays byte-identical and lets Node readline
|
|
5224
|
+
// own the chord; Vim NORMAL mode continues to use the existing engine.
|
|
5225
|
+
if (
|
|
5226
|
+
!_turnAbort &&
|
|
5227
|
+
(!_vimEnabled || !_vim) &&
|
|
5228
|
+
_keybindingFlavor === "readline" &&
|
|
5229
|
+
isReadlineWordRuboutKey(_str, k)
|
|
5230
|
+
) {
|
|
5231
|
+
_consumeReadlineKeypress(key);
|
|
5232
|
+
const next = readlineWordRubout(rl.line, rl.cursor);
|
|
5233
|
+
if (next.changed) {
|
|
5234
|
+
rl.line = next.line;
|
|
5235
|
+
rl.cursor = next.cursor;
|
|
5236
|
+
rl._refreshLine?.();
|
|
5237
|
+
}
|
|
5238
|
+
return;
|
|
5239
|
+
}
|
|
5240
|
+
|
|
5204
5241
|
// 2) Vim mode: modal editing on the current input line.
|
|
5205
5242
|
if (_vimEnabled && !_turnAbort) {
|
|
5206
5243
|
if (!_vim) {
|
|
@@ -5625,7 +5662,7 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
5625
5662
|
` ${chalk.cyan("/voice")} Speech dictation — local-first STT (/voice hold|tap|off)`,
|
|
5626
5663
|
);
|
|
5627
5664
|
logger.log(
|
|
5628
|
-
` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; explanatory/learning built-in)`,
|
|
5665
|
+
` ${chalk.cyan("/output-style")} Response persona (/output-style <name|list>; concise/explanatory/learning built-in)`,
|
|
5629
5666
|
);
|
|
5630
5667
|
logger.log(
|
|
5631
5668
|
` ${chalk.cyan("/editor")} Edit a draft prompt in an external editor`,
|
|
@@ -14,15 +14,38 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @returns {string} the prompt header (no styling, no trailing "Proceed?")
|
|
16
16
|
*/
|
|
17
|
+
export function visualizePermissionText(value) {
|
|
18
|
+
return String(value ?? "").replace(
|
|
19
|
+
/[\u0000-\u001f\u007f-\u009f\u00ad\u034f\u061c\u115f\u1160\u17b4\u17b5\u180b-\u180f\u200b-\u200f\u202a-\u202e\u2060-\u206f\u3164\ufeff\uffa0]/gu,
|
|
20
|
+
(character) => {
|
|
21
|
+
if (character === "\t") return "<TAB>";
|
|
22
|
+
if (character === "\n") return "<LF>";
|
|
23
|
+
if (character === "\r") return "<CR>";
|
|
24
|
+
return `<U+${character.codePointAt(0).toString(16).toUpperCase().padStart(4, "0")}>`;
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
export function buildPermissionPrompt({ tool, args, rule, reason } = {}) {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const visibleTool = visualizePermissionText(tool);
|
|
31
|
+
const command = typeof args?.command === "string" ? args.command : "";
|
|
32
|
+
const source = args?.path ?? args?.file_path ?? args?.source ?? "";
|
|
33
|
+
const destination = args?.destination ?? args?.new_path ?? args?.to ?? "";
|
|
34
|
+
const rawDetail = command
|
|
35
|
+
? command
|
|
36
|
+
: source && destination
|
|
37
|
+
? `${source} -> ${destination}`
|
|
38
|
+
: source || destination;
|
|
39
|
+
const detail = rawDetail ? ` ${visualizePermissionText(rawDetail)}` : "";
|
|
40
|
+
if (rule) {
|
|
41
|
+
return `[Permission] rule "${visualizePermissionText(rule)}" asks before ${visibleTool}:${detail}`;
|
|
42
|
+
}
|
|
43
|
+
if (reason) {
|
|
44
|
+
const reasonText = String(reason);
|
|
45
|
+
const missingTarget = rawDetail && !reasonText.includes(String(rawDetail));
|
|
46
|
+
return `[Permission] ${visualizePermissionText(reasonText)}${missingTarget ? `:${detail}` : ""}`;
|
|
47
|
+
}
|
|
48
|
+
return `[Permission] confirm ${visibleTool}:${detail}`;
|
|
26
49
|
}
|
|
27
50
|
|
|
28
51
|
/**
|
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
/** Declarative, validated keybindings for interactive prompt actions. */
|
|
2
2
|
|
|
3
|
+
export const DEFAULT_REPL_KEYBINDING_FLAVOR = "classic";
|
|
4
|
+
export const REPL_KEYBINDING_FLAVORS = Object.freeze([
|
|
5
|
+
DEFAULT_REPL_KEYBINDING_FLAVOR,
|
|
6
|
+
"readline",
|
|
7
|
+
]);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the prompt editing flavor. Unknown values stay on the compatible
|
|
11
|
+
* classic behavior and include a diagnostic for the caller to surface.
|
|
12
|
+
*/
|
|
13
|
+
export function resolveReplKeybindingFlavor(value) {
|
|
14
|
+
if (value == null || String(value).trim() === "") {
|
|
15
|
+
return { flavor: DEFAULT_REPL_KEYBINDING_FLAVOR, error: null };
|
|
16
|
+
}
|
|
17
|
+
const flavor = String(value).trim().toLowerCase();
|
|
18
|
+
if (REPL_KEYBINDING_FLAVORS.includes(flavor)) {
|
|
19
|
+
return { flavor, error: null };
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
flavor: DEFAULT_REPL_KEYBINDING_FLAVOR,
|
|
23
|
+
error: `keybindingFlavor must be classic or readline (got "${String(value)}")`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** True for the terminal Ctrl+W chord used by readline's unix-word-rubout. */
|
|
28
|
+
export function isReadlineWordRuboutKey(input, key = {}) {
|
|
29
|
+
if (key.meta || key.alt || key.shift) return false;
|
|
30
|
+
const name = String(key.name || "").toLowerCase();
|
|
31
|
+
return (
|
|
32
|
+
key.ctrl === true &&
|
|
33
|
+
(name === "w" || input === "\u0017" || key.sequence === "\u0017")
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Delete the token immediately left of the cursor using whitespace-only word
|
|
39
|
+
* boundaries. This intentionally treats a full path as one token, unlike the
|
|
40
|
+
* classic path-segment behavior. Text right of the cursor is preserved.
|
|
41
|
+
*/
|
|
42
|
+
export function readlineWordRubout(line, cursor) {
|
|
43
|
+
const text = String(line || "");
|
|
44
|
+
const point = Math.max(
|
|
45
|
+
0,
|
|
46
|
+
Math.min(Number.isInteger(cursor) ? cursor : text.length, text.length),
|
|
47
|
+
);
|
|
48
|
+
let start = point;
|
|
49
|
+
while (start > 0 && /\s/u.test(text[start - 1])) start -= 1;
|
|
50
|
+
while (start > 0 && !/\s/u.test(text[start - 1])) start -= 1;
|
|
51
|
+
return {
|
|
52
|
+
line: text.slice(0, start) + text.slice(point),
|
|
53
|
+
cursor: start,
|
|
54
|
+
changed: start !== point,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
3
58
|
export const REPL_KEYBINDING_ACTIONS = Object.freeze([
|
|
4
59
|
"prompt.edit",
|
|
5
60
|
"prompt.stash",
|
|
@@ -136,6 +136,7 @@ import {
|
|
|
136
136
|
} from "../harness/structured-handoff.js";
|
|
137
137
|
import { isMcpRpcError } from "../harness/mcp-client.js";
|
|
138
138
|
import { projectCanonicalResumeMessages } from "../lib/session-message-provenance.js";
|
|
139
|
+
import { releaseOldLiveSessionResults } from "../lib/session-runtime-retention.js";
|
|
139
140
|
import {
|
|
140
141
|
pathMatchesOpenedFileIdentitySync,
|
|
141
142
|
sameOpenedFileIdentity,
|
|
@@ -12571,6 +12572,7 @@ async function _settleAutomaticCompaction({
|
|
|
12571
12572
|
compacted,
|
|
12572
12573
|
stats,
|
|
12573
12574
|
options,
|
|
12575
|
+
trigger = "auto",
|
|
12574
12576
|
}) {
|
|
12575
12577
|
if (!_sameMessageSnapshot(messages, liveExpectedMessages)) {
|
|
12576
12578
|
throw _compactionSettlementError(
|
|
@@ -12590,7 +12592,7 @@ async function _settleAutomaticCompaction({
|
|
|
12590
12592
|
settlement = options.onCompaction(stats, compacted, {
|
|
12591
12593
|
expectedMessages: authorityExpectedMessages,
|
|
12592
12594
|
liveExpectedMessages,
|
|
12593
|
-
trigger
|
|
12595
|
+
trigger,
|
|
12594
12596
|
});
|
|
12595
12597
|
} else if (options.sessionId && options.persistCompaction !== false) {
|
|
12596
12598
|
const store = await import("../harness/jsonl-session-store.js");
|
|
@@ -12605,7 +12607,7 @@ async function _settleAutomaticCompaction({
|
|
|
12605
12607
|
options.sessionId,
|
|
12606
12608
|
{
|
|
12607
12609
|
...stats,
|
|
12608
|
-
trigger
|
|
12610
|
+
trigger,
|
|
12609
12611
|
messages: projectCanonicalResumeMessages(compacted, { strict: true }),
|
|
12610
12612
|
},
|
|
12611
12613
|
authorityExpectedMessages,
|
|
@@ -13180,6 +13182,53 @@ export async function* agentLoop(messages, options) {
|
|
|
13180
13182
|
};
|
|
13181
13183
|
}
|
|
13182
13184
|
|
|
13185
|
+
// Release result bodies that have left the recent display window before
|
|
13186
|
+
// every provider admission, independent of the semantic-compaction token
|
|
13187
|
+
// threshold. Settlement persists a bounded resume checkpoint before the
|
|
13188
|
+
// live array changes; the earlier hash-chained result events remain the
|
|
13189
|
+
// durable evidence for audit/recovery.
|
|
13190
|
+
if (options.runtimeResultRetention !== false && messages.length > 32) {
|
|
13191
|
+
const retentionConfig =
|
|
13192
|
+
options.runtimeResultRetention &&
|
|
13193
|
+
typeof options.runtimeResultRetention === "object"
|
|
13194
|
+
? options.runtimeResultRetention
|
|
13195
|
+
: options.runtimeResultRetentionOptions;
|
|
13196
|
+
const retained = releaseOldLiveSessionResults(messages, retentionConfig);
|
|
13197
|
+
if (
|
|
13198
|
+
retained.stats.released > 0 &&
|
|
13199
|
+
!_sameMessageSnapshot(retained.messages, messages)
|
|
13200
|
+
) {
|
|
13201
|
+
const authorityExpectedMessages = [...messages];
|
|
13202
|
+
const liveExpectedMessages = [...messages];
|
|
13203
|
+
try {
|
|
13204
|
+
await _settleAutomaticCompaction({
|
|
13205
|
+
messages,
|
|
13206
|
+
liveExpectedMessages,
|
|
13207
|
+
authorityExpectedMessages,
|
|
13208
|
+
compacted: retained.messages,
|
|
13209
|
+
stats: retained.stats,
|
|
13210
|
+
options,
|
|
13211
|
+
trigger: "runtime-retention",
|
|
13212
|
+
});
|
|
13213
|
+
yield {
|
|
13214
|
+
type: "session-runtime-retention",
|
|
13215
|
+
runId,
|
|
13216
|
+
stats: retained.stats,
|
|
13217
|
+
};
|
|
13218
|
+
} catch (error) {
|
|
13219
|
+
yield {
|
|
13220
|
+
type: "session-runtime-retention-degraded",
|
|
13221
|
+
runId,
|
|
13222
|
+
reason:
|
|
13223
|
+
error?.code === "SESSION_REVISION_STALE"
|
|
13224
|
+
? "session_messages_changed_during_retention"
|
|
13225
|
+
: "canonical_retention_settlement_failed",
|
|
13226
|
+
code: error?.code || "CC_SESSION_RETENTION_SETTLEMENT_FAILED",
|
|
13227
|
+
};
|
|
13228
|
+
}
|
|
13229
|
+
}
|
|
13230
|
+
}
|
|
13231
|
+
|
|
13183
13232
|
// Headless auto-compaction (Claude-Code `--print` parity). Keeps long
|
|
13184
13233
|
// `-p` / `--resume` runs under the model's context window instead of
|
|
13185
13234
|
// growing until the provider rejects the request. Opt-out with
|