@vibeapi/cli 0.0.148 → 0.0.150
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 +22 -17
- package/components.json +157 -0
- package/dist/commands/components.d.ts +26 -0
- package/dist/commands/components.js +1 -0
- package/dist/commands/config.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/upgrade.d.ts +4 -2
- package/dist/commands/upgrade.js +1 -1
- package/dist/components.json +157 -0
- package/dist/lib/app-update.d.ts +20 -0
- package/dist/lib/app-update.js +1 -1
- package/dist/lib/brand.js +1 -1
- package/dist/lib/claude-code-manager.d.ts +4 -0
- package/dist/lib/claude-code-manager.js +1 -1
- package/dist/lib/command.d.ts +0 -5
- package/dist/lib/command.js +1 -1
- package/dist/lib/components.d.ts +204 -0
- package/dist/lib/components.js +1 -0
- package/dist/lib/config.d.ts +2 -0
- package/dist/lib/config.js +1 -1
- package/dist/lib/dry-run.js +1 -1
- package/dist/lib/env-cleanup.d.ts +32 -28
- package/dist/lib/env-cleanup.js +1 -1
- package/dist/lib/gateway-addresses.d.ts +4 -0
- package/dist/lib/gateway-addresses.js +1 -1
- package/dist/lib/model-registry.d.ts +2 -0
- package/dist/lib/model-registry.js +1 -1
- package/dist/lib/program.js +1 -1
- package/dist/lib/runtime-options.d.ts +5 -0
- package/dist/lib/runtime-options.js +1 -1
- package/dist/lib/tool-manager.d.ts +3 -0
- package/dist/lib/tool-manager.js +1 -1
- package/dist/lib/tool-upgrade.d.ts +2 -0
- package/dist/lib/tool-upgrade.js +1 -1
- package/dist/lib/tools/chatgpt-desktop.d.ts +14 -1
- package/dist/lib/tools/chatgpt-desktop.js +1 -1
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/claude-desktop.d.ts +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/tools/desktop-process.d.ts +4 -1
- package/dist/lib/tools/desktop-process.js +1 -1
- package/dist/lib/tools/tool-installs.d.ts +8 -0
- package/dist/lib/tools/tool-installs.js +1 -1
- package/dist/lib/tools/types.d.ts +26 -9
- package/dist/lib/wizard.js +1 -1
- package/dist/lib/write-plan.d.ts +2 -0
- package/dist/lib/write-plan.js +1 -1
- package/dist/lib/written-values.d.ts +21 -0
- package/dist/lib/written-values.js +1 -0
- package/dist/locales/en_US.json +140 -5
- package/dist/locales/zh_CN.json +140 -5
- package/package.json +2 -1
|
@@ -1,41 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shell 环境变量里的 ANTHROPIC_API_KEY / ANTHROPIC_BASE_URL 会覆盖 vibecli 写进
|
|
3
3
|
* settings.json 的凭据,导致"改了配置却不生效";同理,export 过的 ANTHROPIC_*_MODEL
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* 会盖住模型选择。给 Claude Code 写配置时(写入计划确认之后)只删指向本站的那几处,
|
|
5
|
+
* 先备份;指向别家服务的不动、只提示(new-api#174)。
|
|
6
6
|
*/
|
|
7
|
-
export declare const ANTHROPIC_ENV_VARS: readonly ["ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL", "ANTHROPIC_DEFAULT_FABLE_MODEL", "ANTHROPIC_MODEL", "ANTHROPIC_REASONING_MODEL"];
|
|
7
|
+
export declare const ANTHROPIC_ENV_VARS: readonly ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL", "ANTHROPIC_DEFAULT_HAIKU_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL", "ANTHROPIC_DEFAULT_FABLE_MODEL", "ANTHROPIC_MODEL", "ANTHROPIC_REASONING_MODEL"];
|
|
8
8
|
/**
|
|
9
9
|
* 获取当前 shell 的 rc 文件路径(Windows 不使用 rc 文件,返回 null)。
|
|
10
10
|
*/
|
|
11
11
|
export declare function getShellRcFilePath(): string | null;
|
|
12
|
+
/** A place that sets ANTHROPIC_* for new terminals: a shell / PowerShell profile or a Windows env scope. */
|
|
13
|
+
export interface EnvSource {
|
|
14
|
+
kind: 'file' | 'windows-user' | 'windows-machine';
|
|
15
|
+
/** File path, or `HKCU\Environment` / `HKLM\…\Environment`. */
|
|
16
|
+
location: string;
|
|
17
|
+
vars: Record<string, string>;
|
|
18
|
+
/** Points at this gateway (or carries a key vibecli saved): ours to remove after confirmation. */
|
|
19
|
+
ours: boolean;
|
|
20
|
+
}
|
|
12
21
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
22
|
+
* Every persistent ANTHROPIC_* assignment new terminals pick up: the current shell's rc file
|
|
23
|
+
* (macOS / Linux), Windows user and system environment variables and PowerShell profiles.
|
|
15
24
|
*/
|
|
16
|
-
export declare function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
export declare function anthropicEnvSources(): EnvSource[];
|
|
26
|
+
export interface EnvCleanupResult {
|
|
27
|
+
/** Sources that pointed at this gateway, with what was removed from each. */
|
|
28
|
+
removed: EnvSource[];
|
|
29
|
+
/** Sources pointing somewhere else: left alone, the user decides. */
|
|
30
|
+
foreign: EnvSource[];
|
|
31
|
+
/** System-scope names that need an elevated run to delete. */
|
|
23
32
|
machineLeft: string[];
|
|
24
|
-
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* 检测并清除环境中的 ANTHROPIC_API_KEY / ANTHROPIC_BASE_URL:
|
|
28
|
-
* 1. 从当前 shell 的 rc 文件删掉对应的 export 行(持久来源);
|
|
29
|
-
* 2. 从本进程 process.env 删除——vibecli 会以子进程启动各工具,
|
|
30
|
-
* 不清掉的话残留变量仍会盖过刚写好的配置文件。
|
|
31
|
-
* 返回被清除的变量名(未检测到时为空数组)。
|
|
32
|
-
*/
|
|
33
|
-
export declare function cleanupAnthropicEnvVars(): string[];
|
|
33
|
+
}
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
* environment
|
|
37
|
-
*
|
|
35
|
+
* Removes ANTHROPIC_* settings that point at this gateway from shell profiles and the Windows
|
|
36
|
+
* environment (they override the settings.json vibecli writes), after backing each one up.
|
|
37
|
+
* Settings for another service are left alone and reported (new-api#174: a profile someone else
|
|
38
|
+
* wrote is not ours to delete). Runs when Claude Code is configured, after the write plan was
|
|
39
|
+
* confirmed; the plan lists the same sources (`envCleanupPlan`).
|
|
38
40
|
*/
|
|
39
|
-
export declare function
|
|
40
|
-
/**
|
|
41
|
-
export declare function
|
|
41
|
+
export declare function cleanupAnthropicEnvVars(): EnvCleanupResult;
|
|
42
|
+
/** What the last `cleanupAnthropicEnvVars()` did, for the notes after Claude Code is configured. */
|
|
43
|
+
export declare function lastEnvCleanup(): EnvCleanupResult;
|
|
44
|
+
/** Shown in the write plan before Claude Code is configured: profiles whose ANTHROPIC_* lines go. */
|
|
45
|
+
export declare function envCleanupPlan(): EnvSource[];
|
package/dist/lib/env-cleanup.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as
|
|
1
|
+
import{existsSync as o,mkdirSync as n,readFileSync as e,writeFileSync as r}from"fs";import{join as t}from"path";import{logger as s}from"../utils/logger.js";import{toolHome as c}from"./tools/types.js";import{backupBeforeWrite as i}from"./tools/backup.js";import{configManager as f,savedApiKeys as u}from"./config.js";import{isOurGatewayUrl as a}from"./gateway-addresses.js";import{broadcastEnvChange as l,deleteWindowsEnv as p,readWindowsEnv as m}from"./windows-env.js";export const ANTHROPIC_ENV_VARS=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_HAIKU_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_FABLE_MODEL","ANTHROPIC_MODEL","ANTHROPIC_REASONING_MODEL"];export function getShellRcFilePath(){if("win32"===process.platform)return null;const o=c();switch((process.env.SHELL||"").split("/").pop()||""){case"bash":return t(o,".bashrc");case"zsh":return t(o,".zshrc");case"fish":return t(o,".config","fish","config.fish");default:return t(o,".profile")}}function h(o){const n=o.trim().replace(/\s+#.*$/,""),e=n.match(/^(['"])(.*)\1$/);return e?e[2]:n}const E=o=>new RegExp(String.raw`^\s*export\s+${o}=(.*)$`,"gm"),v=o=>new RegExp(String.raw`^[ \t]*\$env:${o}[ \t]*=(.*)$`,"gim");function g(o){if(a(o.ANTHROPIC_BASE_URL))return!0;const n=u();return[o.ANTHROPIC_API_KEY,o.ANTHROPIC_AUTH_TOKEN].some(o=>Boolean(o)&&n.includes(o.trim()))}export function anthropicEnvSources(){const n=[],r=(r,t)=>{if(r&&o(r))try{const o=function(o,n){const e={};for(const r of ANTHROPIC_ENV_VARS)for(const t of o.matchAll(n(r)))e[r]=h(t[1]);return e}(e(r,"utf-8"),t);Object.keys(o).length>0&&n.push({kind:"file",location:r,vars:o,ours:g(o)})}catch(o){s.logError("envCleanup.read",o)}};if("win32"!==process.platform)return r(getShellRcFilePath(),E),n;for(const o of["user","machine"]){const e={};for(const n of ANTHROPIC_ENV_VARS){const r=m(o,n);void 0!==r&&(e[n]=r)}Object.keys(e).length>0&&n.push({kind:"user"===o?"windows-user":"windows-machine",location:"user"===o?"HKCU\\Environment":"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",vars:e,ours:g(e)})}for(const o of function(){const o=c(),n=[];for(const e of[t(o,"Documents"),t(o,"OneDrive","Documents"),t(o,"OneDrive","文档")])for(const o of["PowerShell","WindowsPowerShell"])n.push(t(e,o,"Microsoft.PowerShell_profile.ps1"),t(e,o,"profile.ps1"));return n}())r(o,v);return n}function O(o,n,t){const c=e(o,"utf-8");let f=c;for(const o of n)f=f.replace(new RegExp(t(o).source+String.raw`(\r?\n)?`,t(o).flags),"");return t===E&&(f=f.replace(/^\s*#\s*Claude Code environment variables\s*$\n?/gm,"")),f!==c&&(i(o),r(o,f,"utf-8"),s.debug(`Removed ${n.join(", ")} from ${o}`),!0)}function A(o,e){try{const s=t(f.getConfigDir(),"backups");n(s,{recursive:!0});const c=t(s,`windows-env-${o}-${(new Date).toISOString().replace(/[:.]/g,"-")}.json`);return r(c,JSON.stringify(e,null,2)+"\n",{mode:384}),c}catch(o){return s.logError("envCleanup.backupWindowsValues",o),null}}let _={removed:[],foreign:[],machineLeft:[]};export function cleanupAnthropicEnvVars(){const o={removed:[],foreign:[],machineLeft:[]};let n=!1;for(const e of anthropicEnvSources()){if(!e.ours){o.foreign.push(e);continue}const r=Object.keys(e.vars);try{if("file"===e.kind){O(e.location,r,e.location.endsWith(".ps1")?v:E)&&o.removed.push(e);continue}const t="windows-user"===e.kind?"user":"machine";A(t,e.vars);const c=[];for(const n of r)try{p(t,n),c.push(n)}catch(e){"machine"===t&&o.machineLeft.push(n),s.logError("envCleanup.deleteWindowsEnv",e)}c.length>0&&(n=!0,o.removed.push({...e,vars:Object.fromEntries(c.map(o=>[o,e.vars[o]]))}))}catch(o){s.logError("envCleanup.cleanupAnthropicEnvVars",o)}}n&&l();for(const n of o.removed)for(const[o,e]of Object.entries(n.vars))process.env[o]===e&&delete process.env[o];return _=o,o}export function lastEnvCleanup(){return _}export function envCleanupPlan(){return anthropicEnvSources().filter(o=>o.ours)}
|
|
@@ -33,6 +33,10 @@ export declare function rememberPublishedAddresses(statusData: unknown, source:
|
|
|
33
33
|
* gateway's order. A built-in address takes the gateway's label when it has one.
|
|
34
34
|
*/
|
|
35
35
|
export declare function gatewayAddresses(): GatewayAddress[];
|
|
36
|
+
/** `url` is one of this gateway's addresses (built-in, published, or the configured one). */
|
|
37
|
+
export declare function isOurGatewayUrl(url: unknown): boolean;
|
|
38
|
+
/** Remember an address vibecli is about to write into a tool, so `isOurGatewayUrl` knows it later. */
|
|
39
|
+
export declare function noteWrittenGatewayUrl(url: string): void;
|
|
36
40
|
export interface ProbeOptions {
|
|
37
41
|
/** With a key the probe lists the models (`GET /v1/models`): the whole relay path works, not just the front page. */
|
|
38
42
|
apiKey?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as r,mkdirSync as e,readFileSync as t,writeFileSync as o}from"fs";import{join as s}from"path";import{configManager as n}from"./config.js";import{
|
|
1
|
+
import{existsSync as r,mkdirSync as e,readFileSync as t,writeFileSync as o}from"fs";import{join as s}from"path";import{configManager as n}from"./config.js";import{noteGatewayUrl as a,wroteGatewayUrl as i}from"./written-values.js";import{getBuiltinGatewayAddresses as l}from"./model-registry.js";import{logger as u}from"../utils/logger.js";const c=new Set(["SELF_SIGNED_CERT_IN_CHAIN","DEPTH_ZERO_SELF_SIGNED_CERT","UNABLE_TO_VERIFY_LEAF_SIGNATURE","UNABLE_TO_GET_ISSUER_CERT_LOCALLY","CERT_HAS_EXPIRED","CERT_NOT_YET_VALID","ERR_TLS_CERT_ALTNAME_INVALID"]);function f(){return s(n.getConfigDir(),"gateway-addresses.json")}export function normalizeBaseUrl(r){let e,t=r.trim();if(!t)return null;/^[a-z][a-z0-9+.-]*:\/\//i.test(t)||(t=`https://${t}`);try{e=new URL(t)}catch{return null}if("https:"!==e.protocol&&"http:"!==e.protocol)return null;const o=e.pathname.replace(/\/+$/,"").replace(/\/v1$/i,"");return`${e.protocol}//${e.host}${o}`}export function parsePublishedAddresses(r){if(!Array.isArray(r))return[];const e=new Set,t=[];for(const o of r){if(!o||"object"!=typeof o)continue;const{url:r,route:s,description:n}=o,a="string"==typeof r?normalizeBaseUrl(r):null;if(!a?.startsWith("https://")||e.has(a))continue;e.add(a);const i="string"==typeof s?s.trim():"",l="string"==typeof n?n.trim():"";t.push({url:a,label:i&&l?`${i}(${l})`:i||l})}return t}export function rememberPublishedAddresses(r,t){if(!r||"object"!=typeof r)return;if(!l().some(r=>normalizeBaseUrl(r.url)===t))return;const s=r;if(!1===s.api_info_enabled)return;const a=parsePublishedAddresses(s.api_info);if(0!==a.length)try{e(n.getConfigDir(),{recursive:!0}),o(f(),JSON.stringify({addresses:a},null,2)+"\n")}catch(r){u.logError("rememberPublishedAddresses",r)}}export function gatewayAddresses(){const e=function(){const e=f();if(!r(e))return[];try{const r=JSON.parse(t(e,"utf-8"));return(Array.isArray(r.addresses)?r.addresses:[]).flatMap(r=>{const e="string"==typeof r?.url?normalizeBaseUrl(r.url):null;return e?[{url:e,label:"string"==typeof r.label?r.label:""}]:[]})}catch{return[]}}(),o=[];for(const r of l()){const t=normalizeBaseUrl(r.url);if(!t||o.some(r=>r.url===t))continue;const s=e.find(r=>r.url===t)?.label||r.label;o.push({url:t,label:s})}for(const r of e)o.some(e=>e.url===r.url)||o.push(r);return o}export function isOurGatewayUrl(r){if("string"!=typeof r)return!1;const e=normalizeBaseUrl(r);return!!e&&(gatewayAddresses().some(r=>r.url===e)||e===normalizeBaseUrl(n.getBaseUrl())||i(e))}export function noteWrittenGatewayUrl(r){const e=normalizeBaseUrl(r);e&&a(e)}function m(r){const e=r?.cause,t="string"==typeof e?.code?e.code:"",o="string"==typeof e?.message?e.message:r instanceof Error?r.message:String(r);return r instanceof Error&&"AbortError"===r.name?{error:"timeout",detail:o}:c.has(t)||/certificate/i.test(o)?{error:"certificate",detail:t||o}:{error:"network",detail:t||o}}export async function probeGatewayAddress(r,e={}){e.apiKey&&!function(r){return r===n.getBaseUrl()||l().some(e=>normalizeBaseUrl(e.url)===r)}(r)&&(e={...e,apiKey:void 0});const t=Math.max(1,e.samples??1),o=[];let s;for(let n=0;n<t;n+=1){const t=await d(r,e);if(!t.ok)return t;o.push(t.ms),s=t.models}return o.sort((r,e)=>r-e),{url:r,ok:!0,ms:o[Math.floor(o.length/2)],...void 0===s?{}:{models:s}}}async function d(r,e){const{apiKey:t,timeoutMs:o=8e3,fetchFn:s=fetch}=e,n=new AbortController,a=setTimeout(()=>n.abort(),o),i=Date.now();try{const e=await s(t?`${r}/v1/models`:`${r}/api/status`,{method:"GET",headers:t?{Authorization:`Bearer ${t}`}:void 0,signal:n.signal});let o;try{o=(await e.json())?.data}catch{o=void 0}const a=Date.now()-i;return!t||401!==e.status&&403!==e.status?t?e.ok&&Array.isArray(o)?{url:r,ok:!0,ms:a,models:o.length}:{url:r,ok:!1,ms:a,error:"not_gateway",detail:`HTTP ${e.status}`}:e.ok&&o&&"object"==typeof o?(rememberPublishedAddresses(o,r),{url:r,ok:!0,ms:a}):{url:r,ok:!1,ms:a,error:"not_gateway",detail:`HTTP ${e.status}`}:{url:r,ok:!1,ms:a,error:"key_rejected",detail:`HTTP ${e.status}`}}catch(e){return{url:r,ok:!1,ms:Date.now()-i,...m(e)}}finally{clearTimeout(a)}}
|
|
@@ -102,6 +102,8 @@ export declare function overlayClientSection(base: ModelRegistryData, v: ClientS
|
|
|
102
102
|
export declare function getDefaultModels(): Models;
|
|
103
103
|
/** Earlier default for this slot, saved into a profile by the wizard's prefilled inputs. */
|
|
104
104
|
export declare function isRetiredDefaultModel(slot: string, model: string): boolean;
|
|
105
|
+
/** Every earlier default of any slot (older vibecli versions wrote these into tool settings). */
|
|
106
|
+
export declare function getRetiredDefaultModelIds(): string[];
|
|
105
107
|
/** The model non-Claude tools use unless the user configured something else. */
|
|
106
108
|
export declare function getDefaultToolModel(): string;
|
|
107
109
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dirname as e,join as
|
|
1
|
+
import{dirname as e,join as t}from"path";import{fileURLToPath as o}from"url";import{existsSync as l,readFileSync as n}from"fs";import{currentClientConfig as r,usableClientSection as s}from"./client-config.js";import{brand as a}from"./brand.js";const i=e(o(import.meta.url)),d=(e=[],t=[])=>[...new Set([...e,...t])];export function overlayClientSection(e,t){if(!t)return e;const o={...e.retiredDefaultModels??{}};for(const[e,l]of Object.entries(t.retiredDefaultModels??{}))o[e]=d(o[e],l);return{...e,defaultModels:{...e.defaultModels,...t.defaultModels??{}},retiredDefaultModels:o,toolDefaults:{...e.toolDefaults??{},...t.toolDefaults??{}},claudeCode:t.tierChains?{...e.claudeCode??{},tierChains:{...e.claudeCode?.tierChains??{},...t.tierChains}}:e.claudeCode,claudeDesktop:t.oneMillionFallback?{...e.claudeDesktop??{},oneMillionFallback:[...t.oneMillionFallback]}:e.claudeDesktop,gatewayModels:t.retiredModels?{...e.gatewayModels??{},retired:d(e.gatewayModels?.retired,t.retiredModels)}:e.gatewayModels,toolMinVersions:{...e.toolMinVersions??{},...t.toolMinVersions??{}},agy:t.agyModels?{...e.agy??{},gatewayModels:[...t.agyModels]}:e.agy}}let u=null;function c(){return u||(u=overlayClientSection(function(){const e=[t(i,"..","..","models.json"),t(i,"..","models.json"),t(i,"models.json")];for(const t of e)if(l(t))return JSON.parse(n(t,"utf-8"));throw new Error(`models.json not found, searched: ${e.join(", ")}`)}(),s(r()?.config))),u}export function getDefaultModels(){return{...c().defaultModels}}export function isRetiredDefaultModel(e,t){return c().retiredDefaultModels?.[e]?.includes(t)??!1}export function getRetiredDefaultModelIds(){return[...new Set(Object.values(c().retiredDefaultModels??{}).flat())]}export function getDefaultToolModel(){return c().defaultToolModel?.trim()||"gpt-5.5"}export function getToolDefaultModel(e){const t=c().toolDefaults;return t&&Object.prototype.hasOwnProperty.call(t,e)?(t[e]??"").trim():getDefaultToolModel()}export function getPresets(){return[...c().presets]}export function resolvePreset(e){return e.models?{...e.models}:e.model?{haiku:e.model,sonnet:e.model,opus:e.model,reasoning:e.model}:getDefaultModels()}export function getClaudeCodeTierChains(){const e=c().claudeCode?.tierChains??{};return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,[...t]]))}export function getClaudeDesktopRules(){const e=c().claudeDesktop??{};return{oneMillionFallback:[...e.oneMillionFallback??[]],oneMillionExclusions:(e.oneMillionExclusions??[]).map(e=>({...e,models:[...e.models]}))}}export function getGatewayModelRules(){const e=c().gatewayModels??{};return{autoCompactRatio:e.autoCompactRatio??.8,models:(e.models??[]).map(e=>({...e})),retired:[...e.retired??[]]}}export function getBuiltinGatewayAddresses(){return a().gatewayAddresses.map(e=>({...e}))}export function getCodexRules(){return{standardContextWindow:c().codex?.standardContextWindow??272e3}}export function getAgyRules(){return{gatewayModels:[...c().agy?.gatewayModels??[]]}}export function compareVersions(e,t){const o=e.split(".").map(e=>parseInt(e,10)||0),l=t.split(".").map(e=>parseInt(e,10)||0);for(let e=0;e<Math.max(o.length,l.length);e++){const t=(o[e]??0)-(l[e]??0);if(0!==t)return t}return 0}export function getToolMinVersion(e){return c().toolMinVersions?.[e]?.trim()||null}export function reloadRegistry(){u=null}
|
package/dist/lib/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as y}from"../commands/logs.js";import{completionCommand as $}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{codexSessionsCommand as w}from"../commands/codex-sessions.js";import{sessionsExportCommand as v,sessionsListCommand as j,sessionsResumeCommand as O,sessionsShowCommand as S}from"../commands/sessions.js";import{setupCommand as A,DEDICATED_KEYS as E}from"../commands/setup.js";import{baseCommand as G}from"../commands/base.js";import{usageError as z}from"./errors.js";import{requireTerminal as C}from"./confirm.js";import{brand as R,brandEnv as B,CLI_NAME as I}from"./brand.js";const L=(R().gatewayAddresses[1]??R().gatewayAddresses[0]).url,N=(R().gatewayAddresses[2]??R().gatewayAddresses[0]).url;function P(e,o){return i.t(`help.${e}`,o)}function T(e,o){return{command:e,note:P(o)}}function U(e){const o=P(e);return o===`help.${e}`?"":o}function H(e,o=[]){return{when:U(`${e}.when`),prerequisites:U(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>T(e,o))}}function K(e){return e.helpCommand("help [command]",P("help_command"))}export function buildProgram(){const R=new e;R.name(`${I}`).summary(P("root.summary")).description(P("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(P("group.global_options")).helpOption("-h, --help",P("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",P("global.version")).option("--base <url>",P("global.base")).option("--non-interactive",P("global.non_interactive")).option("--json",P("global.json")).option("-y, --yes",P("global.yes")).option("--dry-run",P("global.dry_run")).option("--no-color",P("global.no_color")),R.configureOutput({writeErr:()=>{},outputError:()=>{}}),R.showSuggestionAfterError(),R.exitOverride(e=>{throw e}),R.commandsGroup(P("group.configure"));const U=R.command("setup").summary(P("setup.summary")).description(P("setup.description")).option("--key <key>",P("setup.opt.key"));for(const e of E){const s=new o(`--${e.option} <key>`,P(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),U.addOption(s)}U.option("--1m",P("setup.opt.one_m")).option("--no-1m",P("setup.opt.no_one_m")).option("--claude-official <on|off>",P("setup.opt.claude_official")).option("--desktop-registry <on|off>",P("setup.opt.desktop_registry")).option("--force",P("setup.opt.force")).option("--install",P("setup.opt.install")).option("--no-install",P("setup.opt.no_install")).option("--all",P("setup.opt.all")).action(async e=>{e.key||E.some(o=>e[o.option])||(e.key=B("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||E.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw z(i.t("setup.usage"),`${I} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw z(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${I} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw z(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${I} setup --desktop-registry on|off`,"invalid_value");await A({key:e.key,...Object.fromEntries(E.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(U,{...H("setup",[[`${I} init`,"setup.alt.init"],[`${I} config <tool>`,"setup.alt.config"],[`${I} auth <key>`,"setup.alt.auth"]]),sections:[{title:P("setup.autodetect_title"),rows:[["Claude",P("setup.autodetect.claude")],["GPT",P("setup.autodetect.gpt")],["Grok",P("setup.autodetect.grok")],["Gemini",P("setup.autodetect.gemini")]]}],examples:[T(`${I} setup --key sk-xxx`,"setup.ex.key"),T(`${I} setup --install --key sk-xxx`,"setup.ex.install"),T(`${I} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),T(`${I} setup --force --key sk-xxx`,"setup.ex.force"),T(`${I} setup --base ${L} --key sk-xxx`,"setup.ex.base")]});const M=R.command("init").summary(P("init.summary")).description(P("init.description")).action(async()=>{C(),await r.runFirstTimeSetup()});p(M,{...H("init",[[`${I} setup --key <key>`,"init.alt.setup"],[`${I}`,"init.alt.menu"]]),examples:[T(`${I} init`,"init.ex.run"),T(`${I} init --base ${L}`,"init.ex.base"),T(`${I}`,"init.ex.menu")]});const q=R.command("auth").summary(P("auth.summary")).description(P("auth.description")).argument("[token]",P("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});K(q);const D=q.command("revoke").description(P("auth.revoke")).action(async()=>{await d(["revoke"])});p(D,{examples:[T(`${I} auth revoke`,"auth.ex.revoke_ask"),T(`${I} auth revoke --yes`,"auth.ex.revoke")]});const F=q.command("reload <tool>").description(P("auth.reload")).action(async e=>{await d(["reload",e])});p(F,{examples:[T(`${I} auth reload claude-code`,"auth.ex.reload"),T(`${I} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(q,{...H("auth",[[`${I} setup --key <key>`,"auth.alt.setup"]]),examples:[T(`${I} auth`,"auth.ex.prompt"),T(`${I} auth sk-xxx --non-interactive`,"auth.ex.save"),T(`${I} auth revoke --yes`,"auth.ex.revoke"),T(`${I} auth reload claude-code`,"auth.ex.reload")]});const J=R.command("config").summary(P("config.summary")).description(P("config.description")).argument("[args...]",P("config.arg.args")).option("-f, --force",P("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(J,{...H("config",[[`${I} setup --force --key <key>`,"config.alt.setup"],[`${I} status`,"config.alt.status"]]),sections:[{title:P("config.subcommands_title"),rows:[["<tool>",P("config.sub.tool")],["<tool> --force",P("config.sub.tool_force")],["<tool> --non-interactive",P("config.sub.tool_non_interactive")],["<tool> remove",P("config.sub.tool_remove")],["<tool> restore",P("config.sub.tool_restore")],["<tool> backups",P("config.sub.tool_backups")],["<tool> clear-model",P("config.sub.tool_clear_model")],["tool-model list",P("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",P("config.sub.tool_model_set")],["tool-model clear <tool>",P("config.sub.tool_model_clear")],["profile list",P("config.sub.profile_list")],["profile create <name>",P("config.sub.profile_create")],["profile use <name>",P("config.sub.profile_use")],["profile delete <name>",P("config.sub.profile_delete")],["preset list",P("config.sub.preset_list")],["preset save <name>",P("config.sub.preset_save")],["preset use <name>",P("config.sub.preset_use")],["preset delete <name>",P("config.sub.preset_delete")],["backup list",P("config.sub.backup_list")],["backup create [label]",P("config.sub.backup_create")],["backup restore <name>",P("config.sub.backup_restore")]]},{title:P("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[T(`${I} config codex`,"config.ex.menu"),T(`${I} config claude-code --force`,"config.ex.force"),T(`${I} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),T(`${I} config profile create work`,"config.ex.profile"),T(`${I} config codex remove`,"config.ex.remove")]});const Y=R.command("base").summary(P("base.summary")).description(P("base.description")).argument("[target]",P("base.arg.target")).action(async e=>{await G(e)});p(Y,{...H("base",[[`${I} doctor`,"base.alt.doctor"],[`${I} bench`,"base.alt.bench"]]),sections:[{title:P("base.targets_title"),rows:[[P("base.target.none_term"),P("base.target.none")],[P("base.target.index_term"),P("base.target.index")],[P("base.target.url_term"),P("base.target.url")],["auto",P("base.target.auto")],["default",P("base.target.default",{url:l})]]}],examples:[T(`${I} base`,"base.ex.list"),T(`${I} base auto`,"base.ex.auto"),T(`${I} base 2`,"base.ex.index"),T(`${I} base ${L}`,"base.ex.url"),T(`${I} base default`,"base.ex.default")]}),R.commandsGroup(P("group.diagnose"));const Q=R.command("status").summary(P("status.summary")).description(P("status.description")).action(async()=>{await x()});p(Q,{...H("status",[[`${I} doctor`,"status.alt.doctor"]]),examples:[T(`${I} status`,"status.ex.show"),T(`${I} status --json`,"status.ex.json")]});const V=R.command("doctor").summary(P("doctor.summary")).description(P("doctor.description")).option("--deep",P("doctor.opt.deep")).option("--report",P("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(V,{...H("doctor",[[`${I} base auto`,"doctor.alt.base"],[`${I} logs tail`,"doctor.alt.logs"]]),examples:[T(`${I} doctor`,"doctor.ex.run"),T(`${I} doctor --deep`,"doctor.ex.deep"),T(`${I} doctor --report`,"doctor.ex.report")]});const W=R.command("bench").summary(P("bench.summary")).description(P("bench.description")).option("--samples <n>",P("bench.opt.samples"),"5").option("--stream",P("bench.opt.stream")).option("--model <model>",P("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(W,{...H("bench",[[`${I} base`,"bench.alt.base"]]),examples:[T(`${I} bench`,"bench.ex.run"),T(`${I} bench --samples 3`,"bench.ex.samples"),T(`${I} bench --stream`,"bench.ex.stream"),T(`${I} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),T(`${I} bench --json`,"bench.ex.json")]});const X=R.command("logs").summary(P("logs.summary")).description(P("logs.description")).argument("[action]",P("logs.arg.action")).argument("[file]",P("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await y(s)});p(X,{...H("logs",[[`${I} doctor`,"logs.alt.doctor"]]),sections:[{title:P("logs.actions_title"),rows:[["list",P("logs.action.list")],["tail [file]",P("logs.action.tail")],["path",P("logs.action.path")]]}],examples:[T(`${I} logs`,"logs.ex.list"),T(`${I} logs tail`,"logs.ex.tail"),T(`${I} logs path`,"logs.ex.path")]}),R.commandsGroup(P("group.maintain"));const Z=R.command("upgrade").summary(P("upgrade.summary")).description(P("upgrade.description")).argument("[tools...]",P("upgrade.arg.tools")).option("--force",P("upgrade.opt.force")).action(async(e=[],o={})=>{await _(e,{force:o.force})});p(Z,{...H("upgrade",[[`${I} update`,"upgrade.alt.update"]]),examples:[T(`${I} upgrade`,"upgrade.ex.all"),T(`${I} upgrade claude-code`,"upgrade.ex.one"),T(`${I} upgrade codex agy`,"upgrade.ex.many"),T(`${I} upgrade claude-desktop`,"upgrade.ex.desktop"),T(`${I} upgrade chatgpt --force`,"upgrade.ex.force")]});const ee=R.command("refresh").summary(P("refresh.summary")).description(P("refresh.description")).action(async()=>{await h()});p(ee,{...H("refresh",[[`${I} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[T(`${I} refresh`,"refresh.ex.run"),T(`${I} refresh --base ${N}`,"refresh.ex.base")]});const oe=R.command("update").summary(P("update.summary")).description(P("update.description")).action(async()=>{await k()});p(oe,{...H("update",[[`${I} upgrade`,"update.alt.upgrade"]]),examples:[T(`${I} update`,"update.ex.check"),T(`${I} update --json`,"update.ex.json")]});const se=R.command("codex").summary(P("codex.summary")).description(P("codex.description"));K(se);const te=se.command("sessions").summary(P("codex_sessions.summary")).description(P("codex_sessions.description")).option("--to <provider>",P("codex_sessions.opt.to")).option("--undo <dir>",P("codex_sessions.opt.undo")).action(async e=>{await w(e)});p(se,{...H("codex"),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(te,{...H("codex_sessions",[[`${I} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --to custom`,"codex_sessions.ex.to"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ne=R.command("sessions").summary(P("sessions.summary")).description(P("sessions.description"));K(ne);const ae=ne.command("list",{isDefault:!0}).description(P("sessions.list")).option("--tool <tool>",P("sessions.opt.tool")).option("--dir <path>",P("sessions.opt.dir")).option("--here",P("sessions.opt.here")).option("-n, --limit <count>",P("sessions.opt.limit")).option("--all",P("sessions.opt.all")).action(async e=>{await j(e)}),ie=ne.command("show <id>").description(P("sessions.show")).option("-m, --messages <count>",P("sessions.opt.messages")).action(async(e,o)=>{await S(e,o)}),re=ne.command("resume <id>").description(P("sessions.resume")).option("--run",P("sessions.opt.run")).action(async(e,o)=>{await O(e,o)}),ce=ne.command("export <ids...>").description(P("sessions.export")).option("-o, --output <dir>",P("sessions.opt.output")).option("--tools",P("sessions.opt.tools")).action(async(e,o)=>{await v(e,o)});p(ae,{examples:[T(`${I} sessions list`,"sessions.ex.list"),T(`${I} sessions list --tool codex`,"sessions.ex.codex"),T(`${I} sessions list --here --all`,"sessions.ex.here"),T(`${I} sessions list --json`,"sessions.ex.json")]}),p(ie,{examples:[T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(re,{examples:[T(`${I} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ce,{examples:[T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),T(`${I} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ne,{...H("sessions",[[`${I} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[T(`${I} sessions`,"sessions.ex.list"),T(`${I} sessions --tool codex --here`,"sessions.ex.here"),T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const le=R.command("lang").summary(P("lang.summary")).description(P("lang.description"));K(le);const pe=le.command("show").description(P("lang.show")).action(async()=>{await u(["show"])}),me=le.command("set <locale>").description(P("lang.set")).action(async e=>{await u(["set",e])}),ue=[T(`${I} lang show`,"lang.ex.show"),T(`${I} lang set en_US`,"lang.ex.set_en"),T(`${I} lang set zh_CN`,"lang.ex.set_zh")];p(le,{...H("lang",[[`${I} enter lang`,"lang.alt.enter"]]),examples:ue}),p(pe,{examples:[ue[0],T(`${I} lang show --json`,"lang.ex.show_json")]}),p(me,{examples:ue.slice(1)});const de=R.command("completion").summary(P("completion.summary")).description(P("completion.description")).argument("<shell>",P("completion.arg.shell")).action(async e=>{await $([e])});p(de,{...H("completion"),examples:[T(`${I} completion bash > ~/.${I}-completion.bash`,"completion.ex.bash"),T(`${I} completion zsh > ~/.${I}-completion.zsh`,"completion.ex.zsh"),T(`${I} completion fish > ~/.config/fish/completions/${I}.fish`,"completion.ex.fish")]});const fe=R.command("enter").summary(P("enter.summary")).description(P("enter.description")).argument("[option]",P("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||C(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p(fe,{...H("enter",[[`${I}`,"enter.alt.menu"],[`${I} config <tool>`,"enter.alt.config"]]),sections:[{title:P("enter.options_title"),rows:[[P("enter.option.none_term"),P("enter.option.none")],["lang",P("enter.option.lang")],["apikey",P("enter.option.apikey")],["models",P("enter.option.models")],["<tool>",P("enter.option.tool")]]}],examples:[T(`${I} enter`,"enter.ex.menu"),T(`${I} enter models`,"enter.ex.models"),T(`${I} enter codex`,"enter.ex.tool")]}),K(R),R.action(async()=>{C(),await r.run()}),p(R,{examples:[T(`${I}`,"root.ex.menu"),T(`${I} setup --key sk-xxx`,"root.ex.setup"),T(`${I} doctor`,"root.ex.doctor"),T(`${I} base auto`,"root.ex.base"),T(`${I} config codex`,"root.ex.config")]});const ge=e=>{for(const o of e.commands)o.helpOption("-h, --help",P("global.help")),ge(o)};return ge(R),R}
|
|
1
|
+
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as $}from"../commands/logs.js";import{completionCommand as y}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{installCommand as w,listCommand as v}from"../commands/components.js";import{codexSessionsCommand as j}from"../commands/codex-sessions.js";import{sessionsExportCommand as O,sessionsListCommand as S,sessionsResumeCommand as A,sessionsShowCommand as E}from"../commands/sessions.js";import{setupCommand as G,DEDICATED_KEYS as z}from"../commands/setup.js";import{baseCommand as C}from"../commands/base.js";import{usageError as R}from"./errors.js";import{requireTerminal as B}from"./confirm.js";import{brand as I,brandEnv as L,CLI_NAME as N}from"./brand.js";const P=(I().gatewayAddresses[1]??I().gatewayAddresses[0]).url,T=(I().gatewayAddresses[2]??I().gatewayAddresses[0]).url;function U(e,o){return i.t(`help.${e}`,o)}function H(e,o){return{command:e,note:U(o)}}function K(e){const o=U(e);return o===`help.${e}`?"":o}function M(e,o=[]){return{when:K(`${e}.when`),prerequisites:K(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>H(e,o))}}function q(e){return e.helpCommand("help [command]",U("help_command"))}export function buildProgram(){const I=new e;I.name(`${N}`).summary(U("root.summary")).description(U("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(U("group.global_options")).helpOption("-h, --help",U("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",U("global.version")).option("--base <url>",U("global.base")).option("--non-interactive",U("global.non_interactive")).option("--json",U("global.json")).option("-y, --yes",U("global.yes")).option("--dry-run",U("global.dry_run")).option("--no-color",U("global.no_color")),I.configureOutput({writeErr:()=>{},outputError:()=>{}}),I.showSuggestionAfterError(),I.exitOverride(e=>{throw e}),I.commandsGroup(U("group.configure"));const K=I.command("setup").summary(U("setup.summary")).description(U("setup.description")).option("--key <key>",U("setup.opt.key"));for(const e of z){const s=new o(`--${e.option} <key>`,U(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),K.addOption(s)}K.option("--1m",U("setup.opt.one_m")).option("--no-1m",U("setup.opt.no_one_m")).option("--claude-official <on|off>",U("setup.opt.claude_official")).option("--desktop-registry <on|off>",U("setup.opt.desktop_registry")).option("--force",U("setup.opt.force")).option("--install",U("setup.opt.install")).option("--no-install",U("setup.opt.no_install")).option("--all",U("setup.opt.all")).action(async e=>{e.key||z.some(o=>e[o.option])||(e.key=L("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||z.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw R(i.t("setup.usage"),`${N} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw R(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${N} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw R(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${N} setup --desktop-registry on|off`,"invalid_value");await G({key:e.key,...Object.fromEntries(z.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(K,{...M("setup",[[`${N} init`,"setup.alt.init"],[`${N} config <tool>`,"setup.alt.config"],[`${N} auth <key>`,"setup.alt.auth"]]),sections:[{title:U("setup.autodetect_title"),rows:[["Claude",U("setup.autodetect.claude")],["GPT",U("setup.autodetect.gpt")],["Grok",U("setup.autodetect.grok")],["Gemini",U("setup.autodetect.gemini")]]}],examples:[H(`${N} setup --key sk-xxx`,"setup.ex.key"),H(`${N} setup --install --key sk-xxx`,"setup.ex.install"),H(`${N} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),H(`${N} setup --force --key sk-xxx`,"setup.ex.force"),H(`${N} setup --base ${P} --key sk-xxx`,"setup.ex.base")]});const D=I.command("init").summary(U("init.summary")).description(U("init.description")).action(async()=>{B(),await r.runFirstTimeSetup()});p(D,{...M("init",[[`${N} setup --key <key>`,"init.alt.setup"],[`${N}`,"init.alt.menu"]]),examples:[H(`${N} init`,"init.ex.run"),H(`${N} init --base ${P}`,"init.ex.base"),H(`${N}`,"init.ex.menu")]});const F=I.command("auth").summary(U("auth.summary")).description(U("auth.description")).argument("[token]",U("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});q(F);const J=F.command("revoke").description(U("auth.revoke")).action(async()=>{await d(["revoke"])});p(J,{examples:[H(`${N} auth revoke`,"auth.ex.revoke_ask"),H(`${N} auth revoke --yes`,"auth.ex.revoke")]});const Y=F.command("reload <tool>").description(U("auth.reload")).action(async e=>{await d(["reload",e])});p(Y,{examples:[H(`${N} auth reload claude-code`,"auth.ex.reload"),H(`${N} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(F,{...M("auth",[[`${N} setup --key <key>`,"auth.alt.setup"]]),examples:[H(`${N} auth`,"auth.ex.prompt"),H(`${N} auth sk-xxx --non-interactive`,"auth.ex.save"),H(`${N} auth revoke --yes`,"auth.ex.revoke"),H(`${N} auth reload claude-code`,"auth.ex.reload")]});const Q=I.command("config").summary(U("config.summary")).description(U("config.description")).argument("[args...]",U("config.arg.args")).option("-f, --force",U("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(Q,{...M("config",[[`${N} setup --force --key <key>`,"config.alt.setup"],[`${N} status`,"config.alt.status"]]),sections:[{title:U("config.subcommands_title"),rows:[["<tool>",U("config.sub.tool")],["<tool> --force",U("config.sub.tool_force")],["<tool> --non-interactive",U("config.sub.tool_non_interactive")],["<tool> remove",U("config.sub.tool_remove")],["<tool> restore",U("config.sub.tool_restore")],["<tool> backups",U("config.sub.tool_backups")],["<tool> clear-model",U("config.sub.tool_clear_model")],["tool-model list",U("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",U("config.sub.tool_model_set")],["tool-model clear <tool>",U("config.sub.tool_model_clear")],["profile list",U("config.sub.profile_list")],["profile create <name>",U("config.sub.profile_create")],["profile use <name>",U("config.sub.profile_use")],["profile delete <name>",U("config.sub.profile_delete")],["preset list",U("config.sub.preset_list")],["preset save <name>",U("config.sub.preset_save")],["preset use <name>",U("config.sub.preset_use")],["preset delete <name>",U("config.sub.preset_delete")],["backup list",U("config.sub.backup_list")],["backup create [label]",U("config.sub.backup_create")],["backup restore <name>",U("config.sub.backup_restore")]]},{title:U("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[H(`${N} config codex`,"config.ex.menu"),H(`${N} config claude-code --force`,"config.ex.force"),H(`${N} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),H(`${N} config profile create work`,"config.ex.profile"),H(`${N} config codex remove`,"config.ex.remove")]});const V=I.command("base").summary(U("base.summary")).description(U("base.description")).argument("[target]",U("base.arg.target")).action(async e=>{await C(e)});p(V,{...M("base",[[`${N} doctor`,"base.alt.doctor"],[`${N} bench`,"base.alt.bench"]]),sections:[{title:U("base.targets_title"),rows:[[U("base.target.none_term"),U("base.target.none")],[U("base.target.index_term"),U("base.target.index")],[U("base.target.url_term"),U("base.target.url")],["auto",U("base.target.auto")],["default",U("base.target.default",{url:l})]]}],examples:[H(`${N} base`,"base.ex.list"),H(`${N} base auto`,"base.ex.auto"),H(`${N} base 2`,"base.ex.index"),H(`${N} base ${P}`,"base.ex.url"),H(`${N} base default`,"base.ex.default")]}),I.commandsGroup(U("group.diagnose"));const W=I.command("status").summary(U("status.summary")).description(U("status.description")).action(async()=>{await x()});p(W,{...M("status",[[`${N} doctor`,"status.alt.doctor"]]),examples:[H(`${N} status`,"status.ex.show"),H(`${N} status --json`,"status.ex.json")]});const X=I.command("doctor").summary(U("doctor.summary")).description(U("doctor.description")).option("--deep",U("doctor.opt.deep")).option("--report",U("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(X,{...M("doctor",[[`${N} base auto`,"doctor.alt.base"],[`${N} logs tail`,"doctor.alt.logs"]]),examples:[H(`${N} doctor`,"doctor.ex.run"),H(`${N} doctor --deep`,"doctor.ex.deep"),H(`${N} doctor --report`,"doctor.ex.report")]});const Z=I.command("bench").summary(U("bench.summary")).description(U("bench.description")).option("--samples <n>",U("bench.opt.samples"),"5").option("--stream",U("bench.opt.stream")).option("--model <model>",U("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(Z,{...M("bench",[[`${N} base`,"bench.alt.base"]]),examples:[H(`${N} bench`,"bench.ex.run"),H(`${N} bench --samples 3`,"bench.ex.samples"),H(`${N} bench --stream`,"bench.ex.stream"),H(`${N} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),H(`${N} bench --json`,"bench.ex.json")]});const ee=I.command("logs").summary(U("logs.summary")).description(U("logs.description")).argument("[action]",U("logs.arg.action")).argument("[file]",U("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await $(s)});p(ee,{...M("logs",[[`${N} doctor`,"logs.alt.doctor"]]),sections:[{title:U("logs.actions_title"),rows:[["list",U("logs.action.list")],["tail [file]",U("logs.action.tail")],["path",U("logs.action.path")]]}],examples:[H(`${N} logs`,"logs.ex.list"),H(`${N} logs tail`,"logs.ex.tail"),H(`${N} logs path`,"logs.ex.path")]}),I.commandsGroup(U("group.maintain"));const oe=I.command("list").summary(U("list.summary")).description(U("list.description")).option("--refresh",U("list.opt.refresh")).action(async(e={})=>{await v({refresh:e.refresh})});p(oe,{...M("list",[[`${N} doctor`,"list.alt.doctor"]]),examples:[H(`${N} list`,"list.ex.all"),H(`${N} list --refresh`,"list.ex.refresh"),H(`${N} list --json`,"list.ex.json")]});const se=I.command("install").summary(U("install.summary")).description(U("install.description")).argument("<components...>",U("install.arg.components")).option("--force",U("install.opt.force")).action(async(e,o={})=>{await w(e,{force:o.force})});p(se,{...M("install",[[`${N} upgrade`,"install.alt.upgrade"],[`${N} setup --key ${i.t("errors.key_placeholder")}`,"install.alt.setup"]]),examples:[H(`${N} install node uv`,"install.ex.runtimes"),H(`${N} install claude-code codex`,"install.ex.clis"),H(`${N} install chatgpt`,"install.ex.app"),H(`${N} install uv --force`,"install.ex.force"),H(`${N} install node uv --yes --json`,"install.ex.json")]});const te=I.command("upgrade").summary(U("upgrade.summary")).description(U("upgrade.description")).argument("[tools...]",U("upgrade.arg.tools")).option("--force",U("upgrade.opt.force")).action(async(e=[],o={})=>{await _(e,{force:o.force})});p(te,{...M("upgrade",[[`${N} update`,"upgrade.alt.update"]]),examples:[H(`${N} upgrade`,"upgrade.ex.all"),H(`${N} upgrade codex agy`,"upgrade.ex.many"),H(`${N} upgrade claude-desktop`,"upgrade.ex.desktop"),H(`${N} upgrade chatgpt --force`,"upgrade.ex.force"),H(`${N} upgrade node`,"upgrade.ex.runtime")]});const ne=I.command("refresh").summary(U("refresh.summary")).description(U("refresh.description")).action(async()=>{await h()});p(ne,{...M("refresh",[[`${N} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[H(`${N} refresh`,"refresh.ex.run"),H(`${N} refresh --base ${T}`,"refresh.ex.base")]});const ae=I.command("update").summary(U("update.summary")).description(U("update.description")).action(async()=>{await k()});p(ae,{...M("update",[[`${N} upgrade`,"update.alt.upgrade"]]),examples:[H(`${N} update`,"update.ex.check"),H(`${N} update --json`,"update.ex.json")]});const ie=I.command("codex").summary(U("codex.summary")).description(U("codex.description"));q(ie);const re=ie.command("sessions").summary(U("codex_sessions.summary")).description(U("codex_sessions.description")).option("--to <provider>",U("codex_sessions.opt.to")).option("--undo <dir>",U("codex_sessions.opt.undo")).action(async e=>{await j(e)});p(ie,{...M("codex"),examples:[H(`${N} codex sessions`,"codex_sessions.ex.move"),H(`${N} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(re,{...M("codex_sessions",[[`${N} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[H(`${N} codex sessions`,"codex_sessions.ex.move"),H(`${N} codex sessions --to custom`,"codex_sessions.ex.to"),H(`${N} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ce=I.command("sessions").summary(U("sessions.summary")).description(U("sessions.description"));q(ce);const le=ce.command("list",{isDefault:!0}).description(U("sessions.list")).option("--tool <tool>",U("sessions.opt.tool")).option("--dir <path>",U("sessions.opt.dir")).option("--here",U("sessions.opt.here")).option("-n, --limit <count>",U("sessions.opt.limit")).option("--all",U("sessions.opt.all")).action(async e=>{await S(e)}),pe=ce.command("show <id>").description(U("sessions.show")).option("-m, --messages <count>",U("sessions.opt.messages")).action(async(e,o)=>{await E(e,o)}),me=ce.command("resume <id>").description(U("sessions.resume")).option("--run",U("sessions.opt.run")).action(async(e,o)=>{await A(e,o)}),ue=ce.command("export <ids...>").description(U("sessions.export")).option("-o, --output <dir>",U("sessions.opt.output")).option("--tools",U("sessions.opt.tools")).action(async(e,o)=>{await O(e,o)});p(le,{examples:[H(`${N} sessions list`,"sessions.ex.list"),H(`${N} sessions list --tool codex`,"sessions.ex.codex"),H(`${N} sessions list --here --all`,"sessions.ex.here"),H(`${N} sessions list --json`,"sessions.ex.json")]}),p(pe,{examples:[H(`${N} sessions show 01a0f5fe`,"sessions.ex.show"),H(`${N} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(me,{examples:[H(`${N} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),H(`${N} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ue,{examples:[H(`${N} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),H(`${N} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ce,{...M("sessions",[[`${N} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[H(`${N} sessions`,"sessions.ex.list"),H(`${N} sessions --tool codex --here`,"sessions.ex.here"),H(`${N} sessions show 01a0f5fe`,"sessions.ex.show"),H(`${N} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),H(`${N} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const de=I.command("lang").summary(U("lang.summary")).description(U("lang.description"));q(de);const fe=de.command("show").description(U("lang.show")).action(async()=>{await u(["show"])}),ge=de.command("set <locale>").description(U("lang.set")).action(async e=>{await u(["set",e])}),xe=[H(`${N} lang show`,"lang.ex.show"),H(`${N} lang set en_US`,"lang.ex.set_en"),H(`${N} lang set zh_CN`,"lang.ex.set_zh")];p(de,{...M("lang",[[`${N} enter lang`,"lang.alt.enter"]]),examples:xe}),p(fe,{examples:[xe[0],H(`${N} lang show --json`,"lang.ex.show_json")]}),p(ge,{examples:xe.slice(1)});const he=I.command("completion").summary(U("completion.summary")).description(U("completion.description")).argument("<shell>",U("completion.arg.shell")).action(async e=>{await y([e])});p(he,{...M("completion"),examples:[H(`${N} completion bash > ~/.${N}-completion.bash`,"completion.ex.bash"),H(`${N} completion zsh > ~/.${N}-completion.zsh`,"completion.ex.zsh"),H(`${N} completion fish > ~/.config/fish/completions/${N}.fish`,"completion.ex.fish")]});const $e=I.command("enter").summary(U("enter.summary")).description(U("enter.description")).argument("[option]",U("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||B(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p($e,{...M("enter",[[`${N}`,"enter.alt.menu"],[`${N} config <tool>`,"enter.alt.config"]]),sections:[{title:U("enter.options_title"),rows:[[U("enter.option.none_term"),U("enter.option.none")],["lang",U("enter.option.lang")],["apikey",U("enter.option.apikey")],["models",U("enter.option.models")],["<tool>",U("enter.option.tool")]]}],examples:[H(`${N} enter`,"enter.ex.menu"),H(`${N} enter models`,"enter.ex.models"),H(`${N} enter codex`,"enter.ex.tool")]}),q(I),I.action(async()=>{B(),await r.run()}),p(I,{examples:[H(`${N}`,"root.ex.menu"),H(`${N} setup --key sk-xxx`,"root.ex.setup"),H(`${N} doctor`,"root.ex.doctor"),H(`${N} base auto`,"root.ex.base"),H(`${N} config codex`,"root.ex.config")]});const ye=e=>{for(const o of e.commands)o.helpOption("-h, --help",U("global.help")),ye(o)};return ye(I),I}
|
|
@@ -23,3 +23,8 @@ export declare function isColorEnabled(): boolean;
|
|
|
23
23
|
export declare function resetRuntimeOptions(): void;
|
|
24
24
|
export declare function detectColorPreferenceFromEnv(env?: NodeJS.ProcessEnv): boolean;
|
|
25
25
|
export declare function emitJson(data: unknown, output?: (line: string) => void): void;
|
|
26
|
+
/**
|
|
27
|
+
* Under `--json`, everything `fn` prints with console.log goes to stderr, so stdout stays the one JSON document the
|
|
28
|
+
* command emits afterwards (install / upgrade reuse code that reports progress on stdout).
|
|
29
|
+
*/
|
|
30
|
+
export declare function progressToStderr<T>(fn: () => Promise<T>): Promise<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const n={nonInteractive:!1,json:!1,yes:!1,dryRun:!1,color:!0};let
|
|
1
|
+
const n={nonInteractive:!1,json:!1,yes:!1,dryRun:!1,color:!0};let o={...n};export function setRuntimeOptions(n){o={...o,...n}}export function getRuntimeOptions(){return{...o}}export function isJsonMode(){return o.json}export function isNonInteractive(){return o.nonInteractive||o.json}export function isDryRun(){return o.dryRun}export function shouldAutoConfirm(){return o.yes||o.nonInteractive||o.json}export function canPrompt(){return!isNonInteractive()&&Boolean(process.stdin.isTTY)}export function hasExplicitYes(){return o.yes}export function isColorEnabled(){return o.color}export function resetRuntimeOptions(){o={...n}}export function detectColorPreferenceFromEnv(n=process.env){return(!n.NO_COLOR||"0"===n.NO_COLOR)&&"0"!==n.FORCE_COLOR&&"false"!==n.FORCE_COLOR}export function emitJson(n,o=n=>process.stdout.write(n+"\n")){o(JSON.stringify(n,null,2))}export async function progressToStderr(n){if(!isJsonMode())return n();const o=console.log;console.log=(...n)=>console.error(...n);try{return await n()}finally{console.log=o}}
|
|
@@ -22,6 +22,7 @@ export interface ToolInfo {
|
|
|
22
22
|
/** GUI app (no terminal command to type, e.g. Claude Desktop). */
|
|
23
23
|
gui?: boolean;
|
|
24
24
|
}
|
|
25
|
+
/** Every key saved in any profile (default and tool-specific), trimmed. */
|
|
25
26
|
/**
|
|
26
27
|
* Tool metadata keyed by id. Derived from the adapter registry so the list of
|
|
27
28
|
* supported tools lives in exactly one place (`lib/tools/registry.ts`).
|
|
@@ -62,6 +63,7 @@ export declare class ToolManager {
|
|
|
62
63
|
forceResetConfig(toolName: string): string[];
|
|
63
64
|
loadPrivateConfig(toolName: string, apiKey: string, models: VibecliModels, catalog?: ModelCatalog, options?: {
|
|
64
65
|
force?: boolean;
|
|
66
|
+
takeOver?: boolean;
|
|
65
67
|
}): void;
|
|
66
68
|
/**
|
|
67
69
|
* `loadPrivateConfig` plus the network lookup adapters with
|
|
@@ -70,6 +72,7 @@ export declare class ToolManager {
|
|
|
70
72
|
*/
|
|
71
73
|
applyPrivateConfig(toolName: string, apiKey: string, models: VibecliModels, options?: {
|
|
72
74
|
force?: boolean;
|
|
75
|
+
takeOver?: boolean;
|
|
73
76
|
}): Promise<void>;
|
|
74
77
|
private applyPrivateConfigNow;
|
|
75
78
|
/** Post-apply follow-ups the adapter wants shown to the user (may be empty). */
|
package/dist/lib/tool-manager.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{canPrompt as i,shouldAutoConfirm as l}from"./runtime-options.js";import{logger as
|
|
1
|
+
import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{canPrompt as i,shouldAutoConfirm as l}from"./runtime-options.js";import{logger as a}from"../utils/logger.js";import{configManager as s,savedApiKeys as c}from"./config.js";import{getAdapter as d,listAdapters as p,TOOL_ADAPTERS as u}from"./tools/registry.js";import{backupBeforeWrite as m,listBackups as f,restoreBackup as g}from"./tools/backup.js";import{existsSync as h,rmSync as w}from"fs";import{dirname as y,join as P}from"path";import{toolHome as v}from"./tools/types.js";import{stringWidth as $}from"../utils/string-width.js";import{resolveModelCatalog as T}from"./model-catalog.js";import{compareVersions as k,getToolMinVersion as C}from"./model-registry.js";import{findInstalls as E,forgetInstalls as O,installLabel as _,mirrorInstallCommand as S,npmMirrorInstallCommand as N,npmMirrorVersion as j}from"./tools/tool-installs.js";import{mirrorInstall as M}from"./tool-upgrade.js";import{upgradeApp as U}from"./app-update.js";import{CLI_NAME as b}from"./brand.js";import{track as x,trackStep as I}from"./telemetry.js";import{addUserPathDir as R,broadcastEnvChange as F}from"./windows-env.js";export{k as compareVersions};function L(o){const t=u[o];return{name:t.name,command:t.command,installCommand:t.installCommand,configPath:t.configPath,displayName:t.displayName,...t.hidden?{hidden:!0}:{},...t.isInstalled?{gui:!0}:{}}}export const SUPPORTED_TOOLS=Object.fromEntries(Object.keys(u).map(o=>[o,L(o)]));export class ToolManager{static instance;constructor(){}static getInstance(){return ToolManager.instance||(ToolManager.instance=new ToolManager),ToolManager.instance}isToolInstalled(o){if(!SUPPORTED_TOOLS[o])return!1;const t=d(o);if(t?.isInstalled)try{return t.isInstalled()}catch{return!1}return this.isOnPath(o)||null!==this.nativeLauncher(o)}isOnPath(t){const n=SUPPORTED_TOOLS[t];if(!n)return!1;try{const t="win32"===process.platform?`where ${n.command}`:`which ${n.command}`;return o(t,{stdio:"pipe"}),!0}catch{return!1}}nativeLauncher(o){const t=d(o),n=t?.installSpec?.native?.binDir;if(!t||!n)return null;const e="win32"===process.platform?`${t.command}.exe`:t.command,r=P(v(),...n,e);return h(r)?r:null}ensureNativeOnPath(o){if("win32"!==process.platform||this.isOnPath(o))return null;const t=this.nativeLauncher(o);if(!t)return null;const n=y(t);try{if(!R(n))return null}catch(t){return a.logError(`ensureNativeOnPath: ${o}`,t),null}return F(),process.env.Path=`${process.env.Path??""};${n}`,n}async installTool(o){return I(`install:${o}`,()=>this.installToolNow(o))}async installToolNow(t){const a=SUPPORTED_TOOLS[t];if(!a)throw new Error(`Unknown tool: ${t}`);const s=d(t)?.appInstaller;if(s&&!s.blocker()){const o=await U(t,{install:!0});if("failed"===o.result||"unavailable"===o.result)throw new Error(`Failed to install ${a.displayName}`);return}const c=d(t)?.installSpec;if(c&&(c.mirrorScript||c.npmPackage)){const o=S(c);if(await M(c)&&(O(),this.isToolInstalled(t)))return void console.log(r.green("√ "+n.t("wizard.tool_installed")));throw console.log(r.red("× "+n.t("wizard.install_failed"))),console.log(r.yellow(" ! "+n.t("install.manual_command",{tool:a.displayName,command:o}))),c.mirrorScript&&c.npmPackage&&console.log(r.yellow(" ! "+n.t("install.manual_npm",{command:N(c,await j(c))}))),new Error(`Failed to install ${a.displayName}`)}const p=a.installCommand;console.log(r.gray("$ ")+r.white(p));try{return o(p,{stdio:"inherit"}),O(),void console.log(r.green("√ "+n.t("wizard.tool_installed")))}catch(o){if(console.log(r.red("× "+n.t("wizard.install_failed"))),!/EACCES|EPERM|permission denied/i.test(`${o?.message??""}${o?.stderr??""}`)&&243!==o?.status&&!p.startsWith("npm "))throw new Error(`Failed to install ${a.displayName}: ${o}`);console.log(r.yellow(" ! "+("win32"===process.platform?n.t("install.permission_windows",{command:p}):n.t("install.permission_unix",{command:p}))))}const{action:u}=!i()||l()?{action:"continue"}:await e.prompt([{type:"list",name:"action",message:n.t("install.what_next"),choices:[{name:n.t("install.installed_continue"),value:"continue"},{name:n.t("install.cancel_install"),value:"cancel"}]}]);if("cancel"===u)throw new Error(n.t("install.user_cancelled"));if(O(),!this.isToolInstalled(t))throw console.log(r.red("× "+n.t("install.still_not_installed",{tool:a.displayName}))),new Error(`${a.displayName} is not installed`);console.log(r.green("√ "+n.t("install.verified_success",{tool:a.displayName})))}getToolConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{return t.getConfig()}catch(t){return a.warn(`Failed to read config for ${o}:`,t),a.logError(`ToolManager.getToolConfig(${o})`,t),null}}updateToolConfig(o,t){const n=d(o);if(!n)throw new Error(`Unknown tool: ${o}`);if(!n.updateConfig)throw new Error(`Tool ${o} does not support raw config updates`);n.updateConfig(t)}forceResetConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);const n=t.forceResetPaths?t.forceResetPaths():this.backupPathsFor(t),e=[];for(const o of n)h(o)&&(m(o),w(o,{force:!0}),e.push(o));return e}loadPrivateConfig(o,t,n,e,r={}){const i=d(o);if(!i)throw new Error(`Unknown tool: ${o}`);r.force&&this.forceResetConfig(o),i.loadPrivateConfig({apiKey:t,baseUrl:s.getBaseUrl(),models:n,settings:s.getToolSettings(o),...e?{catalog:e}:{},...r.takeOver?{takeOver:!0}:{}})}async applyPrivateConfig(o,t,n,e={}){const r=this.installedVersion(o);return I(`apply:${o}`,()=>this.applyPrivateConfigNow(o,t,n,e),{...r?{tool_version:r}:{},...e.force?{force:!0}:{}})}async applyPrivateConfigNow(o,t,n,e){const r=d(o);if(!r)throw new Error(`Unknown tool: ${o}`);const i=r.wantsModelCatalog?await T(t):null,{force:l,takeOver:a}=e;l||a?this.loadPrivateConfig(o,t,n,i??void 0,{force:l,takeOver:a}):i?this.loadPrivateConfig(o,t,n,i):this.loadPrivateConfig(o,t,n)}applyNotes(o){const t=d(o);if(!t)return[];const e=[];try{t.applyNotes&&e.push(...t.applyNotes())}catch(t){a.logError(`ToolManager.applyNotes(${o})`,t)}const r=this.outdatedVersion(o);if(r){e.push({kind:"action",text:n.t("tools.version_outdated",{current:r.current,min:r.min,upgrade:t.installSpec?`${b} upgrade ${o}`:t.upgradeCommand||t.installCommand})});for(const o of t.upgradeHints?.(r.min)??[])e.push({kind:"action",text:o})}const i=t.installSpec?E(t.installSpec):[];return i.length>1&&e.push({kind:"action",text:n.t("upgrade.duplicates_note",{count:String(i.length),active:_(i[0]),others:i.slice(1).map(_).join("、"),tool:o})}),e}printApplied(o,t=16){const n=SUPPORTED_TOOLS[o]?.displayName??o,e=this.applyNotes(o);for(const o of e.filter(o=>"detail"===o.kind))a.record(`${n}: ${o.text}`);const i=e.filter(o=>"summary"===o.kind).map(o=>o.text).join(";"),l=" ".repeat(Math.max(1,t-$(n)));console.log(r.green("√ "+n)+(i?l+i:""));for(const o of e.filter(o=>"action"===o.kind))console.log(r.yellow(" ! "+o.text))}installedVersion(o){const n=d(o);if(!n)return null;if(n.installSpec)return E(n.installSpec)[0]?.version??null;if(n.installedVersion)try{return n.installedVersion()}catch(t){return a.logError(`ToolManager.installedVersion(${o})`,t),null}if(n.isInstalled)return null;try{const o={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},e=`${("win32"===process.platform?t(`${n.command} --version`,{...o,shell:!0}):t(n.command,["--version"],o)).stdout??""}`.match(/(\d+)\.(\d+)\.(\d+)/);return e?e[0]:null}catch{return null}}outdatedVersion(o){const t=C(o);if(!t)return null;const n=this.installedVersion(o);return n&&k(n,t)<0?{current:n,min:t}:null}unloadPrivateConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{t.unloadPrivateConfig({savedKeys:c()}),x(`remove:${o}`,"ok")}catch(t){throw x(`remove:${o}`,"fail",{error:t}),t}let e=[];try{e=t.unloadNotes?.()??[]}catch(t){a.logError(`ToolManager.unloadNotes(${o})`,t)}return e.length>0?e:[{kind:"action",text:n.t("config.reopen_hint",{tool:t.displayName})}]}async clearPinnedModels(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);if(s.setToolModel(o,null),!t.clearPinnedModels)return[];const n=s.getApiKeyForTool(o),e=t.wantsModelCatalog&&n?await T(n):null;return t.clearPinnedModels(e??void 0)}supportsClearPinnedModels(o){return Boolean(d(o)?.clearPinnedModels)}holdsOurConfig(o){const t=d(o);if(!t)return!1;const n=c();return t.holdsOurConfig?t.holdsOurConfig(n):Boolean(t.detectCurrentConfig().apiKey)}detectCurrentConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);return t.detectCurrentConfig()}backupPathsFor(o){return o.backupPaths?o.backupPaths():[o.configPath]}listToolBackups(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,backups:f(o)}))}restorePrivateConfig(o){const t=d(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,result:g(o)}))}getInstalledTools(){return Object.keys(SUPPORTED_TOOLS).filter(o=>this.isToolInstalled(o))}getSupportedTools(){return p().filter(o=>!o.hidden).map(o=>L(o.name))}isGitInstalled(){try{const t="win32"===process.platform?"where git":"which git";return o(t,{stdio:"pipe"}),!0}catch{return!1}}}export const toolManager=ToolManager.getInstance();
|
|
@@ -6,6 +6,8 @@ export interface RunLimits {
|
|
|
6
6
|
timeoutMs?: number;
|
|
7
7
|
/** Stop once the command has printed nothing for this long (download progress counts as output). */
|
|
8
8
|
idleMs?: number;
|
|
9
|
+
/** Extra environment variables for the command (install scripts' NODE_INSTALL_FORCE …). */
|
|
10
|
+
env?: Record<string, string>;
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* Runs a command with its output passed through to the terminal, stopping it once it goes quiet
|
package/dist/lib/tool-upgrade.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as s}from"./i18n.js";import{logger as a}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as u,forgetInstalls as
|
|
1
|
+
import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as s}from"./i18n.js";import{logger as a}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as m,findInstallsIncludingNative as u,forgetInstalls as d,installLabel as g,npmMirrorInstallCommand as f,npmMirrorVersion as w,npmUninstallCommand as h}from"./tools/tool-installs.js";import{toolHome as y}from"./tools/types.js";import{isJsonMode as v,isNonInteractive as _,shouldAutoConfirm as k}from"./runtime-options.js";import{track as b}from"./telemetry.js";import{isWindowsPowerShell as $,powerShellEnv as j}from"./powershell-env.js";let T="ok",M=async(t,o,r={})=>(console.log(n.gray("$ ")+[t,...o].join(" ")),T=r.idleMs?await runWatched(t,o,r):function(t,o,r){const n=D(t)?e(E(t,o),{stdio:S(),shell:!0,timeout:r}):e(t,o,{stdio:S(),timeout:r,env:x(t)});return n.error&&a.logError(`upgrade: ${t}`,n.error),"ETIMEDOUT"===n.error?.code?"timeout":0===n.status?"ok":"fail"}(t,o,r.timeoutMs),"ok"===T);const D=t=>"win32"===process.platform&&!/\.exe$/i.test(t),x=t=>$(t)?j():process.env,E=(t,e)=>[t,...e].map(t=>/\s/.test(t)?`"${t}"`:t).join(" "),S=()=>["inherit",v()?2:"inherit","inherit"];export function runWatched(e,o,r){return new Promise(n=>{const i=r.env?{...x(e),...r.env}:x(e),s=D(e)?t(E(e,o),{stdio:["inherit","pipe","pipe"],shell:!0,env:i}):t(e,o,{stdio:["inherit","pipe","pipe"],env:i});let l;const c=t=>{l=t,s.kill()};let p;const m=()=>{clearTimeout(p),r.idleMs&&(p=setTimeout(()=>c("stalled"),r.idleMs))},u=r.timeoutMs?setTimeout(()=>c("timeout"),r.timeoutMs):void 0;m(),s.stdout?.on("data",t=>{(v()?process.stderr:process.stdout).write(t),m()}),s.stderr?.on("data",t=>{process.stderr.write(t),m()});const d=t=>{clearTimeout(p),clearTimeout(u),n(t)};s.on("error",t=>{a.logError(`upgrade: ${e}`,t),d(l??"fail")}),s.on("close",t=>{l&&(v()?process.stderr:process.stdout).write("\n"),d(l??(0===t?"ok":"fail"))})})}export function setUpgradeRunnerForTests(t){M=async(e,o,r)=>{const n=await t(e,o,r);return T="string"==typeof n?n:n?"ok":"fail","ok"===T}}const P={ok:"install.script_failed_npm",fail:"install.script_failed_npm",stalled:"install.script_stalled_npm",timeout:"install.script_timeout_npm"};export async function mirrorInstall(t){if(!t.mirrorScript)return I(t);console.log(n.gray(s.t("install.downloading")));const e=`install-script:${t.command}`,o=Date.now();b(e,"start");const r={idleMs:18e4,timeoutMs:36e5},i="win32"===process.platform?await M("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${t.mirrorScript.ps1} -TimeoutSec 30 | iex`],r):await M("sh",["-c",`script=$(curl -fsSL --connect-timeout 15 --max-time 60 ${t.mirrorScript.sh}) && printf '%s\\n' "$script" | sh`],r),a=T;return b(e,"stalled"===a?"timeout":a,{duration_ms:Date.now()-o,..."stalled"===a||"timeout"===a?{detail:{reason:a}}:{}}),i||!t.npmPackage?i:(console.log(n.yellow(" ! "+s.t(P[a],{minutes:String(3)}))),b(e,"fallback"),I(t))}async function I(t){const e=f(t,await w(t)),[o,...r]=e.split(" "),i=`install-npm:${t.command}`,a=Date.now();b(i,"start");const l=await M(o,r);return b(i,l?"ok":"fail",{duration_ms:Date.now()-a}),l||"win32"===process.platform||console.log(n.yellow(" ! "+s.t("upgrade.npm_permission",{command:e}))),l}async function U(t,e){switch(e.kind){case"npm":t.npmPackage&&await M("npm",["uninstall","-g",t.npmPackage]);break;case"brew":t.brew&&await M("brew",["uninstall",t.brew]);break;case"native":try{o(e.path,{force:!0});for(const e of t.native?.dataDirs??[])o(r(y(),...e),{recursive:!0,force:!0})}catch(t){a.logError("upgrade: remove native copy",t)}break;default:return!1}return d(),!m(t).some(t=>t.path===e.path)}function N(t,e){switch(e.kind){case"npm":return h(t);case"brew":return`brew uninstall ${t.brew}`;case"native":return s.t("upgrade.delete_paths",{paths:[e.path,...(t.native?.dataDirs??[]).map(t=>r(y(),...t))].join("、")});default:return s.t("upgrade.delete_paths",{paths:e.path})}}export async function upgradeTool(t){const e=Date.now();b(`upgrade:${t}`,"start");try{const o=await async function(t){const e=p(t),o=e?.installSpec;if(!e||!o)throw new Error(s.t("upgrade.unsupported",{tool:t}));const r=e.displayName;d();const f=m(o);if(console.log(n.bold(`\n${r}`)),0===f.length)console.log(s.t("upgrade.not_installed_installing",{tool:r})),await mirrorInstall(o);else{const t=f[0];console.log(n.gray(" "+s.t("upgrade.current",{copy:g(t)})));const e=await async function(t,e){switch(e.kind){case"native":return M(e.path,t.native?.updateArgs??["update"],{timeoutMs:t.native?.updateTimeoutMs});case"npm":return I(t);case"brew":return!!t.brew&&M("brew",["upgrade",t.brew]);default:return!1}}(o,t);e||"other"!==t.kind?e||"npm"===t.kind||"native"===t.kind&&await async function(t){const e=t.native?.mirrorUpdate;if(!e)return!1;console.log(n.yellow(" ! "+s.t("upgrade.native_mirror_trying")));try{const{version:t,manifestVerified:o}=await e();return console.log(n.green(" √ "+s.t(o?"upgrade.native_mirror_done_verified":"upgrade.native_mirror_done",{version:t}))),!0}catch(t){return a.logError("upgrade: native mirror",t),console.log(n.yellow(" ! "+s.t("upgrade.native_mirror_failed",{reason:t instanceof Error?t.message:String(t)}))),!1}}(o)||(console.log(n.yellow(" ! "+s.t("upgrade.fallback_mirror"))),await mirrorInstall(o)):console.log(n.yellow(" ! "+s.t("upgrade.unknown_install",{path:t.path})))}d(),await async function(t,e){const o=m(t);if(o.length<2)return;const r=function(t){return t.reduce((t,e)=>e.version&&(!t.version||l(e.version,t.version)>0)?e:t)}(o),a=o.filter(t=>t!==r);console.log(n.yellow(" ! "+s.t("upgrade.duplicates",{tool:e,keep:g(r),others:a.map(g).join("、")})));let c=k();c||_()||!process.stdin.isTTY||(c=(await i.prompt([{type:"confirm",name:"remove",message:s.t("upgrade.confirm_remove"),default:!0}])).remove);for(const e of a)c&&await U(t,e)?console.log(n.green(" √ "+s.t("upgrade.removed",{copy:g(e)}))):console.log(n.yellow(" ! "+s.t("upgrade.remove_by_hand",{how:N(t,e)})))}(o,r),d();const w=u(o)[0];if(!w)return console.log(n.red(" × "+s.t("upgrade.still_missing",{tool:r}))),!1;w.onPath||console.log(n.gray(" "+s.t("components.new_terminal")));const h=c(t);if(h&&w.version&&l(w.version,h)<0){console.log(n.yellow(" ! "+s.t("upgrade.still_old",{copy:g(w),min:h})));for(const t of e.upgradeHints?.(h)??[])console.log(n.yellow(" ! "+t));return!1}return console.log(n.green(" √ "+s.t("upgrade.done",{copy:g(w)}))),!0}(t);return b(`upgrade:${t}`,o?"ok":"fail",{duration_ms:Date.now()-e}),o}catch(o){throw b(`upgrade:${t}`,"fail",{duration_ms:Date.now()-e,error:o}),o}}
|
|
@@ -19,14 +19,27 @@ export declare const chatgptInstaller: import("./desktop-app-installer.js").Desk
|
|
|
19
19
|
declare let run: (command: string, args: string[], timeout?: number) => {
|
|
20
20
|
status: number | null;
|
|
21
21
|
stdout: string;
|
|
22
|
+
stderr?: string;
|
|
22
23
|
};
|
|
23
24
|
/** Tests replace the process runner. */
|
|
24
25
|
export declare function setChatgptProcessRunnerForTests(fake: typeof run): void;
|
|
25
26
|
/** Only the installed copy's main process counts (not another app that happens to be called ChatGPT). */
|
|
26
27
|
export declare function isChatgptRunning(): boolean;
|
|
27
|
-
/**
|
|
28
|
+
/** The last `quitChatgpt()` was turned down by the app (see there); it is still running. */
|
|
29
|
+
export declare function chatgptQuitRefused(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Quit (gracefully, then forcibly); true when no instance is left. On macOS ChatGPT can turn the quit down: with a
|
|
32
|
+
* task running or a confirmation open, AppleScript's `quit` comes back with -128 ("User canceled"), or doesn't come
|
|
33
|
+
* back before the timeout while the app asks. Then it is left running, never killed (unsaved work, a running
|
|
34
|
+
* task), and `chatgptQuitRefused()` is true so the caller can ask the user to confirm the quit in the app.
|
|
35
|
+
*/
|
|
28
36
|
export declare function quitChatgpt(): boolean;
|
|
29
37
|
/** Start the installed app; true when it is running afterwards. */
|
|
30
38
|
export declare function launchChatgpt(): boolean;
|
|
39
|
+
/** osascript's answer to `quit`: -128 = the app (or the user, in its dialog) cancelled it; no answer = the app is still asking. */
|
|
40
|
+
export declare function macQuitRefused(answer: {
|
|
41
|
+
status: number | null;
|
|
42
|
+
stderr?: string;
|
|
43
|
+
}): boolean;
|
|
31
44
|
export declare const chatgptDesktopApp: CompanionApp;
|
|
32
45
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{logger as n}from"../../utils/logger.js";import{brand as e}from"../brand.js";import{powerShellEnv as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{logger as n}from"../../utils/logger.js";import{brand as e}from"../brand.js";import{powerShellEnv as r}from"../powershell-env.js";import{existsSync as i}from"fs";import{join as o}from"path";import{appPlatform as s,createDesktopAppInstaller as a,isArm64Machine as p,macAppVersion as l,macBundleId as c}from"./desktop-app-installer.js";import{toolHome as u}from"./types.js";export const OPENAI_TEAM_ID="2DC432GLL2";const d="com.openai.codex";export const CHATGPT_PACKAGE_FAMILY="OpenAI.Codex_2p2nqsd0c76g0";const g=a({id:"chatgpt-desktop",mirror:()=>e().installMirror?.chatgptDesktop,asset:(t,n)=>"darwin"===t?n?"ChatGPT-mac-arm64.dmg":null:"win32"===t?n?"ChatGPT-win-arm64.msix":"ChatGPT-win-x64.msix":null,versionFile:(t,n)=>"win32"===t?`version-win-${n?"arm64":"x64"}.txt`:"version.txt",macApp:{source:"ChatGPT.app",installedNames:["ChatGPT.app","Codex.app"],bundleId:d,teamId:"2DC432GLL2"},windows:{signer:new RegExp("^CN=50BDFD77-8903-4850-9FFE-6E8522F64D5B$"),packageFilter:`$_.PackageFamilyName -eq '${CHATGPT_PACKAGE_FAMILY}'`},extraBlocker:t=>"darwin"===t&&!g.installedMacApp()&&["/Applications",o(u(),"Applications")].some(t=>{const n=o(t,"ChatGPT.app");return i(o(n,"Contents","Info.plist"))&&c(n)!==d})?"other_app":null});export const chatgptInstaller=g;let h=(e,i,o=3e4)=>{const s=t(e,i,{encoding:"utf-8",timeout:o,windowsHide:!0,stdio:["ignore","pipe","pipe"],env:r()});return s.error&&n.logError(`chatgpt-desktop: ${e}`,s.error),{status:s.status,stdout:`${s.stdout??""}`,stderr:`${s.stderr??""}`}};export function setChatgptProcessRunnerForTests(t){h=t}function m(t,n){return h("powershell.exe",["-NoProfile","-NonInteractive","-Command",t],n)}const f=t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),C="Get-Process -ErrorAction SilentlyContinue | Where-Object { $_.Path -like '*\\WindowsApps\\OpenAI.Codex_*\\app\\ChatGPT.exe' }";function w(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}export function isChatgptRunning(){if("darwin"===s()){const t=g.installedMacApp();return Boolean(t)&&0===h("pgrep",["-f",`^${f(t)}/Contents/MacOS/`]).status}return"win32"===s()&&Number(m(`@(${C}).Count`).stdout.trim())>0}let A=!1;export function chatgptQuitRefused(){return A}export function quitChatgpt(){if(A=!1,"darwin"===s()){const t=g.installedMacApp();if(macQuitRefused(h("osascript",["-e",`tell application id "${d}" to quit`]))&&(A=isChatgptRunning(),A))return!1;for(let t=0;t<30&&isChatgptRunning();t++)w(500);t&&isChatgptRunning()&&h("pkill",["-f",`^${f(t)}/Contents/MacOS/`]),w(1e3)}else{if("win32"!==s())return!1;m([`$p = @(${C})`,"$p | ForEach-Object { [void]$_.CloseMainWindow() }","Start-Sleep -Seconds 3",`@(${C}) | Stop-Process -Force -ErrorAction SilentlyContinue`,"Start-Sleep -Seconds 1"].join("\n"),6e4)}return!isChatgptRunning()}export function launchChatgpt(){if("darwin"===s()){const t=g.installedMacApp();if(!t)return!1;h("open",[t])}else{if("win32"!==s())return!1;m(`Start-Process 'shell:AppsFolder\\${CHATGPT_PACKAGE_FAMILY}!App'`,6e4)}for(let t=0;t<20;t++){if(isChatgptRunning())return!0;w(500)}return!1}export function macQuitRefused(t){return null===t.status||/\(-128\)|-1712/.test(t.stderr??"")}export const chatgptDesktopApp={name:"chatgpt",displayName:"ChatGPT",installedVersion:function(){if("darwin"===s()){const t=g.installedMacApp();return t?l(t):null}return"win32"===s()?g.windowsPackageVersion():null},runningApp:{isRunning:isChatgptRunning,quit:quitChatgpt,quitRefused:chatgptQuitRefused,launch:launchChatgpt},appInstaller:{vendor:"OpenAI",sizeMb:()=>"darwin"===s()?800:p()?1050:1e3,downloadPage:"https://chatgpt.com/download",blocker:g.blocker,latestVersion:()=>g.latestVersion(),installedPath:()=>"darwin"===s()?g.installedMacApp():"win32"!==s()?null:g.windowsPackageVersion()?"MSIX":null,install:t=>g.install(t)}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite as
|
|
1
|
+
import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite as n}from"./backup.js";import{i18n as s}from"../i18n.js";import{baseModelId as a}from"../model-catalog.js";import{gatewayModelSpecs as r,prettyModelName as i,vendorNames as l}from"../gateway-models.js";import{toolHome as d}from"./types.js";import{gatewayAddresses as c,normalizeBaseUrl as u}from"../gateway-addresses.js";import{configManager as m,savedApiKeys as p}from"../config.js";import{envCleanupPlan as g,lastEnvCleanup as f}from"../env-cleanup.js";import{maskHome as _}from"../telemetry.js";import{spawnSync as h}from"child_process";import{existsSync as C,readFileSync as v}from"fs";import{detectManagedOverrides as j}from"./claude-managed.js";import{installOfficialPlugins as y}from"./claude-plugins.js";import{findInstalls as k,mirrorInstallCommand as A,brandInstallScripts as P}from"./tool-installs.js";import{updateNativeFromMirror as S}from"./claude-native-mirror.js";import{brandEnv as O}from"../brand.js";import{claudeFormat as x,claudeProjectFiles as T}from"../sessions/formats.js";const N=e(d(),".claude","settings.json"),b=e(d(),".claude.json");let H,R=null,U=()=>0===h("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore"}).status;export function setClaudeKeychainProbeForTests(e){U=e}export function claudeAccountLoginPresent(){const t=process.env.CLAUDE_CONFIG_DIR?.trim()||e(d(),".claude");if(C(e(t,".credentials.json")))return!0;if("darwin"!==process.platform||O("TEST_HOME"))return!1;try{return U()}catch{return!1}}function w(){try{const t=JSON.parse(v(e(d(),".claude","settings.json"),"utf-8"));return"string"==typeof t.autoUpdatesChannel?t.autoUpdatesChannel:"latest"}catch{return"latest"}}function E(e){if(!e)return;const t=new Set(e.models);return r("claude-code",e.clientModels).filter(e=>t.has(e.id))}function L(){const e=o.getSettings().env?.ANTHROPIC_BASE_URL;return"string"==typeof e&&e.trim()?claudeCodeAdapter.holdsOurConfig(p())?null:e.trim():null}let I=null;const M={command:"claude",npmPackage:"@anthropic-ai/claude-code",native:{binDir:[".local","bin"],updateArgs:["update"],dataDirs:[[".local","share","claude"]],mirrorUpdate:()=>S(w())},mirrorScript:P("claude-code"),brew:"claude-code"};export const claudeCodeAdapter={name:"claude-code",displayName:"Claude Code",command:"claude",installCommand:A(M),upgradeCommand:"claude update",installSpec:M,upgradeHints:e=>"stable"===w()?[s.t("tools.claude_code.stable_channel",{min:e})]:[],configPath:N,sessions:{format:x,files:()=>T(e(process.env.CLAUDE_CONFIG_DIR?.trim()||e(d(),".claude"),"projects")),resumeCommand:e=>({command:"claude",args:["--resume",e]})},wantsModelCatalog:!0,loadPrivateConfig(t){I=L(),n(N),n(b),H=E(t.catalog),o.loadPrivateConfig(t.apiKey,t.models,t.catalog?.models,H);const s=e(d(),".local","bin","win32"===process.platform?"claude.exe":"claude"),a=k(claudeCodeAdapter.installSpec)[0]?.path??(C(s)?s:null);R=a?y(a):null},holdsOurConfig(e){const t=o.getSettings().env??{},n="string"==typeof t.ANTHROPIC_AUTH_TOKEN?t.ANTHROPIC_AUTH_TOKEN.trim():"",s="string"==typeof t.ANTHROPIC_BASE_URL?u(t.ANTHROPIC_BASE_URL):null;return!(!n||!e.includes(n))||null!==s&&(c().some(e=>e.url===s)||s===u(m.getBaseUrl()))},planNotes(){const e=[],t=L();t&&e.push(s.t("tools.claude_code.plan_replace_provider",{url:t}));for(const t of g())e.push(s.t("tools.claude_code.plan_env_remove",{location:_(t.location),vars:Object.keys(t.vars).join(", ")}));return e},unloadPrivateConfig(e){const t=o.getSettings().env??{};Boolean(t.ANTHROPIC_AUTH_TOKEN||t.ANTHROPIC_BASE_URL)&&!claudeCodeAdapter.holdsOurConfig(e?.savedKeys??[])||(n(N),o.unloadPrivateConfig())},detectCurrentConfig:()=>o.detectCurrentConfig(),getConfig:()=>({settings:o.getSettings(),mcp:o.getMCPConfig()}),updateConfig(e){const t=e||{};t.settings&&o.saveSettings(t.settings),t.mcp&&o.saveMCPConfig(t.mcp)},clearPinnedModels:e=>(n(N),o.clearPinnedModels(e?.models)),listedModels(){const e=o.getSettings().modelPicker;return Array.isArray(e?.options)?e.options.map(e=>a(String(e.model))):null},refreshModelMenu(e){const s=o.getSettings(),a=t(s,E(e.catalog));JSON.stringify(a)!==JSON.stringify(s)&&(n(N),o.saveSettings(a))},applyNotes(){const e=[];R?.installed.length&&(e.push({kind:"summary",text:s.t("tools.claude_code.plugins_installed",{count:String(R.installed.length)})}),e.push({kind:"detail",text:R.installed.join(", ")})),"git"===R?.skipped?e.push({kind:"action",text:s.t("tools.claude_code.plugins_need_git")}):("marketplace"===R?.skipped||R?.failed.length)&&e.push({kind:"action",text:s.t("tools.claude_code.plugins_failed")}),H&&H.length>0&&(e.push({kind:"summary",text:s.t("tools.claude_code.gateway_models",{count:String(H.length),vendors:l(H.map(e=>e.id)).join(" / ")})}),e.push({kind:"detail",text:H.map(e=>e.name||i(e.id)).join(", ")})),I&&e.push({kind:"summary",text:s.t("tools.claude_code.provider_replaced",{url:I})});const t=f();for(const o of t.removed)e.push({kind:"summary",text:s.t("tools.claude_code.env_removed",{location:_(o.location),vars:Object.keys(o.vars).join(", ")})});for(const o of t.foreign)e.push({kind:"action",text:s.t("tools.claude_code.env_foreign",{location:_(o.location),vars:Object.keys(o.vars).join(", ")})});t.machineLeft.length>0&&e.push({kind:"action",text:s.t("messages.env_vars_machine_left",{vars:t.machineLeft.join(", ")})});const n=o.getLastKept();n.length>0&&e.push({kind:"summary",text:s.t("tools.claude_code.kept_user_models",{values:n.join(", ")})}),"win32"!==process.platform||process.env.CLAUDE_CODE_GIT_BASH_PATH||0===h("where",["git"],{windowsHide:!0,stdio:"ignore"}).status||e.push({kind:"action",text:s.t("tools.claude_code.no_git_bash")}),claudeAccountLoginPresent()&&e.push({kind:"detail",text:s.t("tools.claude_code.account_login_overridden")});for(const t of j())e.push({kind:"action",text:s.t("tools.claude_code.managed_override",{source:t.source,keys:t.keys.join(", ")})});for(const t of o.getLastTierFallbacks())e.push({kind:"detail",text:s.t("tools.claude_code.tier_fallback",{tier:t.tier,from:t.from,to:t.to})});return e},backupPaths:()=>[N,b],forceResetPaths:()=>[N]};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ToolAdapter } from './types.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type VibecliModels } from '../config.js';
|
|
3
3
|
import { type ModelCatalog } from '../model-catalog.js';
|
|
4
4
|
/**
|
|
5
5
|
* Tool setting (config.yaml `tool_settings['claude-desktop'].hide_official_login`).
|