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/repl/btw-command.js
CHANGED
|
@@ -1,30 +1,113 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pure helpers for
|
|
2
|
+
* Pure helpers for ephemeral REPL side questions.
|
|
3
3
|
*
|
|
4
|
-
* `/btw <
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* `/btw <question>` immediately asks a tool-free, single-response question
|
|
5
|
+
* against a snapshot of the current conversation. The snapshot and answer are
|
|
6
|
+
* never added to the parent conversation. `/btw --fork <question>` persists the
|
|
7
|
+
* side thread into an independent child session when the caller has a durable
|
|
8
|
+
* session store.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* The former "inject a note into the next turn" behavior remains available as
|
|
11
|
+
* `/note-next <note>` so `/btw` can keep the same contract as Claude Code.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/** Parse a `/btw …` line. Returns { text } | { error } | null (not a /btw). */
|
|
15
15
|
export function parseBtwCommand(trimmed) {
|
|
16
16
|
const t = String(trimmed == null ? "" : trimmed).trim();
|
|
17
17
|
if (t !== "/btw" && !t.startsWith("/btw ")) return null;
|
|
18
|
-
|
|
18
|
+
let text = t.slice("/btw".length).trim();
|
|
19
|
+
let fork = false;
|
|
20
|
+
if (text === "--fork" || text.startsWith("--fork ")) {
|
|
21
|
+
fork = true;
|
|
22
|
+
text = text.slice("--fork".length).trim();
|
|
23
|
+
}
|
|
24
|
+
if (!text) {
|
|
25
|
+
return {
|
|
26
|
+
error:
|
|
27
|
+
"usage: /btw [--fork] <question> — ask an immediate tool-free side question without changing parent history",
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return fork ? { text, fork: true } : { text };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Parse the legacy next-turn guidance command. */
|
|
34
|
+
export function parseNoteNextCommand(trimmed) {
|
|
35
|
+
const t = String(trimmed == null ? "" : trimmed).trim();
|
|
36
|
+
if (t !== "/note-next" && !t.startsWith("/note-next ")) return null;
|
|
37
|
+
const text = t.slice("/note-next".length).trim();
|
|
19
38
|
if (!text) {
|
|
20
39
|
return {
|
|
21
40
|
error:
|
|
22
|
-
"usage: /
|
|
41
|
+
"usage: /note-next <note> — apply ephemeral guidance to the next main turn",
|
|
23
42
|
};
|
|
24
43
|
}
|
|
25
44
|
return { text };
|
|
26
45
|
}
|
|
27
46
|
|
|
47
|
+
function textContent(content) {
|
|
48
|
+
if (typeof content === "string") return content;
|
|
49
|
+
if (!Array.isArray(content)) return content == null ? "" : String(content);
|
|
50
|
+
return content
|
|
51
|
+
.map((part) => {
|
|
52
|
+
if (typeof part === "string") return part;
|
|
53
|
+
if (part?.type === "text") return String(part.text || "");
|
|
54
|
+
if (part?.type === "image_url" || part?.image_url) return "[image]";
|
|
55
|
+
return "";
|
|
56
|
+
})
|
|
57
|
+
.filter(Boolean)
|
|
58
|
+
.join("\n");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Build a provider-neutral, tool-free snapshot for a side question. Tool
|
|
63
|
+
* results are retained as quoted user context, but tool-call protocol fields
|
|
64
|
+
* are deliberately removed so the side call cannot continue a tool exchange.
|
|
65
|
+
*/
|
|
66
|
+
export function buildBtwMessages(messages, question) {
|
|
67
|
+
const out = [];
|
|
68
|
+
for (const message of Array.isArray(messages) ? messages : []) {
|
|
69
|
+
if (!message || typeof message !== "object") continue;
|
|
70
|
+
const content = textContent(message.content);
|
|
71
|
+
if (!content) continue;
|
|
72
|
+
if (message.role === "system") out.push({ role: "system", content });
|
|
73
|
+
else if (message.role === "assistant")
|
|
74
|
+
out.push({ role: "assistant", content });
|
|
75
|
+
else if (message.role === "tool")
|
|
76
|
+
out.push({ role: "user", content: `[Tool result]\n${content}` });
|
|
77
|
+
else if (message.role === "user") out.push({ role: "user", content });
|
|
78
|
+
}
|
|
79
|
+
out.push({
|
|
80
|
+
role: "system",
|
|
81
|
+
content:
|
|
82
|
+
"Answer the final side question from the supplied conversation context. " +
|
|
83
|
+
"This is an ephemeral, single-response exchange. Do not call or request tools, " +
|
|
84
|
+
"do not change the main task, and answer concisely.",
|
|
85
|
+
});
|
|
86
|
+
out.push({ role: "user", content: String(question || "").trim() });
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Run a single tool-free side question through an injected chat function. */
|
|
91
|
+
export async function runBtwQuestion({
|
|
92
|
+
messages,
|
|
93
|
+
question,
|
|
94
|
+
chatFn,
|
|
95
|
+
model,
|
|
96
|
+
maxTokens = 1024,
|
|
97
|
+
} = {}) {
|
|
98
|
+
if (typeof chatFn !== "function") {
|
|
99
|
+
throw new TypeError("/btw requires a chat function");
|
|
100
|
+
}
|
|
101
|
+
const text = String(question || "").trim();
|
|
102
|
+
if (!text) throw new TypeError("/btw requires a question");
|
|
103
|
+
const snapshot = buildBtwMessages(messages, text);
|
|
104
|
+
const answer = await chatFn(snapshot, { model, maxTokens });
|
|
105
|
+
return {
|
|
106
|
+
answer: String(answer == null ? "" : answer),
|
|
107
|
+
snapshot,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
28
111
|
/**
|
|
29
112
|
* Render queued asides into a single tagged block, or null when there is
|
|
30
113
|
* nothing to add. The note tells the model this is ephemeral user guidance.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clipboard-image capability boundary for terminal REPL hosts.
|
|
3
|
+
*
|
|
4
|
+
* Plain Node readline receives pasted text only; it has no portable clipboard
|
|
5
|
+
* image event. We therefore enable image chips solely when an embedding host
|
|
6
|
+
* supplies an explicit, testable `readImage()` binding. Standard terminals get
|
|
7
|
+
* a truthful path-attachment fallback instead of a fake "paste succeeded".
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const CLIPBOARD_IMAGE_MEDIA_TYPES = Object.freeze([
|
|
11
|
+
"image/png",
|
|
12
|
+
"image/jpeg",
|
|
13
|
+
"image/gif",
|
|
14
|
+
"image/webp",
|
|
15
|
+
]);
|
|
16
|
+
export const MAX_CLIPBOARD_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
17
|
+
|
|
18
|
+
export function detectClipboardImageCapability(binding) {
|
|
19
|
+
if (
|
|
20
|
+
binding?.supportsImagePaste === true &&
|
|
21
|
+
typeof binding.readImage === "function"
|
|
22
|
+
) {
|
|
23
|
+
return {
|
|
24
|
+
supported: true,
|
|
25
|
+
mode: "host-binding",
|
|
26
|
+
reason: "The terminal host exposes clipboard image bytes.",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
supported: false,
|
|
31
|
+
mode: "path-fallback",
|
|
32
|
+
reason:
|
|
33
|
+
"This terminal exposes pasted text only, not clipboard image bytes. Save the image and paste its png/jpg/gif/webp path to attach it.",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function decodeImageData(value) {
|
|
38
|
+
if (Buffer.isBuffer(value)) return value;
|
|
39
|
+
if (value instanceof Uint8Array) return Buffer.from(value);
|
|
40
|
+
if (typeof value !== "string") return null;
|
|
41
|
+
const base64 = value.replace(/^data:[^;,]+;base64,/i, "").trim();
|
|
42
|
+
if (!base64 || !/^[A-Za-z0-9+/]*={0,2}$/.test(base64)) return null;
|
|
43
|
+
try {
|
|
44
|
+
return Buffer.from(base64, "base64");
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Read one image from a trusted host binding and return an OpenAI-shaped image
|
|
52
|
+
* content part (the CLI's provider-neutral internal multimodal shape).
|
|
53
|
+
*/
|
|
54
|
+
export async function readClipboardImageChip(binding, options = {}) {
|
|
55
|
+
const capability = detectClipboardImageCapability(binding);
|
|
56
|
+
if (!capability.supported) return { ok: false, ...capability };
|
|
57
|
+
let image;
|
|
58
|
+
try {
|
|
59
|
+
image = await binding.readImage();
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return {
|
|
62
|
+
ok: false,
|
|
63
|
+
supported: true,
|
|
64
|
+
mode: "host-binding",
|
|
65
|
+
reason: `Clipboard image read failed: ${error.message}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (!image) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
supported: true,
|
|
72
|
+
mode: "host-binding",
|
|
73
|
+
reason: "The clipboard does not currently contain an image.",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const mediaType = String(image.mediaType || image.type || "").toLowerCase();
|
|
77
|
+
if (!CLIPBOARD_IMAGE_MEDIA_TYPES.includes(mediaType)) {
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
supported: true,
|
|
81
|
+
mode: "host-binding",
|
|
82
|
+
reason: `Unsupported clipboard image type: ${mediaType || "unknown"}.`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const data = decodeImageData(image.data);
|
|
86
|
+
if (!data?.length) {
|
|
87
|
+
return {
|
|
88
|
+
ok: false,
|
|
89
|
+
supported: true,
|
|
90
|
+
mode: "host-binding",
|
|
91
|
+
reason: "The clipboard image payload is empty or invalid.",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const maxBytes = Math.max(
|
|
95
|
+
1,
|
|
96
|
+
Number(options.maxBytes) || MAX_CLIPBOARD_IMAGE_BYTES,
|
|
97
|
+
);
|
|
98
|
+
if (data.length > maxBytes) {
|
|
99
|
+
return {
|
|
100
|
+
ok: false,
|
|
101
|
+
supported: true,
|
|
102
|
+
mode: "host-binding",
|
|
103
|
+
reason: `Clipboard image exceeds ${maxBytes} bytes.`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
ok: true,
|
|
108
|
+
supported: true,
|
|
109
|
+
mode: "host-binding",
|
|
110
|
+
bytes: data.length,
|
|
111
|
+
mediaType,
|
|
112
|
+
chip: {
|
|
113
|
+
type: "image_url",
|
|
114
|
+
image_url: {
|
|
115
|
+
url: `data:${mediaType};base64,${data.toString("base64")}`,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -1,141 +1,93 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* active provider/model, which can differ from the file (a --provider flag or
|
|
7
|
-
* .claude/settings.json overrides it).
|
|
8
|
-
*
|
|
9
|
-
* Pure: takes the loaded config + context, returns plain text. The REPL does
|
|
10
|
-
* the I/O. NEVER prints a secret — only "set (…1234)" / "not set".
|
|
11
|
-
*/
|
|
1
|
+
/** Secret-safe rendering and parsing for the interactive `/config` command. */
|
|
2
|
+
import {
|
|
3
|
+
isSecretConfigKey,
|
|
4
|
+
redactConfigValue,
|
|
5
|
+
} from "../lib/config-redaction.js";
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
export function maskSecret(v) {
|
|
15
|
-
if (v == null || v === "") return "not set";
|
|
16
|
-
const s = String(v);
|
|
17
|
-
return s.length <= 4 ? "set (hidden)" : `set (…${s.slice(-4)})`;
|
|
18
|
-
}
|
|
7
|
+
export { isSecretConfigKey } from "../lib/config-redaction.js";
|
|
19
8
|
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* Matched on the last dotted segment (e.g. `llm.apiKey`, `webSearch.apiKey`).
|
|
24
|
-
*/
|
|
25
|
-
const SECRET_KEY_RE = /(api[_-]?key|secret|token|password|passwd)$/i;
|
|
26
|
-
export function isSecretConfigKey(key) {
|
|
27
|
-
if (!key) return false;
|
|
28
|
-
const last = String(key).split(".").pop();
|
|
29
|
-
return SECRET_KEY_RE.test(last);
|
|
9
|
+
/** Report only presence; never retain a suffix from a credential. */
|
|
10
|
+
export function maskSecret(value) {
|
|
11
|
+
return value == null || value === "" ? "not set" : "set (hidden)";
|
|
30
12
|
}
|
|
31
13
|
|
|
32
|
-
/**
|
|
33
|
-
* Parse the argument string after `/config` into an action.
|
|
34
|
-
* Mirrors Claude Code's `/config key=value` syntax, and also accepts the
|
|
35
|
-
* `/config key value` form. Returns one of:
|
|
36
|
-
* { action: "show" } // `/config`
|
|
37
|
-
* { action: "get", key } // `/config llm.model`
|
|
38
|
-
* { action: "set", key, value } // `/config llm.model=opus` | `/config llm.model opus`
|
|
39
|
-
* { action: "error", message }
|
|
40
|
-
* `value` is the raw string; the caller coerces (true/false/null/number) via
|
|
41
|
-
* config-manager's setConfigValue.
|
|
42
|
-
*
|
|
43
|
-
* @param {string} argStr everything after the literal `/config`
|
|
44
|
-
*/
|
|
45
14
|
export function parseConfigCommand(argStr) {
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const eq = s.indexOf("=");
|
|
55
|
-
if (eq !== -1) {
|
|
56
|
-
const key = s.slice(0, eq).trim();
|
|
57
|
-
const value = s.slice(eq + 1).trim();
|
|
15
|
+
const input = (argStr || "").trim();
|
|
16
|
+
if (input === "") return { action: "show" };
|
|
17
|
+
if (/^(--help|-h|help|\?)$/i.test(input)) return { action: "help" };
|
|
18
|
+
|
|
19
|
+
const equals = input.indexOf("=");
|
|
20
|
+
if (equals !== -1) {
|
|
21
|
+
const key = input.slice(0, equals).trim();
|
|
22
|
+
const value = input.slice(equals + 1).trim();
|
|
58
23
|
if (!key) return { action: "error", message: "missing key before '='" };
|
|
59
24
|
return { action: "set", key, value };
|
|
60
25
|
}
|
|
61
26
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return { action: "get", key: s };
|
|
27
|
+
const spaced = input.match(/^(\S+)\s+([\s\S]+)$/);
|
|
28
|
+
if (spaced) {
|
|
29
|
+
return { action: "set", key: spaced[1], value: spaced[2].trim() };
|
|
30
|
+
}
|
|
31
|
+
return { action: "get", key: input };
|
|
68
32
|
}
|
|
69
33
|
|
|
70
|
-
/**
|
|
71
|
-
* The common config keys, surfaced by `/config --help`. cc's `/config` accepts
|
|
72
|
-
* any dotted key (free-form), so this is a curated quick-reference of the keys
|
|
73
|
-
* the CLI actually reads — not an exhaustive schema.
|
|
74
|
-
*/
|
|
75
34
|
export const COMMON_CONFIG_KEYS = Object.freeze([
|
|
76
|
-
[
|
|
77
|
-
"llm.provider",
|
|
78
|
-
"LLM provider (ollama | volcengine | anthropic | openai | …)",
|
|
79
|
-
],
|
|
35
|
+
["llm.provider", "LLM provider id"],
|
|
80
36
|
["llm.model", "default text model id"],
|
|
81
|
-
["llm.visionModel", "model used for image turns
|
|
37
|
+
["llm.visionModel", "model used for image turns"],
|
|
82
38
|
["llm.baseUrl", "provider API base URL"],
|
|
83
|
-
["llm.apiKey", "provider API key (
|
|
84
|
-
[
|
|
85
|
-
|
|
86
|
-
"web_search backend (auto | tavily | brave | duckduckgo | …)",
|
|
87
|
-
],
|
|
88
|
-
["webSearch.apiKey", "web-search API key"],
|
|
39
|
+
["llm.apiKey", "provider API key (use cc config set-secret)"],
|
|
40
|
+
["webSearch.provider", "web-search backend"],
|
|
41
|
+
["webSearch.apiKey", "web-search API key (use cc config set-secret)"],
|
|
89
42
|
["cli.theme", "REPL color theme (auto | dark | light | mono)"],
|
|
90
43
|
]);
|
|
91
44
|
|
|
92
|
-
/** Render `/config --help`: usage + the common config keys. */
|
|
93
45
|
export function renderConfigHelp() {
|
|
94
46
|
const lines = [
|
|
95
|
-
"/config — show or edit configuration:",
|
|
47
|
+
"/config — show or edit non-secret configuration:",
|
|
96
48
|
" /config show effective config (secret-safe)",
|
|
97
|
-
" /config <key> read a value
|
|
98
|
-
" /config <key>=<value> set a value
|
|
99
|
-
" /config <key> <value> set a value
|
|
49
|
+
" /config <key> read a value",
|
|
50
|
+
" /config <key>=<value> set a non-secret value",
|
|
51
|
+
" /config <key> <value> set a non-secret value",
|
|
100
52
|
" /config --help this list",
|
|
101
53
|
"",
|
|
102
54
|
"Common keys:",
|
|
103
55
|
];
|
|
104
|
-
const width = Math.max(...COMMON_CONFIG_KEYS.map(([
|
|
105
|
-
for (const [key,
|
|
106
|
-
lines.push(` ${key.padEnd(width)} ${
|
|
56
|
+
const width = Math.max(...COMMON_CONFIG_KEYS.map(([key]) => key.length));
|
|
57
|
+
for (const [key, description] of COMMON_CONFIG_KEYS) {
|
|
58
|
+
lines.push(` ${key.padEnd(width)} ${description}`);
|
|
107
59
|
}
|
|
108
60
|
lines.push("");
|
|
109
|
-
lines.push(
|
|
61
|
+
lines.push(
|
|
62
|
+
" Unknown keys are rejected; use `cc config set --allow-unknown` only for extension development.",
|
|
63
|
+
);
|
|
64
|
+
lines.push(
|
|
65
|
+
" Secrets cannot be set here; use the hidden `cc config set-secret <key>` input.",
|
|
66
|
+
);
|
|
110
67
|
return lines.join("\n");
|
|
111
68
|
}
|
|
112
69
|
|
|
113
|
-
/** Render a single config value for `/config <key>`, masking secrets. */
|
|
114
70
|
export function renderConfigGet(key, value) {
|
|
115
71
|
if (value === undefined) return `${key} = (unset)`;
|
|
116
72
|
if (isSecretConfigKey(key)) return `${key} = ${maskSecret(value)}`;
|
|
73
|
+
const safe = redactConfigValue(key, value);
|
|
117
74
|
const shown =
|
|
118
|
-
|
|
119
|
-
? JSON.stringify(
|
|
120
|
-
: String(
|
|
75
|
+
safe !== null && typeof safe === "object"
|
|
76
|
+
? JSON.stringify(safe)
|
|
77
|
+
: String(safe);
|
|
121
78
|
return `${key} = ${shown}`;
|
|
122
79
|
}
|
|
123
80
|
|
|
124
|
-
/** Render the confirmation line after `/config <key>=<value>`. */
|
|
125
81
|
export function renderConfigSet(key, storedValue) {
|
|
126
82
|
if (isSecretConfigKey(key)) return `set ${key} = ${maskSecret(storedValue)}`;
|
|
83
|
+
const safe = redactConfigValue(key, storedValue);
|
|
127
84
|
const shown =
|
|
128
|
-
|
|
129
|
-
? JSON.stringify(
|
|
130
|
-
: String(
|
|
85
|
+
safe !== null && typeof safe === "object"
|
|
86
|
+
? JSON.stringify(safe)
|
|
87
|
+
: String(safe);
|
|
131
88
|
return `set ${key} = ${shown}`;
|
|
132
89
|
}
|
|
133
90
|
|
|
134
|
-
/**
|
|
135
|
-
* @param {object|null} config loaded config.json
|
|
136
|
-
* @param {object} [opts] { path, activeProvider, activeModel }
|
|
137
|
-
* @returns {string}
|
|
138
|
-
*/
|
|
139
91
|
export function renderConfigSummary(config, opts = {}) {
|
|
140
92
|
const cfg = config || {};
|
|
141
93
|
const llm = cfg.llm || {};
|
|
@@ -143,31 +95,35 @@ export function renderConfigSummary(config, opts = {}) {
|
|
|
143
95
|
if (opts.path) lines.push(` config file: ${opts.path}`);
|
|
144
96
|
|
|
145
97
|
lines.push(" llm:");
|
|
146
|
-
lines.push(` provider: ${llm.provider || "(unset
|
|
98
|
+
lines.push(` provider: ${llm.provider || "(unset; defaults to ollama)"}`);
|
|
147
99
|
lines.push(` model: ${llm.model || "(unset)"}`);
|
|
148
100
|
if (llm.visionModel) lines.push(` vision: ${llm.visionModel}`);
|
|
149
|
-
if (llm.baseUrl)
|
|
101
|
+
if (llm.baseUrl)
|
|
102
|
+
lines.push(
|
|
103
|
+
` baseUrl: ${redactConfigValue("llm.baseUrl", llm.baseUrl)}`,
|
|
104
|
+
);
|
|
150
105
|
lines.push(` apiKey: ${maskSecret(llm.apiKey)}`);
|
|
151
106
|
|
|
152
|
-
const
|
|
153
|
-
if (
|
|
107
|
+
const webSearch = cfg.webSearch || {};
|
|
108
|
+
if (webSearch.provider || webSearch.apiKey) {
|
|
154
109
|
lines.push(" webSearch:");
|
|
155
|
-
lines.push(` provider: ${
|
|
156
|
-
lines.push(` apiKey: ${maskSecret(
|
|
110
|
+
lines.push(` provider: ${webSearch.provider || "(unset; auto)"}`);
|
|
111
|
+
lines.push(` apiKey: ${maskSecret(webSearch.apiKey)}`);
|
|
157
112
|
}
|
|
158
113
|
|
|
159
114
|
if (opts.activeProvider || opts.activeModel) {
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
const differs =
|
|
115
|
+
const provider = opts.activeProvider || "?";
|
|
116
|
+
const model = opts.activeModel || "?";
|
|
117
|
+
const differs =
|
|
118
|
+
Boolean(llm.provider) &&
|
|
119
|
+
(provider !== llm.provider || model !== llm.model);
|
|
163
120
|
lines.push(
|
|
164
|
-
` active this session: ${
|
|
165
|
-
(differs ? " (overrides config)" : ""),
|
|
121
|
+
` active this session: ${provider} · ${model}${differs ? " (overrides config)" : ""}`,
|
|
166
122
|
);
|
|
167
123
|
}
|
|
168
124
|
|
|
169
125
|
lines.push(
|
|
170
|
-
" note:
|
|
126
|
+
" note: secret values are hidden; environment variables can override config at runtime.",
|
|
171
127
|
);
|
|
172
128
|
return lines.join("\n");
|
|
173
129
|
}
|