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
|
@@ -44,6 +44,7 @@ export class SubAgentContext {
|
|
|
44
44
|
* @param {string[]} [options.allowedTools] - Tool whitelist (null = all tools)
|
|
45
45
|
* @param {number} [options.maxIterations] - Iteration limit (fallback if no budget)
|
|
46
46
|
* @param {import('./iteration-budget.js').IterationBudget} [options.iterationBudget] - Shared iteration budget (takes priority over maxIterations)
|
|
47
|
+
* @param {import('./session-resource-budget.js').SessionResourceBudget} [options.sessionBudget] - Shared session-wide resource authority
|
|
47
48
|
* @param {number} [options.tokenBudget] - Optional token budget
|
|
48
49
|
* @param {object} [options.db] - Database instance (memory recall source)
|
|
49
50
|
* @param {object} [options.permanentMemory] - Permanent memory instance
|
|
@@ -72,9 +73,10 @@ export class SubAgentContext {
|
|
|
72
73
|
this._profile?.maxIterations ||
|
|
73
74
|
DEFAULT_MAX_ITERATIONS;
|
|
74
75
|
this.iterationBudget = options.iterationBudget || null; // shared budget from parent
|
|
76
|
+
this.sessionBudget = options.sessionBudget || null;
|
|
75
77
|
this.tokenBudget = options.tokenBudget || null;
|
|
76
78
|
this.inheritedContext = options.inheritedContext || null;
|
|
77
|
-
this.allowedTools = options.allowedTools
|
|
79
|
+
this.allowedTools = options.allowedTools ?? null; // null = all; [] = none
|
|
78
80
|
this.depth = options.depth || 1; // nesting level (parent main loop = 0)
|
|
79
81
|
// Shared run-wide TOTAL-sub-agent counter (one object across the whole tree)
|
|
80
82
|
// so this sub-agent's own spawns draw from the same breadth pool.
|
|
@@ -163,7 +165,12 @@ export class SubAgentContext {
|
|
|
163
165
|
// registry's `cancel(id)`), independent of any external signal.
|
|
164
166
|
this._signal = options.signal || null;
|
|
165
167
|
this._abortController = new AbortController();
|
|
168
|
+
this._runAbortController = null;
|
|
169
|
+
this._abortLinkCleanup = [];
|
|
166
170
|
this._cancelReason = null;
|
|
171
|
+
this._sessionBudgetLease = null;
|
|
172
|
+
this._unregisterSessionAbortable = null;
|
|
173
|
+
this._running = false;
|
|
167
174
|
|
|
168
175
|
// Optional MCP / external tool plumbing. These are forwarded into the
|
|
169
176
|
// agentLoop options so MCP-backed tools (e.g. from a cowork template's
|
|
@@ -183,6 +190,8 @@ export class SubAgentContext {
|
|
|
183
190
|
? options.externalToolExecutors
|
|
184
191
|
: {};
|
|
185
192
|
this._mcpClient = options.mcpClient || null;
|
|
193
|
+
this._mcpCallLedger = options.mcpCallLedger || null;
|
|
194
|
+
this._mcpConflictScheduler = options.mcpConflictScheduler || null;
|
|
186
195
|
|
|
187
196
|
// Inherited settings hooks (Pre/PostToolUse) for this child loop. null =
|
|
188
197
|
// no hooks (the spawn default). The spawn path passes the parent's hooks
|
|
@@ -200,6 +209,22 @@ export class SubAgentContext {
|
|
|
200
209
|
// gated headlessly (CONFIRM→no-confirmer→DENY).
|
|
201
210
|
this._approvalGate = options.approvalGate || null;
|
|
202
211
|
|
|
212
|
+
// Parent execution authority. These values are applied AFTER any internal
|
|
213
|
+
// loop options so a child/worktree path can tighten but never replace the
|
|
214
|
+
// parent's policy, Plan lock, workspace sandbox, or unattended boundary.
|
|
215
|
+
this._parentAuthority = Object.freeze({
|
|
216
|
+
permissionRules: options.permissionRules || null,
|
|
217
|
+
hostManagedToolPolicy: options.hostManagedToolPolicy || null,
|
|
218
|
+
planManager: options.planManager || null,
|
|
219
|
+
sandbox: options.sandbox || null,
|
|
220
|
+
additionalDirectories: Array.isArray(options.additionalDirectories)
|
|
221
|
+
? Object.freeze([...options.additionalDirectories])
|
|
222
|
+
: null,
|
|
223
|
+
shellPolicyOverrides: options.shellPolicyOverrides || null,
|
|
224
|
+
classifyAllShell: options.classifyAllShell === true,
|
|
225
|
+
unattendedActionPolicy: options.unattendedActionPolicy || null,
|
|
226
|
+
});
|
|
227
|
+
|
|
203
228
|
// Build isolated system prompt
|
|
204
229
|
const basePrompt = buildSystemPrompt(this.cwd);
|
|
205
230
|
const profilePrompt = this._profile?.systemPrompt
|
|
@@ -231,28 +256,139 @@ export class SubAgentContext {
|
|
|
231
256
|
);
|
|
232
257
|
}
|
|
233
258
|
|
|
234
|
-
|
|
235
|
-
if (
|
|
236
|
-
if (isGitRepo(this._repoDir)) {
|
|
237
|
-
return this._runInWorktree(userPrompt, loopOptions);
|
|
238
|
-
}
|
|
239
|
-
// FAIL CLOSED: isolation was explicitly requested but this is not a git
|
|
240
|
-
// repo. Never silently fall back to the parent checkout — refuse.
|
|
259
|
+
const admission = this._acquireSessionBudget();
|
|
260
|
+
if (!admission.ok) {
|
|
241
261
|
this.status = "failed";
|
|
242
262
|
this.completedAt = new Date().toISOString();
|
|
243
263
|
this.result = {
|
|
244
|
-
summary:
|
|
245
|
-
"Worktree isolation was requested but the working directory is not a git repository — refusing to run in the parent checkout.",
|
|
264
|
+
summary: `Sub-agent blocked by session budget: ${admission.reason}`,
|
|
246
265
|
artifacts: [],
|
|
247
266
|
tokenCount: this._tokenCount,
|
|
248
267
|
toolsUsed: [...new Set(this._toolsUsed)],
|
|
249
268
|
iterationCount: this._iterationCount,
|
|
250
|
-
|
|
269
|
+
budgetReason: admission.reason,
|
|
251
270
|
};
|
|
252
271
|
return this.result;
|
|
253
272
|
}
|
|
254
273
|
|
|
255
|
-
|
|
274
|
+
this._running = true;
|
|
275
|
+
try {
|
|
276
|
+
this._activateAbortLinks(loopOptions.signal || null);
|
|
277
|
+
|
|
278
|
+
// If worktree isolation is enabled, wrap execution in isolated worktree.
|
|
279
|
+
if (this._useWorktree) {
|
|
280
|
+
if (isGitRepo(this._repoDir)) {
|
|
281
|
+
return await this._runInWorktree(userPrompt, loopOptions);
|
|
282
|
+
}
|
|
283
|
+
// FAIL CLOSED: isolation was explicitly requested but this is not a git
|
|
284
|
+
// repo. Never silently fall back to the parent checkout — refuse.
|
|
285
|
+
this.status = "failed";
|
|
286
|
+
this.completedAt = new Date().toISOString();
|
|
287
|
+
this.result = {
|
|
288
|
+
summary:
|
|
289
|
+
"Worktree isolation was requested but the working directory is not a git repository — refusing to run in the parent checkout.",
|
|
290
|
+
artifacts: [],
|
|
291
|
+
tokenCount: this._tokenCount,
|
|
292
|
+
toolsUsed: [...new Set(this._toolsUsed)],
|
|
293
|
+
iterationCount: this._iterationCount,
|
|
294
|
+
isolationError: true,
|
|
295
|
+
};
|
|
296
|
+
return this.result;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return await this._runCore(userPrompt, loopOptions);
|
|
300
|
+
} finally {
|
|
301
|
+
this._running = false;
|
|
302
|
+
this._deactivateAbortLinks();
|
|
303
|
+
this._releaseSessionBudget();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
_acquireSessionBudget() {
|
|
308
|
+
if (!this.sessionBudget?.acquireWork) return { ok: true };
|
|
309
|
+
const lease = this.sessionBudget.acquireWork({
|
|
310
|
+
id: this.id,
|
|
311
|
+
kind: "sub-agent",
|
|
312
|
+
depth: this.depth,
|
|
313
|
+
});
|
|
314
|
+
if (!lease.ok) return lease;
|
|
315
|
+
this._sessionBudgetLease = lease;
|
|
316
|
+
try {
|
|
317
|
+
this._unregisterSessionAbortable =
|
|
318
|
+
this.sessionBudget.registerAbortable?.(
|
|
319
|
+
`sub-agent:${this.id}`,
|
|
320
|
+
(reason) =>
|
|
321
|
+
this.abort(
|
|
322
|
+
reason?.budgetReason || reason?.message || "session-budget",
|
|
323
|
+
),
|
|
324
|
+
) || null;
|
|
325
|
+
} catch (error) {
|
|
326
|
+
lease.release();
|
|
327
|
+
this._sessionBudgetLease = null;
|
|
328
|
+
throw error;
|
|
329
|
+
}
|
|
330
|
+
return lease;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
_releaseSessionBudget() {
|
|
334
|
+
try {
|
|
335
|
+
this._unregisterSessionAbortable?.();
|
|
336
|
+
} catch {
|
|
337
|
+
// Session cancellation remains authoritative if observer cleanup fails.
|
|
338
|
+
}
|
|
339
|
+
this._unregisterSessionAbortable = null;
|
|
340
|
+
try {
|
|
341
|
+
this._sessionBudgetLease?.release?.();
|
|
342
|
+
} catch {
|
|
343
|
+
// A released/aborted budget lease is idempotent.
|
|
344
|
+
}
|
|
345
|
+
this._sessionBudgetLease = null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
_activateAbortLinks(extraSignal = null) {
|
|
349
|
+
this._deactivateAbortLinks();
|
|
350
|
+
this._runAbortController = new AbortController();
|
|
351
|
+
const signals = [
|
|
352
|
+
this._signal,
|
|
353
|
+
this._abortController.signal,
|
|
354
|
+
this.sessionBudget?.signal || null,
|
|
355
|
+
extraSignal,
|
|
356
|
+
].filter(Boolean);
|
|
357
|
+
for (const source of signals) {
|
|
358
|
+
const propagate = () => {
|
|
359
|
+
if (!this._cancelReason) {
|
|
360
|
+
this._cancelReason =
|
|
361
|
+
source.reason?.budgetReason ||
|
|
362
|
+
source.reason?.message ||
|
|
363
|
+
"cancelled";
|
|
364
|
+
}
|
|
365
|
+
if (!this._runAbortController.signal.aborted) {
|
|
366
|
+
try {
|
|
367
|
+
this._runAbortController.abort(source.reason);
|
|
368
|
+
} catch {
|
|
369
|
+
this._runAbortController.abort();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
if (source.aborted) propagate();
|
|
374
|
+
else {
|
|
375
|
+
source.addEventListener?.("abort", propagate, { once: true });
|
|
376
|
+
this._abortLinkCleanup.push(() =>
|
|
377
|
+
source.removeEventListener?.("abort", propagate),
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
_deactivateAbortLinks() {
|
|
384
|
+
for (const cleanup of this._abortLinkCleanup.splice(0)) {
|
|
385
|
+
try {
|
|
386
|
+
cleanup();
|
|
387
|
+
} catch {
|
|
388
|
+
// Abort-listener removal is best-effort cleanup only.
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
this._runAbortController = null;
|
|
256
392
|
}
|
|
257
393
|
|
|
258
394
|
/**
|
|
@@ -332,7 +468,7 @@ export class SubAgentContext {
|
|
|
332
468
|
// computed via _getFilteredTools() but never handed to agentLoop, so a
|
|
333
469
|
// sub-agent's `tools`/frontmatter allowlist was silently ignored at the
|
|
334
470
|
// LLM surface. agentLoop consumes NAMES via enabledToolNames.
|
|
335
|
-
...(Array.isArray(this.allowedTools)
|
|
471
|
+
...(Array.isArray(this.allowedTools)
|
|
336
472
|
? { enabledToolNames: this.allowedTools }
|
|
337
473
|
: {}),
|
|
338
474
|
contextEngine: this.contextEngine,
|
|
@@ -342,6 +478,7 @@ export class SubAgentContext {
|
|
|
342
478
|
// Shared total-sub-agent counter so a nested spawn_sub_agent draws from
|
|
343
479
|
// (and is bounded by) the run's single breadth pool.
|
|
344
480
|
subAgentBudget: this.subAgentBudget,
|
|
481
|
+
sessionBudget: this.sessionBudget,
|
|
345
482
|
// This context's effective contract = the ceiling for its nested spawns.
|
|
346
483
|
subAgentContract: this.subAgentContract,
|
|
347
484
|
toolAdmission: this.toolAdmission,
|
|
@@ -353,6 +490,39 @@ export class SubAgentContext {
|
|
|
353
490
|
: {}),
|
|
354
491
|
...loopOptions,
|
|
355
492
|
};
|
|
493
|
+
// Re-apply tighten-only capability fields after loopOptions. In particular,
|
|
494
|
+
// [] must survive as deny-all and cannot be replaced by a worktree/direct
|
|
495
|
+
// runner override.
|
|
496
|
+
if (Array.isArray(this.allowedTools)) {
|
|
497
|
+
options.enabledToolNames = [...this.allowedTools];
|
|
498
|
+
options.exactToolNames = true;
|
|
499
|
+
}
|
|
500
|
+
options.subAgentContract = this.subAgentContract;
|
|
501
|
+
options.sessionBudget = this.sessionBudget;
|
|
502
|
+
if (this._runAbortController) {
|
|
503
|
+
options.signal = this._runAbortController.signal;
|
|
504
|
+
}
|
|
505
|
+
options.toolAdmission = this.toolAdmission;
|
|
506
|
+
options.skillAllowlist = this.skillAllowlist;
|
|
507
|
+
const authority = this._parentAuthority;
|
|
508
|
+
if (authority.permissionRules) {
|
|
509
|
+
options.permissionRules = authority.permissionRules;
|
|
510
|
+
}
|
|
511
|
+
if (authority.hostManagedToolPolicy) {
|
|
512
|
+
options.hostManagedToolPolicy = authority.hostManagedToolPolicy;
|
|
513
|
+
}
|
|
514
|
+
if (authority.planManager) options.planManager = authority.planManager;
|
|
515
|
+
if (authority.sandbox) options.sandbox = authority.sandbox;
|
|
516
|
+
if (authority.additionalDirectories) {
|
|
517
|
+
options.additionalDirectories = [...authority.additionalDirectories];
|
|
518
|
+
}
|
|
519
|
+
if (authority.shellPolicyOverrides) {
|
|
520
|
+
options.shellPolicyOverrides = authority.shellPolicyOverrides;
|
|
521
|
+
}
|
|
522
|
+
if (authority.classifyAllShell) options.classifyAllShell = true;
|
|
523
|
+
if (authority.unattendedActionPolicy) {
|
|
524
|
+
options.unattendedActionPolicy = authority.unattendedActionPolicy;
|
|
525
|
+
}
|
|
356
526
|
if (this.iterationBudget) {
|
|
357
527
|
options.iterationBudget = this.iterationBudget;
|
|
358
528
|
}
|
|
@@ -379,6 +549,12 @@ export class SubAgentContext {
|
|
|
379
549
|
if (this._mcpClient) {
|
|
380
550
|
options.mcpClient = this._mcpClient;
|
|
381
551
|
}
|
|
552
|
+
if (this._mcpCallLedger) {
|
|
553
|
+
options.mcpCallLedger = this._mcpCallLedger;
|
|
554
|
+
}
|
|
555
|
+
if (this._mcpConflictScheduler) {
|
|
556
|
+
options.mcpConflictScheduler = this._mcpConflictScheduler;
|
|
557
|
+
}
|
|
382
558
|
// Inherited Pre/PostToolUse hooks (spawn passes the parent's, filtered by
|
|
383
559
|
// the contract's `hooks` allow-list). Only set when non-null so a plain
|
|
384
560
|
// sub-agent keeps its no-hooks default.
|
|
@@ -420,18 +596,31 @@ export class SubAgentContext {
|
|
|
420
596
|
}
|
|
421
597
|
}
|
|
422
598
|
|
|
423
|
-
if (event.type === "token-usage"
|
|
424
|
-
//
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
|
|
599
|
+
if (event.type === "token-usage") {
|
|
600
|
+
// Attributed usage was already charged by the nested child sharing
|
|
601
|
+
// this same authority. Only direct usage is folded here, otherwise a
|
|
602
|
+
// child-of-child would be counted once at every ancestor level.
|
|
603
|
+
if (!event.attribution && this.sessionBudget?.recordUsage) {
|
|
604
|
+
this.sessionBudget.recordUsage({
|
|
428
605
|
provider: event.provider || null,
|
|
429
606
|
model: event.model || null,
|
|
430
607
|
usage: event.usage || null,
|
|
431
|
-
attribution: event.attribution || null,
|
|
432
608
|
});
|
|
433
|
-
}
|
|
434
|
-
|
|
609
|
+
}
|
|
610
|
+
if (this._onUsage) {
|
|
611
|
+
// Forward real usage to the spawner. A nested child's event already
|
|
612
|
+
// carries its own attribution frame — preserve it (deepest wins).
|
|
613
|
+
try {
|
|
614
|
+
this._onUsage({
|
|
615
|
+
provider: event.provider || null,
|
|
616
|
+
model: event.model || null,
|
|
617
|
+
usage: event.usage || null,
|
|
618
|
+
...(event.source ? { source: event.source } : {}),
|
|
619
|
+
attribution: event.attribution || null,
|
|
620
|
+
});
|
|
621
|
+
} catch (_e) {
|
|
622
|
+
// Usage forwarding is best-effort — never break the child loop
|
|
623
|
+
}
|
|
435
624
|
}
|
|
436
625
|
}
|
|
437
626
|
|
|
@@ -499,6 +688,13 @@ export class SubAgentContext {
|
|
|
499
688
|
}
|
|
500
689
|
}
|
|
501
690
|
} catch (err) {
|
|
691
|
+
if (this.isAborted()) {
|
|
692
|
+
this.forceComplete(this._cancelReason || "cancelled", {
|
|
693
|
+
partialContent: lastContent,
|
|
694
|
+
artifacts,
|
|
695
|
+
});
|
|
696
|
+
return this.result;
|
|
697
|
+
}
|
|
502
698
|
this.status = "failed";
|
|
503
699
|
this.completedAt = new Date().toISOString();
|
|
504
700
|
// Return partial work to the parent instead of discarding it: the
|
|
@@ -527,6 +723,13 @@ export class SubAgentContext {
|
|
|
527
723
|
if (this.status !== "active") {
|
|
528
724
|
return this.result;
|
|
529
725
|
}
|
|
726
|
+
if (this.isAborted()) {
|
|
727
|
+
this.forceComplete(this._cancelReason || "cancelled", {
|
|
728
|
+
partialContent: lastContent,
|
|
729
|
+
artifacts,
|
|
730
|
+
});
|
|
731
|
+
return this.result;
|
|
732
|
+
}
|
|
530
733
|
|
|
531
734
|
// Summarize the result
|
|
532
735
|
const summary = this.summarize(lastContent);
|
|
@@ -590,7 +793,7 @@ export class SubAgentContext {
|
|
|
590
793
|
* @returns {Array} Filtered AGENT_TOOLS
|
|
591
794
|
*/
|
|
592
795
|
_getFilteredTools() {
|
|
593
|
-
if (
|
|
796
|
+
if (this.allowedTools === null) {
|
|
594
797
|
return AGENT_TOOLS;
|
|
595
798
|
}
|
|
596
799
|
return AGENT_TOOLS.filter((t) =>
|
|
@@ -638,10 +841,8 @@ export class SubAgentContext {
|
|
|
638
841
|
parentTraceId: this._hookParentTraceId || null,
|
|
639
842
|
checkpointIds: [...this._checkpointIds],
|
|
640
843
|
toolUseIds: [...this._toolUseIds],
|
|
641
|
-
worktreeId:
|
|
642
|
-
|
|
643
|
-
worktreePath:
|
|
644
|
-
worktree?.path || this._worktreePath || null,
|
|
844
|
+
worktreeId: worktree?.branch || this._worktreeBranch || null,
|
|
845
|
+
worktreePath: worktree?.path || this._worktreePath || null,
|
|
645
846
|
};
|
|
646
847
|
}
|
|
647
848
|
|
|
@@ -653,7 +854,10 @@ export class SubAgentContext {
|
|
|
653
854
|
*/
|
|
654
855
|
isAborted() {
|
|
655
856
|
return Boolean(
|
|
656
|
-
this._signal?.aborted ||
|
|
857
|
+
this._signal?.aborted ||
|
|
858
|
+
this._abortController.signal.aborted ||
|
|
859
|
+
this._runAbortController?.signal.aborted ||
|
|
860
|
+
this.sessionBudget?.signal?.aborted,
|
|
657
861
|
);
|
|
658
862
|
}
|
|
659
863
|
|
|
@@ -668,7 +872,11 @@ export class SubAgentContext {
|
|
|
668
872
|
return false;
|
|
669
873
|
}
|
|
670
874
|
this._cancelReason = reason;
|
|
671
|
-
|
|
875
|
+
try {
|
|
876
|
+
this._abortController.abort(reason);
|
|
877
|
+
} catch {
|
|
878
|
+
this._abortController.abort();
|
|
879
|
+
}
|
|
672
880
|
return true;
|
|
673
881
|
}
|
|
674
882
|
|
|
@@ -182,6 +182,10 @@ export class SubAgentRegistry {
|
|
|
182
182
|
forceCompleteAll(sessionId) {
|
|
183
183
|
for (const [id, subCtx] of this._active) {
|
|
184
184
|
if (!sessionId || subCtx.parentId === sessionId) {
|
|
185
|
+
// Trip the live loop's AbortSignal before recording a terminal result.
|
|
186
|
+
// forceComplete() alone only changed bookkeeping, so a provider/tool
|
|
187
|
+
// call could continue after the session had supposedly closed.
|
|
188
|
+
subCtx.abort?.("session-closed");
|
|
185
189
|
subCtx.forceComplete("session-closed");
|
|
186
190
|
this.complete(id, subCtx.result);
|
|
187
191
|
}
|
|
@@ -215,6 +219,7 @@ export class SubAgentRegistry {
|
|
|
215
219
|
const cutoff = Date.now() - maxAgeMs;
|
|
216
220
|
for (const [id, subCtx] of this._active) {
|
|
217
221
|
if (new Date(subCtx.createdAt).getTime() < cutoff) {
|
|
222
|
+
subCtx.abort?.("timeout");
|
|
218
223
|
subCtx.forceComplete("timeout");
|
|
219
224
|
this.complete(id, subCtx.result);
|
|
220
225
|
}
|
|
@@ -72,6 +72,100 @@ export const SUBAGENT_EFFORT_LEVELS = Object.freeze([
|
|
|
72
72
|
]);
|
|
73
73
|
const EFFORT_SYNONYMS = Object.freeze({ med: "medium", max: "xhigh" });
|
|
74
74
|
|
|
75
|
+
function contractValidationError(field, message) {
|
|
76
|
+
const error = new Error(
|
|
77
|
+
`invalid subagent contract field "${field}": ${message}`,
|
|
78
|
+
);
|
|
79
|
+
error.code = "CC_SUBAGENT_CONTRACT_INVALID";
|
|
80
|
+
return error;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Strict validation for authority-bearing declarations at the spawn boundary.
|
|
85
|
+
* The legacy normalizer remains permissive for read/display callers, but a
|
|
86
|
+
* malformed explicit field must never silently become "unspecified" and widen
|
|
87
|
+
* a live child session.
|
|
88
|
+
*/
|
|
89
|
+
export function assertValidSubagentContract(raw = {}) {
|
|
90
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
91
|
+
throw contractValidationError("contract", "expected an object");
|
|
92
|
+
}
|
|
93
|
+
if (
|
|
94
|
+
raw.permissionMode != null &&
|
|
95
|
+
!SUBAGENT_PERMISSION_MODES.includes(raw.permissionMode)
|
|
96
|
+
) {
|
|
97
|
+
throw contractValidationError(
|
|
98
|
+
"permissionMode",
|
|
99
|
+
`expected one of ${SUBAGENT_PERMISSION_MODES.join(", ")}`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
if (raw.context != null && !SUBAGENT_CONTEXT_MODES.includes(raw.context)) {
|
|
103
|
+
throw contractValidationError(
|
|
104
|
+
"context",
|
|
105
|
+
`expected one of ${SUBAGENT_CONTEXT_MODES.join(", ")}`,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
for (const field of ["skills", "mcpServers", "hooks"]) {
|
|
109
|
+
const value = raw[field];
|
|
110
|
+
if (value == null) continue;
|
|
111
|
+
if (
|
|
112
|
+
typeof value !== "string" &&
|
|
113
|
+
!(
|
|
114
|
+
Array.isArray(value) &&
|
|
115
|
+
value.every((entry) => typeof entry === "string")
|
|
116
|
+
)
|
|
117
|
+
) {
|
|
118
|
+
throw contractValidationError(field, "expected a string or string array");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const field of ["tools", "disallowedTools"]) {
|
|
122
|
+
const value = raw[field];
|
|
123
|
+
if (
|
|
124
|
+
value != null &&
|
|
125
|
+
!(
|
|
126
|
+
Array.isArray(value) &&
|
|
127
|
+
value.every((entry) => typeof entry === "string")
|
|
128
|
+
)
|
|
129
|
+
) {
|
|
130
|
+
throw contractValidationError(field, "expected a string array");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
for (const field of ["memory", "background"]) {
|
|
134
|
+
if (raw[field] != null && toBool(raw[field]) == null) {
|
|
135
|
+
throw contractValidationError(field, "expected a boolean value");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (raw.effort != null) {
|
|
139
|
+
const effort = String(raw.effort).trim().toLowerCase();
|
|
140
|
+
const canonical = EFFORT_SYNONYMS[effort] || effort;
|
|
141
|
+
if (!SUBAGENT_EFFORT_LEVELS.includes(canonical)) {
|
|
142
|
+
throw contractValidationError(
|
|
143
|
+
"effort",
|
|
144
|
+
`expected one of ${SUBAGENT_EFFORT_LEVELS.join(", ")}`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
for (const field of ["maxDepth", "maxChildren"]) {
|
|
149
|
+
if (raw[field] != null && toPosInt(raw[field]) == null) {
|
|
150
|
+
throw contractValidationError(field, "expected a positive integer");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (raw.budget != null) {
|
|
154
|
+
if (typeof raw.budget !== "object" || Array.isArray(raw.budget)) {
|
|
155
|
+
throw contractValidationError("budget", "expected an object");
|
|
156
|
+
}
|
|
157
|
+
for (const field of ["tokens", "cost", "costUsd", "time", "timeMs"]) {
|
|
158
|
+
if (raw.budget[field] != null && toPosNum(raw.budget[field]) == null) {
|
|
159
|
+
throw contractValidationError(
|
|
160
|
+
`budget.${field}`,
|
|
161
|
+
"expected a positive number",
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return raw;
|
|
167
|
+
}
|
|
168
|
+
|
|
75
169
|
// ─── small pure helpers ─────────────────────────────────────────────────────
|
|
76
170
|
|
|
77
171
|
function toBool(v) {
|