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
package/src/commands/config.js
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
2
3
|
import {
|
|
3
4
|
loadConfig,
|
|
4
5
|
getConfigValue,
|
|
5
6
|
setConfigValue,
|
|
6
7
|
resetConfig,
|
|
7
8
|
saveConfig,
|
|
9
|
+
loadUserConfig,
|
|
10
|
+
setSecretConfigValue,
|
|
11
|
+
backupConfigForMigration,
|
|
12
|
+
withConfigLock,
|
|
8
13
|
} from "../lib/config-manager.js";
|
|
9
|
-
import { getConfigPath } from "../lib/paths.js";
|
|
14
|
+
import { getConfigPath, getHomeDir } from "../lib/paths.js";
|
|
10
15
|
import logger from "../lib/logger.js";
|
|
11
16
|
import { listFeatures, setFeature, getFlagInfo } from "../lib/feature-flags.js";
|
|
12
17
|
import { executionBroker } from "../lib/process-execution-broker/index.js";
|
|
18
|
+
import {
|
|
19
|
+
CONFIG_SCHEMA_VERSION,
|
|
20
|
+
getConfigDescriptor,
|
|
21
|
+
getConfigDescriptors,
|
|
22
|
+
getConfigJsonSchema,
|
|
23
|
+
isSecretConfigKey,
|
|
24
|
+
migrateConfigDocument,
|
|
25
|
+
validateConfigDocument,
|
|
26
|
+
} from "../lib/config-schema.js";
|
|
27
|
+
import {
|
|
28
|
+
CONFIG_REDACTED,
|
|
29
|
+
redactConfigObject,
|
|
30
|
+
redactConfigValue,
|
|
31
|
+
} from "../lib/config-redaction.js";
|
|
32
|
+
import {
|
|
33
|
+
ensurePrivateDirectory,
|
|
34
|
+
inspectPrivatePaths,
|
|
35
|
+
repairPrivatePaths,
|
|
36
|
+
} from "../lib/secure-fs.js";
|
|
13
37
|
|
|
14
38
|
export const _deps = {
|
|
15
39
|
spawnSync: (...args) => executionBroker.spawnSync(...args),
|
|
40
|
+
platform: () => process.platform,
|
|
16
41
|
};
|
|
17
42
|
|
|
18
43
|
/** Parse the conventional $EDITOR string without invoking a shell. */
|
|
@@ -79,6 +104,287 @@ export function openConfigEditor(editor, configPath, deps = _deps) {
|
|
|
79
104
|
});
|
|
80
105
|
}
|
|
81
106
|
|
|
107
|
+
export async function readSecretInput(options = {}) {
|
|
108
|
+
const stdin = options.stdin || process.stdin;
|
|
109
|
+
if (stdin.isTTY) {
|
|
110
|
+
const askPassword =
|
|
111
|
+
options.askPassword || (await import("../lib/prompts.js")).askPassword;
|
|
112
|
+
return String(await askPassword(options.message || "Secret value:"));
|
|
113
|
+
}
|
|
114
|
+
let value = "";
|
|
115
|
+
stdin.setEncoding?.("utf8");
|
|
116
|
+
for await (const chunk of stdin) value += chunk;
|
|
117
|
+
// Drop only line endings introduced by piping/Enter. Spaces may be part of
|
|
118
|
+
// the credential and must not be silently changed.
|
|
119
|
+
return value.replace(/[\r\n]+$/, "");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function getNested(obj, key) {
|
|
123
|
+
let current = obj;
|
|
124
|
+
for (const part of String(key).split(".")) {
|
|
125
|
+
if (current == null || typeof current !== "object") return undefined;
|
|
126
|
+
current = current[part];
|
|
127
|
+
}
|
|
128
|
+
return current;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function hasNested(obj, key) {
|
|
132
|
+
let current = obj;
|
|
133
|
+
for (const part of String(key).split(".")) {
|
|
134
|
+
if (
|
|
135
|
+
current == null ||
|
|
136
|
+
typeof current !== "object" ||
|
|
137
|
+
!Object.prototype.hasOwnProperty.call(current, part)
|
|
138
|
+
) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
current = current[part];
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function setNested(obj, key, value) {
|
|
147
|
+
const parts = String(key).split(".");
|
|
148
|
+
let current = obj;
|
|
149
|
+
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
150
|
+
current = current[parts[index]] ||= {};
|
|
151
|
+
}
|
|
152
|
+
current[parts.at(-1)] = value;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function recordUserProvenance(value, prefix, provenance, source) {
|
|
156
|
+
if (prefix) {
|
|
157
|
+
provenance[prefix] = {
|
|
158
|
+
source,
|
|
159
|
+
layer: "user",
|
|
160
|
+
overridden: [],
|
|
161
|
+
locked: false,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
165
|
+
for (const [name, child] of Object.entries(value)) {
|
|
166
|
+
recordUserProvenance(
|
|
167
|
+
child,
|
|
168
|
+
prefix ? `${prefix}.${name}` : name,
|
|
169
|
+
provenance,
|
|
170
|
+
source,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Inspect, and optionally repair, the owner-only config storage contract. */
|
|
176
|
+
export function checkConfigStoragePermissions(options = {}) {
|
|
177
|
+
const home = options.home || getHomeDir();
|
|
178
|
+
const configPath = options.configPath || getConfigPath();
|
|
179
|
+
const platform = options.platform || _deps.platform();
|
|
180
|
+
const secureOptions = { platform, ...(options.secureOptions || {}) };
|
|
181
|
+
const pathExists =
|
|
182
|
+
options.existsSync || secureOptions.deps?.fs?.existsSync || existsSync;
|
|
183
|
+
|
|
184
|
+
const definitions = [
|
|
185
|
+
{ name: "home", target: home, kind: "directory" },
|
|
186
|
+
{ name: "config", target: configPath, kind: "file" },
|
|
187
|
+
];
|
|
188
|
+
const results = new Map();
|
|
189
|
+
const existing = [];
|
|
190
|
+
for (const definition of definitions) {
|
|
191
|
+
let exists = false;
|
|
192
|
+
try {
|
|
193
|
+
exists = pathExists(definition.target);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
results.set(definition.name, {
|
|
196
|
+
ok: false,
|
|
197
|
+
exists: false,
|
|
198
|
+
platform,
|
|
199
|
+
error: error.message,
|
|
200
|
+
});
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (!exists && options.fix && definition.kind === "directory") {
|
|
204
|
+
try {
|
|
205
|
+
ensurePrivateDirectory(definition.target, {
|
|
206
|
+
...secureOptions,
|
|
207
|
+
failIfUnavailable: true,
|
|
208
|
+
});
|
|
209
|
+
results.set(definition.name, { ok: true, exists: true, platform });
|
|
210
|
+
} catch (error) {
|
|
211
|
+
results.set(definition.name, {
|
|
212
|
+
ok: false,
|
|
213
|
+
exists: false,
|
|
214
|
+
platform,
|
|
215
|
+
error: error.message,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (!exists) {
|
|
221
|
+
results.set(definition.name, { ok: false, exists: false, platform });
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
existing.push(definition);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (existing.length > 0) {
|
|
228
|
+
const targets = existing.map((entry) => entry.target);
|
|
229
|
+
let inspected;
|
|
230
|
+
try {
|
|
231
|
+
inspected = options.fix
|
|
232
|
+
? repairPrivatePaths(targets, secureOptions)
|
|
233
|
+
: inspectPrivatePaths(targets, secureOptions);
|
|
234
|
+
} catch (error) {
|
|
235
|
+
// A batch repair may partially succeed. Read back every target so the
|
|
236
|
+
// report reflects durable post-fix state rather than a generic failure.
|
|
237
|
+
inspected = inspectPrivatePaths(targets, secureOptions).map((entry) => ({
|
|
238
|
+
...entry,
|
|
239
|
+
...(entry.ok ? {} : { error: entry.error || error.message }),
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
for (let index = 0; index < existing.length; index += 1) {
|
|
243
|
+
results.set(existing[index].name, inspected[index]);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
home: results.get("home"),
|
|
249
|
+
config: results.get("config"),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Secure config.json for an editor without parsing or rewriting it. */
|
|
254
|
+
export function prepareConfigForEdit(options = {}) {
|
|
255
|
+
const configPath = options.configPath || getConfigPath();
|
|
256
|
+
const pathExists = options.existsSync || existsSync;
|
|
257
|
+
if (pathExists(configPath)) {
|
|
258
|
+
const checkPermissions =
|
|
259
|
+
options.checkPermissions || checkConfigStoragePermissions;
|
|
260
|
+
const permissions = checkPermissions({
|
|
261
|
+
fix: true,
|
|
262
|
+
configPath,
|
|
263
|
+
...(options.home ? { home: options.home } : {}),
|
|
264
|
+
});
|
|
265
|
+
if (!permissions.home.ok || !permissions.config.ok) {
|
|
266
|
+
throw new Error("Could not secure config.json before editing");
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
const load = options.loadConfig || loadConfig;
|
|
270
|
+
const save = options.saveConfig || saveConfig;
|
|
271
|
+
save(load());
|
|
272
|
+
}
|
|
273
|
+
return configPath;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const PROVIDER_KEY_ENV = Object.freeze({
|
|
277
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
278
|
+
openai: "OPENAI_API_KEY",
|
|
279
|
+
volcengine: "VOLCENGINE_API_KEY",
|
|
280
|
+
deepseek: "DEEPSEEK_API_KEY",
|
|
281
|
+
dashscope: "DASHSCOPE_API_KEY",
|
|
282
|
+
gemini: "GEMINI_API_KEY",
|
|
283
|
+
kimi: "MOONSHOT_API_KEY",
|
|
284
|
+
minimax: "MINIMAX_API_KEY",
|
|
285
|
+
mistral: "MISTRAL_API_KEY",
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
/** Resolve the config layers used by CLI agent startup, with provenance. */
|
|
289
|
+
export async function resolveEffectiveConfig(options = {}) {
|
|
290
|
+
const env = options.env || process.env;
|
|
291
|
+
const cwd = options.cwd || process.cwd();
|
|
292
|
+
const raw = loadUserConfig();
|
|
293
|
+
const config = loadConfig({ resolveSecrets: false });
|
|
294
|
+
const provenance = {};
|
|
295
|
+
let settingsLayer = {
|
|
296
|
+
files: [],
|
|
297
|
+
managedFile: null,
|
|
298
|
+
environmentVariables: [],
|
|
299
|
+
sandbox: null,
|
|
300
|
+
};
|
|
301
|
+
let settingsEnv = {};
|
|
302
|
+
let settingsEnvSources = {};
|
|
303
|
+
recordUserProvenance(raw, "", provenance, getConfigPath());
|
|
304
|
+
for (const entry of getConfigDescriptors()) {
|
|
305
|
+
if (!hasNested(raw, entry.key) && entry.default !== undefined) {
|
|
306
|
+
provenance[entry.key] = {
|
|
307
|
+
source: "built-in default",
|
|
308
|
+
layer: "default",
|
|
309
|
+
overridden: [],
|
|
310
|
+
locked: false,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
try {
|
|
316
|
+
const imported = await import("../lib/settings-loader.cjs");
|
|
317
|
+
const settings = imported.default || imported;
|
|
318
|
+
const loaded = settings.loadSettingsConfig({ cwd, env });
|
|
319
|
+
settingsEnv = loaded.env || {};
|
|
320
|
+
settingsEnvSources = loaded.envSources || {};
|
|
321
|
+
settingsLayer = {
|
|
322
|
+
files: loaded.files || [],
|
|
323
|
+
managedFile: loaded.managedFile || null,
|
|
324
|
+
environmentVariables: Object.keys(settingsEnv).sort(),
|
|
325
|
+
sandbox: redactConfigObject(loaded.sandbox),
|
|
326
|
+
};
|
|
327
|
+
if (loaded.model) {
|
|
328
|
+
const previous = provenance["llm.model"]?.source;
|
|
329
|
+
setNested(config, "llm.model", loaded.model);
|
|
330
|
+
const modelSource =
|
|
331
|
+
loaded.modelSource || loaded.files.at(-1) || "settings";
|
|
332
|
+
provenance["llm.model"] = {
|
|
333
|
+
source: modelSource,
|
|
334
|
+
layer:
|
|
335
|
+
loaded.managedFile && modelSource === loaded.managedFile
|
|
336
|
+
? "managed"
|
|
337
|
+
: "settings",
|
|
338
|
+
overridden: previous ? [previous] : [],
|
|
339
|
+
locked: Boolean(
|
|
340
|
+
loaded.managedFile && modelSource === loaded.managedFile,
|
|
341
|
+
),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
} catch (error) {
|
|
345
|
+
provenance.$settings = {
|
|
346
|
+
source: "settings",
|
|
347
|
+
layer: "error",
|
|
348
|
+
overridden: [],
|
|
349
|
+
locked: false,
|
|
350
|
+
error: error.message,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const provider = config?.llm?.provider;
|
|
355
|
+
const effectiveEnv = { ...env, ...settingsEnv };
|
|
356
|
+
const envName = effectiveEnv.CC_API_KEY
|
|
357
|
+
? "CC_API_KEY"
|
|
358
|
+
: PROVIDER_KEY_ENV[String(provider || "").toLowerCase()];
|
|
359
|
+
if (envName && effectiveEnv[envName]) {
|
|
360
|
+
const previous = provenance["llm.apiKey"]?.source;
|
|
361
|
+
const settingsSource = settingsEnvSources[envName];
|
|
362
|
+
setNested(config, "llm.apiKey", CONFIG_REDACTED);
|
|
363
|
+
provenance["llm.apiKey"] = {
|
|
364
|
+
source: settingsSource
|
|
365
|
+
? `${settingsSource}:env.${envName}`
|
|
366
|
+
: `environment:${envName}`,
|
|
367
|
+
layer:
|
|
368
|
+
settingsSource && settingsSource === settingsLayer.managedFile
|
|
369
|
+
? "managed"
|
|
370
|
+
: settingsSource
|
|
371
|
+
? "settings-environment"
|
|
372
|
+
: "environment",
|
|
373
|
+
overridden: previous ? [previous] : [],
|
|
374
|
+
locked: Boolean(
|
|
375
|
+
settingsSource && settingsSource === settingsLayer.managedFile,
|
|
376
|
+
),
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return {
|
|
381
|
+
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
382
|
+
config: redactConfigObject(config),
|
|
383
|
+
provenance,
|
|
384
|
+
settings: settingsLayer,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
82
388
|
export function registerConfigCommand(program) {
|
|
83
389
|
const cmd = program
|
|
84
390
|
.command("config")
|
|
@@ -87,8 +393,13 @@ export function registerConfigCommand(program) {
|
|
|
87
393
|
cmd
|
|
88
394
|
.command("list")
|
|
89
395
|
.description("Show all configuration values")
|
|
90
|
-
.
|
|
91
|
-
|
|
396
|
+
.option("--json", "Output redacted JSON")
|
|
397
|
+
.action((options) => {
|
|
398
|
+
const config = redactConfigObject(loadConfig({ resolveSecrets: false }));
|
|
399
|
+
if (options.json) {
|
|
400
|
+
console.log(JSON.stringify(config, null, 2));
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
92
403
|
logger.log(chalk.bold(`\n Config: ${getConfigPath()}\n`));
|
|
93
404
|
printConfig(config, " ");
|
|
94
405
|
logger.newline();
|
|
@@ -130,16 +441,21 @@ export function registerConfigCommand(program) {
|
|
|
130
441
|
.command("get")
|
|
131
442
|
.description("Get a configuration value")
|
|
132
443
|
.argument("<key>", "Config key (dot-notation, e.g. llm.provider)")
|
|
133
|
-
.
|
|
134
|
-
|
|
444
|
+
.option("--json", "Output a redacted JSON envelope")
|
|
445
|
+
.action((key, options) => {
|
|
446
|
+
const value = getConfigValue(key, { resolveSecrets: false });
|
|
135
447
|
if (value === undefined) {
|
|
136
448
|
logger.error(`Key not found: ${key}`);
|
|
137
|
-
process.
|
|
449
|
+
process.exitCode = 1;
|
|
450
|
+
return;
|
|
138
451
|
}
|
|
139
|
-
|
|
140
|
-
|
|
452
|
+
const redacted = redactConfigValue(key, value);
|
|
453
|
+
if (options.json) {
|
|
454
|
+
console.log(JSON.stringify({ key, value: redacted }, null, 2));
|
|
455
|
+
} else if (typeof redacted === "object") {
|
|
456
|
+
logger.log(JSON.stringify(redacted, null, 2));
|
|
141
457
|
} else {
|
|
142
|
-
logger.log(String(
|
|
458
|
+
logger.log(String(redacted));
|
|
143
459
|
}
|
|
144
460
|
});
|
|
145
461
|
|
|
@@ -148,9 +464,22 @@ export function registerConfigCommand(program) {
|
|
|
148
464
|
.description("Set a configuration value")
|
|
149
465
|
.argument("<key>", "Config key (dot-notation)")
|
|
150
466
|
.argument("<value>", "Value to set")
|
|
151
|
-
.
|
|
152
|
-
|
|
153
|
-
|
|
467
|
+
.option(
|
|
468
|
+
"--allow-unknown",
|
|
469
|
+
"Allow an unregistered key for extension development",
|
|
470
|
+
)
|
|
471
|
+
.action(async (key, value, options) => {
|
|
472
|
+
if (isSecretConfigKey(key)) {
|
|
473
|
+
logger.error(
|
|
474
|
+
`Refusing a secret in argv for ${key}. Pipe it to "cc config set-secret ${key}" or use its hidden TTY prompt.`,
|
|
475
|
+
);
|
|
476
|
+
process.exitCode = 1;
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
setConfigValue(key, value, {
|
|
480
|
+
allowUnknown: options.allowUnknown === true,
|
|
481
|
+
});
|
|
482
|
+
logger.success(`Set ${key}`);
|
|
154
483
|
// Claude-Code parity: if the user just pinned a retired/deprecated model
|
|
155
484
|
// id (llm.model / llm.visionModel / llm.fallbackModel), warn now — at pin
|
|
156
485
|
// time — rather than only when a later run fails. stderr-only, vitest-safe.
|
|
@@ -169,11 +498,173 @@ export function registerConfigCommand(program) {
|
|
|
169
498
|
}
|
|
170
499
|
});
|
|
171
500
|
|
|
501
|
+
cmd
|
|
502
|
+
.command("set-secret")
|
|
503
|
+
.description("Set a secret from a hidden TTY prompt or stdin (never argv)")
|
|
504
|
+
.argument("<key>", "Schema-declared secret key")
|
|
505
|
+
.option(
|
|
506
|
+
"--storage <mode>",
|
|
507
|
+
"Storage: auto (OS store then 0600 fallback), keychain, or file",
|
|
508
|
+
"auto",
|
|
509
|
+
)
|
|
510
|
+
.action(async (key, options) => {
|
|
511
|
+
if (!isSecretConfigKey(key)) {
|
|
512
|
+
logger.error(`${key} is not a registered secret key`);
|
|
513
|
+
process.exitCode = 1;
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const value = await readSecretInput({
|
|
517
|
+
message: `Secret value for ${key}:`,
|
|
518
|
+
});
|
|
519
|
+
if (!value) {
|
|
520
|
+
logger.error("Secret input was empty; configuration was not changed");
|
|
521
|
+
process.exitCode = 1;
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
const result = setSecretConfigValue(key, value, {
|
|
525
|
+
storage: options.storage,
|
|
526
|
+
});
|
|
527
|
+
logger.success(
|
|
528
|
+
`Set ${key} (${result.storage === "keychain" ? result.backend : "owner-only config file"})`,
|
|
529
|
+
);
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
cmd
|
|
533
|
+
.command("schema")
|
|
534
|
+
.description("Print the versioned JSON Schema for config.json")
|
|
535
|
+
.option("--json", "Output JSON (default)")
|
|
536
|
+
.action(() => {
|
|
537
|
+
console.log(JSON.stringify(getConfigJsonSchema(), null, 2));
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
cmd
|
|
541
|
+
.command("validate")
|
|
542
|
+
.description("Validate config.json types, keys and filesystem permissions")
|
|
543
|
+
.option("--fix", "Apply safe migrations and owner-only permissions")
|
|
544
|
+
.option("--allow-unknown", "Permit extension-development keys")
|
|
545
|
+
.option("--json", "Output JSON")
|
|
546
|
+
.action((options) => {
|
|
547
|
+
const permissions = checkConfigStoragePermissions({
|
|
548
|
+
fix: options.fix === true,
|
|
549
|
+
});
|
|
550
|
+
const inspectAndMaybeMigrate = () => {
|
|
551
|
+
const raw = loadUserConfig({ failIfUnavailable: true });
|
|
552
|
+
const migrated = migrateConfigDocument(raw);
|
|
553
|
+
const validation = validateConfigDocument(
|
|
554
|
+
options.fix ? migrated.config : raw,
|
|
555
|
+
{ allowUnknown: options.allowUnknown === true },
|
|
556
|
+
);
|
|
557
|
+
if (options.fix && migrated.migrations.length && validation.valid) {
|
|
558
|
+
backupConfigForMigration(
|
|
559
|
+
`.before-schema-v${CONFIG_SCHEMA_VERSION.split(".")[0]}`,
|
|
560
|
+
{ applyWindowsAcl: true, failIfUnavailable: true },
|
|
561
|
+
);
|
|
562
|
+
saveConfig(migrated.config);
|
|
563
|
+
}
|
|
564
|
+
return { migrated, validation };
|
|
565
|
+
};
|
|
566
|
+
// Re-read, migrate, back up and save under one cross-process lock. A
|
|
567
|
+
// concurrent `config set` can therefore never be overwritten by a stale
|
|
568
|
+
// pre-migration snapshot.
|
|
569
|
+
const { migrated, validation } = options.fix
|
|
570
|
+
? withConfigLock(inspectAndMaybeMigrate)
|
|
571
|
+
: inspectAndMaybeMigrate();
|
|
572
|
+
const ok =
|
|
573
|
+
validation.valid &&
|
|
574
|
+
permissions.home.ok &&
|
|
575
|
+
(!permissions.config.exists || permissions.config.ok);
|
|
576
|
+
const result = {
|
|
577
|
+
ok,
|
|
578
|
+
...validation,
|
|
579
|
+
migrations: migrated.migrations,
|
|
580
|
+
permissions,
|
|
581
|
+
};
|
|
582
|
+
if (options.json) {
|
|
583
|
+
console.log(JSON.stringify(result, null, 2));
|
|
584
|
+
} else if (ok) {
|
|
585
|
+
logger.success(
|
|
586
|
+
`Configuration is valid (schema ${CONFIG_SCHEMA_VERSION})`,
|
|
587
|
+
);
|
|
588
|
+
} else {
|
|
589
|
+
for (const issue of validation.issues) logger.error(issue.message);
|
|
590
|
+
if (!permissions.home.ok) logger.error("Config home is not owner-only");
|
|
591
|
+
if (permissions.config.exists && !permissions.config.ok) {
|
|
592
|
+
logger.error("config.json is not owner-only");
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (!ok) process.exitCode = 1;
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
cmd
|
|
599
|
+
.command("effective")
|
|
600
|
+
.description("Show the redacted effective configuration and provenance")
|
|
601
|
+
.option("--json", "Output JSON")
|
|
602
|
+
.action(async (options) => {
|
|
603
|
+
const result = await resolveEffectiveConfig();
|
|
604
|
+
if (options.json) {
|
|
605
|
+
console.log(JSON.stringify(result, null, 2));
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
logger.log(
|
|
609
|
+
chalk.bold(`\n Effective config (schema ${result.schemaVersion})\n`),
|
|
610
|
+
);
|
|
611
|
+
printConfig(result.config, " ");
|
|
612
|
+
logger.newline();
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
cmd
|
|
616
|
+
.command("explain")
|
|
617
|
+
.description("Explain a key's type, redacted value, source and policy lock")
|
|
618
|
+
.argument("<key>", "Known config key")
|
|
619
|
+
.option("--json", "Output JSON")
|
|
620
|
+
.action(async (key, options) => {
|
|
621
|
+
const entry = getConfigDescriptor(key);
|
|
622
|
+
if (!entry) {
|
|
623
|
+
logger.error(`Unknown configuration key: ${key}`);
|
|
624
|
+
process.exitCode = 1;
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
const effective = await resolveEffectiveConfig();
|
|
628
|
+
const result = {
|
|
629
|
+
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
630
|
+
key,
|
|
631
|
+
type: entry.type,
|
|
632
|
+
secret: entry.secret === true || isSecretConfigKey(key),
|
|
633
|
+
scope: entry.scope,
|
|
634
|
+
managedLock: entry.managedLock,
|
|
635
|
+
deprecated: entry.deprecated === true,
|
|
636
|
+
migration: entry.migration || null,
|
|
637
|
+
value: redactConfigValue(key, getNested(effective.config, key)),
|
|
638
|
+
provenance: effective.provenance[key] || {
|
|
639
|
+
source: "unset",
|
|
640
|
+
layer: "unset",
|
|
641
|
+
overridden: [],
|
|
642
|
+
locked: false,
|
|
643
|
+
},
|
|
644
|
+
};
|
|
645
|
+
if (options.json) {
|
|
646
|
+
console.log(JSON.stringify(result, null, 2));
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
logger.log(`${chalk.cyan(key)} = ${String(result.value ?? "(unset)")}`);
|
|
650
|
+
logger.log(
|
|
651
|
+
` type: ${Array.isArray(result.type) ? result.type.join(" | ") : result.type}`,
|
|
652
|
+
);
|
|
653
|
+
logger.log(` source: ${result.provenance.source}`);
|
|
654
|
+
logger.log(
|
|
655
|
+
` policy lock: ${result.provenance.locked ? "managed" : "not locked"}`,
|
|
656
|
+
);
|
|
657
|
+
if (result.migration)
|
|
658
|
+
logger.warn(` deprecated; migrate to ${result.migration}`);
|
|
659
|
+
});
|
|
660
|
+
|
|
172
661
|
cmd
|
|
173
662
|
.command("edit")
|
|
174
663
|
.description("Open config file in default editor")
|
|
175
664
|
.action(async () => {
|
|
176
|
-
|
|
665
|
+
// Existing malformed JSON must reach the editor byte-for-byte; this only
|
|
666
|
+
// repairs owner-only permissions. A missing file is created atomically.
|
|
667
|
+
const configPath = prepareConfigForEdit();
|
|
177
668
|
const editor =
|
|
178
669
|
process.env.EDITOR ||
|
|
179
670
|
process.env.VISUAL ||
|
|
@@ -314,18 +805,13 @@ export function registerConfigCommand(program) {
|
|
|
314
805
|
});
|
|
315
806
|
}
|
|
316
807
|
|
|
317
|
-
function printConfig(obj, indent = "") {
|
|
808
|
+
export function printConfig(obj, indent = "") {
|
|
318
809
|
for (const [key, value] of Object.entries(obj)) {
|
|
319
810
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
320
811
|
logger.log(`${indent}${chalk.cyan(key)}:`);
|
|
321
812
|
printConfig(value, indent + " ");
|
|
322
813
|
} else {
|
|
323
|
-
const displayValue =
|
|
324
|
-
value === null
|
|
325
|
-
? chalk.gray("null")
|
|
326
|
-
: key.toLowerCase().includes("key") && value
|
|
327
|
-
? chalk.yellow("****")
|
|
328
|
-
: String(value);
|
|
814
|
+
const displayValue = value === null ? chalk.gray("null") : String(value);
|
|
329
815
|
logger.log(`${indent}${chalk.cyan(key)}: ${displayValue}`);
|
|
330
816
|
}
|
|
331
817
|
}
|
package/src/commands/doctor.js
CHANGED
|
@@ -107,7 +107,10 @@ export function registerDoctorCommand(program) {
|
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
const sections = await collectCheckupSections({
|
|
110
|
+
const sections = await collectCheckupSections({
|
|
111
|
+
cwd: process.cwd(),
|
|
112
|
+
verifyWindowsAcl: true,
|
|
113
|
+
});
|
|
111
114
|
const fixResults = options.fix ? await runCheckupFixes(sections) : null;
|
|
112
115
|
|
|
113
116
|
const checkupErrs = sections
|
package/src/commands/hub.js
CHANGED
|
@@ -3475,7 +3475,7 @@ export function registerHubCommand(program) {
|
|
|
3475
3475
|
" Separate key/account for the hub? set an object instead:\n" +
|
|
3476
3476
|
" cc config set hub.llm.provider volcengine\n" +
|
|
3477
3477
|
" cc config set hub.llm.model doubao-seed-2-1-pro-260628\n" +
|
|
3478
|
-
" cc config set hub.llm.apiKeyEnv MY_HUB_KEY (or hub.llm.apiKey
|
|
3478
|
+
" cc config set hub.llm.apiKeyEnv MY_HUB_KEY (or: cc config set-secret hub.llm.apiKey)\n" +
|
|
3479
3479
|
" • Ephemeral: CC_HUB_LLM=config|<provider> cc hub ask … --accept-non-local\n" +
|
|
3480
3480
|
" (a one-off override still needs an explicit egress flag).",
|
|
3481
3481
|
)
|