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
|
@@ -60,6 +60,8 @@ export function publicArtifactMetadata(entry) {
|
|
|
60
60
|
sessionId,
|
|
61
61
|
createdAt,
|
|
62
62
|
expiresAt,
|
|
63
|
+
immutable,
|
|
64
|
+
recordDigest,
|
|
63
65
|
} = entry;
|
|
64
66
|
return {
|
|
65
67
|
id,
|
|
@@ -72,6 +74,8 @@ export function publicArtifactMetadata(entry) {
|
|
|
72
74
|
sessionId,
|
|
73
75
|
createdAt,
|
|
74
76
|
expiresAt,
|
|
77
|
+
immutable: immutable === true,
|
|
78
|
+
recordDigest: recordDigest || null,
|
|
75
79
|
};
|
|
76
80
|
}
|
|
77
81
|
|
|
@@ -158,8 +162,70 @@ export class ArtifactStore {
|
|
|
158
162
|
);
|
|
159
163
|
}
|
|
160
164
|
const body = fs.readFileSync(abs);
|
|
165
|
+
return this._publishData(body, {
|
|
166
|
+
fileName: path.basename(abs),
|
|
167
|
+
title,
|
|
168
|
+
kind,
|
|
169
|
+
sessionId,
|
|
170
|
+
ttlDays,
|
|
171
|
+
sourcePath: abs,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Publish generated bytes without an intermediate temp file. This is used by
|
|
177
|
+
* versioned evidence records so the exact digested JSON bytes are the bytes
|
|
178
|
+
* stored in the artifact directory.
|
|
179
|
+
*/
|
|
180
|
+
publishData({
|
|
181
|
+
data,
|
|
182
|
+
fileName = "artifact.bin",
|
|
183
|
+
title,
|
|
184
|
+
kind,
|
|
185
|
+
mime,
|
|
186
|
+
sessionId = null,
|
|
187
|
+
ttlDays,
|
|
188
|
+
immutable = false,
|
|
189
|
+
recordDigest = null,
|
|
190
|
+
} = {}) {
|
|
191
|
+
if (typeof data !== "string" && !Buffer.isBuffer(data)) {
|
|
192
|
+
throw new Error("publishData requires string or Buffer data");
|
|
193
|
+
}
|
|
194
|
+
return this._publishData(Buffer.from(data), {
|
|
195
|
+
fileName,
|
|
196
|
+
title,
|
|
197
|
+
kind,
|
|
198
|
+
mime,
|
|
199
|
+
sessionId,
|
|
200
|
+
ttlDays,
|
|
201
|
+
immutable,
|
|
202
|
+
recordDigest,
|
|
203
|
+
sourcePath: null,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
_publishData(
|
|
208
|
+
body,
|
|
209
|
+
{
|
|
210
|
+
fileName,
|
|
211
|
+
title,
|
|
212
|
+
kind,
|
|
213
|
+
mime,
|
|
214
|
+
sessionId,
|
|
215
|
+
ttlDays,
|
|
216
|
+
immutable = false,
|
|
217
|
+
recordDigest = null,
|
|
218
|
+
sourcePath = null,
|
|
219
|
+
},
|
|
220
|
+
) {
|
|
221
|
+
if (body.length > MAX_ARTIFACT_BYTES) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`artifact too large (${body.length} bytes > ${MAX_ARTIFACT_BYTES}); artifacts are deliverables, not build output`,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
const safeFileName = path.basename(String(fileName || "artifact.bin"));
|
|
161
227
|
const sha256 = crypto.createHash("sha256").update(body).digest("hex");
|
|
162
|
-
const ext = path.extname(
|
|
228
|
+
const ext = path.extname(safeFileName);
|
|
163
229
|
const id = `art_${this._now().toString(36)}_${crypto
|
|
164
230
|
.randomBytes(4)
|
|
165
231
|
.toString("hex")}`;
|
|
@@ -169,19 +235,30 @@ export class ArtifactStore {
|
|
|
169
235
|
const createdAt = this._now();
|
|
170
236
|
const entry = {
|
|
171
237
|
id,
|
|
172
|
-
title: String(title ||
|
|
238
|
+
title: String(title || safeFileName),
|
|
173
239
|
kind: normalizeKind(kind),
|
|
174
|
-
mime: mimeForExt(ext),
|
|
175
|
-
size:
|
|
240
|
+
mime: mime ? String(mime) : mimeForExt(ext),
|
|
241
|
+
size: body.length,
|
|
176
242
|
sha256,
|
|
177
|
-
sourcePath
|
|
243
|
+
sourcePath,
|
|
178
244
|
file: `${id}${ext}`,
|
|
179
245
|
sessionId: sessionId ? String(sessionId) : null,
|
|
180
246
|
createdAt: new Date(createdAt).toISOString(),
|
|
181
247
|
expiresAt: new Date(createdAt + days * 24 * 60 * 60 * 1000).toISOString(),
|
|
248
|
+
immutable: immutable === true,
|
|
249
|
+
recordDigest: recordDigest ? String(recordDigest) : null,
|
|
182
250
|
};
|
|
183
251
|
this._ensureDirs();
|
|
184
|
-
|
|
252
|
+
const storedPath = path.join(this._filesDir(), entry.file);
|
|
253
|
+
fs.writeFileSync(storedPath, body, { flag: "wx" });
|
|
254
|
+
if (entry.immutable) {
|
|
255
|
+
try {
|
|
256
|
+
fs.chmodSync(storedPath, 0o444);
|
|
257
|
+
} catch {
|
|
258
|
+
// The content hash still detects mutation on filesystems without mode
|
|
259
|
+
// support; immutable here means append-only/no update API, not WORM.
|
|
260
|
+
}
|
|
261
|
+
}
|
|
185
262
|
fs.appendFileSync(this._indexFile(), JSON.stringify(entry) + "\n", "utf-8");
|
|
186
263
|
return entry;
|
|
187
264
|
}
|
|
@@ -223,13 +300,59 @@ export class ArtifactStore {
|
|
|
223
300
|
return path.join(this._filesDir(), entry.file);
|
|
224
301
|
}
|
|
225
302
|
|
|
303
|
+
/** Recompute the stored copy's digest; unknown/missing bytes fail closed. */
|
|
304
|
+
verifyIntegrity(idOrEntry) {
|
|
305
|
+
const entry =
|
|
306
|
+
typeof idOrEntry === "object" && idOrEntry
|
|
307
|
+
? idOrEntry
|
|
308
|
+
: this.get(idOrEntry);
|
|
309
|
+
if (!entry) {
|
|
310
|
+
return {
|
|
311
|
+
ok: false,
|
|
312
|
+
reason: "artifact-not-found",
|
|
313
|
+
expectedSha256: null,
|
|
314
|
+
actualSha256: null,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
let body;
|
|
318
|
+
try {
|
|
319
|
+
body = fs.readFileSync(this.storedPath(entry));
|
|
320
|
+
} catch {
|
|
321
|
+
return {
|
|
322
|
+
ok: false,
|
|
323
|
+
reason: "artifact-bytes-unavailable",
|
|
324
|
+
expectedSha256: entry.sha256 || null,
|
|
325
|
+
actualSha256: null,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
const actualSha256 = crypto.createHash("sha256").update(body).digest("hex");
|
|
329
|
+
return {
|
|
330
|
+
ok: actualSha256 === entry.sha256,
|
|
331
|
+
reason: actualSha256 === entry.sha256 ? "ok" : "artifact-digest-mismatch",
|
|
332
|
+
expectedSha256: entry.sha256 || null,
|
|
333
|
+
actualSha256,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
_deleteStoredFile(entry) {
|
|
338
|
+
const storedPath = this.storedPath(entry);
|
|
339
|
+
if (entry?.immutable) {
|
|
340
|
+
try {
|
|
341
|
+
fs.chmodSync(storedPath, 0o666);
|
|
342
|
+
} catch {
|
|
343
|
+
// Explicit deletion remains best-effort on filesystems without modes.
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
fs.rmSync(storedPath, { force: true });
|
|
347
|
+
}
|
|
348
|
+
|
|
226
349
|
/** Remove one artifact (file + index row). @returns {boolean} found */
|
|
227
350
|
remove(id) {
|
|
228
351
|
const entries = this.list();
|
|
229
352
|
const target = entries.find((e) => e.id === id);
|
|
230
353
|
if (!target) return false;
|
|
231
354
|
try {
|
|
232
|
-
|
|
355
|
+
this._deleteStoredFile(target);
|
|
233
356
|
} catch {
|
|
234
357
|
/* best-effort — the index row is the source of truth */
|
|
235
358
|
}
|
|
@@ -250,7 +373,7 @@ export class ArtifactStore {
|
|
|
250
373
|
const exp = Date.parse(e.expiresAt || "");
|
|
251
374
|
if (Number.isFinite(exp) && exp <= now) {
|
|
252
375
|
try {
|
|
253
|
-
|
|
376
|
+
this._deleteStoredFile(e);
|
|
254
377
|
} catch {
|
|
255
378
|
/* best-effort */
|
|
256
379
|
}
|
|
@@ -22,6 +22,16 @@ import {
|
|
|
22
22
|
} from "./agent-worktree.js";
|
|
23
23
|
import { rejectPendingBackgroundInteractions } from "./background-interaction-journal.js";
|
|
24
24
|
import executionBroker from "./process-execution-broker/index.js";
|
|
25
|
+
import {
|
|
26
|
+
assessBackgroundLaunchProfileCompatibility,
|
|
27
|
+
buildArgvFromBackgroundLaunchProfile,
|
|
28
|
+
captureBackgroundLaunchProfile,
|
|
29
|
+
fingerprintBackgroundLaunchProfile,
|
|
30
|
+
normalizeBackgroundLaunchProfile,
|
|
31
|
+
refreshBackgroundLaunchProfileSources,
|
|
32
|
+
stripBackgroundLaunchSecrets,
|
|
33
|
+
verifyBackgroundLaunchProfileSources,
|
|
34
|
+
} from "./background-launch-profile.js";
|
|
25
35
|
|
|
26
36
|
export const DEFAULT_HEARTBEAT_INTERVAL_MS = 5000;
|
|
27
37
|
export const DEFAULT_HEARTBEAT_STALE_MS = 120000;
|
|
@@ -364,10 +374,40 @@ export function writeBackgroundAgentState(state) {
|
|
|
364
374
|
branch: current.branch,
|
|
365
375
|
};
|
|
366
376
|
}
|
|
377
|
+
// The launch profile is immutable same-id identity. A heartbeat/finalize
|
|
378
|
+
// writer holding an older snapshot must never drop it and silently turn a
|
|
379
|
+
// profile-aware record back into legacy minimal-resume semantics.
|
|
380
|
+
if (current.launchProfile) {
|
|
381
|
+
next = {
|
|
382
|
+
...next,
|
|
383
|
+
launchProfile: current.launchProfile,
|
|
384
|
+
configFingerprint: current.configFingerprint,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
367
387
|
}
|
|
368
|
-
|
|
388
|
+
// Multiple async state writers can run in one process; a pid-only temporary
|
|
389
|
+
// name lets them overwrite each other's staging file. A unique suffix keeps
|
|
390
|
+
// each atomic replacement independent. Windows scanners/readers can also
|
|
391
|
+
// hold the destination for a few milliseconds, so retry only that bounded
|
|
392
|
+
// transient class rather than surfacing a spurious EPERM background failure.
|
|
393
|
+
const tmp = `${target}.${process.pid}.${randomBytes(4).toString("hex")}.tmp`;
|
|
369
394
|
writeFileSync(tmp, JSON.stringify(next, null, 2), { mode: 0o600 });
|
|
370
|
-
|
|
395
|
+
for (let attempt = 0; ; attempt++) {
|
|
396
|
+
try {
|
|
397
|
+
renameSync(tmp, target);
|
|
398
|
+
break;
|
|
399
|
+
} catch (error) {
|
|
400
|
+
if (
|
|
401
|
+
process.platform !== "win32" ||
|
|
402
|
+
!new Set(["EPERM", "EACCES", "EBUSY"]).has(error?.code) ||
|
|
403
|
+
attempt >= 5
|
|
404
|
+
) {
|
|
405
|
+
rmSync(tmp, { force: true });
|
|
406
|
+
throw error;
|
|
407
|
+
}
|
|
408
|
+
sleepSyncMs(5 * (attempt + 1));
|
|
409
|
+
}
|
|
410
|
+
}
|
|
371
411
|
return next;
|
|
372
412
|
}
|
|
373
413
|
|
|
@@ -860,13 +900,23 @@ function persistedWorktree(state) {
|
|
|
860
900
|
}
|
|
861
901
|
|
|
862
902
|
/**
|
|
863
|
-
* Continue a finished/crashed
|
|
864
|
-
*
|
|
865
|
-
*
|
|
866
|
-
*
|
|
867
|
-
* come from config defaults, and the headless runner replays the JSONL
|
|
868
|
-
* transcript for the session id.
|
|
903
|
+
* Continue a finished/crashed run as a NEW background agent on the same
|
|
904
|
+
* conversation. Versioned records rebuild their secret-free launch profile;
|
|
905
|
+
* legacy records retain the old minimal argv behavior. Callers must explicitly
|
|
906
|
+
* opt in before an incompatible profile override can change the run envelope.
|
|
869
907
|
*/
|
|
908
|
+
function incompatibleLaunchProfileError(id, reasons) {
|
|
909
|
+
const normalized = Array.isArray(reasons) ? reasons.filter(Boolean) : [];
|
|
910
|
+
const error = new Error(
|
|
911
|
+
`Background agent ${id} launch profile is incompatible: ${
|
|
912
|
+
normalized.join(", ") || "unknown profile mismatch"
|
|
913
|
+
}. Refusing to resume without an explicit compatibility override.`,
|
|
914
|
+
);
|
|
915
|
+
error.code = "BACKGROUND_LAUNCH_PROFILE_INCOMPATIBLE";
|
|
916
|
+
error.reasons = normalized;
|
|
917
|
+
return error;
|
|
918
|
+
}
|
|
919
|
+
|
|
870
920
|
export function resumeBackgroundAgent(id, prompt, options = {}) {
|
|
871
921
|
const state = effectiveBackgroundAgentState(readBackgroundAgentState(id), {
|
|
872
922
|
now: options.now,
|
|
@@ -893,7 +943,88 @@ export function resumeBackgroundAgent(id, prompt, options = {}) {
|
|
|
893
943
|
`Background agent ${id} is bound to worktree "${worktree.worktreePath}" and cannot resume in a different cwd`,
|
|
894
944
|
);
|
|
895
945
|
}
|
|
896
|
-
|
|
946
|
+
let launchProfile = null;
|
|
947
|
+
if (state.launchProfile) {
|
|
948
|
+
let persisted;
|
|
949
|
+
try {
|
|
950
|
+
persisted = normalizeBackgroundLaunchProfile(state.launchProfile);
|
|
951
|
+
} catch (error) {
|
|
952
|
+
throw incompatibleLaunchProfileError(id, [
|
|
953
|
+
`invalid-profile:${error.message}`,
|
|
954
|
+
]);
|
|
955
|
+
}
|
|
956
|
+
const actualFingerprint = fingerprintBackgroundLaunchProfile(persisted);
|
|
957
|
+
const storedFingerprint =
|
|
958
|
+
state.configFingerprint || state.launchProfileFingerprint || null;
|
|
959
|
+
const explicitReplacement =
|
|
960
|
+
options.launchProfileOverride &&
|
|
961
|
+
options.allowIncompatibleProfile === true;
|
|
962
|
+
if (storedFingerprint !== actualFingerprint && !explicitReplacement) {
|
|
963
|
+
throw incompatibleLaunchProfileError(id, [
|
|
964
|
+
storedFingerprint
|
|
965
|
+
? "profile-fingerprint-mismatch"
|
|
966
|
+
: "profile-fingerprint-missing",
|
|
967
|
+
]);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
if (options.launchProfileOverride) {
|
|
971
|
+
let proposed;
|
|
972
|
+
try {
|
|
973
|
+
proposed = normalizeBackgroundLaunchProfile(
|
|
974
|
+
options.launchProfileOverride,
|
|
975
|
+
);
|
|
976
|
+
} catch (error) {
|
|
977
|
+
throw incompatibleLaunchProfileError(id, [
|
|
978
|
+
`invalid-profile-override:${error.message}`,
|
|
979
|
+
]);
|
|
980
|
+
}
|
|
981
|
+
const compatibility = assessBackgroundLaunchProfileCompatibility(
|
|
982
|
+
persisted,
|
|
983
|
+
proposed,
|
|
984
|
+
);
|
|
985
|
+
if (
|
|
986
|
+
!compatibility.compatible &&
|
|
987
|
+
options.allowIncompatibleProfile !== true
|
|
988
|
+
) {
|
|
989
|
+
throw incompatibleLaunchProfileError(id, compatibility.reasons);
|
|
990
|
+
}
|
|
991
|
+
launchProfile = proposed;
|
|
992
|
+
} else {
|
|
993
|
+
launchProfile = persisted;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
const sourceCheck = verifyBackgroundLaunchProfileSources(launchProfile);
|
|
997
|
+
if (!sourceCheck.valid && options.allowIncompatibleProfile !== true) {
|
|
998
|
+
throw incompatibleLaunchProfileError(id, sourceCheck.issues);
|
|
999
|
+
}
|
|
1000
|
+
if (!sourceCheck.valid) {
|
|
1001
|
+
launchProfile = refreshBackgroundLaunchProfileSources(launchProfile);
|
|
1002
|
+
}
|
|
1003
|
+
if (
|
|
1004
|
+
launchProfile.credentials.apiKey === "external" &&
|
|
1005
|
+
!options.apiKey &&
|
|
1006
|
+
!process.env.CC_API_KEY
|
|
1007
|
+
) {
|
|
1008
|
+
throw incompatibleLaunchProfileError(id, [
|
|
1009
|
+
"external-api-key-unavailable",
|
|
1010
|
+
]);
|
|
1011
|
+
}
|
|
1012
|
+
} else if (options.launchProfileOverride) {
|
|
1013
|
+
// Explicit profiles can migrate legacy records, which have no prior
|
|
1014
|
+
// launch envelope to compare against.
|
|
1015
|
+
launchProfile = normalizeBackgroundLaunchProfile(
|
|
1016
|
+
options.launchProfileOverride,
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const followUpArgv = launchProfile
|
|
1021
|
+
? [
|
|
1022
|
+
...buildArgvFromBackgroundLaunchProfile(launchProfile),
|
|
1023
|
+
"--session",
|
|
1024
|
+
state.sessionId,
|
|
1025
|
+
]
|
|
1026
|
+
: ["agent", "--session", state.sessionId];
|
|
1027
|
+
const argv = [...followUpArgv, "-p", text];
|
|
897
1028
|
return launchBackgroundAgent({
|
|
898
1029
|
argv,
|
|
899
1030
|
// Worktree sessions fail closed: never fall back to process.cwd(), which
|
|
@@ -902,9 +1033,19 @@ export function resumeBackgroundAgent(id, prompt, options = {}) {
|
|
|
902
1033
|
sessionId: state.sessionId,
|
|
903
1034
|
title: options.title || state.title || text.slice(0, 100),
|
|
904
1035
|
cliEntry: options.cliEntry,
|
|
905
|
-
followUpArgv
|
|
1036
|
+
followUpArgv,
|
|
906
1037
|
worktree,
|
|
907
|
-
governance:
|
|
1038
|
+
governance: launchProfile
|
|
1039
|
+
? {
|
|
1040
|
+
permissionMode: launchProfile.permission.mode,
|
|
1041
|
+
resourceBudget: {
|
|
1042
|
+
maxTurns: launchProfile.budget.maxTurns,
|
|
1043
|
+
maxCostUsd: launchProfile.budget.maxCostUsd,
|
|
1044
|
+
},
|
|
1045
|
+
}
|
|
1046
|
+
: state.governance,
|
|
1047
|
+
launchProfile,
|
|
1048
|
+
apiKey: options.apiKey,
|
|
908
1049
|
});
|
|
909
1050
|
}
|
|
910
1051
|
|
|
@@ -944,6 +1085,8 @@ export function launchBackgroundAgent({
|
|
|
944
1085
|
followUpArgv,
|
|
945
1086
|
worktree,
|
|
946
1087
|
governance,
|
|
1088
|
+
launchProfile,
|
|
1089
|
+
apiKey,
|
|
947
1090
|
}) {
|
|
948
1091
|
assertUsableCwd(cwd);
|
|
949
1092
|
const worktreeState = normalizeBackgroundWorktree(worktree, cwd);
|
|
@@ -952,6 +1095,28 @@ export function launchBackgroundAgent({
|
|
|
952
1095
|
id,
|
|
953
1096
|
sessionId,
|
|
954
1097
|
});
|
|
1098
|
+
const initialSecrets = stripBackgroundLaunchSecrets(argv);
|
|
1099
|
+
const followUpSecrets = stripBackgroundLaunchSecrets(followUpArgv);
|
|
1100
|
+
const forwardedApiKey =
|
|
1101
|
+
apiKey || initialSecrets.apiKey || followUpSecrets.apiKey || null;
|
|
1102
|
+
const runtimeApiKey = forwardedApiKey || process.env.CC_API_KEY || null;
|
|
1103
|
+
let launchProfileState = launchProfile
|
|
1104
|
+
? normalizeBackgroundLaunchProfile(launchProfile)
|
|
1105
|
+
: captureBackgroundLaunchProfile({
|
|
1106
|
+
argv,
|
|
1107
|
+
cwd,
|
|
1108
|
+
worktree: worktreeState,
|
|
1109
|
+
governance: governanceState,
|
|
1110
|
+
});
|
|
1111
|
+
if (runtimeApiKey && launchProfileState.credentials.apiKey !== "external") {
|
|
1112
|
+
launchProfileState = normalizeBackgroundLaunchProfile({
|
|
1113
|
+
...launchProfileState,
|
|
1114
|
+
credentials: { apiKey: "external" },
|
|
1115
|
+
omitted: [...launchProfileState.omitted, "apiKey"],
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
1118
|
+
const configFingerprint =
|
|
1119
|
+
fingerprintBackgroundLaunchProfile(launchProfileState);
|
|
955
1120
|
const dir = backgroundAgentsDir();
|
|
956
1121
|
const jobFile = join(dir, `${id}.job.${process.pid}.json`);
|
|
957
1122
|
const worker = fileURLToPath(
|
|
@@ -959,7 +1124,7 @@ export function launchBackgroundAgent({
|
|
|
959
1124
|
);
|
|
960
1125
|
const job = {
|
|
961
1126
|
id,
|
|
962
|
-
argv,
|
|
1127
|
+
argv: initialSecrets.argv,
|
|
963
1128
|
cwd,
|
|
964
1129
|
sessionId,
|
|
965
1130
|
title: title || "Background agent",
|
|
@@ -969,7 +1134,9 @@ export function launchBackgroundAgent({
|
|
|
969
1134
|
governance: governanceState,
|
|
970
1135
|
// Present = interactive attach can start follow-up turns; absent = the
|
|
971
1136
|
// transport rejects prompts (log-only session).
|
|
972
|
-
...(Array.isArray(followUpArgv)
|
|
1137
|
+
...(Array.isArray(followUpArgv)
|
|
1138
|
+
? { followUpArgv: followUpSecrets.argv }
|
|
1139
|
+
: {}),
|
|
973
1140
|
};
|
|
974
1141
|
writeFileSync(jobFile, JSON.stringify(job), { mode: 0o600 });
|
|
975
1142
|
// Write the initial state BEFORE spawning so the worker's own merges (the
|
|
@@ -992,6 +1159,8 @@ export function launchBackgroundAgent({
|
|
|
992
1159
|
logFile: job.logFile,
|
|
993
1160
|
...(worktreeState || {}),
|
|
994
1161
|
governance: governanceState,
|
|
1162
|
+
launchProfile: launchProfileState,
|
|
1163
|
+
configFingerprint,
|
|
995
1164
|
};
|
|
996
1165
|
writeBackgroundAgentState(state);
|
|
997
1166
|
let child;
|
|
@@ -1007,6 +1176,9 @@ export function launchBackgroundAgent({
|
|
|
1007
1176
|
detached: true,
|
|
1008
1177
|
stdio: ["ignore", workerLogFd, workerLogFd],
|
|
1009
1178
|
windowsHide: true,
|
|
1179
|
+
...(forwardedApiKey
|
|
1180
|
+
? { env: { ...process.env, CC_API_KEY: forwardedApiKey } }
|
|
1181
|
+
: {}),
|
|
1010
1182
|
origin: "background-agent:worker",
|
|
1011
1183
|
policy: "allow",
|
|
1012
1184
|
scope: "background-agent",
|
|
@@ -11,6 +11,7 @@ import { createHash } from "node:crypto";
|
|
|
11
11
|
import {
|
|
12
12
|
appendEvent as storeAppendEvent,
|
|
13
13
|
readEvents as storeReadEvents,
|
|
14
|
+
findLatestEvent as storeFindLatestEvent,
|
|
14
15
|
} from "../harness/jsonl-session-store.js";
|
|
15
16
|
import {
|
|
16
17
|
normalizeInteractionBinding,
|
|
@@ -27,8 +28,41 @@ const TERMINAL_STATUSES = new Set(["resolved", "rejected", "cancelled"]);
|
|
|
27
28
|
export const _deps = {
|
|
28
29
|
appendEvent: storeAppendEvent,
|
|
29
30
|
readEvents: storeReadEvents,
|
|
31
|
+
findLatestEvent: storeFindLatestEvent,
|
|
30
32
|
};
|
|
31
33
|
|
|
34
|
+
function findLatestJournalEvent(sessionId, backgroundAgentId) {
|
|
35
|
+
const valid = (event) => event?.data?.backgroundAgentId === backgroundAgentId;
|
|
36
|
+
if (
|
|
37
|
+
typeof _deps.findLatestEvent === "function" &&
|
|
38
|
+
_deps.findLatestEvent !== storeFindLatestEvent
|
|
39
|
+
) {
|
|
40
|
+
return _deps.findLatestEvent(
|
|
41
|
+
sessionId,
|
|
42
|
+
BACKGROUND_INTERACTION_JOURNAL_EVENT,
|
|
43
|
+
valid,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (_deps.readEvents !== storeReadEvents) {
|
|
47
|
+
const events = _deps.readEvents(sessionId) || [];
|
|
48
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
49
|
+
const event = events[index];
|
|
50
|
+
if (
|
|
51
|
+
event?.type === BACKGROUND_INTERACTION_JOURNAL_EVENT &&
|
|
52
|
+
valid(event)
|
|
53
|
+
) {
|
|
54
|
+
return event;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return storeFindLatestEvent(
|
|
60
|
+
sessionId,
|
|
61
|
+
BACKGROUND_INTERACTION_JOURNAL_EVENT,
|
|
62
|
+
valid,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
32
66
|
function journalError(message, code, details = {}) {
|
|
33
67
|
const error = new Error(message);
|
|
34
68
|
error.code = code;
|
|
@@ -316,15 +350,9 @@ export function loadBackgroundInteractionJournal(
|
|
|
316
350
|
if (!sessionId || !backgroundAgentId) {
|
|
317
351
|
throw new TypeError("sessionId and backgroundAgentId are required");
|
|
318
352
|
}
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (
|
|
323
|
-
event?.type === BACKGROUND_INTERACTION_JOURNAL_EVENT &&
|
|
324
|
-
event.data?.backgroundAgentId === backgroundAgentId
|
|
325
|
-
) {
|
|
326
|
-
return BackgroundInteractionJournal.fromJSON(event.data, options);
|
|
327
|
-
}
|
|
353
|
+
const event = findLatestJournalEvent(sessionId, backgroundAgentId);
|
|
354
|
+
if (event) {
|
|
355
|
+
return BackgroundInteractionJournal.fromJSON(event.data, options);
|
|
328
356
|
}
|
|
329
357
|
return new BackgroundInteractionJournal({
|
|
330
358
|
backgroundAgentId,
|