chainlesschain 0.162.188 → 0.162.193
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/README.md +61 -11
- package/bin/chainlesschain.js +7 -52
- package/completions/_cc +209 -0
- package/completions/cc.bash +18 -0
- package/completions/cc.fish +13 -0
- package/completions/cc.ps1 +226 -0
- package/package.json +10 -2
- package/src/assets/web-panel/assets/{AIOps-Brr1LVcE.js → AIOps-DBLkaTje.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DQU74DKG.js → ActionButton-BAy-Qebo.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CYp9178y.js → Analytics-Dfb1Mlau.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DW4SCYsW.js → AppLayout-BbFkN8m0.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CYlD_ed1.js → Artifacts-kM4-cEEH.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CWl1rZOi.js → Audit-BSQfYWf3.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BOR-LPsa.js → BackgroundAgents-CWDbI_fG.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DLpG7j1X.js → Backup-BxLPbq_Q.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B35K9wdr.js → BaseInput-DuIbdrp6.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CwUJb9gB.js → Chat-NEmjGahU.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-1v6aMS1m.js → ChatBubbleRenderer-DfJEo-5_.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-pi3-tPNW.js → Checkbox-CaoeG3Ns.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-FyNF35eL.js → Codegen-BFf_g3xY.js} +1 -1
- package/src/assets/web-panel/assets/{Col-tGt_JDEr.js → Col-CNOd8mdQ.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CC7LonQX.js → Community-BhpDqz-i.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BGXrHHjE.js → Compact-CQ42T7Z6.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DSW0TBZ8.js → Compliance-DI5PcLMN.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Bhk7rbvE.js → Cowork-wYYZe0wR.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DxyiQ2NZ.js → Cron-Dlq03DD_.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B2ZkxHok.js → Crosschain-BzqS8PP3.js} +1 -1
- package/src/assets/web-panel/assets/{DID-yOJV99eJ.js → DID-It55Yem7.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CKsttz7D.js → Dashboard-9HkH6oxn.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CVFldXSL.js → Dropdown-00e2YWRB.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Bufv638J.js → EmailListRenderer-By-ugRDL.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-4ncjoIjL.js → FamilyGuardDashboard-C396yu5m.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DsknEDoX.js → Federation-BME5sbZY.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Cqe5jWXA.js → FormItemContext-B4TEZCr-.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-NAJaFKxc.js → GenericCardRenderer-_9CX9ieY.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CszKQpnl.js → Git-BrS6WVSr.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BXGodXi6.js → Governance-BMdCWnKF.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CkoYuG2c.js → Inference-Bcp3vzcA.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DFlEr_T0.js → KnowledgeGraph-DlLuqGY5.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CVaENddA.js → Logs-D-W_6x09.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DElGPxCZ.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CDlLT0fw.js → Marketplace-Dzn2guvI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DdwOyszN.js → McpTools-uPict-KL.js} +6 -6
- package/src/assets/web-panel/assets/{Memory-DKQnkKuG.js → Memory-BCw43kOb.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DGseqlzJ.js → MobileBridge-DmV8Wv7F.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-COBbEOlj.js → MobileProjects-C-HaCmSM.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-O61Vwyli.js → Mtc-C6jxJ34Y.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-Dw2SyasS.js → MtcAudit-Za8ExwhQ.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-hSu_l8kf.js → Multisig-KKDbuEgb.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CX1Epurr.js → NLProgramming-Dj97zbCk.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-R9xX8o8_.js → Notes-DBXvMraU.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-jtSNLCuK.js → NotificationSettings-DOxITLYl.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-7DVjZwMM.js +1 -0
- package/src/assets/web-panel/assets/{Organization-Pu2WO-U3.js → Organization-D1i73mjb.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BjnqUyFp.js → Overflow-kW6Q3rvg.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-jjkvz44c.js → P2P-C-v_8p2v.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-tUbbY64W.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-D4yDpivd.js → Permissions-DkHxEZ58.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-0qsL6iH1.js → PersonalDataHub-DWuMPGrK.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-Cx7Ybrk2.js → Pipeline-30IYXWWm.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-PbfR_M_V.js → Privacy-DZNQ4RrH.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CyV6Gsub.js → ProjectInit-De2MCElf.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C7KZ2Wdk.js → ProjectSettings-5uHk9wsC.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DQDjO-yK.js → Projects-XjDfrFLb.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DyFVBBMX.js → Providers-Bgwj6gcE.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CzB1BC9_.js → QrScannerModal-gKql9umv.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Bk636mC1.js → QuickAsk-BWvmwkh7.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DoWxHIT3.js → Recommend-Uok4hZPd.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-oOVIv9wq.js → RemoteSession-DLJzTk9a.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-BucoReGG.js → Reputation-ZVwIPMSO.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DzmOdJU7.js → Row-CN04HxWR.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C1tK7KGU.js → RssFeed-BdSrEG4g.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CSnInOqk.js → Search-5PwVd0IR.js} +1 -1
- package/src/assets/web-panel/assets/{Security-dlejr15l.js → Security-DdBo4zjN.js} +3 -3
- package/src/assets/web-panel/assets/{Services-BioPZuNh.js → Services-D3letU7M.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DWMibwpC.js → Skeleton--Jb83f1v.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BAAnx1B2.js → Skills-Bg-CulHX.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-jWNp4hNO.js → Sla-7QOa7S-X.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-y5kqKha-.js → SpeechSettings-DQwppjRw.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B9GNsc3e.js → SyncSettings-dNPQGL-s.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BDBYKRen.js → Tasks-Ggs-Z48q.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DRiE5eaN.js → Templates-78TYHgRO.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BGlAvExF.js → Tenant-xHwwv9vO.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B8uzrbNY.js → Terminal-BJXSJfm4.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-Df48iveY.js → TimelineRenderer-fLbjRhJw.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CcmHndN6.js → Tokens-oMSBSBmB.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DPkWxmQ2.js → Trigger-CfnY_wX_.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DTb5a5AV.js → Trust-AdyTgYKO.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CBmg5vch.js → UkeySign-C5K_81dS.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B0mZrz4O.js → VideoEditing-vcGVDqki.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Bxs7_mpd.js → Wallet-hhOc3hlY.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C8x3cMxU.js → WebAuthn-CVloC11s.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-DPrNznrP.js → WorkflowEditor-CYeE32R5.js} +1 -1
- package/src/assets/web-panel/assets/{chat-D3bYWu7S.js → chat-CNROR5bN.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DY-PwMu4.js → colors-Cjx-cnwU.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-LDk10Kw6.js → compact-item-DOIfelvD.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C-2MZnFq.js → createContext-DfA7UZ8u.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BQIBjcnB.js → hasIn-BMSCzcfM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQVb2dWp.js → index-5-HXgOX5.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdXnYMCZ.js → index-AWg-0M1S.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cx6D_dx2.js → index-B4iYzpkL.js} +1 -1
- package/src/assets/web-panel/assets/{index-_HRO_cIu.js → index-B5Udeb_6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlRYqt3S.js → index-B7gf77CJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BrnRO9yE.js → index-BEMwBBHk.js} +1 -1
- package/src/assets/web-panel/assets/{index-VCh5zNJo.js → index-BM1y_9hM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRI3ngNg.js → index-BUonmKSE.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3GNvExG.js → index-BbQ2eQ8H.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSvo_bp0.js → index-BemJ2u_E.js} +1 -1
- package/src/assets/web-panel/assets/{index-L6qixyLc.js → index-BolaOQxx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BI4KgcYC.js → index-BxOk9vkG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CY4KnaO9.js → index-By61ojUx.js} +1 -1
- package/src/assets/web-panel/assets/{index-L3smcoQX.js → index-C2K9SNVX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BX2b9Orc.js → index-C3L5gdiD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cz4b6Z_7.js → index-C7xn0Nub.js} +1 -1
- package/src/assets/web-panel/assets/{index-COG61sRv.js → index-CAnvhwg6.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7FC8cP2.js → index-CEKMcOyU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BN-xdSWZ.js → index-CNC5onm4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DY2FIrmz.js → index-CVL27kXC.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiTvBAr-.js → index-CVm1_i3t.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhRt9cYJ.js → index-CdYBye8B.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5pgtZnY.js → index-ClNMrqEY.js} +1 -1
- package/src/assets/web-panel/assets/{index-7xKu7Fns.js → index-Cs6l7uRu.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4K1weKc.js → index-CshQbilz.js} +1 -1
- package/src/assets/web-panel/assets/{index-k7C_oDCO.js → index-Cyweh0Hy.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3Oq-DLL.js → index-DBpWXFed.js} +3 -3
- package/src/assets/web-panel/assets/{index-DYyLJPlF.js → index-DHtpHZAQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dh-tkpKQ.js → index-DLmn0BoK.js} +1 -1
- package/src/assets/web-panel/assets/{index-8JC9BJa1.js → index-DPAWBrMf.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dd2Km97U.js → index-DjEsxO5h.js} +1 -1
- package/src/assets/web-panel/assets/{index-KFZO_lcx.js → index-FBc_CJBd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTIZpPtG.js → index-Icdoqmzt.js} +1 -1
- package/src/assets/web-panel/assets/index-Q2IajL54.js +1 -0
- package/src/assets/web-panel/assets/index-bRkHgOMc.js +1 -0
- package/src/assets/web-panel/assets/{index-lmm9p-jm.js → index-dCd8cSUq.js} +1 -1
- package/src/assets/web-panel/assets/{index-HasPt4-h.js → index-m2vG9gG_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaslYch6.js → index-mTpHoEzr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbR6ROOa.js → index-ti_lnTWl.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-zQPSHf2C.js → initDefaultProps-Bu8k7H1Y.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CKCStGVk.js → motion-s3iVK41k.js} +1 -1
- package/src/assets/web-panel/assets/{move-BufVDGYF.js → move-B6B-E5Jz.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DcaFxy5D.js → mtc-parser-BiYgTidA.js} +1 -1
- package/src/assets/web-panel/assets/{omit-EScpkGdo.js → omit-pU1RdUDA.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-72hG_qfT.js → pickAttrs-Cdoq_SeM.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CMFWiH20.js → placementArrow-DIuvAn2K.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DKQHS41p.js → responsiveObserve-8w16YR2D.js} +1 -1
- package/src/assets/web-panel/assets/{slide-QVAFHTIQ.js → slide-VZ01cZe3.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DIz38e2G.js → statusUtils-lh8YMN8Z.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-zK5cyLby.js → styleChecker-CmDyreec.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DhZngk62.js → useFlexGapSupport-hiJWMU5y.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BvV2cvkg.js → useFs-Thnu-Iaj.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CRmxb9l3.js → usePersonalDataHub-LBdOxjwY.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CgQIbobP.js → vnode-Cg6lFY_X.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D4XrrO0R.js → zoom-DVfsR1YO.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/cli-help.js +181 -0
- package/src/command-help-index.json +181 -0
- package/src/command-manifest.json +1107 -175
- package/src/command-surface-policy.js +197 -0
- package/src/commands/agent.js +98 -33
- package/src/commands/artifacts.js +400 -2
- package/src/commands/background-session.js +41 -3
- package/src/commands/checkpoint-managed.js +1059 -0
- package/src/commands/checkpoint-restore-recovery.js +1476 -0
- package/src/commands/checkpoint.js +950 -22
- package/src/commands/compact.js +101 -25
- package/src/commands/config.js +506 -20
- package/src/commands/doctor.js +4 -1
- package/src/commands/hub.js +1 -1
- package/src/commands/mcp.js +688 -24
- package/src/commands/pack.js +16 -2
- package/src/commands/plugin.js +20 -12
- package/src/commands/session-mcp-recovery.js +218 -0
- package/src/commands/session.js +470 -110
- package/src/commands/setup.js +36 -10
- package/src/commands/skill.js +181 -110
- package/src/commands/status.js +21 -5
- package/src/commands/team-distributed.js +3324 -0
- package/src/commands/team.js +1130 -74
- package/src/commands/update.js +68 -6
- package/src/constants.js +11 -0
- package/src/data/changelog.json +26 -0
- package/src/gateways/ws/action-protocol.js +10 -0
- package/src/gateways/ws/session-protocol.js +555 -27
- package/src/gateways/ws/ws-agent-handler.js +541 -14
- package/src/gateways/ws/ws-session-gateway.js +129 -22
- package/src/gateways/ws/ws-session-state.js +431 -0
- package/src/harness/background-task-manager.js +233 -36
- package/src/harness/jsonl-session-store.js +2551 -167
- package/src/harness/mcp-client.js +802 -61
- package/src/harness/prompt-compressor.js +227 -27
- package/src/harness/session-index.js +89 -38
- package/src/harness/session-list-index.js +254 -0
- package/src/harness/structured-handoff.js +410 -0
- package/src/lazy-dispatch.js +747 -84
- package/src/lib/__tests__/logger.test.js +50 -2
- package/src/lib/advisor-runtime.js +1047 -0
- package/src/lib/agent-core.js +2 -0
- package/src/lib/agent-sandbox.js +120 -26
- package/src/lib/agent-session-export.js +20 -0
- package/src/lib/agent-team/task-lease.js +271 -3
- package/src/lib/agent-team/team-adjudication.js +1501 -0
- package/src/lib/agent-team/team-budget.js +4 -1
- package/src/lib/agent-team/team-control-store.js +582 -0
- package/src/lib/agent-team/team-distributed-queue.js +5246 -0
- package/src/lib/agent-team/team-process-checkpoint.js +211 -0
- package/src/lib/agent-team/team-runner.js +543 -24
- package/src/lib/agent-team/team-worktree.js +1403 -95
- package/src/lib/artifact-store.js +131 -8
- package/src/lib/background-agent-supervisor.js +185 -13
- package/src/lib/background-interaction-journal.js +37 -9
- package/src/lib/background-launch-profile.js +1058 -0
- package/src/lib/checkpoint-restore-already-completed-controller.js +902 -0
- package/src/lib/checkpoint-restore-orchestrator.js +987 -0
- package/src/lib/checkpoint-restore-partial-rollback-controller.js +1953 -0
- package/src/lib/checkpoint-restore-recovery-controller.js +689 -0
- package/src/lib/checkpoint-restore-recovery.js +884 -0
- package/src/lib/checkpoint-restore-retention.js +126 -0
- package/src/lib/checkpoint-restore-saga.js +5079 -0
- package/src/lib/checkpoint-restore-session-recovery.js +1178 -0
- package/src/lib/checkpoint-restore-workspace-target-verifier.js +270 -0
- package/src/lib/checkpoint-store.js +1688 -97
- package/src/lib/checkpoint-timeline-authority.js +522 -0
- package/src/lib/checkpoint-timeline.js +642 -0
- package/src/lib/config-keys.js +18 -119
- package/src/lib/config-manager.js +446 -27
- package/src/lib/config-redaction.js +57 -0
- package/src/lib/config-schema.js +853 -0
- package/src/lib/cowork-mcp-tools.js +5 -0
- package/src/lib/cowork-task-runner.js +458 -63
- package/src/lib/delivery-coordinator.js +1234 -0
- package/src/lib/delivery-evidence.js +450 -0
- package/src/lib/doctor-checkup.js +199 -14
- package/src/lib/executable-path.js +34 -0
- package/src/lib/fatal-handler.js +16 -0
- package/src/lib/file-checkpoint.js +4909 -186
- package/src/lib/file-lines.js +125 -0
- package/src/lib/headless-config-command.js +16 -5
- package/src/lib/hook-runner.cjs +139 -38
- package/src/lib/hooks-v2-workspace-context.js +10 -0
- package/src/lib/impacted-gate-selector.js +424 -0
- package/src/lib/interaction-adapter.js +62 -0
- package/src/lib/jsonl-session-store.js +1 -35
- package/src/lib/logger.js +66 -14
- package/src/lib/managed-checkpoint-render.js +60 -0
- package/src/lib/managed-tool-checkpoint.js +194 -0
- package/src/lib/mcp-call-ledger-store.js +1069 -0
- package/src/lib/mcp-call-ledger.js +747 -0
- package/src/lib/mcp-client.js +5 -0
- package/src/lib/mcp-conflict-scheduler.js +468 -0
- package/src/lib/mcp-effect-contract.js +102 -0
- package/src/lib/mcp-headers-helper-trust.js +145 -0
- package/src/lib/mcp-headers-helper.js +616 -0
- package/src/lib/mcp-host-recovery-runtime.js +131 -0
- package/src/lib/mcp-ledger-recovery-admission.js +1065 -0
- package/src/lib/mcp-recovery-adjudication.js +443 -0
- package/src/lib/output-context.js +86 -0
- package/src/lib/packer/file-identity.js +170 -0
- package/src/lib/packer/index.js +3 -0
- package/src/lib/packer/native-update-state.js +277 -0
- package/src/lib/packer/pack-update-applier.js +1983 -136
- package/src/lib/packer/pack-update-checker.js +34 -0
- package/src/lib/packer/pack-update-downloader.js +875 -86
- package/src/lib/packer/pack-update-signature.js +86 -0
- package/src/lib/packer/pkg-config-generator.js +6 -0
- package/src/lib/paths.js +65 -10
- package/src/lib/plan-mode.js +831 -14
- package/src/lib/plan-persistence.js +540 -0
- package/src/lib/plugin-runtime/hooks.js +227 -69
- package/src/lib/plugin-runtime/plugin-options.js +189 -44
- package/src/lib/pr-automation-policy.js +146 -8
- package/src/lib/process-execution-broker/credential-agent.js +7 -0
- package/src/lib/process-execution-broker/index.js +491 -13
- package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +28 -1
- package/src/lib/process-execution-broker/linux-generic-bwrap.js +28 -4
- package/src/lib/process-execution-broker/platform-sandbox.js +92 -70
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +284 -19
- package/src/lib/process-execution-broker/workspace-transaction.js +4459 -0
- package/src/lib/project-instructions.js +165 -29
- package/src/lib/project-mcp-trust.js +67 -0
- package/src/lib/public-ide-capability-manifest.js +272 -0
- package/src/lib/public-ide-capability-validation.js +351 -0
- package/src/lib/secret-store.js +267 -43
- package/src/lib/secure-file-identity.js +433 -0
- package/src/lib/secure-fs.js +1089 -0
- package/src/lib/security-audit.js +58 -0
- package/src/lib/service-manager.js +34 -13
- package/src/lib/session-budget-runtime.js +1452 -0
- package/src/lib/session-host-snapshot.js +388 -0
- package/src/lib/session-message-provenance.js +429 -0
- package/src/lib/session-projection.js +804 -0
- package/src/lib/session-resource-budget.js +1495 -0
- package/src/lib/settings-hooks.cjs +138 -22
- package/src/lib/settings-loader.cjs +25 -2
- package/src/lib/side-effect-ledger-store.js +45 -23
- package/src/lib/skill-execution-identity.js +217 -0
- package/src/lib/skill-loader.js +299 -18
- package/src/lib/sub-agent-context.js +236 -28
- package/src/lib/sub-agent-registry.js +5 -0
- package/src/lib/subagent-contract.js +94 -0
- package/src/lib/todo-manager.js +185 -18
- package/src/lib/todo-persistence.js +417 -0
- package/src/lib/turn-binding-store.js +41 -23
- package/src/lib/turn-binding.js +160 -2
- package/src/lib/with-file-lock.js +165 -24
- package/src/lib/ws-chat-handler.js +21 -0
- package/src/program-base.js +18 -0
- package/src/repl/advisor-command.js +103 -0
- package/src/repl/agent-repl.js +2175 -146
- package/src/repl/btw-command.js +93 -10
- package/src/repl/clipboard-image.js +119 -0
- package/src/repl/config-summary.js +64 -108
- package/src/repl/prompt-editor.js +233 -0
- package/src/repl/prompt-interactions.js +344 -0
- package/src/repl/prompt-stash.js +354 -0
- package/src/repl/prompt-suggestions.js +312 -0
- package/src/repl/repl-keybindings.js +227 -0
- package/src/repl/session-recap.js +217 -0
- package/src/repl/slash-command-registry.js +22 -0
- package/src/repl/terminal-layout.js +88 -0
- package/src/runtime/agent-core.js +1630 -447
- package/src/runtime/coding-agent-contract-shared.cjs +13 -1
- package/src/runtime/coding-agent-managed-tool-policy.cjs +7 -2
- package/src/runtime/diagnostics.js +32 -13
- package/src/runtime/headless-runner.js +310 -118
- package/src/runtime/headless-stream.js +356 -95
- package/src/runtime/mcp-config.js +148 -14
- package/src/runtime/policies/agent-policy.js +14 -0
- package/src/runtime/status-diagnostics-lite.js +137 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-7iWGwZ-r.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-BU2Yqq5H.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-69ca_WeR.js +0 -7
- package/src/assets/web-panel/assets/devWarning-B4dXIJqD.js +0 -1
- package/src/assets/web-panel/assets/index-C-C7DaG6.js +0 -1
- package/src/assets/web-panel/assets/index-DkfWzWtd.js +0 -1
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* - bypassPermissions → AUTOPILOT (everything allowed)
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
+
import { randomUUID } from "node:crypto";
|
|
25
26
|
import { bootstrap } from "./bootstrap.js";
|
|
26
27
|
import {
|
|
27
28
|
buildSystemPrompt,
|
|
@@ -46,7 +47,10 @@ import {
|
|
|
46
47
|
appendLlmRetryCompact as jsonlAppendLlmRetryCompact,
|
|
47
48
|
appendCompactEvent as jsonlAppendCompactEvent,
|
|
48
49
|
appendEvent as jsonlAppendEvent,
|
|
50
|
+
appendAuthorityEvent as jsonlAppendAuthorityEvent,
|
|
49
51
|
readEvents as jsonlReadEvents,
|
|
52
|
+
readVerifiedEvents as jsonlReadVerifiedEvents,
|
|
53
|
+
findLatestEvent as jsonlFindLatestEvent,
|
|
50
54
|
rebuildMessages as jsonlRebuildMessages,
|
|
51
55
|
sessionExists as jsonlSessionExists,
|
|
52
56
|
getLastSessionId as jsonlGetLastSessionId,
|
|
@@ -60,6 +64,13 @@ import {
|
|
|
60
64
|
} from "../lib/side-effect-ledger.js";
|
|
61
65
|
import { DiffReviewFollowUpTracker } from "../lib/diff-review-follow-up.js";
|
|
62
66
|
import { SIDE_EFFECT_LEDGER_EVENT } from "../lib/side-effect-ledger-store.js";
|
|
67
|
+
import {
|
|
68
|
+
createSessionMcpLedgerSink,
|
|
69
|
+
formatMcpLedgerRecoveryNotice,
|
|
70
|
+
loadMcpLedgerRecovery,
|
|
71
|
+
} from "../lib/mcp-call-ledger-store.js";
|
|
72
|
+
import { createMcpHostRecoveryRuntime } from "../lib/mcp-host-recovery-runtime.js";
|
|
73
|
+
import { readSessionHostResumeState } from "../lib/session-host-snapshot.js";
|
|
63
74
|
import { TurnBindingLog, createTurnBindingFeed } from "../lib/turn-binding.js";
|
|
64
75
|
import { TURN_BINDING_EVENT } from "../lib/turn-binding-store.js";
|
|
65
76
|
import { operationIdempotencyKey } from "../lib/idempotency.js";
|
|
@@ -99,6 +110,7 @@ import {
|
|
|
99
110
|
} from "../lib/repl-denials.js";
|
|
100
111
|
import executionBroker from "../lib/process-execution-broker/index.js";
|
|
101
112
|
import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
|
|
113
|
+
import { formatManagedCheckpointEvent } from "../lib/managed-checkpoint-render.js";
|
|
102
114
|
|
|
103
115
|
const goalBrokerRunner = executionBroker.spawnSync.bind(executionBroker);
|
|
104
116
|
|
|
@@ -295,7 +307,7 @@ export function resolveHeadlessSession(options = {}, store = {}, fallbackId) {
|
|
|
295
307
|
* apart from the injected store's side effect; both `sessionExists`/`forkSession`
|
|
296
308
|
* are injection seams so this is unit-testable without disk.
|
|
297
309
|
*
|
|
298
|
-
* @param {{forkSession?:boolean, sessionId?:string|null}} opts
|
|
310
|
+
* @param {{forkSession?:boolean, sessionId?:string|null, forkRequestId?:string}} opts
|
|
299
311
|
* @param {{sessionExists?:Function, forkSession?:Function}} store
|
|
300
312
|
* @returns {{ sessionId:string|null, forkedFrom:string|null, missing:boolean }}
|
|
301
313
|
*/
|
|
@@ -306,8 +318,14 @@ export function applyForkSession(opts = {}, store = {}) {
|
|
|
306
318
|
if (typeof store.sessionExists === "function" && !store.sessionExists(id)) {
|
|
307
319
|
return { sessionId: id, forkedFrom: null, missing: true };
|
|
308
320
|
}
|
|
321
|
+
const requestId =
|
|
322
|
+
typeof opts.forkRequestId === "string" && opts.forkRequestId.length > 0
|
|
323
|
+
? opts.forkRequestId
|
|
324
|
+
: `cli-${randomUUID()}`;
|
|
309
325
|
const newId =
|
|
310
|
-
typeof store.forkSession === "function"
|
|
326
|
+
typeof store.forkSession === "function"
|
|
327
|
+
? store.forkSession(id, { requestId })
|
|
328
|
+
: null;
|
|
311
329
|
if (!newId) return { sessionId: id, forkedFrom: null, missing: false };
|
|
312
330
|
return { sessionId: newId, forkedFrom: id, missing: false };
|
|
313
331
|
}
|
|
@@ -341,7 +359,7 @@ export function applyForkSession(opts = {}, store = {}) {
|
|
|
341
359
|
* @param {boolean} [options.expandFileRefs=true] Expand `@path` file references
|
|
342
360
|
* in the prompt into context blocks.
|
|
343
361
|
* @param {object} [deps] Injection seam for tests.
|
|
344
|
-
* @returns {Promise<{ exitCode:number, result:string, isError:boolean }>}
|
|
362
|
+
* @returns {Promise<{ exitCode:number, result:string, isError:boolean, sessionSnapshot?:object }>}
|
|
345
363
|
*/
|
|
346
364
|
export async function runAgentHeadless(options = {}, deps = {}) {
|
|
347
365
|
const trustedWorkspaceRoot = options.cwd || process.cwd();
|
|
@@ -365,6 +383,80 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
365
383
|
);
|
|
366
384
|
}
|
|
367
385
|
|
|
386
|
+
const isStream = outputFormat === "stream-json";
|
|
387
|
+
const isJson = outputFormat === "json";
|
|
388
|
+
const isText = outputFormat === "text";
|
|
389
|
+
const writeOut = deps.writeOut || ((s) => process.stdout.write(s));
|
|
390
|
+
const writeErr = deps.writeErr || ((s) => process.stderr.write(s));
|
|
391
|
+
if (!deps.writeOut && !deps.writeErr) installPipeSafety();
|
|
392
|
+
|
|
393
|
+
const hasInjectedSessionStore =
|
|
394
|
+
typeof deps.sessionExists === "function" ||
|
|
395
|
+
typeof deps.rebuildMessages === "function" ||
|
|
396
|
+
typeof deps.appendEvent === "function" ||
|
|
397
|
+
typeof deps.appendAuthorityEvent === "function" ||
|
|
398
|
+
typeof deps.readVerifiedEvents === "function";
|
|
399
|
+
const { sessionId, resumeId, persist } = resolveHeadlessSession(
|
|
400
|
+
options,
|
|
401
|
+
{ getLastSessionId: deps.getLastSessionId || jsonlGetLastSessionId },
|
|
402
|
+
`headless-${Date.now()}-${process.pid}`,
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
const emitHeadlessError = (resultMsg) => {
|
|
406
|
+
if (isStream) {
|
|
407
|
+
writeOut(
|
|
408
|
+
JSON.stringify({
|
|
409
|
+
type: "result",
|
|
410
|
+
subtype: "error",
|
|
411
|
+
is_error: true,
|
|
412
|
+
error: resultMsg,
|
|
413
|
+
}) + "\n",
|
|
414
|
+
);
|
|
415
|
+
} else if (isJson) {
|
|
416
|
+
writeOut(
|
|
417
|
+
JSON.stringify(
|
|
418
|
+
buildResultEnvelope({
|
|
419
|
+
subtype: "error",
|
|
420
|
+
isError: true,
|
|
421
|
+
result: resultMsg,
|
|
422
|
+
sessionId,
|
|
423
|
+
toolCalls: [],
|
|
424
|
+
usage: {},
|
|
425
|
+
numTurns: 0,
|
|
426
|
+
durationMs: 0,
|
|
427
|
+
}),
|
|
428
|
+
) + "\n",
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
// Resume authority is the first host boundary after argument validation.
|
|
434
|
+
// In particular this precedes /config writes, slash-macro bang expansion,
|
|
435
|
+
// settings/plugin loading, bootstrap, model access, hooks, MCP and tools.
|
|
436
|
+
const canReadCanonicalResume =
|
|
437
|
+
!hasInjectedSessionStore || typeof deps.readVerifiedEvents === "function";
|
|
438
|
+
const canonicalResume =
|
|
439
|
+
resumeId && canReadCanonicalResume
|
|
440
|
+
? readSessionHostResumeState(resumeId, {
|
|
441
|
+
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
442
|
+
readVerifiedEvents:
|
|
443
|
+
deps.readVerifiedEvents || jsonlReadVerifiedEvents,
|
|
444
|
+
})
|
|
445
|
+
: null;
|
|
446
|
+
if (canonicalResume && !canonicalResume.snapshot.verified) {
|
|
447
|
+
const message =
|
|
448
|
+
"CC_SESSION_HOST_SNAPSHOT_UNVERIFIED: canonical JSONL session is not " +
|
|
449
|
+
"fully verified; resume was refused";
|
|
450
|
+
emitHeadlessError(message);
|
|
451
|
+
writeErr(`${message}\n`);
|
|
452
|
+
return {
|
|
453
|
+
exitCode: 1,
|
|
454
|
+
result: message,
|
|
455
|
+
isError: true,
|
|
456
|
+
sessionSnapshot: canonicalResume.snapshot,
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
368
460
|
// `let` (not const): a custom-command macro's `model:` frontmatter may
|
|
369
461
|
// override it below (when the user passed no explicit --model), mirroring
|
|
370
462
|
// `cc command run`.
|
|
@@ -418,16 +510,20 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
418
510
|
let settingsHooks = options.settingsHooks || null;
|
|
419
511
|
if (!settingsHooks) {
|
|
420
512
|
try {
|
|
421
|
-
const { loadHooks, projectHookTrustNotice } =
|
|
513
|
+
const { loadHooks, projectHookTrustNotice, attachAuthorityErrors } =
|
|
422
514
|
await import("../lib/settings-hooks.cjs");
|
|
423
515
|
const loaded = loadHooks({ cwd, settingsFile: options.settingsFile });
|
|
424
516
|
// Fold in installed plugins' hooks/hooks.json (Phase 3.3c) — plugins ADD
|
|
425
517
|
// to the user's settings hooks, never replace them.
|
|
426
518
|
const { mergePluginHooks } =
|
|
427
519
|
await import("../lib/plugin-runtime/hooks.js");
|
|
428
|
-
const effectiveHooks = mergePluginHooks(
|
|
520
|
+
const effectiveHooks = mergePluginHooks(
|
|
521
|
+
attachAuthorityErrors(loaded.hooks, loaded.authorityErrors),
|
|
522
|
+
{ cwd },
|
|
523
|
+
);
|
|
429
524
|
settingsHooks =
|
|
430
|
-
|
|
525
|
+
Object.keys(effectiveHooks).length > 0 ||
|
|
526
|
+
effectiveHooks._authorityErrors.length > 0
|
|
431
527
|
? effectiveHooks
|
|
432
528
|
: null;
|
|
433
529
|
// First-run trust notice for an untrusted/cloned repo's shell-running
|
|
@@ -441,8 +537,17 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
441
537
|
} catch {
|
|
442
538
|
/* trust notice is best-effort */
|
|
443
539
|
}
|
|
444
|
-
} catch {
|
|
445
|
-
settingsHooks =
|
|
540
|
+
} catch (error) {
|
|
541
|
+
settingsHooks = {};
|
|
542
|
+
Object.defineProperty(settingsHooks, "_authorityErrors", {
|
|
543
|
+
value: Object.freeze([
|
|
544
|
+
Object.freeze({
|
|
545
|
+
sourceFile: null,
|
|
546
|
+
code: error?.code || "CC_HOOK_AUTHORITY_LOAD_FAILED",
|
|
547
|
+
}),
|
|
548
|
+
]),
|
|
549
|
+
enumerable: false,
|
|
550
|
+
});
|
|
446
551
|
}
|
|
447
552
|
}
|
|
448
553
|
|
|
@@ -493,18 +598,36 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
493
598
|
const m = await import("../lib/session-core-singletons.js");
|
|
494
599
|
return m.getApprovalGate();
|
|
495
600
|
});
|
|
496
|
-
// stdout carries the machine-consumable payload; stderr carries the human
|
|
497
|
-
// trace so `cc agent -p ... > out.txt` keeps `out.txt` clean.
|
|
498
|
-
const writeOut = deps.writeOut || ((s) => process.stdout.write(s));
|
|
499
|
-
const writeErr = deps.writeErr || ((s) => process.stderr.write(s));
|
|
500
|
-
// Only when we own the real stdout/stderr (no injected seams = production,
|
|
501
|
-
// not tests): guard against a downstream `| head` closing the pipe, which
|
|
502
|
-
// would otherwise crash with an unhandled EPIPE. Idempotent across calls.
|
|
503
|
-
if (!deps.writeOut && !deps.writeErr) {
|
|
504
|
-
installPipeSafety();
|
|
505
|
-
}
|
|
506
601
|
// Session persistence seam (file-based JSONL; DB-free, like the rest of
|
|
507
602
|
// headless). Defaults to the real store; tests inject fakes.
|
|
603
|
+
const storeReadEvents = deps.readEvents || jsonlReadEvents;
|
|
604
|
+
const unavailableAuthorityCapability = (operation) => () => {
|
|
605
|
+
const error = new Error(
|
|
606
|
+
`Injected session store must provide ${operation} for MCP authority`,
|
|
607
|
+
);
|
|
608
|
+
error.code = "SESSION_AUTHORITY_CAPABILITY_UNAVAILABLE";
|
|
609
|
+
throw error;
|
|
610
|
+
};
|
|
611
|
+
const storeFindLatestEvent =
|
|
612
|
+
deps.findLatestEvent ||
|
|
613
|
+
(deps.readEvents
|
|
614
|
+
? (sessionId, type, predicate = null) => {
|
|
615
|
+
const events = storeReadEvents(sessionId) || [];
|
|
616
|
+
const wanted = Array.isArray(type) ? new Set(type) : null;
|
|
617
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
618
|
+
const event = events[index];
|
|
619
|
+
const typeMatches = wanted
|
|
620
|
+
? wanted.has(event?.type)
|
|
621
|
+
: type == null || event?.type === type;
|
|
622
|
+
if (!typeMatches) continue;
|
|
623
|
+
if (typeof predicate === "function" && !predicate(event)) continue;
|
|
624
|
+
return event;
|
|
625
|
+
}
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
: hasInjectedSessionStore
|
|
629
|
+
? () => null
|
|
630
|
+
: jsonlFindLatestEvent);
|
|
508
631
|
const store = {
|
|
509
632
|
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
510
633
|
rebuildMessages: deps.rebuildMessages || jsonlRebuildMessages,
|
|
@@ -514,19 +637,34 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
514
637
|
deps.appendAssistantMessage || jsonlAppendAssistantMessage,
|
|
515
638
|
appendTokenUsage: deps.appendTokenUsage || jsonlAppendTokenUsage,
|
|
516
639
|
appendToolCallCompact:
|
|
517
|
-
deps.appendToolCallCompact ||
|
|
640
|
+
deps.appendToolCallCompact ||
|
|
641
|
+
(hasInjectedSessionStore ? () => true : jsonlAppendToolCallCompact),
|
|
518
642
|
appendLlmRetryCompact:
|
|
519
|
-
deps.appendLlmRetryCompact ||
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
643
|
+
deps.appendLlmRetryCompact ||
|
|
644
|
+
(hasInjectedSessionStore ? () => true : jsonlAppendLlmRetryCompact),
|
|
645
|
+
appendCompactEvent:
|
|
646
|
+
deps.appendCompactEvent ||
|
|
647
|
+
(hasInjectedSessionStore ? () => true : jsonlAppendCompactEvent),
|
|
648
|
+
appendEvent:
|
|
649
|
+
deps.appendEvent ||
|
|
650
|
+
(hasInjectedSessionStore ? () => true : jsonlAppendEvent),
|
|
651
|
+
appendAuthorityEvent:
|
|
652
|
+
deps.appendAuthorityEvent ||
|
|
653
|
+
(hasInjectedSessionStore
|
|
654
|
+
? unavailableAuthorityCapability("appendAuthorityEvent")
|
|
655
|
+
: jsonlAppendAuthorityEvent),
|
|
656
|
+
readEvents: storeReadEvents,
|
|
657
|
+
readVerifiedEvents:
|
|
658
|
+
deps.readVerifiedEvents ||
|
|
659
|
+
(hasInjectedSessionStore
|
|
660
|
+
? unavailableAuthorityCapability("readVerifiedEvents")
|
|
661
|
+
: jsonlReadVerifiedEvents),
|
|
662
|
+
findLatestEvent: storeFindLatestEvent,
|
|
523
663
|
getLastSessionId: deps.getLastSessionId || jsonlGetLastSessionId,
|
|
524
|
-
verifySession:
|
|
664
|
+
verifySession:
|
|
665
|
+
deps.verifySession ||
|
|
666
|
+
(hasInjectedSessionStore ? () => null : jsonlVerifySession),
|
|
525
667
|
};
|
|
526
|
-
const isStream = outputFormat === "stream-json";
|
|
527
|
-
const isJson = outputFormat === "json";
|
|
528
|
-
const isText = outputFormat === "text";
|
|
529
|
-
|
|
530
668
|
// ── Headless `/config` directive (Claude-Code 2.1.181: /config in -p mode) ──
|
|
531
669
|
// A leading `/config …` prompt is a one-shot config get/set/show, not a task
|
|
532
670
|
// for the LLM — handled before bootstrap/session/model so it never spends a
|
|
@@ -571,6 +709,10 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
571
709
|
return { exitCode: isError ? 1 : 0, result: text, isError };
|
|
572
710
|
}
|
|
573
711
|
|
|
712
|
+
if (options.continueSession === true && !resumeId && isText) {
|
|
713
|
+
writeErr("No previous session to continue; starting a new one.\n");
|
|
714
|
+
}
|
|
715
|
+
|
|
574
716
|
// ── Custom slash-command macros (Claude-Code parity: a .claude/commands/*
|
|
575
717
|
// command runs in `-p` mode too, not just the interactive REPL). A leading
|
|
576
718
|
// `/name …` that resolves to a user/project command is expanded into its
|
|
@@ -661,50 +803,6 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
661
803
|
// Continue without DB — static-prompt fallback.
|
|
662
804
|
}
|
|
663
805
|
|
|
664
|
-
// ── Resolve session continuity (--resume / --continue) ─────────────────
|
|
665
|
-
const { sessionId, resumeId, persist } = resolveHeadlessSession(
|
|
666
|
-
options,
|
|
667
|
-
store,
|
|
668
|
-
`headless-${Date.now()}-${process.pid}`,
|
|
669
|
-
);
|
|
670
|
-
if (options.continueSession === true && !resumeId && isText) {
|
|
671
|
-
writeErr("No previous session to continue; starting a new one.\n");
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
// Machine-readable modes (`--output-format json` / `stream-json`) must ALWAYS
|
|
675
|
-
// end with a terminal result envelope — a consumer parsing stdout otherwise
|
|
676
|
-
// gets nothing and can't tell success from failure. Several setup-phase error
|
|
677
|
-
// paths below early-return BEFORE the main loop's try/catch envelope (and
|
|
678
|
-
// before `system/init`), so route them through this so stdout is never empty.
|
|
679
|
-
// No-op in text mode (those paths already writeErr a human message).
|
|
680
|
-
const emitHeadlessError = (resultMsg) => {
|
|
681
|
-
if (isStream) {
|
|
682
|
-
writeOut(
|
|
683
|
-
JSON.stringify({
|
|
684
|
-
type: "result",
|
|
685
|
-
subtype: "error",
|
|
686
|
-
is_error: true,
|
|
687
|
-
error: resultMsg,
|
|
688
|
-
}) + "\n",
|
|
689
|
-
);
|
|
690
|
-
} else if (isJson) {
|
|
691
|
-
writeOut(
|
|
692
|
-
JSON.stringify(
|
|
693
|
-
buildResultEnvelope({
|
|
694
|
-
subtype: "error",
|
|
695
|
-
isError: true,
|
|
696
|
-
result: resultMsg,
|
|
697
|
-
sessionId,
|
|
698
|
-
toolCalls: [],
|
|
699
|
-
usage: {},
|
|
700
|
-
numTurns: 0,
|
|
701
|
-
durationMs: 0,
|
|
702
|
-
}),
|
|
703
|
-
) + "\n",
|
|
704
|
-
);
|
|
705
|
-
}
|
|
706
|
-
};
|
|
707
|
-
|
|
708
806
|
const setupHooks = await executeLifecycleHooks(
|
|
709
807
|
"Setup",
|
|
710
808
|
{
|
|
@@ -747,15 +845,19 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
747
845
|
}
|
|
748
846
|
userContent = expansion.prompt;
|
|
749
847
|
|
|
750
|
-
// Load prior conversation when resuming an existing session. The fresh
|
|
751
|
-
// system prompt always leads;
|
|
752
|
-
//
|
|
848
|
+
// Load prior conversation when resuming an existing session. The fresh host
|
|
849
|
+
// system prompt always leads; all system turns from the same verified
|
|
850
|
+
// canonical sample follow it (including compact checkpoint summaries).
|
|
753
851
|
let history = [];
|
|
754
|
-
if (
|
|
755
|
-
|
|
852
|
+
if (canonicalResume) {
|
|
853
|
+
history = canonicalResume.messages.filter(Boolean);
|
|
854
|
+
} else if (resumeId && store.sessionExists(resumeId)) {
|
|
855
|
+
// Compatibility gate for injected stores without a verified event reader.
|
|
856
|
+
// Real JSONL resumes were handled above and never reach this branch. A
|
|
857
|
+
// broken transcript hash chain means the file was edited
|
|
756
858
|
// outside the store. Headless runs fail closed — a tampered transcript is
|
|
757
859
|
// never silently rebuilt into trusted model context. Escape hatch:
|
|
758
|
-
// CC_ALLOW_TAMPERED_RESUME=1
|
|
860
|
+
// CC_ALLOW_TAMPERED_RESUME=1 is retained only for this injected-store path.
|
|
759
861
|
let trust = null;
|
|
760
862
|
try {
|
|
761
863
|
trust = store.verifySession(resumeId);
|
|
@@ -825,6 +927,9 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
825
927
|
let sideEffectSeq = 0;
|
|
826
928
|
let currentSideEffectOpId = null;
|
|
827
929
|
let resumeSideEffectContext = null;
|
|
930
|
+
let resumeMcpCallContext = null;
|
|
931
|
+
let resumeMcpRecovery = null;
|
|
932
|
+
let resumeMcpRecoveryError = null;
|
|
828
933
|
let resumeAsyncHookContext = null;
|
|
829
934
|
const persistSideEffectLedger = () => {
|
|
830
935
|
if (!persist) return;
|
|
@@ -862,18 +967,13 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
862
967
|
let turnBindingLoadError = null;
|
|
863
968
|
if (persist) {
|
|
864
969
|
try {
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
Array.isArray(e.data.turns)
|
|
873
|
-
) {
|
|
874
|
-
turnBindingLog = TurnBindingLog.fromJSON(e.data);
|
|
875
|
-
break;
|
|
876
|
-
}
|
|
970
|
+
const event = store.findLatestEvent(
|
|
971
|
+
sessionId,
|
|
972
|
+
TURN_BINDING_EVENT,
|
|
973
|
+
(candidate) => Array.isArray(candidate?.data?.turns),
|
|
974
|
+
);
|
|
975
|
+
if (event) {
|
|
976
|
+
turnBindingLog = TurnBindingLog.fromJSON(event.data);
|
|
877
977
|
}
|
|
878
978
|
} catch (cause) {
|
|
879
979
|
const error = new Error(
|
|
@@ -918,20 +1018,15 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
918
1018
|
};
|
|
919
1019
|
if (persist) {
|
|
920
1020
|
try {
|
|
921
|
-
const
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
)
|
|
930
|
-
sideEffectLedger = SideEffectLedger.fromJSON(e.data, {
|
|
931
|
-
clock: deps.now || null,
|
|
932
|
-
});
|
|
933
|
-
break;
|
|
934
|
-
}
|
|
1021
|
+
const event = store.findLatestEvent(
|
|
1022
|
+
sessionId,
|
|
1023
|
+
SIDE_EFFECT_LEDGER_EVENT,
|
|
1024
|
+
(candidate) => Array.isArray(candidate?.data?.ops),
|
|
1025
|
+
);
|
|
1026
|
+
if (event) {
|
|
1027
|
+
sideEffectLedger = SideEffectLedger.fromJSON(event.data, {
|
|
1028
|
+
clock: deps.now || null,
|
|
1029
|
+
});
|
|
935
1030
|
}
|
|
936
1031
|
} catch (cause) {
|
|
937
1032
|
const error = new Error(
|
|
@@ -978,6 +1073,41 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
978
1073
|
} catch {
|
|
979
1074
|
resumeSideEffectContext = null;
|
|
980
1075
|
}
|
|
1076
|
+
// MCP calls have their own content-free started/settled ledger. A
|
|
1077
|
+
// started-only record means the external server may have completed the
|
|
1078
|
+
// operation before the process died, so replay must stop for inspection.
|
|
1079
|
+
try {
|
|
1080
|
+
const mcpRecovery =
|
|
1081
|
+
canonicalResume?.recovery ||
|
|
1082
|
+
loadMcpLedgerRecovery(resumeId, {
|
|
1083
|
+
readVerifiedEvents: store.readVerifiedEvents,
|
|
1084
|
+
});
|
|
1085
|
+
resumeMcpRecovery = mcpRecovery;
|
|
1086
|
+
resumeMcpCallContext = formatMcpLedgerRecoveryNotice(mcpRecovery);
|
|
1087
|
+
if (resumeMcpCallContext) {
|
|
1088
|
+
const risky = mcpRecovery.unsettled.filter(
|
|
1089
|
+
(record) => record.effectContract?.effect !== "read",
|
|
1090
|
+
).length;
|
|
1091
|
+
writeErr(
|
|
1092
|
+
`⚠ ${mcpRecovery.unsettled.length} interrupted MCP call(s) and ${mcpRecovery.incidents.length} ledger incident(s) require inspection before replay (resume ${resumeId}).\n`,
|
|
1093
|
+
);
|
|
1094
|
+
if (risky > 0 || mcpRecovery.incidents.length > 0) {
|
|
1095
|
+
_bgPhase.reportUncertainSideEffects(
|
|
1096
|
+
risky + mcpRecovery.incidents.length,
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
resumeMcpRecoveryError = error;
|
|
1102
|
+
resumeMcpCallContext =
|
|
1103
|
+
"MCP recovery notice — the durable MCP call ledger could not be read. " +
|
|
1104
|
+
"Do not execute or retry MCP tools until the session transcript has " +
|
|
1105
|
+
`been inspected (${error?.code || "CC_MCP_LEDGER_EVENT_READ_FAILED"}).`;
|
|
1106
|
+
writeErr(
|
|
1107
|
+
`⚠ MCP ledger recovery failed closed for resume ${resumeId}; MCP calls require inspection.\n`,
|
|
1108
|
+
);
|
|
1109
|
+
_bgPhase.reportUncertainSideEffects(1);
|
|
1110
|
+
}
|
|
981
1111
|
// On resume, recover any async-hook REWAKE (a background check that opted
|
|
982
1112
|
// in and FAILED) that the previous run parked but died before draining —
|
|
983
1113
|
// surface it to the model instead of silently swallowing the failure. The
|
|
@@ -1232,6 +1362,9 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1232
1362
|
...(resumeSideEffectContext
|
|
1233
1363
|
? [{ role: "system", content: resumeSideEffectContext }]
|
|
1234
1364
|
: []),
|
|
1365
|
+
...(resumeMcpCallContext
|
|
1366
|
+
? [{ role: "system", content: resumeMcpCallContext }]
|
|
1367
|
+
: []),
|
|
1235
1368
|
...(resumeAsyncHookContext
|
|
1236
1369
|
? [{ role: "system", content: resumeAsyncHookContext }]
|
|
1237
1370
|
: []),
|
|
@@ -1328,18 +1461,33 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1328
1461
|
}
|
|
1329
1462
|
}
|
|
1330
1463
|
|
|
1464
|
+
const mcpRecoveryRuntime = createMcpHostRecoveryRuntime({
|
|
1465
|
+
bundle: mcp,
|
|
1466
|
+
sessionId,
|
|
1467
|
+
sink: persist
|
|
1468
|
+
? createSessionMcpLedgerSink(sessionId, {
|
|
1469
|
+
appendEvent: store.appendAuthorityEvent,
|
|
1470
|
+
})
|
|
1471
|
+
: null,
|
|
1472
|
+
recovery: resumeMcpRecovery,
|
|
1473
|
+
recoveryError: resumeMcpRecoveryError,
|
|
1474
|
+
});
|
|
1475
|
+
const hostMcp = mcp
|
|
1476
|
+
? { ...mcp, mcpClient: mcpRecoveryRuntime.client || mcp.mcpClient }
|
|
1477
|
+
: null;
|
|
1478
|
+
|
|
1331
1479
|
// Seed MCP roots for --add-dir (Claude-Code roots/list_changed parity): a
|
|
1332
1480
|
// headless session started with extra workspace roots must advertise the FULL
|
|
1333
1481
|
// root list to connected MCP servers, exactly like the REPL /add-dir path —
|
|
1334
1482
|
// otherwise a server's roots/list only ever sees the cwd. Only meaningful when
|
|
1335
1483
|
// extra roots exist (setRoots fires only when the list actually changes); no
|
|
1336
1484
|
// --add-dir → workspaceRootDirs = [cwd] and this is a no-op. Best-effort.
|
|
1337
|
-
if (
|
|
1485
|
+
if (hostMcp?.mcpClient && additionalDirectories.length > 0) {
|
|
1338
1486
|
try {
|
|
1339
1487
|
const { notifyMcpRootsChanged, workspaceRootDirs } =
|
|
1340
1488
|
await import("../repl/add-dir.js");
|
|
1341
1489
|
notifyMcpRootsChanged(
|
|
1342
|
-
[
|
|
1490
|
+
[hostMcp.mcpClient],
|
|
1343
1491
|
workspaceRootDirs(options.cwd || process.cwd(), additionalDirectories),
|
|
1344
1492
|
);
|
|
1345
1493
|
} catch {
|
|
@@ -1357,7 +1505,7 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1357
1505
|
await import("../lib/ide-context.js");
|
|
1358
1506
|
const last = messages[messages.length - 1];
|
|
1359
1507
|
const ideCtx = await (deps.buildIdePromptContext || buildIdePromptContext)(
|
|
1360
|
-
|
|
1508
|
+
hostMcp,
|
|
1361
1509
|
);
|
|
1362
1510
|
if (ideCtx) {
|
|
1363
1511
|
last.content = appendTextToContent(last.content, ideCtx);
|
|
@@ -1366,7 +1514,7 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1366
1514
|
// (Claude-Code parity). Scan the ORIGINAL prompt so injected file-ref
|
|
1367
1515
|
// blocks can't spoof a mention; append the expansion to the in-flight
|
|
1368
1516
|
// message only (ephemeral, like the ambient block above).
|
|
1369
|
-
const mentioned = await expandIdeMentions(prompt,
|
|
1517
|
+
const mentioned = await expandIdeMentions(prompt, hostMcp);
|
|
1370
1518
|
for (const w of mentioned.warnings) writeErr(` @ide: ${w}\n`);
|
|
1371
1519
|
if (mentioned.block) {
|
|
1372
1520
|
last.content = appendTextToContent(last.content, mentioned.block);
|
|
@@ -1401,7 +1549,7 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1401
1549
|
approvalGate.setConfirmer(
|
|
1402
1550
|
_bgPhase.wrapConfirmer(
|
|
1403
1551
|
makePermissionPromptConfirmer({
|
|
1404
|
-
mcpClient:
|
|
1552
|
+
mcpClient: hostMcp.mcpClient,
|
|
1405
1553
|
server: ppt.server,
|
|
1406
1554
|
tool: ppt.tool,
|
|
1407
1555
|
writeErr,
|
|
@@ -1572,6 +1720,9 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1572
1720
|
additionalDirectories,
|
|
1573
1721
|
sandbox: options.sandbox || null,
|
|
1574
1722
|
sessionId,
|
|
1723
|
+
// Content-free continuity metadata from the same verified sample used for
|
|
1724
|
+
// replay history and MCP recovery authority.
|
|
1725
|
+
sessionHostSnapshot: canonicalResume?.snapshot || null,
|
|
1575
1726
|
// Auto-pin (default ON since 2026-07-07): pin the original task through
|
|
1576
1727
|
// compaction. Precedence: --auto-pin flag > CC_AUTO_PIN ("1"/"0") >
|
|
1577
1728
|
// config context.autoPin > default on. Falsy → agent-core passes no pin
|
|
@@ -1579,6 +1730,9 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1579
1730
|
autoPin: _autoPinResolved,
|
|
1580
1731
|
autoCheckpoint: options.autoCheckpoint || false,
|
|
1581
1732
|
checkpointSession: options.checkpointSession || sessionId,
|
|
1733
|
+
managedCheckpoint: options.managedCheckpoint === true,
|
|
1734
|
+
managedCheckpointStateDir: options.managedCheckpointStateDir || null,
|
|
1735
|
+
managedCheckpointExclusions: options.managedCheckpointExclusions || [],
|
|
1582
1736
|
hookDb: db,
|
|
1583
1737
|
approvalGate,
|
|
1584
1738
|
permissionRules,
|
|
@@ -1634,9 +1788,16 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1634
1788
|
: {}),
|
|
1635
1789
|
// --mcp-config wiring: tool defs for the LLM + dispatch map + live client.
|
|
1636
1790
|
mcpClient: mcp?.mcpClient || null,
|
|
1791
|
+
mcpHostClient: mcpRecoveryRuntime.client || mcp?.mcpClient || null,
|
|
1637
1792
|
extraToolDefinitions: mcp?.extraToolDefinitions || undefined,
|
|
1638
1793
|
externalToolExecutors: mcp?.externalToolExecutors || undefined,
|
|
1639
1794
|
externalToolDescriptors: mcp?.externalToolDescriptors || undefined,
|
|
1795
|
+
// Persist every MCP started/settled record into this exact canonical
|
|
1796
|
+
// session. Unknown/write/destructive prewrite failure then blocks before
|
|
1797
|
+
// the external call; a settlement failure leaves a recoverable started row.
|
|
1798
|
+
// Keep the guarded in-memory ledger when persistence is disabled so an
|
|
1799
|
+
// outcome-unknown call still latches UNSAFE for the rest of this process.
|
|
1800
|
+
mcpCallLedger: mcpRecoveryRuntime.ledger,
|
|
1640
1801
|
// chatFn passthrough lets tests drive the loop deterministically.
|
|
1641
1802
|
chatFn: deps.chatFn || options.chatFn || undefined,
|
|
1642
1803
|
signal: options.signal || undefined,
|
|
@@ -1725,6 +1886,7 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1725
1886
|
// so a non-interactive run surfaces what got blocked the way the REPL's
|
|
1726
1887
|
// `/permissions denials` does (Claude-Code 2.1.193 denial reasons).
|
|
1727
1888
|
const denials = [];
|
|
1889
|
+
const compactionDegradations = [];
|
|
1728
1890
|
const usage = {
|
|
1729
1891
|
input_tokens: 0,
|
|
1730
1892
|
output_tokens: 0,
|
|
@@ -1910,15 +2072,10 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
1910
2072
|
let restoredSnap = null;
|
|
1911
2073
|
if (resumeId) {
|
|
1912
2074
|
try {
|
|
1913
|
-
const
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
const snap = ev.data;
|
|
1918
|
-
if (snap && snap.state && snap.state.done !== true)
|
|
1919
|
-
restoredSnap = snap;
|
|
1920
|
-
break; // only the latest goal_snapshot matters
|
|
1921
|
-
}
|
|
2075
|
+
const event = store.findLatestEvent(resumeId, "goal_snapshot");
|
|
2076
|
+
const snap = event?.data;
|
|
2077
|
+
if (snap && snap.state && snap.state.done !== true) {
|
|
2078
|
+
restoredSnap = snap;
|
|
1922
2079
|
}
|
|
1923
2080
|
} catch {
|
|
1924
2081
|
restoredSnap = null; // unreadable transcript → start fresh
|
|
@@ -2006,6 +2163,14 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
2006
2163
|
for await (const event of runLoop(messages, loopOptions)) {
|
|
2007
2164
|
if (turnBindingFeed) turnBindingFeed.handleEvent(event);
|
|
2008
2165
|
switch (event.type) {
|
|
2166
|
+
case "managed-checkpoint":
|
|
2167
|
+
case "managed-checkpoint-settled":
|
|
2168
|
+
case "managed-checkpoint-error": {
|
|
2169
|
+
const line = formatManagedCheckpointEvent(event);
|
|
2170
|
+
if (isText && line) writeErr(`${line}\n`);
|
|
2171
|
+
if (isStream) emitStream(event);
|
|
2172
|
+
break;
|
|
2173
|
+
}
|
|
2009
2174
|
case "checkpoint": {
|
|
2010
2175
|
if (isText)
|
|
2011
2176
|
writeErr(` ⎌ checkpoint ${event.id} (before ${event.tool})\n`);
|
|
@@ -2138,6 +2303,23 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
2138
2303
|
}
|
|
2139
2304
|
break;
|
|
2140
2305
|
}
|
|
2306
|
+
case "compaction-degraded": {
|
|
2307
|
+
const reason = String(event.reason || "semantic-summary-degraded")
|
|
2308
|
+
.replace(/\s+/g, " ")
|
|
2309
|
+
.slice(0, 500);
|
|
2310
|
+
const degradation = {
|
|
2311
|
+
reason,
|
|
2312
|
+
summary_mode: event.summaryMode || "none",
|
|
2313
|
+
};
|
|
2314
|
+
compactionDegradations.push(degradation);
|
|
2315
|
+
if (isText) {
|
|
2316
|
+
writeErr(
|
|
2317
|
+
` Semantic compaction degraded to ${degradation.summary_mode}: ${reason}\n`,
|
|
2318
|
+
);
|
|
2319
|
+
}
|
|
2320
|
+
emitStream({ ...event, reason });
|
|
2321
|
+
break;
|
|
2322
|
+
}
|
|
2141
2323
|
case "token-usage": {
|
|
2142
2324
|
if (event.attribution) {
|
|
2143
2325
|
// Child-loop (sub-agent / isolated-skill) spend: excluded from
|
|
@@ -2164,6 +2346,7 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
2164
2346
|
provider: event.provider,
|
|
2165
2347
|
model: event.model,
|
|
2166
2348
|
usage: event.usage,
|
|
2349
|
+
...(event.source ? { source: event.source } : {}),
|
|
2167
2350
|
});
|
|
2168
2351
|
if (costBudget) {
|
|
2169
2352
|
costBudget.add({
|
|
@@ -2419,6 +2602,7 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
2419
2602
|
numTurns: budget.consumed,
|
|
2420
2603
|
durationMs: (deps.now ? deps.now() : Date.now()) - startedAt,
|
|
2421
2604
|
denials,
|
|
2605
|
+
compactionDegradations,
|
|
2422
2606
|
}),
|
|
2423
2607
|
) + "\n",
|
|
2424
2608
|
);
|
|
@@ -2700,6 +2884,9 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
2700
2884
|
num_turns: budget.consumed,
|
|
2701
2885
|
duration_ms: durationMs,
|
|
2702
2886
|
usage,
|
|
2887
|
+
...(compactionDegradations.length
|
|
2888
|
+
? { compaction_degradations: compactionDegradations }
|
|
2889
|
+
: {}),
|
|
2703
2890
|
});
|
|
2704
2891
|
} else if (isJson) {
|
|
2705
2892
|
writeOut(
|
|
@@ -2714,6 +2901,7 @@ async function runAgentHeadlessInWorkspace(options = {}, deps = {}) {
|
|
|
2714
2901
|
numTurns: budget.consumed,
|
|
2715
2902
|
durationMs,
|
|
2716
2903
|
denials,
|
|
2904
|
+
compactionDegradations,
|
|
2717
2905
|
}),
|
|
2718
2906
|
) + "\n",
|
|
2719
2907
|
);
|
|
@@ -2773,6 +2961,7 @@ function buildResultEnvelope({
|
|
|
2773
2961
|
numTurns,
|
|
2774
2962
|
durationMs,
|
|
2775
2963
|
denials,
|
|
2964
|
+
compactionDegradations,
|
|
2776
2965
|
}) {
|
|
2777
2966
|
const env = {
|
|
2778
2967
|
type: "result",
|
|
@@ -2788,5 +2977,8 @@ function buildResultEnvelope({
|
|
|
2788
2977
|
// Only present when something was blocked — keeps the no-denial envelope
|
|
2789
2978
|
// byte-identical to before (Claude-Code 2.1.193 denial reasons, json mode).
|
|
2790
2979
|
if (Array.isArray(denials) && denials.length) env.denials = denials;
|
|
2980
|
+
if (Array.isArray(compactionDegradations) && compactionDegradations.length) {
|
|
2981
|
+
env.compaction_degradations = compactionDegradations;
|
|
2982
|
+
}
|
|
2791
2983
|
return env;
|
|
2792
2984
|
}
|