chainlesschain 0.165.4 → 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/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-C__nnraW.js → AIOps-vfoDb6HZ.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CsKWHEZ-.js → ActionButton-Cm5f7p93.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BhIjfjWO.js → Analytics-yRuvgWxa.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BjuXFzWZ.js → AppLayout-BROsC4h1.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-k6whDkZJ.js → Artifacts-CimHApb1.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-C4FBMYRh.js → Audit-DI8kr8zI.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C_vRrSXk.js → BackgroundAgents-DSLzKy-n.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CngFZeVp.js → Backup-DkH_n2r1.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B_H9EBRm.js → BaseInput-CKSrUoRA.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DLEC5kt7.js → Chat-ClwfMXUS.js} +3 -3
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CjMaqfL7.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-m3ClR4xh.js → Checkbox-BYTehcQG.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CmLSFrgp.js → Codegen-B8AMcp6J.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DFGQteHN.js → Col-BNSogPo3.js} +1 -1
- package/src/assets/web-panel/assets/{Community-EUUVORHE.js → Community-JxPvGb8O.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-2PSg0Yr7.js → Compact-DF7bFAgE.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CcKur7gB.js → Compliance-Bvhqnwrq.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DK_Fezfa.js → Cowork-BDS0CJvM.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Dbw89xl7.js → Cron-DqvRfxoQ.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CH66h_Ec.js → Crosschain-CDcIvnqS.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D1igRb17.js → DID-D7jaUxU3.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DVAsrobk.js → Dashboard-B5A18wEV.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Dl7W8AQs.js → Dropdown-_6IVkGag.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-D5tpaEQC.js → EmailListRenderer-C9PeiKCG.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-O_VQf8gq.js → FamilyGuardDashboard-DXjuEHrX.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BTVcgS9n.js → Federation-B4IAR9zv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BRnkJAIz.js → FormItemContext-CxQeSNx1.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-8OWSCkDj.js → GenericCardRenderer-B8GS-Y3N.js} +1 -1
- package/src/assets/web-panel/assets/{Git-WXLYTQj2.js → Git-BS8SouUX.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BezaUhtc.js → Governance-Dq9aYb5Q.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CuRay3Gu.js → Inference-BrCEe9AJ.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DfWLDW1m.js → KnowledgeGraph-DybOpiY2.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-C55y2pPY.js → Logs-DBpzbRfx.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-CFyt8iUd.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Dk08Uycg.js → Marketplace-Cc7CCSCu.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-C11fSB5V.js → McpTools-DFaIhOfu.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-mr0eZc97.js → Memory-KCqlp9ol.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-C0iCSRbb.js → MobileBridge-Bys84ySN.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CY-xMG8Z.js → MobileProjects-B-6qU-je.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-Bplqc_Wc.js → Mtc-BgY-fvCq.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-BlzwsoSM.js → MtcAudit-B8pCmqQJ.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BBLmTty6.js → Multisig-BbOmYutA.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DtT1uf1W.js → NLProgramming-BocLQz_M.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DcqQAxTK.js → Notes-CSwbxEop.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-cb0kWoZe.js → NotificationSettings-CqFNSYG3.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-kw9HZQNN.js → OrderTableRenderer-C6gMfAk7.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DlTlbkUN.js → Organization-QrDXVdMJ.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-pp1qs-oY.js → Overflow-Cxntotjt.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BESLnyYz.js → P2P-CIdBOwNq.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-B-J1mGuf.js → PdhVaultBrowser-CT5aP8rD.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-B36PeT1_.js → Permissions-DH7OM8XU.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CTK2ad-3.js → PersonalDataHub-CnJqbWce.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-zJNGXsac.js → Pipeline-5C3HG1kH.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-b9fz0Qf0.js → Privacy-B4yIp7xK.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DjZbZgiB.js → ProjectInit-BMvt-2M0.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C-hHJXlD.js → ProjectSettings-CvSTEMRG.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BKBJxEek.js +1 -0
- package/src/assets/web-panel/assets/Providers-BdwUqFWN.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-A0yoQ3-3.js → QrScannerModal-DtnCKlTm.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DrFgFJNC.js → QuickAsk-sTbgwyNr.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-KC8hF1g4.js → Recommend-Bzr14gSb.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DGTPIk6u.js → RemoteSession-C_TF5IaJ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-QmbwM7Yk.js → Reputation-GCAM4H2K.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BxjJylia.js → Row-Dir0r6OQ.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B7Wda1J6.js → RssFeed-CpGnlecX.js} +2 -2
- package/src/assets/web-panel/assets/{Search-_plQ_YSA.js → Search-DMMamC6u.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CD2YJZfx.js → Security-yqay5yG-.js} +4 -4
- package/src/assets/web-panel/assets/{Services-qQE7NmwE.js → Services-C5i2wh9G.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DgQqkFf7.js → Skeleton-vUqk35yj.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-C4C0oFFt.js → Skills-DzcSkhot.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Px2N2B5c.js → Sla-CB6qbYNr.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DN6C3lQd.js → SpeechSettings-BHUI7cox.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-jm5aH_m7.js → SyncSettings-D-RrsxTJ.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DlkJcv67.js → Tasks-DFxdOJiq.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DyrTHUBs.js → Templates-SKAob_Aq.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-mC434PtL.js → Tenant-BPfsfHQ-.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-o0_s3NgK.js → Terminal-8iw7FpUf.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DAGlAXOw.js → TimelineRenderer-C4Gjj5Su.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BnulS_bs.js → Tokens-COYhN18e.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-suQbVXYM.js → Trigger-B-JzXcf6.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DbIJAPo5.js → Trust-BJ5bg0nI.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CQNpbIHi.js → UkeySign-BG_ByRMf.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-D8aWCERk.js → VideoEditing-B3kOnSiU.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CuLpYfZc.js → Wallet-CcoGFnK7.js} +2 -2
- package/src/assets/web-panel/assets/{WebAuthn-CsfG8ZMc.js → WebAuthn-DdT8vRC_.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BYsEAZbd.js → WorkflowEditor-CZu3M9N8.js} +1 -1
- package/src/assets/web-panel/assets/{chat-FT4Um3-I.js → chat-DxJt3Qba.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CKbS_Wlt.js → colors-DdYfwJaB.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CFJtzuJM.js → compact-item-BG3SUzwj.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-B9kSRW6K.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-DR-x0Xpi.js → hasIn-B0apZ3KJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjEP7WkH.js → index-3jWkIu5j.js} +1 -1
- package/src/assets/web-panel/assets/{index-7jHr_A_k.js → index-B3rWuPMW.js} +1 -1
- package/src/assets/web-panel/assets/{index-DcfxhKXR.js → index-B5rLiEo0.js} +1 -1
- package/src/assets/web-panel/assets/{index-tqSEHPRT.js → index-BBPf3TpM.js} +1 -1
- package/src/assets/web-panel/assets/index-BETiL0a3.js +1 -0
- package/src/assets/web-panel/assets/{index-Cr2FLUsD.js → index-BIrJfqO4.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bt4fS2eL.js → index-BLIbGOLX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BwR7yc2h.js → index-BP94CrBV.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVPU43b1.js → index-BWF8_mkx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DShSkww-.js → index-BYINoRLK.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bzz0C1BZ.js → index-BZ_0qm4g.js} +1 -1
- package/src/assets/web-panel/assets/{index-KqDaCApw.js → index-BewKYrX9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BW-t9n-q.js → index-BfWYsB9t.js} +1 -1
- package/src/assets/web-panel/assets/index-BhAVHuW8.js +1 -0
- package/src/assets/web-panel/assets/{index-B7osrXqy.js → index-Bissefox.js} +3 -3
- package/src/assets/web-panel/assets/{index-DW4BWjTk.js → index-BkvcEo4p.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdkIhfi-.js → index-Bos5_aMV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTxNy0ZU.js → index-C1C9i79A.js} +1 -1
- package/src/assets/web-panel/assets/{index-QBSeNVO3.js → index-CAhHirVH.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4LfPvWA.js → index-CNIxXMmN.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_enk9I_.js → index-CW93tZDv.js} +1 -1
- package/src/assets/web-panel/assets/{index-WE08gMJP.js → index-CWEuZWCK.js} +1 -1
- package/src/assets/web-panel/assets/{index-r2VI1Ikk.js → index-Cp6e-hGw.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dap9c3eD.js → index-CpjZhgNd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWdqx7zI.js → index-CzmQElZy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGbPnC5x.js → index-DCn8IcxV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DiNUEpSQ.js → index-DE76D-kA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtkFqPVA.js → index-DaIz0NAW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGaXUsIs.js → index-Da_WBdLX.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3ZX81mK.js → index-Dz49VOyQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BK3TiKVq.js → index-Q2SCX-MI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJmIQ9XR.js → index-RD6O-0C6.js} +1 -1
- package/src/assets/web-panel/assets/{index-CvrCCqJt.js → index-SQqOlR3d.js} +1 -1
- package/src/assets/web-panel/assets/{index-BI5hP_qy.js → index-ZFbps9po.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeSgw-WV.js → index-ZxtP8jG7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DMGmg497.js → index-bP_VlDb4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfFCQHL3.js → index-kf57LJ93.js} +1 -1
- package/src/assets/web-panel/assets/{index-OSzjTzGM.js → index-oxRrmFO9.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2JvmYRc.js → index-p1_8SbI1.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Dd7n7VgI.js → initDefaultProps-BWJktcg8.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BwxouRw1.js → motion-BEXBzUFV.js} +1 -1
- package/src/assets/web-panel/assets/{move-DObN0PG9.js → move-BUKwn2sx.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-B3nOUQc7.js → mtc-parser-FTI7btqQ.js} +1 -1
- package/src/assets/web-panel/assets/{omit-o9WU2Nbl.js → omit-CsLtSPH3.js} +1 -1
- package/src/assets/web-panel/assets/parsers-YNLm7sQ0.js +4 -0
- package/src/assets/web-panel/assets/{pickAttrs-CL_vvfQ_.js → pickAttrs-DWZxsT_S.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CYrM2tyK.js → placementArrow-Bcfs43CX.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-k_06cQ96.js → responsiveObserve-a9bcC1p-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CPKG0pxS.js → slide-BDTzgOXN.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BDDEeLTw.js → statusUtils-Iq1j_HUg.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Cmb7RTh7.js → styleChecker-DAZEYxeh.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-e2IedC4N.js → useFlexGapSupport-DVkjyDrh.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CE_gxVnm.js → useFs-wXTpNTHt.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BkMIIKMz.js → usePersonalDataHub-CtQM_aZr.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DW886XV1.js → vnode-hjEoG85v.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Dwo_adaf.js → zoom-BHVpyKg_.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +14 -2
- package/src/commands/artifacts.js +235 -0
- package/src/commands/background-session.js +100 -10
- package/src/commands/cowork.js +86 -57
- 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-location.js +20 -1
- package/src/commands/session-message.js +171 -0
- package/src/commands/session.js +75 -69
- package/src/data/changelog.json +29 -3
- package/src/gateways/ws/message-dispatcher.js +57 -0
- package/src/harness/mcp-client.js +141 -10
- package/src/lib/artifact-access-ledger.js +1 -0
- package/src/lib/artifact-deletion-ledger.js +1 -0
- package/src/lib/artifact-recovery.js +970 -0
- package/src/lib/artifact-workbench-projection.js +171 -0
- package/src/lib/background-session-transport.js +153 -27
- package/src/lib/dynamic-workflow-runtime.js +408 -1
- package/src/lib/execution-location-target.js +4 -2
- 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-stdio-executable-identity.js +16 -0
- package/src/lib/mcp-stdio-native-code-policy.js +74 -0
- package/src/lib/mcp-stdio-package-materialization.js +12 -3
- 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/process-execution-broker/index.js +112 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +57 -3
- package/src/lib/process-execution-broker/workspace-transaction.js +26 -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 +171 -12
- 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 +63 -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-xijcWkJe.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-hDpWdiBc.js +0 -1
- package/src/assets/web-panel/assets/Projects-BC9KSDM6.js +0 -1
- package/src/assets/web-panel/assets/Providers-Dz-CAYYU.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DJZ0gAMu.js +0 -1
- package/src/assets/web-panel/assets/index-Bizb4hkw.js +0 -1
- package/src/assets/web-panel/assets/index-OHSl-xCh.js +0 -1
- package/src/assets/web-panel/assets/parsers-UEvh_ShA.js +0 -4
|
@@ -14,8 +14,8 @@ import {
|
|
|
14
14
|
SESSION_STATES,
|
|
15
15
|
} from "./session-lifecycle.js";
|
|
16
16
|
|
|
17
|
-
export const SESSION_PROJECTION_SCHEMA = "chainlesschain.session-projection/
|
|
18
|
-
export const SESSION_PROJECTION_VERSION =
|
|
17
|
+
export const SESSION_PROJECTION_SCHEMA = "chainlesschain.session-projection/v2";
|
|
18
|
+
export const SESSION_PROJECTION_VERSION = 2;
|
|
19
19
|
|
|
20
20
|
export const PROJECTION_KINDS = Object.freeze([
|
|
21
21
|
"local",
|
|
@@ -23,6 +23,7 @@ export const PROJECTION_KINDS = Object.freeze([
|
|
|
23
23
|
"remote",
|
|
24
24
|
"team",
|
|
25
25
|
"workflow",
|
|
26
|
+
"dynamic_workflow",
|
|
26
27
|
]);
|
|
27
28
|
|
|
28
29
|
export const PROJECTION_STATES = Object.freeze([
|
|
@@ -43,6 +44,9 @@ export const PROJECTION_ACTIONS = Object.freeze([
|
|
|
43
44
|
"stop",
|
|
44
45
|
"checkpoint",
|
|
45
46
|
"archive",
|
|
47
|
+
"pause",
|
|
48
|
+
"resume",
|
|
49
|
+
"recover",
|
|
46
50
|
]);
|
|
47
51
|
|
|
48
52
|
export const PROJECTION_ACTION_EXECUTORS = Object.freeze([
|
|
@@ -115,6 +119,7 @@ function sourceSessionId(source, fallback = null) {
|
|
|
115
119
|
asText(source?.sessionId) ||
|
|
116
120
|
asText(source?.agentSessionId) ||
|
|
117
121
|
asText(source?.remoteSessionId) ||
|
|
122
|
+
asText(source?.executionAuthoritySessionId) ||
|
|
118
123
|
fallback
|
|
119
124
|
);
|
|
120
125
|
}
|
|
@@ -214,6 +219,22 @@ function mapWorkflowState(source) {
|
|
|
214
219
|
return "working";
|
|
215
220
|
}
|
|
216
221
|
|
|
222
|
+
function mapDynamicWorkflowState(source) {
|
|
223
|
+
const status = String(source?.status || "")
|
|
224
|
+
.trim()
|
|
225
|
+
.toLowerCase();
|
|
226
|
+
if (status === "completed") return "done";
|
|
227
|
+
if (status === "stopped") return "stopped";
|
|
228
|
+
if (status === "failed") return "failed";
|
|
229
|
+
if (["input_requested", "needs_input"].includes(status)) {
|
|
230
|
+
return "needs_input";
|
|
231
|
+
}
|
|
232
|
+
if (["pause_requested", "paused", "blocked"].includes(status)) {
|
|
233
|
+
return "blocked";
|
|
234
|
+
}
|
|
235
|
+
return ["ready", "running"].includes(status) ? "working" : "failed";
|
|
236
|
+
}
|
|
237
|
+
|
|
217
238
|
function preview(executor, argv, { mutates = false, input = null } = {}) {
|
|
218
239
|
return {
|
|
219
240
|
executor,
|
|
@@ -290,6 +311,49 @@ function actionPreviews(kind, state, source, sourceId, linkedSessionId) {
|
|
|
290
311
|
"--cwd",
|
|
291
312
|
cwd,
|
|
292
313
|
]);
|
|
314
|
+
} else if (kind === "dynamic_workflow" && cwd) {
|
|
315
|
+
const expectedRevision = String(source?.revision || "");
|
|
316
|
+
const runtimeArgs = (action) => [
|
|
317
|
+
"cowork",
|
|
318
|
+
"workflow",
|
|
319
|
+
`runtime-${action}`,
|
|
320
|
+
sourceId,
|
|
321
|
+
"--expected-revision",
|
|
322
|
+
expectedRevision,
|
|
323
|
+
"--cwd",
|
|
324
|
+
cwd,
|
|
325
|
+
"--json",
|
|
326
|
+
];
|
|
327
|
+
routes.peek = preview("cli", [
|
|
328
|
+
"cowork",
|
|
329
|
+
"workflow",
|
|
330
|
+
"runtime-status",
|
|
331
|
+
sourceId,
|
|
332
|
+
"--cwd",
|
|
333
|
+
cwd,
|
|
334
|
+
"--json",
|
|
335
|
+
]);
|
|
336
|
+
if (
|
|
337
|
+
!TERMINAL_PROJECTION_STATES.has(state) &&
|
|
338
|
+
!["paused", "input_requested", "needs_input"].includes(source?.status)
|
|
339
|
+
) {
|
|
340
|
+
routes.pause = preview("cli", runtimeArgs("pause"), { mutates: true });
|
|
341
|
+
}
|
|
342
|
+
if (
|
|
343
|
+
["paused", "failed", "blocked"].includes(source?.status) &&
|
|
344
|
+
Number(source?.agents?.pending || 0) === 0 &&
|
|
345
|
+
Number(source?.input?.pending || 0) === 0
|
|
346
|
+
) {
|
|
347
|
+
routes.resume = preview("cli", runtimeArgs("resume"), { mutates: true });
|
|
348
|
+
}
|
|
349
|
+
if (!["completed", "stopped"].includes(source?.status)) {
|
|
350
|
+
routes.stop = preview("cli", runtimeArgs("stop"), { mutates: true });
|
|
351
|
+
}
|
|
352
|
+
if (Number(source?.recovery?.terminal || 0) > 0) {
|
|
353
|
+
routes.recover = preview("cli", runtimeArgs("recover-checkpoints"), {
|
|
354
|
+
mutates: true,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
293
357
|
}
|
|
294
358
|
|
|
295
359
|
if (checkpointAvailable) {
|
|
@@ -356,6 +420,18 @@ function actionAvailability(kind, state, source, sourceId, linkedSessionId) {
|
|
|
356
420
|
: kind === "workflow"
|
|
357
421
|
? "coding workflow state has no non-destructive archive route"
|
|
358
422
|
: "no non-destructive session archive capability is available",
|
|
423
|
+
pause:
|
|
424
|
+
kind === "dynamic_workflow"
|
|
425
|
+
? "workflow run cannot be paused in its current state"
|
|
426
|
+
: "pause is only supported by durable dynamic workflow runs",
|
|
427
|
+
resume:
|
|
428
|
+
kind === "dynamic_workflow"
|
|
429
|
+
? "workflow run has pending input/effects or is not resumable"
|
|
430
|
+
: "resume is only supported by durable dynamic workflow runs",
|
|
431
|
+
recover:
|
|
432
|
+
kind === "dynamic_workflow"
|
|
433
|
+
? "no terminal checkpoint recovery is currently available"
|
|
434
|
+
: "recovery is only supported by durable dynamic workflow runs",
|
|
359
435
|
};
|
|
360
436
|
|
|
361
437
|
return PROJECTION_ACTIONS.map((id) => {
|
|
@@ -464,6 +540,24 @@ function artifactSummary(sessionIds, artifacts) {
|
|
|
464
540
|
};
|
|
465
541
|
}
|
|
466
542
|
|
|
543
|
+
function dynamicWorkflowSummary(source) {
|
|
544
|
+
if (source?.schema !== "cc-dynamic-workflow-workbench-state/v1") return null;
|
|
545
|
+
return {
|
|
546
|
+
runtimeRevision: source.revision,
|
|
547
|
+
phase: source.phase,
|
|
548
|
+
agents: source.agents,
|
|
549
|
+
budget: source.budget,
|
|
550
|
+
artifacts: source.artifacts,
|
|
551
|
+
checkpoints: source.checkpoints,
|
|
552
|
+
recovery: source.recovery,
|
|
553
|
+
recoveryPolicy: source.recoveryPolicy,
|
|
554
|
+
recent: source.recent,
|
|
555
|
+
definitionDigest: source.definitionDigest,
|
|
556
|
+
admissionDigest: source.admissionDigest,
|
|
557
|
+
stateDigest: source.stateDigest,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
467
561
|
function prSummary(sessionIds, prLinks) {
|
|
468
562
|
const linked = [];
|
|
469
563
|
for (const sessionId of Array.isArray(sessionIds)
|
|
@@ -501,20 +595,57 @@ function approvalSummary(source, state) {
|
|
|
501
595
|
0,
|
|
502
596
|
);
|
|
503
597
|
}
|
|
598
|
+
if (source?.schema === "cc-dynamic-workflow-workbench-state/v1") {
|
|
599
|
+
count +=
|
|
600
|
+
asCount(source?.input?.pending) + asCount(source?.recovery?.terminal);
|
|
601
|
+
}
|
|
504
602
|
const needsInput = state === "needs_input";
|
|
505
603
|
return {
|
|
506
604
|
pending: needsInput || state === "blocked" || count > 0,
|
|
507
605
|
type: needsInput
|
|
508
606
|
? "input"
|
|
509
|
-
:
|
|
510
|
-
? "
|
|
511
|
-
: count > 0
|
|
512
|
-
? "
|
|
513
|
-
:
|
|
607
|
+
: source?.schema === "cc-dynamic-workflow-workbench-state/v1" && count > 0
|
|
608
|
+
? "recovery"
|
|
609
|
+
: Array.isArray(source?.units) && count > 0
|
|
610
|
+
? "adjudication"
|
|
611
|
+
: count > 0
|
|
612
|
+
? "approval"
|
|
613
|
+
: null,
|
|
514
614
|
count,
|
|
515
615
|
};
|
|
516
616
|
}
|
|
517
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
|
+
|
|
518
649
|
function lastEventFor(source, state) {
|
|
519
650
|
const at =
|
|
520
651
|
toIso(source?.lastEvent?.at) ||
|
|
@@ -529,7 +660,11 @@ function lastEventFor(source, state) {
|
|
|
529
660
|
};
|
|
530
661
|
}
|
|
531
662
|
|
|
532
|
-
function projectOne(
|
|
663
|
+
function projectOne(
|
|
664
|
+
kind,
|
|
665
|
+
source,
|
|
666
|
+
{ artifacts, prLinks, sessionMessageFabric },
|
|
667
|
+
) {
|
|
533
668
|
let sourceId;
|
|
534
669
|
if (kind === "remote") {
|
|
535
670
|
const stateFile = asText(source?.stateFile);
|
|
@@ -552,7 +687,9 @@ function projectOne(kind, source, { artifacts, prLinks }) {
|
|
|
552
687
|
if (kind === "local") state = "stopped";
|
|
553
688
|
else if (kind === "team") state = mapTeamState(source);
|
|
554
689
|
else if (kind === "workflow") state = mapWorkflowState(source);
|
|
555
|
-
else if (kind === "
|
|
690
|
+
else if (kind === "dynamic_workflow") {
|
|
691
|
+
state = mapDynamicWorkflowState(source);
|
|
692
|
+
} else if (kind === "remote") {
|
|
556
693
|
state = source?.invalid ? "failed" : source?.alive ? "working" : "stopped";
|
|
557
694
|
} else state = mapLifecycleState(source);
|
|
558
695
|
|
|
@@ -583,7 +720,9 @@ function projectOne(kind, source, { artifacts, prLinks }) {
|
|
|
583
720
|
? `Team run ${sourceId}`
|
|
584
721
|
: kind === "workflow"
|
|
585
722
|
? `Workflow ${sourceId}`
|
|
586
|
-
:
|
|
723
|
+
: kind === "dynamic_workflow"
|
|
724
|
+
? `Dynamic workflow ${source?.workflowId || sourceId}`
|
|
725
|
+
: `${kind} ${sourceId}`),
|
|
587
726
|
capabilities: actions
|
|
588
727
|
.filter((action) => action.available)
|
|
589
728
|
.map((action) => action.id),
|
|
@@ -592,9 +731,14 @@ function projectOne(kind, source, { artifacts, prLinks }) {
|
|
|
592
731
|
owner: ownerSummary(source, kind),
|
|
593
732
|
environment: environmentSummary(source, kind),
|
|
594
733
|
worktree: worktreeSummary(source),
|
|
595
|
-
artifact:
|
|
734
|
+
artifact:
|
|
735
|
+
kind === "dynamic_workflow"
|
|
736
|
+
? { count: asCount(source?.artifacts?.count), latest: null }
|
|
737
|
+
: artifactSummary(linkedSessionIds, artifacts),
|
|
596
738
|
approval: approvalSummary(source, state),
|
|
739
|
+
messaging: messagingSummary(linkedSessionIds, sessionMessageFabric),
|
|
597
740
|
pr: prSummary(linkedSessionIds, prLinks),
|
|
741
|
+
workflow: dynamicWorkflowSummary(source),
|
|
598
742
|
lastEvent: lastEventFor(source, state),
|
|
599
743
|
};
|
|
600
744
|
return { ...projected, revision: projectionRevision(projected) };
|
|
@@ -615,12 +759,14 @@ export function buildSessionProjection({
|
|
|
615
759
|
remote = [],
|
|
616
760
|
team = [],
|
|
617
761
|
workflow = [],
|
|
762
|
+
dynamicWorkflow = [],
|
|
618
763
|
artifacts = [],
|
|
619
764
|
prLinks = {},
|
|
765
|
+
sessionMessageFabric = null,
|
|
620
766
|
sourceErrors = {},
|
|
621
767
|
generatedAt = new Date().toISOString(),
|
|
622
768
|
} = {}) {
|
|
623
|
-
const context = { artifacts, prLinks };
|
|
769
|
+
const context = { artifacts, prLinks, sessionMessageFabric };
|
|
624
770
|
const sessions = [
|
|
625
771
|
...(Array.isArray(local) ? local : []).map((source) =>
|
|
626
772
|
projectOne("local", source, context),
|
|
@@ -637,6 +783,9 @@ export function buildSessionProjection({
|
|
|
637
783
|
...(Array.isArray(workflow) ? workflow : []).map((source) =>
|
|
638
784
|
projectOne("workflow", source, context),
|
|
639
785
|
),
|
|
786
|
+
...(Array.isArray(dynamicWorkflow) ? dynamicWorkflow : []).map((source) =>
|
|
787
|
+
projectOne("dynamic_workflow", source, context),
|
|
788
|
+
),
|
|
640
789
|
].sort((left, right) => {
|
|
641
790
|
const priority = { needs_input: 0, blocked: 1, working: 2 };
|
|
642
791
|
const rank = (item) => priority[item.state] ?? 3;
|
|
@@ -669,6 +818,16 @@ export function buildSessionProjection({
|
|
|
669
818
|
Array.isArray(workflow) ? workflow.length : 0,
|
|
670
819
|
sourceErrors.workflow,
|
|
671
820
|
),
|
|
821
|
+
dynamicWorkflow: sourceStatus(
|
|
822
|
+
Array.isArray(dynamicWorkflow) ? dynamicWorkflow.length : 0,
|
|
823
|
+
sourceErrors.dynamicWorkflow,
|
|
824
|
+
),
|
|
825
|
+
sessionMessageFabric: sourceStatus(
|
|
826
|
+
Array.isArray(sessionMessageFabric?.endpoints)
|
|
827
|
+
? sessionMessageFabric.endpoints.length
|
|
828
|
+
: 0,
|
|
829
|
+
sourceErrors.sessionMessageFabric,
|
|
830
|
+
),
|
|
672
831
|
};
|
|
673
832
|
const revision = projectionRevision({
|
|
674
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
|
/**
|