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
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { randomUUID } from "node:crypto";
|
|
20
|
+
import { isProxy } from "node:util/types";
|
|
20
21
|
import {
|
|
21
22
|
approvalBindingDigest,
|
|
22
23
|
verifyApprovalBinding,
|
|
@@ -85,10 +86,17 @@ import {
|
|
|
85
86
|
appendToolCallCompact as jsonlAppendToolCallCompact,
|
|
86
87
|
appendLlmRetryCompact as jsonlAppendLlmRetryCompact,
|
|
87
88
|
appendEvent as jsonlAppendEvent,
|
|
89
|
+
appendAuthorityEvent as jsonlAppendAuthorityEvent,
|
|
88
90
|
readEvents as jsonlReadEvents,
|
|
89
|
-
|
|
91
|
+
readVerifiedEvents as jsonlReadVerifiedEvents,
|
|
92
|
+
readVerifiedProjection as jsonlReadVerifiedProjection,
|
|
93
|
+
findLatestEvent as jsonlFindLatestEvent,
|
|
90
94
|
sessionExists as jsonlSessionExists,
|
|
91
95
|
} from "../harness/jsonl-session-store.js";
|
|
96
|
+
import {
|
|
97
|
+
isVerifiedSessionHostSnapshot,
|
|
98
|
+
readSessionHostResumeState,
|
|
99
|
+
} from "../lib/session-host-snapshot.js";
|
|
92
100
|
import { classifyStreamRetryReason } from "../lib/stream-retry.js";
|
|
93
101
|
import {
|
|
94
102
|
SideEffectLedger,
|
|
@@ -100,6 +108,11 @@ import {
|
|
|
100
108
|
loadSideEffectLedger,
|
|
101
109
|
persistSideEffectLedger,
|
|
102
110
|
} from "../lib/side-effect-ledger-store.js";
|
|
111
|
+
import {
|
|
112
|
+
createSessionMcpLedgerSink,
|
|
113
|
+
formatMcpLedgerRecoveryNotice,
|
|
114
|
+
} from "../lib/mcp-call-ledger-store.js";
|
|
115
|
+
import { createMcpHostRecoveryRuntime } from "../lib/mcp-host-recovery-runtime.js";
|
|
103
116
|
import { operationIdempotencyKey } from "../lib/idempotency.js";
|
|
104
117
|
import { TurnBindingLog, createTurnBindingFeed } from "../lib/turn-binding.js";
|
|
105
118
|
import { TURN_BINDING_EVENT } from "../lib/turn-binding-store.js";
|
|
@@ -111,6 +124,35 @@ import {
|
|
|
111
124
|
} from "./session-slash-commands.js";
|
|
112
125
|
import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
|
|
113
126
|
|
|
127
|
+
function invalidMcpRecoveryTransaction(capability, expected) {
|
|
128
|
+
const error = new TypeError(
|
|
129
|
+
`${capability} must ${expected} synchronously during MCP recovery`,
|
|
130
|
+
);
|
|
131
|
+
error.code = "CC_MCP_LEDGER_RECOVERY_TRANSACTION_INVALID";
|
|
132
|
+
return error;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function requireSynchronousRecoveryResult(value, capability) {
|
|
136
|
+
if (
|
|
137
|
+
value === null ||
|
|
138
|
+
value === undefined ||
|
|
139
|
+
(typeof value !== "object" && typeof value !== "function")
|
|
140
|
+
) {
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
if (isProxy(value)) {
|
|
144
|
+
throw invalidMcpRecoveryTransaction(capability, "return a non-Proxy value");
|
|
145
|
+
}
|
|
146
|
+
if (typeof value.then === "function") {
|
|
147
|
+
// The async result is never authority, but a rejected Promise still needs
|
|
148
|
+
// an observer so rejecting it fail-closed does not leak an unhandled
|
|
149
|
+
// rejection into the host process.
|
|
150
|
+
void Promise.resolve(value).catch(() => {});
|
|
151
|
+
throw invalidMcpRecoveryTransaction(capability, "complete");
|
|
152
|
+
}
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
|
|
114
156
|
/**
|
|
115
157
|
* Resolve the streaming-delta coalesce window (ms). Adjacent partial-message
|
|
116
158
|
* text/thinking deltas are batched into a single `stream_event` line over this
|
|
@@ -943,6 +985,7 @@ async function runTurn(
|
|
|
943
985
|
provider: event.provider,
|
|
944
986
|
model: event.model,
|
|
945
987
|
usage: event.usage,
|
|
988
|
+
...(event.source ? { source: event.source } : {}),
|
|
946
989
|
});
|
|
947
990
|
if (costBudget) {
|
|
948
991
|
costBudget.add({
|
|
@@ -1013,6 +1056,168 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1013
1056
|
const provider = options.provider || "ollama";
|
|
1014
1057
|
const baseUrl = options.baseUrl || "http://localhost:11434";
|
|
1015
1058
|
const apiKey = options.apiKey || null;
|
|
1059
|
+
const writeOut = deps.writeOut || ((s) => process.stdout.write(s));
|
|
1060
|
+
const writeErr = deps.writeErr || ((s) => process.stderr.write(s));
|
|
1061
|
+
if (!deps.writeOut && !deps.writeErr) installPipeSafety();
|
|
1062
|
+
|
|
1063
|
+
const sessionId =
|
|
1064
|
+
options.sessionId || `headless-stream-${Date.now()}-${process.pid}`;
|
|
1065
|
+
const persist = Boolean(options.sessionId) && options.ephemeral !== true;
|
|
1066
|
+
const traceId = resolveTraceId(options, process.env, deps);
|
|
1067
|
+
const fieldGate = {
|
|
1068
|
+
seq: true,
|
|
1069
|
+
trace_id: true,
|
|
1070
|
+
tool_use_id: true,
|
|
1071
|
+
permission_decision: true,
|
|
1072
|
+
};
|
|
1073
|
+
const streamCoalescer =
|
|
1074
|
+
deps.streamCoalescer ||
|
|
1075
|
+
createStreamCoalescer({
|
|
1076
|
+
writeOut,
|
|
1077
|
+
coalesceMs: resolveStreamCoalesceMs(options, process.env),
|
|
1078
|
+
traceId,
|
|
1079
|
+
fieldGate,
|
|
1080
|
+
});
|
|
1081
|
+
const emit = streamCoalescer.emit;
|
|
1082
|
+
|
|
1083
|
+
const hasInjectedSessionStore =
|
|
1084
|
+
typeof deps.sessionExists === "function" ||
|
|
1085
|
+
typeof deps.rebuildMessages === "function" ||
|
|
1086
|
+
typeof deps.appendEvent === "function" ||
|
|
1087
|
+
typeof deps.appendAuthorityEvent === "function" ||
|
|
1088
|
+
typeof deps.readVerifiedEvents === "function" ||
|
|
1089
|
+
typeof deps.readVerifiedProjection === "function";
|
|
1090
|
+
const unavailableAuthorityCapability = (operation) => () => {
|
|
1091
|
+
const error = new Error(
|
|
1092
|
+
`Injected session store must provide ${operation} for MCP authority`,
|
|
1093
|
+
);
|
|
1094
|
+
error.code = "SESSION_AUTHORITY_CAPABILITY_UNAVAILABLE";
|
|
1095
|
+
throw error;
|
|
1096
|
+
};
|
|
1097
|
+
|
|
1098
|
+
// A persisted stream resume is an authority boundary, not best-effort chat
|
|
1099
|
+
// history. Resolve it before config/settings, Setup hooks, bootstrap, MCP,
|
|
1100
|
+
// model or tool access. The canonical reader folds active messages and MCP
|
|
1101
|
+
// recovery from one verified, anchored transcript sample under the writer
|
|
1102
|
+
// lock; a damaged or asynchronous seam refuses the entire host session.
|
|
1103
|
+
let canonicalResume = null;
|
|
1104
|
+
let canonicalResumeMessages = null;
|
|
1105
|
+
let canonicalMcpCallRecovery = null;
|
|
1106
|
+
if (persist) {
|
|
1107
|
+
const readResumeState =
|
|
1108
|
+
deps.readSessionHostResumeState || readSessionHostResumeState;
|
|
1109
|
+
const readVerifiedEvents =
|
|
1110
|
+
deps.readVerifiedEvents ||
|
|
1111
|
+
(hasInjectedSessionStore
|
|
1112
|
+
? unavailableAuthorityCapability("readVerifiedEvents")
|
|
1113
|
+
: jsonlReadVerifiedEvents);
|
|
1114
|
+
const readVerifiedProjection =
|
|
1115
|
+
typeof deps.readVerifiedProjection === "function"
|
|
1116
|
+
? deps.readVerifiedProjection
|
|
1117
|
+
: !hasInjectedSessionStore
|
|
1118
|
+
? jsonlReadVerifiedProjection
|
|
1119
|
+
: null;
|
|
1120
|
+
const resumeDependencies = {
|
|
1121
|
+
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
1122
|
+
readVerifiedEvents: (...args) =>
|
|
1123
|
+
requireSynchronousRecoveryResult(
|
|
1124
|
+
readVerifiedEvents(...args),
|
|
1125
|
+
"readVerifiedEvents",
|
|
1126
|
+
),
|
|
1127
|
+
...(readVerifiedProjection
|
|
1128
|
+
? {
|
|
1129
|
+
readVerifiedProjection: (...args) =>
|
|
1130
|
+
requireSynchronousRecoveryResult(
|
|
1131
|
+
readVerifiedProjection(...args),
|
|
1132
|
+
"readVerifiedProjection",
|
|
1133
|
+
),
|
|
1134
|
+
}
|
|
1135
|
+
: {}),
|
|
1136
|
+
};
|
|
1137
|
+
try {
|
|
1138
|
+
const existingSession = requireSynchronousRecoveryResult(
|
|
1139
|
+
resumeDependencies.sessionExists(sessionId),
|
|
1140
|
+
"sessionExists",
|
|
1141
|
+
);
|
|
1142
|
+
if (typeof existingSession !== "boolean") {
|
|
1143
|
+
throw invalidMcpRecoveryTransaction(
|
|
1144
|
+
"sessionExists",
|
|
1145
|
+
"return a boolean",
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
canonicalResume = existingSession
|
|
1149
|
+
? requireSynchronousRecoveryResult(
|
|
1150
|
+
readResumeState(sessionId, {
|
|
1151
|
+
...resumeDependencies,
|
|
1152
|
+
sessionExists: () => true,
|
|
1153
|
+
}),
|
|
1154
|
+
"readSessionHostResumeState",
|
|
1155
|
+
)
|
|
1156
|
+
: null;
|
|
1157
|
+
if (canonicalResume !== null) {
|
|
1158
|
+
if (
|
|
1159
|
+
isProxy(canonicalResume) ||
|
|
1160
|
+
!isVerifiedSessionHostSnapshot(canonicalResume.snapshot) ||
|
|
1161
|
+
!Array.isArray(canonicalResume.messages) ||
|
|
1162
|
+
isProxy(canonicalResume.messages) ||
|
|
1163
|
+
!canonicalResume.recovery ||
|
|
1164
|
+
typeof canonicalResume.recovery !== "object" ||
|
|
1165
|
+
isProxy(canonicalResume.recovery) ||
|
|
1166
|
+
!Array.isArray(canonicalResume.recovery.unsettled) ||
|
|
1167
|
+
isProxy(canonicalResume.recovery.unsettled) ||
|
|
1168
|
+
!Array.isArray(canonicalResume.recovery.incidents) ||
|
|
1169
|
+
isProxy(canonicalResume.recovery.incidents)
|
|
1170
|
+
) {
|
|
1171
|
+
throw invalidMcpRecoveryTransaction(
|
|
1172
|
+
"readSessionHostResumeState",
|
|
1173
|
+
"return one verified session-host projection",
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
if (
|
|
1177
|
+
!canonicalResume.messages.every(
|
|
1178
|
+
(message) =>
|
|
1179
|
+
message &&
|
|
1180
|
+
!isProxy(message) &&
|
|
1181
|
+
["system", "user", "assistant", "tool"].includes(message.role),
|
|
1182
|
+
)
|
|
1183
|
+
) {
|
|
1184
|
+
throw invalidMcpRecoveryTransaction(
|
|
1185
|
+
"readSessionHostResumeState",
|
|
1186
|
+
"return plain replay messages with supported roles",
|
|
1187
|
+
);
|
|
1188
|
+
}
|
|
1189
|
+
canonicalResumeMessages = [...canonicalResume.messages];
|
|
1190
|
+
const notice = formatMcpLedgerRecoveryNotice(canonicalResume.recovery);
|
|
1191
|
+
if (notice) {
|
|
1192
|
+
canonicalMcpCallRecovery = {
|
|
1193
|
+
count: canonicalResume.recovery.unsettled.length,
|
|
1194
|
+
incidents: canonicalResume.recovery.incidents.length,
|
|
1195
|
+
items: canonicalResume.recovery.unsettled
|
|
1196
|
+
.slice(0, 10)
|
|
1197
|
+
.map((record) => ({
|
|
1198
|
+
ledgerId: record.ledgerId,
|
|
1199
|
+
server: record.serverName,
|
|
1200
|
+
tool: record.toolName,
|
|
1201
|
+
effect: record.effectContract?.effect || "unknown",
|
|
1202
|
+
})),
|
|
1203
|
+
notice,
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
} catch {
|
|
1208
|
+
const code = "CC_SESSION_HOST_SNAPSHOT_UNVERIFIED";
|
|
1209
|
+
emit({
|
|
1210
|
+
type: "result",
|
|
1211
|
+
subtype: "error_session_resume",
|
|
1212
|
+
is_error: true,
|
|
1213
|
+
code,
|
|
1214
|
+
error: "Canonical stream session could not be verified",
|
|
1215
|
+
session_id: sessionId,
|
|
1216
|
+
});
|
|
1217
|
+
writeErr(`${code}: canonical stream resume was refused\n`);
|
|
1218
|
+
return { exitCode: 1, turns: 0 };
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1016
1221
|
// Vision model (config.llm.visionModel) — image turns switch to it for that
|
|
1017
1222
|
// turn only (resolveVisionLlm falls back to the default when unset), so a
|
|
1018
1223
|
// pasted/typed image is read by a vision-capable model even though the
|
|
@@ -1067,12 +1272,19 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1067
1272
|
let settingsHooks = options.settingsHooks || null;
|
|
1068
1273
|
if (!settingsHooks) {
|
|
1069
1274
|
try {
|
|
1070
|
-
const { loadHooks, projectHookTrustNotice } =
|
|
1275
|
+
const { loadHooks, projectHookTrustNotice, attachAuthorityErrors } =
|
|
1071
1276
|
await import("../lib/settings-hooks.cjs");
|
|
1072
1277
|
const loaded = loadHooks({ cwd, settingsFile: options.settingsFile });
|
|
1278
|
+
const { mergePluginHooks } =
|
|
1279
|
+
await import("../lib/plugin-runtime/hooks.js");
|
|
1280
|
+
const effectiveHooks = mergePluginHooks(
|
|
1281
|
+
attachAuthorityErrors(loaded.hooks, loaded.authorityErrors),
|
|
1282
|
+
{ cwd },
|
|
1283
|
+
);
|
|
1073
1284
|
settingsHooks =
|
|
1074
|
-
|
|
1075
|
-
|
|
1285
|
+
Object.keys(effectiveHooks).length > 0 ||
|
|
1286
|
+
effectiveHooks._authorityErrors.length > 0
|
|
1287
|
+
? effectiveHooks
|
|
1076
1288
|
: null;
|
|
1077
1289
|
// First-run trust notice for an untrusted/cloned repo's shell-running
|
|
1078
1290
|
// hooks (Claude-Code 2.1.195 parity). stderr keeps the NDJSON stdout clean.
|
|
@@ -1085,8 +1297,17 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1085
1297
|
} catch {
|
|
1086
1298
|
/* trust notice is best-effort */
|
|
1087
1299
|
}
|
|
1088
|
-
} catch {
|
|
1089
|
-
settingsHooks =
|
|
1300
|
+
} catch (error) {
|
|
1301
|
+
settingsHooks = {};
|
|
1302
|
+
Object.defineProperty(settingsHooks, "_authorityErrors", {
|
|
1303
|
+
value: Object.freeze([
|
|
1304
|
+
Object.freeze({
|
|
1305
|
+
sourceFile: null,
|
|
1306
|
+
code: error?.code || "CC_HOOK_AUTHORITY_LOAD_FAILED",
|
|
1307
|
+
}),
|
|
1308
|
+
]),
|
|
1309
|
+
enumerable: false,
|
|
1310
|
+
});
|
|
1090
1311
|
}
|
|
1091
1312
|
}
|
|
1092
1313
|
|
|
@@ -1113,44 +1334,6 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1113
1334
|
const doExpand = deps.expandFileRefs || expandFileRefsAsync;
|
|
1114
1335
|
const runSessionSlashCommand =
|
|
1115
1336
|
deps.executeSessionSlashCommand || executeSessionSlashCommand;
|
|
1116
|
-
const writeOut = deps.writeOut || ((s) => process.stdout.write(s));
|
|
1117
|
-
const writeErr = deps.writeErr || ((s) => process.stderr.write(s));
|
|
1118
|
-
// Guard the real stdout/stderr against a downstream `| head` closing the pipe
|
|
1119
|
-
// (unhandled async EPIPE → crash). Only when we own the streams (no injected
|
|
1120
|
-
// seams = production, not tests). Idempotent; shared with the -p runner.
|
|
1121
|
-
if (!deps.writeOut && !deps.writeErr) {
|
|
1122
|
-
installPipeSafety();
|
|
1123
|
-
}
|
|
1124
|
-
// Run-scoped cross-event trace id (additive protocol-v1, docs/PROTOCOL.md
|
|
1125
|
-
// §1.2.1): one id stamped on EVERY stdout line so a consumer can correlate
|
|
1126
|
-
// the whole run across Webview → Bridge → CLI logs, transcripts and
|
|
1127
|
-
// diagnostic bundles. The IDE bridge may thread its own id through
|
|
1128
|
-
// `--trace-id` / options.traceId / CC_TRACE_ID; otherwise a per-process id
|
|
1129
|
-
// is minted (unique even when two runs resume the same session_id).
|
|
1130
|
-
const traceId = resolveTraceId(options, process.env, deps);
|
|
1131
|
-
// Live field-gate for the capability handshake (docs/PROTOCOL.md §1.3): a
|
|
1132
|
-
// client `hello` narrowing the wire features flips these to suppress the
|
|
1133
|
-
// additive fields it can't parse. All true by default = current behavior
|
|
1134
|
-
// byte-for-byte; the coalescer reads it per line.
|
|
1135
|
-
const fieldGate = {
|
|
1136
|
-
seq: true,
|
|
1137
|
-
trace_id: true,
|
|
1138
|
-
tool_use_id: true,
|
|
1139
|
-
permission_decision: true,
|
|
1140
|
-
};
|
|
1141
|
-
// Batch consecutive partial-message text/thinking deltas into one stream_event
|
|
1142
|
-
// line (Claude-Code 2.1.191 streaming-CPU optimization). `emit` flushes any
|
|
1143
|
-
// pending deltas before writing a non-delta line, so ordering is preserved;
|
|
1144
|
-
// CC_STREAM_COALESCE_MS=0 restores the per-token emit behavior.
|
|
1145
|
-
const streamCoalescer =
|
|
1146
|
-
deps.streamCoalescer ||
|
|
1147
|
-
createStreamCoalescer({
|
|
1148
|
-
writeOut,
|
|
1149
|
-
coalesceMs: resolveStreamCoalesceMs(options, process.env),
|
|
1150
|
-
traceId,
|
|
1151
|
-
fieldGate,
|
|
1152
|
-
});
|
|
1153
|
-
const emit = streamCoalescer.emit;
|
|
1154
1337
|
|
|
1155
1338
|
const getApprovalGate =
|
|
1156
1339
|
deps.getApprovalGate ||
|
|
@@ -1181,9 +1364,6 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1181
1364
|
// DB optional — static-prompt fallback.
|
|
1182
1365
|
}
|
|
1183
1366
|
|
|
1184
|
-
const sessionId =
|
|
1185
|
-
options.sessionId || `headless-stream-${Date.now()}-${process.pid}`;
|
|
1186
|
-
|
|
1187
1367
|
const setupHooks = await executeLifecycleHooks(
|
|
1188
1368
|
"Setup",
|
|
1189
1369
|
{
|
|
@@ -1216,6 +1396,23 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1216
1396
|
// prior history is rebuilt into the conversation and every new turn is
|
|
1217
1397
|
// appended, so a later run with the same id picks up where this one left
|
|
1218
1398
|
// off. Anonymous runs (no id) stay persistence-free, exactly as before.
|
|
1399
|
+
const storeReadEvents = deps.readEvents || jsonlReadEvents;
|
|
1400
|
+
const storeFindLatestEvent =
|
|
1401
|
+
deps.findLatestEvent ||
|
|
1402
|
+
(deps.readEvents
|
|
1403
|
+
? (sessionId, type, predicate = null) => {
|
|
1404
|
+
const events = storeReadEvents(sessionId) || [];
|
|
1405
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
1406
|
+
const event = events[index];
|
|
1407
|
+
if (type != null && event?.type !== type) continue;
|
|
1408
|
+
if (typeof predicate === "function" && !predicate(event)) continue;
|
|
1409
|
+
return event;
|
|
1410
|
+
}
|
|
1411
|
+
return null;
|
|
1412
|
+
}
|
|
1413
|
+
: hasInjectedSessionStore
|
|
1414
|
+
? () => null
|
|
1415
|
+
: jsonlFindLatestEvent);
|
|
1219
1416
|
const store = {
|
|
1220
1417
|
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
1221
1418
|
startSession: deps.startSession || jsonlStartSession,
|
|
@@ -1223,16 +1420,35 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1223
1420
|
appendAssistantMessage:
|
|
1224
1421
|
deps.appendAssistantMessage || jsonlAppendAssistantMessage,
|
|
1225
1422
|
appendToolCallCompact:
|
|
1226
|
-
deps.appendToolCallCompact ||
|
|
1423
|
+
deps.appendToolCallCompact ||
|
|
1424
|
+
(hasInjectedSessionStore ? () => true : jsonlAppendToolCallCompact),
|
|
1227
1425
|
appendLlmRetryCompact:
|
|
1228
|
-
deps.appendLlmRetryCompact ||
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1426
|
+
deps.appendLlmRetryCompact ||
|
|
1427
|
+
(hasInjectedSessionStore ? () => true : jsonlAppendLlmRetryCompact),
|
|
1428
|
+
appendEvent:
|
|
1429
|
+
deps.appendEvent ||
|
|
1430
|
+
(hasInjectedSessionStore ? () => true : jsonlAppendEvent),
|
|
1431
|
+
appendAuthorityEvent:
|
|
1432
|
+
deps.appendAuthorityEvent ||
|
|
1433
|
+
(hasInjectedSessionStore
|
|
1434
|
+
? unavailableAuthorityCapability("appendAuthorityEvent")
|
|
1435
|
+
: jsonlAppendAuthorityEvent),
|
|
1436
|
+
readEvents: storeReadEvents,
|
|
1437
|
+
readVerifiedEvents:
|
|
1438
|
+
deps.readVerifiedEvents ||
|
|
1439
|
+
(hasInjectedSessionStore
|
|
1440
|
+
? unavailableAuthorityCapability("readVerifiedEvents")
|
|
1441
|
+
: jsonlReadVerifiedEvents),
|
|
1442
|
+
readVerifiedProjection:
|
|
1443
|
+
deps.readVerifiedProjection ||
|
|
1444
|
+
(hasInjectedSessionStore ? null : jsonlReadVerifiedProjection),
|
|
1445
|
+
findLatestEvent: storeFindLatestEvent,
|
|
1232
1446
|
};
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1447
|
+
const mcpLedgerSink = persist
|
|
1448
|
+
? createSessionMcpLedgerSink(sessionId, {
|
|
1449
|
+
appendEvent: store.appendAuthorityEvent,
|
|
1450
|
+
})
|
|
1451
|
+
: null;
|
|
1236
1452
|
|
|
1237
1453
|
// ── P0-2: crash-safe side-effect ledger — the stream twin of the
|
|
1238
1454
|
// single-prompt runner (headless-runner.js) and the WS bridge
|
|
@@ -1328,17 +1544,13 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1328
1544
|
};
|
|
1329
1545
|
if (persist) {
|
|
1330
1546
|
try {
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
) {
|
|
1339
|
-
turnBindingLog = TurnBindingLog.fromJSON(event.data);
|
|
1340
|
-
break;
|
|
1341
|
-
}
|
|
1547
|
+
const event = store.findLatestEvent(
|
|
1548
|
+
sessionId,
|
|
1549
|
+
TURN_BINDING_EVENT,
|
|
1550
|
+
(candidate) => candidate?.data && typeof candidate.data === "object",
|
|
1551
|
+
);
|
|
1552
|
+
if (event) {
|
|
1553
|
+
turnBindingLog = TurnBindingLog.fromJSON(event.data);
|
|
1342
1554
|
}
|
|
1343
1555
|
} catch (error) {
|
|
1344
1556
|
recordTurnBindingFailure(error, "read");
|
|
@@ -1705,34 +1917,53 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1705
1917
|
// leads; persisted system turns are dropped, mirroring runAgentHeadless).
|
|
1706
1918
|
let resumedMessages = 0;
|
|
1707
1919
|
let sideEffectRecovery = null;
|
|
1920
|
+
let mcpCallRecovery = null;
|
|
1921
|
+
let mcpLedgerRecovery = null;
|
|
1922
|
+
let mcpLedgerRecoveryError = null;
|
|
1708
1923
|
if (persist) {
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1924
|
+
if (canonicalResume) {
|
|
1925
|
+
// The history and MCP authority below came from the same verified head.
|
|
1926
|
+
// No second pathname read is allowed between verification and replay.
|
|
1927
|
+
if (sideEffectLedger) {
|
|
1928
|
+
sideEffectRecovery = buildSideEffectRecovery(sideEffectLedger);
|
|
1929
|
+
}
|
|
1930
|
+
if (sideEffectRecovery) {
|
|
1931
|
+
messages.push({ role: "system", content: sideEffectRecovery.notice });
|
|
1932
|
+
}
|
|
1933
|
+
mcpLedgerRecovery = canonicalResume.recovery;
|
|
1934
|
+
mcpCallRecovery = canonicalMcpCallRecovery;
|
|
1935
|
+
if (mcpCallRecovery) {
|
|
1936
|
+
messages.push({ role: "system", content: mcpCallRecovery.notice });
|
|
1937
|
+
}
|
|
1938
|
+
messages.push(...canonicalResumeMessages);
|
|
1939
|
+
// Preserve the existing public counter semantics: control-plane stream
|
|
1940
|
+
// metadata counts conversational turns, never private system context.
|
|
1941
|
+
resumedMessages = canonicalResumeMessages.filter(
|
|
1942
|
+
(message) => message.role !== "system",
|
|
1943
|
+
).length;
|
|
1944
|
+
} else {
|
|
1945
|
+
try {
|
|
1946
|
+
requireSynchronousRecoveryResult(
|
|
1947
|
+
store.startSession(sessionId, {
|
|
1948
|
+
title: "stream session",
|
|
1949
|
+
provider,
|
|
1950
|
+
model,
|
|
1951
|
+
}),
|
|
1952
|
+
"startSession",
|
|
1724
1953
|
);
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1954
|
+
} catch {
|
|
1955
|
+
const code = "CC_SESSION_PERSISTENCE_START_FAILED";
|
|
1956
|
+
emit({
|
|
1957
|
+
type: "result",
|
|
1958
|
+
subtype: "error_session_persistence",
|
|
1959
|
+
is_error: true,
|
|
1960
|
+
code,
|
|
1961
|
+
error: "Canonical stream session could not be created",
|
|
1962
|
+
session_id: sessionId,
|
|
1732
1963
|
});
|
|
1964
|
+
writeErr(`${code}: canonical stream session creation was refused\n`);
|
|
1965
|
+
return { exitCode: 1, turns: 0 };
|
|
1733
1966
|
}
|
|
1734
|
-
} catch {
|
|
1735
|
-
// persistence is best-effort — never fail the stream over it
|
|
1736
1967
|
}
|
|
1737
1968
|
}
|
|
1738
1969
|
|
|
@@ -1794,6 +2025,17 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1794
2025
|
session_id: sessionId,
|
|
1795
2026
|
});
|
|
1796
2027
|
}
|
|
2028
|
+
if (mcpCallRecovery) {
|
|
2029
|
+
emit({
|
|
2030
|
+
type: "raw",
|
|
2031
|
+
subtype: "mcp_call_recovery",
|
|
2032
|
+
text: `⚠️ ${mcpCallRecovery.count} interrupted MCP call(s) and ${mcpCallRecovery.incidents} ledger incident(s) need inspection before replay (resume ${sessionId}).`,
|
|
2033
|
+
count: mcpCallRecovery.count,
|
|
2034
|
+
incidents: mcpCallRecovery.incidents,
|
|
2035
|
+
items: mcpCallRecovery.items,
|
|
2036
|
+
session_id: sessionId,
|
|
2037
|
+
});
|
|
2038
|
+
}
|
|
1797
2039
|
|
|
1798
2040
|
// Goal binding (cc goal, Phase 1) — resolved once and injected on every turn.
|
|
1799
2041
|
// `--goal <id>` binds explicitly; `--goal` with no value auto-resolves.
|
|
@@ -1872,6 +2114,17 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1872
2114
|
}
|
|
1873
2115
|
}
|
|
1874
2116
|
|
|
2117
|
+
const mcpRecoveryRuntime = createMcpHostRecoveryRuntime({
|
|
2118
|
+
bundle: mcp,
|
|
2119
|
+
sessionId,
|
|
2120
|
+
sink: mcpLedgerSink,
|
|
2121
|
+
recovery: mcpLedgerRecovery,
|
|
2122
|
+
recoveryError: mcpLedgerRecoveryError,
|
|
2123
|
+
});
|
|
2124
|
+
const hostMcp = mcp
|
|
2125
|
+
? { ...mcp, mcpClient: mcpRecoveryRuntime.client || mcp.mcpClient }
|
|
2126
|
+
: null;
|
|
2127
|
+
|
|
1875
2128
|
// MCP servers may pause a tool flow with `elicitation/create`. Register the
|
|
1876
2129
|
// handler only after MCP resolution so the client is initialized before use.
|
|
1877
2130
|
// Reuse the structured Desktop/headless question channel, while preserving
|
|
@@ -1968,12 +2221,12 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
1968
2221
|
// workspace-root list to connected MCP servers when the stream session started
|
|
1969
2222
|
// with extra roots. No --add-dir → workspaceRootDirs = [cwd] → no-op. Mirrors
|
|
1970
2223
|
// the single-prompt runner + the REPL /add-dir path. Best-effort.
|
|
1971
|
-
if (
|
|
2224
|
+
if (hostMcp?.mcpClient && additionalDirectories.length > 0) {
|
|
1972
2225
|
try {
|
|
1973
2226
|
const { notifyMcpRootsChanged, workspaceRootDirs } =
|
|
1974
2227
|
await import("../repl/add-dir.js");
|
|
1975
2228
|
notifyMcpRootsChanged(
|
|
1976
|
-
[
|
|
2229
|
+
[hostMcp.mcpClient],
|
|
1977
2230
|
workspaceRootDirs(options.cwd || process.cwd(), additionalDirectories),
|
|
1978
2231
|
);
|
|
1979
2232
|
} catch {
|
|
@@ -2000,7 +2253,7 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
2000
2253
|
if (approvalGate && typeof approvalGate.setConfirmer === "function") {
|
|
2001
2254
|
approvalGate.setConfirmer(
|
|
2002
2255
|
makePermissionPromptConfirmer({
|
|
2003
|
-
mcpClient:
|
|
2256
|
+
mcpClient: hostMcp.mcpClient,
|
|
2004
2257
|
server: ppt.server,
|
|
2005
2258
|
tool: ppt.tool,
|
|
2006
2259
|
}),
|
|
@@ -2057,6 +2310,7 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
2057
2310
|
cwd,
|
|
2058
2311
|
additionalDirectories,
|
|
2059
2312
|
sessionId,
|
|
2313
|
+
sessionHostSnapshot: canonicalResume?.snapshot || null,
|
|
2060
2314
|
// Auto-checkpoint (Claude-Code parity): snapshot the work tree before each
|
|
2061
2315
|
// mutating tool so a stream consumer (e.g. the IDE chat panel) can rewind.
|
|
2062
2316
|
// Keyed by this run's sessionId — agent-core falls back to it — so the panel
|
|
@@ -2065,6 +2319,9 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
2065
2319
|
// only, a no-op outside a git repo.
|
|
2066
2320
|
autoCheckpoint: options.autoCheckpoint || false,
|
|
2067
2321
|
checkpointSession: options.checkpointSession || sessionId,
|
|
2322
|
+
managedCheckpoint: options.managedCheckpoint === true,
|
|
2323
|
+
managedCheckpointStateDir: options.managedCheckpointStateDir || null,
|
|
2324
|
+
managedCheckpointExclusions: options.managedCheckpointExclusions || [],
|
|
2068
2325
|
hookDb: db,
|
|
2069
2326
|
approvalGate,
|
|
2070
2327
|
permissionRules,
|
|
@@ -2086,9 +2343,13 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
2086
2343
|
prepareCall: goalPrepareCallFn,
|
|
2087
2344
|
// --mcp-config wiring (tool defs + dispatch map + live client).
|
|
2088
2345
|
mcpClient: mcp?.mcpClient || null,
|
|
2346
|
+
mcpHostClient: mcpRecoveryRuntime.client || mcp?.mcpClient || null,
|
|
2089
2347
|
extraToolDefinitions: mcp?.extraToolDefinitions || undefined,
|
|
2090
2348
|
externalToolExecutors: mcp?.externalToolExecutors || undefined,
|
|
2091
2349
|
externalToolDescriptors: mcp?.externalToolDescriptors || undefined,
|
|
2350
|
+
// A null sink disables durable writes, not recovery admission. Retain the
|
|
2351
|
+
// guarded ledger so outcome-unknown calls cannot be retried in-process.
|
|
2352
|
+
mcpCallLedger: mcpRecoveryRuntime.ledger,
|
|
2092
2353
|
chatFn: deps.chatFn || options.chatFn || undefined,
|
|
2093
2354
|
signal: options.signal || undefined,
|
|
2094
2355
|
// --include-partial-messages: stream live assistant-text deltas as
|
|
@@ -2709,11 +2970,11 @@ async function runAgentHeadlessStreamInWorkspace(options = {}, deps = {}) {
|
|
|
2709
2970
|
try {
|
|
2710
2971
|
const ideCtx = await (
|
|
2711
2972
|
deps.buildIdePromptContext || buildIdePromptContext
|
|
2712
|
-
)(
|
|
2973
|
+
)(hostMcp);
|
|
2713
2974
|
if (ideCtx) userContent += `\n\n${ideCtx}`;
|
|
2714
2975
|
// Explicit @selection / @diagnostics mentions (Claude-Code parity);
|
|
2715
2976
|
// scan the original user event text, append the expansion ephemerally.
|
|
2716
|
-
const mentioned = await expandIdeMentions(parsed.text,
|
|
2977
|
+
const mentioned = await expandIdeMentions(parsed.text, hostMcp);
|
|
2717
2978
|
for (const w of mentioned.warnings) writeErr(` @ide: ${w}\n`);
|
|
2718
2979
|
if (mentioned.block) userContent += `\n\n${mentioned.block}`;
|
|
2719
2980
|
} catch {
|