@marsapi/cli 0.0.147 → 0.0.151
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/client-config.snapshot.json +12 -12
- package/components.json +157 -0
- package/dist/client-config.snapshot.json +12 -12
- package/dist/commands/components.js +1 -0
- package/dist/commands/config.js +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/upgrade.js +1 -1
- package/dist/components.json +157 -0
- package/dist/lib/app-update.js +1 -1
- package/dist/lib/brand.js +1 -1
- package/dist/lib/claude-code-manager.js +1 -1
- package/dist/lib/codex-sessions.js +1 -1
- package/dist/lib/command.js +1 -1
- package/dist/lib/components.js +1 -0
- package/dist/lib/config.js +1 -1
- package/dist/lib/dry-run.js +1 -1
- package/dist/lib/env-cleanup.js +1 -1
- package/dist/lib/gateway-addresses.js +1 -1
- package/dist/lib/i18n.js +1 -1
- package/dist/lib/model-registry.js +1 -1
- package/dist/lib/post-apply.js +1 -1
- package/dist/lib/powershell-env.js +1 -0
- package/dist/lib/program.js +1 -1
- package/dist/lib/runtime-options.js +1 -1
- package/dist/lib/tool-manager.js +1 -1
- package/dist/lib/tool-upgrade.js +1 -1
- package/dist/lib/tools/chatgpt-desktop.js +1 -0
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/claude-desktop-app.js +1 -1
- package/dist/lib/tools/claude-desktop-cli.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/tools/desktop-app-installer.js +1 -0
- package/dist/lib/tools/desktop-process.js +1 -1
- package/dist/lib/tools/elevated-reg.js +1 -1
- package/dist/lib/tools/tool-installs.js +1 -1
- package/dist/lib/windows-env.js +1 -1
- package/dist/lib/wizard.js +1 -1
- package/dist/lib/write-plan.js +1 -1
- package/dist/lib/written-values.js +1 -0
- package/dist/locales/en_US.json +175 -12
- package/dist/locales/zh_CN.json +175 -12
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as e}from"child_process";import{logger as t}from"../../utils/logger.js";export const WINDOWS_PACKAGE_FAMILIES=["Claude_pzs8sxrjxfjjc","AnthropicPBC.Claude_fnn82j28hfe8t"];const
|
|
1
|
+
import{spawnSync as e}from"child_process";import{logger as t}from"../../utils/logger.js";import{powerShellEnv as r}from"../powershell-env.js";export const WINDOWS_PACKAGE_FAMILIES=["Claude_pzs8sxrjxfjjc","AnthropicPBC.Claude_fnn82j28hfe8t"];const o="Get-Process -Name claude -ErrorAction SilentlyContinue | Where-Object { $_.Path -and ($_.Path -like '*\\AnthropicClaude\\*' -or $_.Path -like '*\\Programs\\Claude\\*' -or $_.Path -like '*\\WindowsApps\\*Claude*') }";let s=(o,s,n=3e4)=>{const i=e(o,s,{encoding:"utf-8",timeout:n,windowsHide:!0,stdio:["ignore","pipe","pipe"],env:r()});return i.error&&t.logError(`desktop-process: ${o}`,i.error),{status:i.status,stdout:`${i.stdout??""}`,stderr:`${i.stderr??""}`}};export function setDesktopProcessRunnerForTests(e){s=e}function n(e,t){return s("powershell.exe",["-NoProfile","-NonInteractive","-Command",e],t)}function i(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}export function isDesktopRunning(){return"darwin"===process.platform?0===s("pgrep",["-x","Claude"]).status:"win32"===process.platform&&Number(n(`@(${o}).Count`).stdout.trim())>0}export function canRestartDesktop(){return"darwin"===process.platform||"win32"===process.platform}let a=!1;export function desktopQuitRefused(){return a}export function quitDesktop(){if(a=!1,"darwin"===process.platform){const e=s("osascript",["-e",'quit app "Claude"']);if((null===e.status||/\(-128\)|-1712/.test(e.stderr??""))&&isDesktopRunning())return a=!0,!1;for(let e=0;e<30&&isDesktopRunning();e++)i(500);isDesktopRunning()&&s("pkill",["-x","Claude"]),i(1e3)}else{if("win32"!==process.platform)return!1;n([`$p = @(${o})`,"$p | ForEach-Object { [void]$_.CloseMainWindow() }","Start-Sleep -Seconds 3","$p | Where-Object { -not $_.HasExited } | Stop-Process -Force -ErrorAction SilentlyContinue","Start-Sleep -Seconds 1"].join("\n"),6e4)}return!isDesktopRunning()}export function launchDesktop(){if("darwin"===process.platform)s("open",["-a","Claude"]);else{if("win32"!==process.platform)return!1;n(["$squirrel = Join-Path $env:LOCALAPPDATA 'AnthropicClaude\\claude.exe'","$programs = Join-Path $env:LOCALAPPDATA 'Programs\\Claude\\Claude.exe'","if (Test-Path $squirrel) { Start-Process $squirrel }","elseif (Test-Path $programs) { Start-Process $programs }",`else { $pkg = Get-AppxPackage | Where-Object { @(${WINDOWS_PACKAGE_FAMILIES.map(e=>`'${e}'`).join(",")}) -contains $_.PackageFamilyName } | Select-Object -First 1`," if ($pkg) { $id = (Get-AppxPackageManifest $pkg).Package.Applications.Application.Id | Select-Object -First 1",' Start-Process "shell:AppsFolder\\$($pkg.PackageFamilyName)!$id" } }'].join("\n"),6e4)}for(let e=0;e<20;e++){if(isDesktopRunning())return!0;i(500)}return!1}export function restartDesktop(){return!!canRestartDesktop()&&!(!quitDesktop()&&a)&&launchDesktop()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as r}from"child_process";import{mkdtempSync as e,rmSync as t,writeFileSync as o}from"fs";import{tmpdir as n}from"os";import{join as i}from"path";import{logger as s}from"../../utils/logger.js";import{CLI_NAME as u}from"../brand.js";function
|
|
1
|
+
import{spawnSync as r}from"child_process";import{mkdtempSync as e,rmSync as t,writeFileSync as o}from"fs";import{tmpdir as n}from"os";import{join as i}from"path";import{logger as s}from"../../utils/logger.js";import{CLI_NAME as u}from"../brand.js";import{powerShellEnv as f}from"../powershell-env.js";function d(r){return`"${r.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}export function buildRegFile(r,e,t,o=!1){const n=`HKEY_USERS\\${r}\\${e}`;return o?`Windows Registry Editor Version 5.00\r\n\r\n[-${n}]\r\n`:`Windows Registry Editor Version 5.00\r\n\r\n[${n}]\r\n${Object.entries(t).map(([r,e])=>`${d(r)}=${null===e?"-":function(r){return"boolean"==typeof r?"dword:"+(r?"00000001":"00000000"):"number"==typeof r?`dword:${(r>>>0).toString(16).padStart(8,"0")}`:d("string"==typeof r?r:JSON.stringify(r))}(e)}`).join("\r\n")}\r\n`}let l=()=>{const e=r("whoami",["/user","/fo","csv","/nh"],{encoding:"utf-8",windowsHide:!0});return/"(S-1-[\d-]+)"/.exec(`${e.stdout??""}`)?.[1]??null},m=e=>{const t=r("powershell.exe",["-NoProfile","-NonInteractive","-Command",`$p = Start-Process -FilePath 'reg.exe' -ArgumentList @('import', '"${e}"') -Verb RunAs -Wait -PassThru -WindowStyle Hidden; exit $p.ExitCode`],{encoding:"utf-8",windowsHide:!0,timeout:3e5,env:f()});return 0!==t.status&&s.logError("elevatedImport",new Error(`${t.stderr??""}`.trim()||`exit ${t.status}`)),0===t.status};export function setElevationForTests(r,e){l=r,m=e}export function setUserRegistryElevated(r,s,f=!1){const d=l();if(!d)return!1;const c=e(i(n(),`${u}-reg-`)),p=i(c,`${u}.reg`);try{return o(p,Buffer.concat([Buffer.from([255,254]),Buffer.from(buildRegFile(d,r,s,f),"utf16le")])),m(p)}finally{t(c,{recursive:!0,force:!0})}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{existsSync as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{existsSync as n,realpathSync as r,statSync as e}from"fs";import{delimiter as o,dirname as s,isAbsolute as i,join as a}from"path";import{i18n as c}from"../i18n.js";import{toolHome as p}from"./types.js";import{brand as m}from"../brand.js";export const NPM_MIRROR="https://registry.npmmirror.com";export function brandInstallScripts(t){const n=m().installMirror?.scripts;return n?{sh:`${n}/${t}.sh`,ps1:`${n}/${t}.ps1`}:void 0}export function npmMirrorInstallCommand(t,n="latest"){return`npm install -g ${t.npmPackage}@${n} --registry=${NPM_MIRROR}`}const l=/^(\d+)\.(\d+)\.(\d+)$/;function u(t,n){const r=l.exec(t).slice(1).map(Number),e=l.exec(n).slice(1).map(Number);for(let o=0;o<3;o++)if(r[o]!==e[o])return r[o]>e[o]?t:n;return t}async function f(t,n,r){const e=await fetch(t,{signal:AbortSignal.timeout(n),headers:r});if(!e.ok)throw new Error(`HTTP ${e.status}`);return e.json()}export async function npmMirrorVersion(t){if(!t.npmPackage||!t.npmMirrorTagStale)return"latest";let n=d.get(t.npmPackage);return n||d.set(t.npmPackage,n=async function(t){try{const{version:n}=await f(`https://registry.npmjs.org/${t}/latest`,1e4);if("string"==typeof n&&l.test(n))return n}catch{}try{const n=await f(`${NPM_MIRROR}/${t}`,2e4,{accept:"application/vnd.npm.install-v1+json"}),r=Object.keys(n.versions??{}).filter(t=>l.test(t));if(r.length)return r.reduce(u)}catch{}return"latest"}(t.npmPackage)),n}const d=new Map;export function mirrorInstallCommand(t){return t.mirrorScript?"win32"===process.platform?`powershell -NoProfile -ExecutionPolicy Bypass -Command "irm ${t.mirrorScript.ps1} | iex"`:`curl -fsSL ${t.mirrorScript.sh} | sh`:t.npmPackage?npmMirrorInstallCommand(t):""}export function npmUninstallCommand(t){return`npm uninstall -g ${t.npmPackage}`}export function installLabel(t){return c.t("upgrade.install_label",{kind:c.t(`upgrade.kind.${t.kind}`),version:t.version??"?",path:t.path})}let h=n=>{const r={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]};return`${(/\.cmd$/i.test(n)?t(`"${n}" --version`,{...r,shell:!0}):t(n,["--version"],r)).stdout??""}`};const g=new Map;export function setVersionRunnerForTests(t){h=t,g.clear(),d.clear()}export function forgetInstalls(){g.clear()}function $(t,n){return"win32"===process.platform?t.toLowerCase()===n.toLowerCase():t===n}function w(t){try{return e(t).isFile()}catch{return!1}}function v(t,e){if(t.native&&$(s(e),a(p(),...t.native.binDir)))return"native";const o=t.npmPackage?a("node_modules",...t.npmPackage.split("/")):null;if(o&&n(a(s(e),o)))return"npm";let i=e;try{i=r(e)}catch{return"other"}return o&&i.includes(o)?"npm":/[\\/](Cellar|Caskroom)[\\/]/.test(i)?"brew":"other"}export function findInstalls(t){const n=g.get(t.command);if(n)return n;const e="win32"===process.platform?[`${t.command}.exe`,`${t.command}.cmd`]:[t.command],s=new Set,c=[];for(const n of(process.env.PATH??"").split(o))if(n&&i(n))for(const o of e){const e=a(n,o);if(!w(e))continue;let i=e;try{i=r(e)}catch{}const p="win32"===process.platform?i.toLowerCase():i;if(s.has(p))continue;s.add(p);const m=h(e).match(/(\d+)\.(\d+)\.(\d+)/);c.push({path:e,kind:v(t,e),version:m?m[0]:null})}return g.set(t.command,c),c}export function findInstallsIncludingNative(t){const n=findInstalls(t).map(t=>({...t,onPath:!0}));if(!t.native)return n;const r=a(p(),...t.native.binDir),e="win32"===process.platform?[`${t.command}.exe`]:[t.command];for(const t of e){const e=a(r,t);if(!w(e)||n.some(t=>$(t.path,e)))continue;const o=h(e).match(/(\d+)\.(\d+)\.(\d+)/);n.push({path:e,kind:"native",version:o?o[0]:null,onPath:!1})}return n}
|
package/dist/lib/windows-env.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{execFileSync as e,spawn as r}from"child_process";import{logger as n}from"../utils/logger.js";import{brandEnvName as t}from"./brand.js";const
|
|
1
|
+
import{execFileSync as e,spawn as r}from"child_process";import{logger as n}from"../utils/logger.js";import{brandEnvName as t}from"./brand.js";import{powerShellEnv as o}from"./powershell-env.js";const s={user:"HKCU\\Environment",machine:"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"},i=r=>e("reg.exe",r,{encoding:"utf-8",windowsHide:!0,timeout:15e3,stdio:["ignore","pipe","pipe"]}),a=()=>{const e=r("powershell.exe",["-NoProfile","-NonInteractive","-Command",`[Environment]::SetEnvironmentVariable('${t("ENV_REFRESH")}',$null,'User')`],{detached:!0,stdio:"ignore",windowsHide:!0,env:o()});e.on("error",e=>n.logError("windowsEnv.broadcast",e)),e.unref()};let d=i,c=a;export function setWindowsEnvRunnersForTests(e,r){d=e??i,c=e?r??(()=>{}):a}export function readWindowsEnv(e,r){let n;try{n=d(["query",s[e],"/v",r])}catch{return}const t=n.match(new RegExp(String.raw`^\s*${r}\s+REG_(?:EXPAND_)?SZ\s+(.*?)\r?$`,"im"));return t?t[1]:void 0}export function addUserPathDir(e){let r="REG_EXPAND_SZ",n="";try{const e=d(["query",s.user,"/v","Path"]).match(/^\s*Path\s+(REG_(?:EXPAND_)?SZ)\s+(.*?)\r?$/im);e&&([,r,n]=e)}catch{}const t=e=>(e=>e.replace(/%([^%]+)%/g,(e,r)=>process.env[r]??e))(e).replace(/[\\/]+$/,"").toLowerCase();return!n.split(";").some(r=>r&&t(r)===t(e))&&(d(["add",s.user,"/v","Path","/t",r,"/d",n?`${n.replace(/;+$/,"")};${e}`:e,"/f"]),!0)}export function setUserEnv(e,r){d(["add",s.user,"/v",e,"/t","REG_SZ","/d",r,"/f"])}export function deleteWindowsEnv(e,r){d(["delete",s[e],"/v",r,"/f"])}export function broadcastEnvChange(){c()}
|
package/dist/lib/wizard.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"inquirer";import t from"chalk";import a from"ora";import{configManager as o,DEFAULT_MODELS as i}from"./config.js";import{getPresets as n,resolvePreset as r,getToolDefaultModel as s}from"./model-registry.js";import{toolManager as l,SUPPORTED_TOOLS as c}from"./tool-manager.js";import{confirmWritePlan as d}from"./write-plan.js";import{postApplyPrompts as p}from"./post-apply.js";import{appStatus as m,appStatusText as u,appTools as _,cachedAppStatus as g,upgradeApp as w}from"./app-update.js";import{i18n as f,detectSystemLang as y}from"./i18n.js";import{createBorderLine as h,createContentLine as z}from"../utils/string-width.js";import{validateApiKey as v,fetchModels as k}from"./api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as x}from"./tools/codex.js";import{CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as b}from"./tools/claude-desktop.js";import{addressesWithCurrent as S,ensureReachableGatewayAddress as C,fastestIndex as M,probeAll as T,probeSummary as A,reasonText as N,savedApiKey as K,switchGatewayAddress as B}from"../commands/base.js";import{readFileSync as P}from"fs";import{dirname as j,join as H}from"path";import{fileURLToPath as O}from"url";import{brand as W}from"./brand.js";const L=j(O(import.meta.url)),F=t.hex("#FF8700");export class Wizard{static instance;BOX_WIDTH=63;validatedApiKeys=new Set;constructor(){}static getInstance(){return Wizard.instance||(Wizard.instance=new Wizard),Wizard.instance}createBox(e){console.log(F.bold("\n"+h("╔","╗","═",this.BOX_WIDTH))),console.log(F.bold(z(e,"║","║",this.BOX_WIDTH,"center"))),console.log(F.bold(h("╚","╝","═",this.BOX_WIDTH))),console.log("")}showOperationHints(){const e=[t.gray(f.t("wizard.hint_navigate")),t.gray(f.t("wizard.hint_confirm"))];console.log(t.gray("💡 ")+e.join(t.gray(" | "))+"\n")}async promptWithHints(t){this.showOperationHints();const a=t.map(e=>"list"!==e.type||e.pageSize?e:{...e,pageSize:20});return e.prompt(a)}printBanner(){const e=60,t=f.t("wizard.banner_subtitle"),a=z(t,"║","║",e,"center"),o=z("","║","║",e,"center"),i=z(`${W().productName} v${function(){try{return JSON.parse(P(H(L,"..","..","package.json"),"utf-8")).version}catch{return"0.0.0"}}()}`,"║","║",e,"center"),n=[String.raw`__ ___ _ ____ _ ___ `,String.raw`\ \ / (_) |__ ___ / ___| | |_ _|`,String.raw` \ \ / /| | '_ \ / _ \ | | | | | `,String.raw` \ V / | | |_) | __/ |___| |___ | | `,String.raw` \_/ |_|_.__/ \___|\____|_____|___|`],r=Math.max(...n.map(e=>e.length)),s=" ".repeat(Math.floor((58-r)/2)),l=n.map(t=>z(s+t,"║","║",e,"left")),c=[h("╔","╗","═",e),o,...l,o,i,a,h("╚","╝","═",e)];console.log(F.bold("\n"+c.join("\n")))}resetScreen(){console.clear(),this.printBanner()}printGoodbye(){const e=l.getSupportedTools().filter(e=>{if(e.gui)return!1;try{return Boolean(l.detectCurrentConfig(e.name).apiKey)&&l.isToolInstalled(e.name)}catch{return!1}});let a;if(e.length>0){const t=e.map(e=>e.command).join(" / ");a=f.t("wizard.goodbye_message_tools",{commands:t}),e.some(e=>"claude-code"===e.name)&&(a+=" "+f.t("wizard.goodbye_claude_hint"))}else a=f.t("wizard.goodbye_message");console.log(t.green("\n👋 "+a)),this.printPathReloadHint(e.map(e=>e.name))}printPathReloadHint(e){const a=e.filter(e=>!l.isOnPath(e));if(0===a.length)return;const o=a.map(e=>c[e].command).join(" / ");console.log(t.yellow(" ! "+f.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:o})))}async runFirstTimeSetup(){const e="zh_CN"===y();e&&(o.setLang("zh_CN"),f.setLocale("zh_CN")),this.resetScreen(),console.log(F.bold("\n"+f.t("wizard.welcome"))),console.log(t.gray(f.t("wizard.privacy_note")+"\n")),e?console.log(t.gray(f.t("wizard.lang_auto_zh")+"\n")):await this.configLanguage(),await C(),await this.configApiKey()&&await this.selectAndConfigureTool(!0)}async configLanguage(){for(;;){this.resetScreen(),this.createBox(f.t("wizard.select_language"));const a=f.getLocale(),{language:i}=await this.promptWithHints([{type:"list",name:"language",message:"✨ "+f.t("wizard.select_language"),choices:[{name:"[EN] English"+("en_US"===a?t.green(" ✓ ("+f.t("wizard.current_active")+")"):""),value:"en_US"},{name:"[CN] 中文"+("zh_CN"===a?t.green(" ✓ ("+f.t("wizard.current_active")+")"):""),value:"zh_CN"},new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"back"},{name:"x "+f.t("wizard.nav_exit"),value:"exit"}],default:"zh_CN"}]);if("exit"===i)this.printGoodbye(),process.exit(0);else if("back"===i)return;return o.setLang(i),void f.setLocale(i)}}buildPresetChoices(){const a=n(),o=a.filter(e=>e.recommended),i=a.filter(e=>!e.recommended),r=e=>({name:(f.t(e.name)!==e.name?f.t(e.name):e.name)+(e.models?t.gray(` [H:${e.models.haiku} S:${e.models.sonnet} O:${e.models.opus}]`):""),value:{type:"preset",preset:e}}),s=[];return o.length>0&&(s.push(new e.Separator(t.hex("#FF8700")("── "+f.t("wizard.recommended")+" ──"))),s.push(...o.map(r))),i.length>0&&(s.push(new e.Separator(t.gray("── "+f.t("wizard.other_models")+" ──"))),s.push(...i.map(r))),s}async handleCustomModelInput(){const a=o.getModels(),{customMode:n}=await e.prompt([{type:"list",name:"customMode",message:f.t("wizard.custom_model_mode"),choices:[{name:f.t("wizard.custom_model_single"),value:"single"},{name:f.t("wizard.custom_model_per_role"),value:"per_role"}]}]);if("single"===n){const{customModel:t}=await e.prompt([{type:"input",name:"customModel",message:f.t("wizard.input_custom_model"),default:i.sonnet}]);o.setModels({haiku:t,sonnet:t,opus:t,reasoning:t})}else{const t=await e.prompt([{type:"input",name:"haiku",message:f.t("wizard.model_haiku"),default:a.haiku},{type:"input",name:"sonnet",message:f.t("wizard.model_sonnet"),default:a.sonnet},{type:"input",name:"opus",message:f.t("wizard.model_opus"),default:a.opus},{type:"input",name:"reasoning",message:f.t("wizard.model_reasoning"),default:a.reasoning}]);o.setModels(t)}console.log(t.green("\n✓ "+f.t("wizard.models_saved")))}async configModels(a){const i=o.getApiKey();if(await this.validatedKeyForConfiguration(i))for(;;){this.resetScreen(),this.createBox(f.t("wizard.config_models"));const i=[...this.buildPresetChoices()];i.push(new e.Separator),i.push({name:"✏️ "+f.t("wizard.custom_model_input"),value:{type:"custom_input"}}),i.push(new e.Separator),i.push({name:"<- "+f.t("wizard.nav_return"),value:{type:"back"}}),i.push({name:"x "+f.t("wizard.nav_exit"),value:{type:"exit"}});const{modelChoice:n}=await this.promptWithHints([{type:"list",name:"modelChoice",message:f.t("wizard.select_model_config"),choices:i}]);if("exit"===n.type)this.printGoodbye(),process.exit(0);else{if("back"===n.type)return;if("custom_input"===n.type)return await this.handleCustomModelInput(),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig());if("preset"===n.type){const e=r(n.preset);return o.setModels(e),console.log(t.green("\n✓ "+f.t("wizard.models_saved"))),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig())}}}else await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}async promptLoadAfterModelConfig(){const{shouldLoad:t}=await e.prompt([{type:"list",name:"shouldLoad",message:f.t("wizard.load_config_now"),choices:[{name:f.t("wizard.load_config_yes"),value:!0},{name:f.t("wizard.load_config_later"),value:!1}]}]);t&&await this.selectAndConfigureTool()}async configBaseUrl(){const i=o.getBaseUrl(),n=S(),r=a(f.t("wizard.base_testing")).start(),s=await T(n,{apiKey:K(),samples:3});r.stop();const l=M(s),c=n.map((e,a)=>{const o=e.url===i?t.cyan(` ← ${f.t("base.current_mark")}`):"";return{name:`${e.url} ${t.gray(e.label)} ${A(s[a],a===l)}${o}`,value:e.url}});c.push(new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"__back__"});const{url:d}=await this.promptWithHints([{type:"list",name:"url",message:f.t("wizard.base_select"),choices:c,default:i}]);if("__back__"===d)return;const p=s[n.findIndex(e=>e.url===d)];p.ok?await B(d):console.log(t.red(f.t("base.unreachable",{url:d,reason:N(p)}))),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}async configApiKey(){for(;;){this.resetScreen(),this.createBox(f.t("wizard.input_api_key")),console.log(t.gray("\n💡 "+f.t("wizard.api_key_input_hint"))),console.log(t.gray(" "+f.t("wizard.api_key_get_hint",{url:W().links.tokenPage}))),console.log();const{apiKey:i}=await e.prompt([{type:"password",name:"apiKey",message:f.t("wizard.input_your_api_key"),mask:"*"}]);if(!i||""===i.trim()){const{action:t}=await e.prompt([{type:"list",name:"action",message:f.t("wizard.select_action"),choices:[{name:f.t("wizard.retry_input"),value:"retry"},{name:"<- "+f.t("wizard.nav_return"),value:"back"}]}]);if("back"===t)return!1;continue}const n=a(f.t("wizard.validating_api_key")).start(),r=await v(i.trim());if(n.stop(),r.valid)return o.setApiKey(i.trim()),this.validatedApiKeys.add(i.trim()),console.log(t.green("\n✓ "+f.t("wizard.api_key_valid"))),!0;{this.validatedApiKeys.delete(i.trim()),"invalid_api_key"===r.error?console.log(t.red("\n✗ "+f.t("wizard.api_key_invalid"))):console.log(t.red("\n✗ "+f.t("wizard.api_key_network_error")));const{action:a}=await e.prompt([{type:"list",name:"action",message:f.t("wizard.select_action"),choices:[{name:f.t("wizard.retry_input"),value:"retry"},{name:"<- "+f.t("wizard.nav_return"),value:"back"}]}]);if("back"===a)return!1}}}async selectAndConfigureTool(a=!1){for(const e of _())await m(e).catch(()=>{});for(;;){this.resetScreen(),this.createBox(f.t("wizard.select_tool"));const o=l.getSupportedTools().map(e=>{const a=_().includes(e.name)?g(e.name):null;return{name:e.displayName+(a?.outdated?t.yellow(" "+u(a)):""),value:e.name}}),{tool:i}=await this.promptWithHints([{type:"list",name:"tool",message:"🛠️ "+f.t("wizard.select_tool"),choices:[...o,new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"back"},{name:"x "+f.t("wizard.nav_exit"),value:"exit"}]}]);if("exit"===i)this.printGoodbye(),process.exit(0);else if("back"===i)return;await this.configureTool(i,a)}}async configureTool(a,o=!1){const i=c[a];if(i){if(!l.isToolInstalled(a)){console.log(t.yellow("\n"+f.t("wizard.tool_not_installed",{tool:i.displayName})));const{install:o}=await e.prompt([{type:"confirm",name:"install",message:f.t("wizard.install_tool_confirm"),default:!0}]);if(!o)return;try{await l.installTool(a)}catch{return void console.log(t.red(f.t("wizard.install_failed")))}}o?await this.configureToolModel(a)&&await this.loadConfig(a):await this.showToolMenu(a)}}async showToolMenu(t){for(;;){this.resetScreen();const a=c[t];if(!a)return;this.createBox(a.displayName+" "+f.t("wizard.menu_title"));const o=[{name:"📥 "+f.t("wizard.action_load_config",{tool:a.displayName}),value:"load"},{name:"📤 "+f.t("wizard.action_unload_config",{tool:a.displayName}),value:"unload"}];l.supportsClearPinnedModels(t)&&o.push({name:"🧹 "+f.t("wizard.action_clear_model",{tool:a.displayName}),value:"clear-model"});const i=_().includes(t)?g(t):null;if(i&&!i.blocker&&i.latest&&(i.outdated||!i.installed)){const e=i.installed?f.t("wizard.action_upgrade_app",{tool:a.displayName,current:i.current??"?",latest:i.latest}):f.t("wizard.action_install_app",{tool:a.displayName,latest:i.latest});o.unshift({name:"↑ "+e,value:"upgrade-app"})}o.push({name:"🧨 "+f.t("wizard.action_force_config",{tool:a.displayName}),value:"force"},{name:"↩️ "+f.t("wizard.action_restore_config",{tool:a.displayName}),value:"restore"},new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"back"},{name:"x "+f.t("wizard.nav_exit"),value:"exit"});const{action:n}=await this.promptWithHints([{type:"list",name:"action",message:"⚙️ "+f.t("wizard.select_action"),choices:o}]);if("exit"===n)this.printGoodbye(),process.exit(0);else{if("back"===n)return;"load"===n?await this.configureToolModel(t)&&await this.loadConfig(t):"force"===n?await this.forceConfig(t):"unload"===n?await this.unloadConfig(t):"upgrade-app"===n?(await w(t,{install:!0}),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])):"clear-model"===n?await this.clearPinnedModels(t):"restore"===n&&await this.restoreConfig(t)}}}singleModelOverride(e){const t=e.trim();return/claude/i.test(t)?{opus:t}:{haiku:t,sonnet:t,opus:t,reasoning:t}}hasConfiguredApiKey(){return!!o.getApiKey()?.trim()||o.listToolApiKeys().some(e=>Boolean(o.getApiKeyForTool(e)?.trim()))}async validatedKeyForConfiguration(e){const o=e?.trim();if(!o)return console.log(t.red("\n"+f.t("wizard.api_key_required"))),console.log(t.yellow(f.t("wizard.please_config_api_key_first"))),null;if(this.validatedApiKeys.has(o))return o;const i=a(f.t("wizard.validating_api_key")).start(),n=await v(o);if(n.valid)return this.validatedApiKeys.add(o),i.succeed(f.t("wizard.api_key_valid")),o;this.validatedApiKeys.delete(o);const r="invalid_api_key"===n.error?f.t("wizard.api_key_invalid"):f.t("wizard.api_key_network_error");return i.fail(r),console.log(t.red("\n"+f.t("wizard.please_reconfig_api_key"))),null}async configureToolModel(i){const n=c[i];if(!n)return!1;const l=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!l)return await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}]),!1;const d="claude-code"===i,p=d||"claude-desktop"===i||"agy"===i,m=s(i),u=p||!m?f.t("wizard.model_builtin_default"):m;this.resetScreen(),this.createBox(n.displayName+" · "+f.t("wizard.config_models"));const _=[{name:"✅ "+f.t("wizard.use_default_model",{model:u}),value:{type:"default"}},{name:"🌐 "+f.t("wizard.fetch_models_from_api"),value:{type:"fetch"}},...this.buildPresetChoices(),new e.Separator,{name:"✏️ "+f.t("wizard.input_custom_model"),value:{type:"custom"}},new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:{type:"back"}}],{choice:g}=await this.promptWithHints([{type:"list",name:"choice",message:f.t("wizard.select_tool_model",{tool:n.displayName}),choices:_}]);if("back"===g.type)return!1;if("default"===g.type)o.setToolModel(i,null);else if("preset"===g.type)o.setToolModel(i,r(g.preset));else if("custom"===g.type){const{model:t}=await e.prompt([{type:"input",name:"model",message:f.t("wizard.input_custom_model"),default:!p&&m?m:void 0}]),a=(t||"").trim();o.setToolModel(i,a?this.singleModelOverride(a):null)}else if("fetch"===g.type){const n=a(f.t("wizard.fetching_models")).start(),r=await k(l);let s;if(n.stop(),r.ok&&r.models.length>0){const{model:t}=await e.prompt([{type:"list",name:"model",message:f.t("wizard.select_fetched_model"),pageSize:20,choices:[...r.models,new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"__back__"}]}]);if("__back__"===t)return!1;s=t}else{console.log(t.yellow("\n"+f.t("wizard.fetch_models_failed")));const{model:a}=await e.prompt([{type:"input",name:"model",message:f.t("wizard.input_custom_model"),default:!p&&m?m:void 0}]);s=(a||"").trim()}o.setToolModel(i,s?this.singleModelOverride(s):null)}if("codex"===i){const t=o.getToolSetting(i,x),{enableOneMillionContext:a}=await e.prompt([{type:"confirm",name:"enableOneMillionContext",message:f.t("wizard.codex_enable_1m_context"),default:!1!==t}]);o.setToolSetting(i,x,Boolean(a))}if("claude-desktop"===i){const t=o.getToolSetting(i,b),{hideOfficialLogin:a}=await e.prompt([{type:"confirm",name:"hideOfficialLogin",message:f.t("wizard.desktop_hide_official_login"),default:!1!==t}]);o.setToolSetting(i,b,Boolean(a))}return console.log(t.green("\n✓ "+f.t("wizard.models_saved"))),d&&console.log(t.gray("💡 "+f.t("wizard.claude_model_hint"))),!0}async forceConfig(t){const a=c[t]?.displayName||t,{confirm:o}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("config.confirm_force",{tool:a}),default:!1}]);o&&await this.loadConfig(t,{force:!0})}async loadConfig(i,n={}){const r=o.getModelsForTool(i),s=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!s)return void await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}]);if(!n.force&&!await d([i]))return;const m=a(f.t("wizard.loading_config")).start();try{await l.applyPrivateConfig(i,s,r,n),m.stop(),l.printApplied(i),await p([i],{apps:{install:!1}}),n.force&&console.log(t.yellow(f.t("config.force_done",{tool:c[i]?.displayName||i,name:i})));const a=c[i];a&&!a.gui&&(l.isOnPath(i)&&console.log(t.green("\n"+f.t("wizard.run_tool_hint",{command:a.command}))),this.printPathReloadHint([i]));const{nextAction:o}=await e.prompt([{type:"list",name:"nextAction",message:f.t("wizard.what_next"),choices:[{name:f.t("wizard.exit_and_start"),value:"exit"},{name:f.t("wizard.continue_config"),value:"continue"}]}]);"exit"===o&&(this.printGoodbye(),process.exit(0))}catch(a){m.fail(f.t("wizard.config_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}}async clearPinnedModels(a){const o=c[a]?.displayName||a,{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("wizard.confirm_clear_model",{tool:o}),default:!1}]);if(i){try{const e=await l.clearPinnedModels(a);0===e.length?console.log(t.yellow("\n"+f.t("config.clear_model_none",{tool:o}))):(console.log(t.green("\n✓ "+f.t("config.clear_model_done",{tool:o}))),e.forEach(e=>console.log(t.gray(` - ${e}`))),console.log(t.gray(f.t("config.clear_model_restart_hint",{tool:o}))))}catch(e){console.log(t.red("\n"+(e instanceof Error?e.message:String(e))))}await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}}async unloadConfig(o){const{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("wizard.confirm_unload_config",{tool:c[o]?.displayName||o}),default:!1}]);if(!i)return;const n=a(f.t("wizard.unloading_config")).start();try{const a=l.holdsOurConfig(o),i=l.unloadPrivateConfig(o);if(!a)return void n.info(f.t("config.remove_nothing",{tool:c[o]?.displayName||o}));n.succeed(f.t("wizard.config_unloaded")),i.forEach(e=>console.log(t.yellow(" ! "+e.text)));const{nextAction:r}=await e.prompt([{type:"list",name:"nextAction",message:f.t("wizard.what_next"),choices:[{name:f.t("wizard.nav_exit"),value:"exit"},{name:f.t("wizard.continue_config"),value:"continue"}]}]);"exit"===r&&(this.printGoodbye(),process.exit(0))}catch(a){n.fail(f.t("wizard.config_unload_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}}async restoreConfig(o){const i=c[o]?.displayName||o,{confirm:n}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("wizard.confirm_restore_config",{tool:i}),default:!1}]);if(!n)return;const r=a(f.t("wizard.restoring_config")).start();try{const e=l.restorePrivateConfig(o).filter(e=>e.result.restored);0===e.length?r.warn(f.t("wizard.restore_no_backup")):(r.succeed(f.t("wizard.config_restored",{tool:i})),e.forEach(e=>console.log(t.gray(` ${e.file} ← ${e.result.from}`))),console.log(t.yellow(" ! "+f.t("config.reopen_hint",{tool:i}))))}catch(e){r.fail(f.t("wizard.config_restore_failed")),console.log(t.red(e instanceof Error?e.message:String(e)))}await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}async run(){await this.showMainMenu()}async showMainMenu(){if(this.hasConfiguredApiKey())for(;;){this.resetScreen();const a=o.getApiKey()||"",i=a.length>4?"sk-****"+a.slice(-4):"****";console.log(t.gray(` 🔑 API Key: ${i}`)+t.green(" ✓")),console.log("");const n=l.getSupportedTools().map(e=>({name:"🛠️ "+e.displayName,value:{type:"tool",tool:e.name}})),r=[new e.Separator(F("── "+f.t("wizard.select_tool")+" ──")),...n,new e.Separator(t.gray("── "+f.t("wizard.settings")+" ──")),{name:"🔑 "+f.t("wizard.menu_change_api_key"),value:{type:"apikey"}},{name:"🔗 "+f.t("wizard.menu_base_url",{url:o.getBaseUrl()}),value:{type:"base"}},{name:"🌐 "+f.t("wizard.menu_config_language"),value:{type:"language"}},new e.Separator,{name:"x "+f.t("wizard.nav_exit"),value:{type:"exit"}}],{action:s}=await this.promptWithHints([{type:"list",name:"action",message:"🛠️ "+f.t("wizard.select_tool"),choices:r}]);"exit"===s.type?(this.printGoodbye(),process.exit(0)):"tool"===s.type?await this.configureTool(s.tool):"apikey"===s.type?await this.configApiKey():"base"===s.type?await this.configBaseUrl():"language"===s.type&&await this.configLanguage()}else await this.runFirstTimeSetup()}}export const wizard=Wizard.getInstance();
|
|
1
|
+
import e from"inquirer";import t from"chalk";import a from"ora";import{configManager as o,DEFAULT_MODELS as i}from"./config.js";import{getPresets as n,resolvePreset as r,getToolDefaultModel as s}from"./model-registry.js";import{toolManager as l,SUPPORTED_TOOLS as c}from"./tool-manager.js";import{confirmWritePlan as d}from"./write-plan.js";import{postApplyPrompts as p}from"./post-apply.js";import{appStatus as m,appStatusText as u,appTools as _,appsForTools as g,cachedAppStatus as w,upgradeApp as f}from"./app-update.js";import{i18n as y,detectSystemLang as h}from"./i18n.js";import{createBorderLine as z,createContentLine as v}from"../utils/string-width.js";import{validateApiKey as k,fetchModels as x}from"./api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as b}from"./tools/codex.js";import{CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as S}from"./tools/claude-desktop.js";import{addressesWithCurrent as C,ensureReachableGatewayAddress as M,fastestIndex as T,probeAll as A,probeSummary as K,reasonText as N,savedApiKey as B,switchGatewayAddress as O}from"../commands/base.js";import{readFileSync as P}from"fs";import{dirname as W,join as j}from"path";import{fileURLToPath as H}from"url";import{brand as L}from"./brand.js";const $=W(H(import.meta.url)),F=t.hex("#FF8700");export class Wizard{static instance;BOX_WIDTH=63;validatedApiKeys=new Set;constructor(){}static getInstance(){return Wizard.instance||(Wizard.instance=new Wizard),Wizard.instance}createBox(e){console.log(F.bold("\n"+z("╔","╗","═",this.BOX_WIDTH))),console.log(F.bold(v(e,"║","║",this.BOX_WIDTH,"center"))),console.log(F.bold(z("╚","╝","═",this.BOX_WIDTH))),console.log("")}showOperationHints(){const e=[t.gray(y.t("wizard.hint_navigate")),t.gray(y.t("wizard.hint_confirm"))];console.log(t.gray("💡 ")+e.join(t.gray(" | "))+"\n")}async promptWithHints(t){this.showOperationHints();const a=t.map(e=>"list"!==e.type||e.pageSize?e:{...e,pageSize:20});return e.prompt(a)}printBanner(){const e=60,t=y.t("wizard.banner_subtitle"),a=v(t,"║","║",e,"center"),o=v("","║","║",e,"center"),i=v(`${L().productName} v${function(){try{return JSON.parse(P(j($,"..","..","package.json"),"utf-8")).version}catch{return"0.0.0"}}()}`,"║","║",e,"center"),n=[String.raw`__ ___ _ ____ _ ___ `,String.raw`\ \ / (_) |__ ___ / ___| | |_ _|`,String.raw` \ \ / /| | '_ \ / _ \ | | | | | `,String.raw` \ V / | | |_) | __/ |___| |___ | | `,String.raw` \_/ |_|_.__/ \___|\____|_____|___|`],r=Math.max(...n.map(e=>e.length)),s=" ".repeat(Math.floor((58-r)/2)),l=n.map(t=>v(s+t,"║","║",e,"left")),c=[z("╔","╗","═",e),o,...l,o,i,a,z("╚","╝","═",e)];console.log(F.bold("\n"+c.join("\n")))}resetScreen(){console.clear(),this.printBanner()}printGoodbye(){const e=l.getSupportedTools().filter(e=>{if(e.gui)return!1;try{return Boolean(l.detectCurrentConfig(e.name).apiKey)&&l.isToolInstalled(e.name)}catch{return!1}});let a;if(e.length>0){const t=e.map(e=>e.command).join(" / ");a=y.t("wizard.goodbye_message_tools",{commands:t}),e.some(e=>"claude-code"===e.name)&&(a+=" "+y.t("wizard.goodbye_claude_hint"))}else a=y.t("wizard.goodbye_message");console.log(t.green("\n👋 "+a)),this.printPathReloadHint(e.map(e=>e.name))}printPathReloadHint(e){const a=e.filter(e=>!l.isOnPath(e));if(0===a.length)return;const o=a.map(e=>c[e].command).join(" / ");console.log(t.yellow(" ! "+y.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:o})))}async runFirstTimeSetup(){const e="zh_CN"===h();e&&(o.setLang("zh_CN"),y.setLocale("zh_CN")),this.resetScreen(),console.log(F.bold("\n"+y.t("wizard.welcome"))),console.log(t.gray(y.t("wizard.privacy_note")+"\n")),e?console.log(t.gray(y.t("wizard.lang_auto_zh")+"\n")):await this.configLanguage(),await M(),await this.configApiKey()&&await this.selectAndConfigureTool(!0)}async configLanguage(){for(;;){this.resetScreen(),this.createBox(y.t("wizard.select_language"));const a=y.getLocale(),{language:i}=await this.promptWithHints([{type:"list",name:"language",message:"✨ "+y.t("wizard.select_language"),choices:[{name:"[EN] English"+("en_US"===a?t.green(" ✓ ("+y.t("wizard.current_active")+")"):""),value:"en_US"},{name:"[CN] 中文"+("zh_CN"===a?t.green(" ✓ ("+y.t("wizard.current_active")+")"):""),value:"zh_CN"},new e.Separator,{name:"<- "+y.t("wizard.nav_return"),value:"back"},{name:"x "+y.t("wizard.nav_exit"),value:"exit"}],default:"zh_CN"}]);if("exit"===i)this.printGoodbye(),process.exit(0);else if("back"===i)return;return o.setLang(i),void y.setLocale(i)}}buildPresetChoices(){const a=n(),o=a.filter(e=>e.recommended),i=a.filter(e=>!e.recommended),r=e=>({name:(y.t(e.name)!==e.name?y.t(e.name):e.name)+(e.models?t.gray(` [H:${e.models.haiku} S:${e.models.sonnet} O:${e.models.opus}]`):""),value:{type:"preset",preset:e}}),s=[];return o.length>0&&(s.push(new e.Separator(t.hex("#FF8700")("── "+y.t("wizard.recommended")+" ──"))),s.push(...o.map(r))),i.length>0&&(s.push(new e.Separator(t.gray("── "+y.t("wizard.other_models")+" ──"))),s.push(...i.map(r))),s}async handleCustomModelInput(){const a=o.getModels(),{customMode:n}=await e.prompt([{type:"list",name:"customMode",message:y.t("wizard.custom_model_mode"),choices:[{name:y.t("wizard.custom_model_single"),value:"single"},{name:y.t("wizard.custom_model_per_role"),value:"per_role"}]}]);if("single"===n){const{customModel:t}=await e.prompt([{type:"input",name:"customModel",message:y.t("wizard.input_custom_model"),default:i.sonnet}]);o.setModels({haiku:t,sonnet:t,opus:t,reasoning:t})}else{const t=await e.prompt([{type:"input",name:"haiku",message:y.t("wizard.model_haiku"),default:a.haiku},{type:"input",name:"sonnet",message:y.t("wizard.model_sonnet"),default:a.sonnet},{type:"input",name:"opus",message:y.t("wizard.model_opus"),default:a.opus},{type:"input",name:"reasoning",message:y.t("wizard.model_reasoning"),default:a.reasoning}]);o.setModels(t)}console.log(t.green("\n✓ "+y.t("wizard.models_saved")))}async configModels(a){const i=o.getApiKey();if(await this.validatedKeyForConfiguration(i))for(;;){this.resetScreen(),this.createBox(y.t("wizard.config_models"));const i=[...this.buildPresetChoices()];i.push(new e.Separator),i.push({name:"✏️ "+y.t("wizard.custom_model_input"),value:{type:"custom_input"}}),i.push(new e.Separator),i.push({name:"<- "+y.t("wizard.nav_return"),value:{type:"back"}}),i.push({name:"x "+y.t("wizard.nav_exit"),value:{type:"exit"}});const{modelChoice:n}=await this.promptWithHints([{type:"list",name:"modelChoice",message:y.t("wizard.select_model_config"),choices:i}]);if("exit"===n.type)this.printGoodbye(),process.exit(0);else{if("back"===n.type)return;if("custom_input"===n.type)return await this.handleCustomModelInput(),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig());if("preset"===n.type){const e=r(n.preset);return o.setModels(e),console.log(t.green("\n✓ "+y.t("wizard.models_saved"))),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig())}}}else await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}])}async promptLoadAfterModelConfig(){const{shouldLoad:t}=await e.prompt([{type:"list",name:"shouldLoad",message:y.t("wizard.load_config_now"),choices:[{name:y.t("wizard.load_config_yes"),value:!0},{name:y.t("wizard.load_config_later"),value:!1}]}]);t&&await this.selectAndConfigureTool()}async configBaseUrl(){const i=o.getBaseUrl(),n=C(),r=a(y.t("wizard.base_testing")).start(),s=await A(n,{apiKey:B(),samples:3});r.stop();const l=T(s),c=n.map((e,a)=>{const o=e.url===i?t.cyan(` ← ${y.t("base.current_mark")}`):"";return{name:`${e.url} ${t.gray(e.label)} ${K(s[a],a===l)}${o}`,value:e.url}});c.push(new e.Separator,{name:"<- "+y.t("wizard.nav_return"),value:"__back__"});const{url:d}=await this.promptWithHints([{type:"list",name:"url",message:y.t("wizard.base_select"),choices:c,default:i}]);if("__back__"===d)return;const p=s[n.findIndex(e=>e.url===d)];p.ok?await O(d):console.log(t.red(y.t("base.unreachable",{url:d,reason:N(p)}))),await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}])}async configApiKey(){for(;;){this.resetScreen(),this.createBox(y.t("wizard.input_api_key")),console.log(t.gray("\n💡 "+y.t("wizard.api_key_input_hint"))),console.log(t.gray(" "+y.t("wizard.api_key_get_hint",{url:L().links.tokenPage}))),console.log();const{apiKey:i}=await e.prompt([{type:"password",name:"apiKey",message:y.t("wizard.input_your_api_key"),mask:"*"}]);if(!i||""===i.trim()){const{action:t}=await e.prompt([{type:"list",name:"action",message:y.t("wizard.select_action"),choices:[{name:y.t("wizard.retry_input"),value:"retry"},{name:"<- "+y.t("wizard.nav_return"),value:"back"}]}]);if("back"===t)return!1;continue}const n=a(y.t("wizard.validating_api_key")).start(),r=await k(i.trim());if(n.stop(),r.valid)return o.setApiKey(i.trim()),this.validatedApiKeys.add(i.trim()),console.log(t.green("\n✓ "+y.t("wizard.api_key_valid"))),!0;{this.validatedApiKeys.delete(i.trim()),"invalid_api_key"===r.error?console.log(t.red("\n✗ "+y.t("wizard.api_key_invalid"))):console.log(t.red("\n✗ "+y.t("wizard.api_key_network_error")));const{action:a}=await e.prompt([{type:"list",name:"action",message:y.t("wizard.select_action"),choices:[{name:y.t("wizard.retry_input"),value:"retry"},{name:"<- "+y.t("wizard.nav_return"),value:"back"}]}]);if("back"===a)return!1}}}async selectAndConfigureTool(a=!1){for(const e of _())await m(e).catch(()=>{});for(;;){this.resetScreen(),this.createBox(y.t("wizard.select_tool"));const o=l.getSupportedTools().map(e=>{const a=g([e.name]).map(e=>w(e)).find(e=>e.outdated);return{name:e.displayName+(a?t.yellow(" "+(a.tool===e.name?"":`${a.name} `)+u(a)):""),value:e.name}}),{tool:i}=await this.promptWithHints([{type:"list",name:"tool",message:"🛠️ "+y.t("wizard.select_tool"),choices:[...o,new e.Separator,{name:"<- "+y.t("wizard.nav_return"),value:"back"},{name:"x "+y.t("wizard.nav_exit"),value:"exit"}]}]);if("exit"===i)this.printGoodbye(),process.exit(0);else if("back"===i)return;await this.configureTool(i,a)}}async configureTool(a,o=!1){const i=c[a];if(i){if(!l.isToolInstalled(a)){console.log(t.yellow("\n"+y.t("wizard.tool_not_installed",{tool:i.displayName})));const{install:o}=await e.prompt([{type:"confirm",name:"install",message:y.t("wizard.install_tool_confirm"),default:!0}]);if(!o)return;try{await l.installTool(a)}catch{return void console.log(t.red(y.t("wizard.install_failed")))}}o?await this.configureToolModel(a)&&await this.loadConfig(a):await this.showToolMenu(a)}}async showToolMenu(t){for(;;){this.resetScreen();const a=c[t];if(!a)return;this.createBox(a.displayName+" "+y.t("wizard.menu_title"));const o=[{name:"📥 "+y.t("wizard.action_load_config",{tool:a.displayName}),value:"load"},{name:"📤 "+y.t("wizard.action_unload_config",{tool:a.displayName}),value:"unload"}];l.supportsClearPinnedModels(t)&&o.push({name:"🧹 "+y.t("wizard.action_clear_model",{tool:a.displayName}),value:"clear-model"});for(const e of g([t]).map(e=>w(e)).reverse()){if(e.blocker||!e.latest||!e.outdated&&e.installed)continue;const t=e.installed?y.t("wizard.action_upgrade_app",{tool:e.name,current:e.current??"?",latest:e.latest}):y.t("wizard.action_install_app",{tool:e.name,latest:e.latest});o.unshift({name:"↑ "+t,value:`upgrade-app:${e.tool}`})}o.push({name:"🧨 "+y.t("wizard.action_force_config",{tool:a.displayName}),value:"force"},{name:"↩️ "+y.t("wizard.action_restore_config",{tool:a.displayName}),value:"restore"},new e.Separator,{name:"<- "+y.t("wizard.nav_return"),value:"back"},{name:"x "+y.t("wizard.nav_exit"),value:"exit"});const{action:i}=await this.promptWithHints([{type:"list",name:"action",message:"⚙️ "+y.t("wizard.select_action"),choices:o}]);if("exit"===i)this.printGoodbye(),process.exit(0);else{if("back"===i)return;"load"===i?await this.configureToolModel(t)&&await this.loadConfig(t):"force"===i?await this.forceConfig(t):"unload"===i?await this.unloadConfig(t):"string"==typeof i&&i.startsWith("upgrade-app:")?(await f(i.slice(12),{install:!0}),await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}])):"clear-model"===i?await this.clearPinnedModels(t):"restore"===i&&await this.restoreConfig(t)}}}singleModelOverride(e){const t=e.trim();return/claude/i.test(t)?{opus:t}:{haiku:t,sonnet:t,opus:t,reasoning:t}}hasConfiguredApiKey(){return!!o.getApiKey()?.trim()||o.listToolApiKeys().some(e=>Boolean(o.getApiKeyForTool(e)?.trim()))}async validatedKeyForConfiguration(e){const o=e?.trim();if(!o)return console.log(t.red("\n"+y.t("wizard.api_key_required"))),console.log(t.yellow(y.t("wizard.please_config_api_key_first"))),null;if(this.validatedApiKeys.has(o))return o;const i=a(y.t("wizard.validating_api_key")).start(),n=await k(o);if(n.valid)return this.validatedApiKeys.add(o),i.succeed(y.t("wizard.api_key_valid")),o;this.validatedApiKeys.delete(o);const r="invalid_api_key"===n.error?y.t("wizard.api_key_invalid"):y.t("wizard.api_key_network_error");return i.fail(r),console.log(t.red("\n"+y.t("wizard.please_reconfig_api_key"))),null}async configureToolModel(i){const n=c[i];if(!n)return!1;const l=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!l)return await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}]),!1;const d="claude-code"===i,p=d||"claude-desktop"===i||"agy"===i,m=s(i),u=p||!m?y.t("wizard.model_builtin_default"):m;this.resetScreen(),this.createBox(n.displayName+" · "+y.t("wizard.config_models"));const _=[{name:"✅ "+y.t("wizard.use_default_model",{model:u}),value:{type:"default"}},{name:"🌐 "+y.t("wizard.fetch_models_from_api"),value:{type:"fetch"}},...this.buildPresetChoices(),new e.Separator,{name:"✏️ "+y.t("wizard.input_custom_model"),value:{type:"custom"}},new e.Separator,{name:"<- "+y.t("wizard.nav_return"),value:{type:"back"}}],{choice:g}=await this.promptWithHints([{type:"list",name:"choice",message:y.t("wizard.select_tool_model",{tool:n.displayName}),choices:_}]);if("back"===g.type)return!1;if("default"===g.type)o.setToolModel(i,null);else if("preset"===g.type)o.setToolModel(i,r(g.preset));else if("custom"===g.type){const{model:t}=await e.prompt([{type:"input",name:"model",message:y.t("wizard.input_custom_model"),default:!p&&m?m:void 0}]),a=(t||"").trim();o.setToolModel(i,a?this.singleModelOverride(a):null)}else if("fetch"===g.type){const n=a(y.t("wizard.fetching_models")).start(),r=await x(l);let s;if(n.stop(),r.ok&&r.models.length>0){const{model:t}=await e.prompt([{type:"list",name:"model",message:y.t("wizard.select_fetched_model"),pageSize:20,choices:[...r.models,new e.Separator,{name:"<- "+y.t("wizard.nav_return"),value:"__back__"}]}]);if("__back__"===t)return!1;s=t}else{console.log(t.yellow("\n"+y.t("wizard.fetch_models_failed")));const{model:a}=await e.prompt([{type:"input",name:"model",message:y.t("wizard.input_custom_model"),default:!p&&m?m:void 0}]);s=(a||"").trim()}o.setToolModel(i,s?this.singleModelOverride(s):null)}if("codex"===i){const t=o.getToolSetting(i,b),{enableOneMillionContext:a}=await e.prompt([{type:"confirm",name:"enableOneMillionContext",message:y.t("wizard.codex_enable_1m_context"),default:!1!==t}]);o.setToolSetting(i,b,Boolean(a))}if("claude-desktop"===i){const t=o.getToolSetting(i,S),{hideOfficialLogin:a}=await e.prompt([{type:"confirm",name:"hideOfficialLogin",message:y.t("wizard.desktop_hide_official_login"),default:!1!==t}]);o.setToolSetting(i,S,Boolean(a))}return console.log(t.green("\n✓ "+y.t("wizard.models_saved"))),d&&console.log(t.gray("💡 "+y.t("wizard.claude_model_hint"))),!0}async forceConfig(t){const a=c[t]?.displayName||t,{confirm:o}=await e.prompt([{type:"confirm",name:"confirm",message:y.t("config.confirm_force",{tool:a}),default:!1}]);o&&await this.loadConfig(t,{force:!0})}async loadConfig(i,n={}){const r=o.getModelsForTool(i),s=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!s)return void await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}]);if(!n.force&&!await d([i]))return;const m=a(y.t("wizard.loading_config")).start();try{await l.applyPrivateConfig(i,s,r,{...n,takeOver:!0}),m.stop(),l.printApplied(i),await p([i],{apps:{install:!1}}),n.force&&console.log(t.yellow(y.t("config.force_done",{tool:c[i]?.displayName||i,name:i})));const a=c[i];a&&!a.gui&&(l.isOnPath(i)&&console.log(t.green("\n"+y.t("wizard.run_tool_hint",{command:a.command}))),this.printPathReloadHint([i]));const{nextAction:o}=await e.prompt([{type:"list",name:"nextAction",message:y.t("wizard.what_next"),choices:[{name:y.t("wizard.exit_and_start"),value:"exit"},{name:y.t("wizard.continue_config"),value:"continue"}]}]);"exit"===o&&(this.printGoodbye(),process.exit(0))}catch(a){m.fail(y.t("wizard.config_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}])}}async clearPinnedModels(a){const o=c[a]?.displayName||a,{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:y.t("wizard.confirm_clear_model",{tool:o}),default:!1}]);if(i){try{const e=await l.clearPinnedModels(a);0===e.length?console.log(t.yellow("\n"+y.t("config.clear_model_none",{tool:o}))):(console.log(t.green("\n✓ "+y.t("config.clear_model_done",{tool:o}))),e.forEach(e=>console.log(t.gray(` - ${e}`))),console.log(t.gray(y.t("config.clear_model_restart_hint",{tool:o}))))}catch(e){console.log(t.red("\n"+(e instanceof Error?e.message:String(e))))}await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}])}}async unloadConfig(o){const{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:y.t("wizard.confirm_unload_config",{tool:c[o]?.displayName||o}),default:!1}]);if(!i)return;const n=a(y.t("wizard.unloading_config")).start();try{const a=l.holdsOurConfig(o),i=l.unloadPrivateConfig(o);if(!a)return void n.info(y.t("config.remove_nothing",{tool:c[o]?.displayName||o}));n.succeed(y.t("wizard.config_unloaded")),i.forEach(e=>console.log(t.yellow(" ! "+e.text)));const{nextAction:r}=await e.prompt([{type:"list",name:"nextAction",message:y.t("wizard.what_next"),choices:[{name:y.t("wizard.nav_exit"),value:"exit"},{name:y.t("wizard.continue_config"),value:"continue"}]}]);"exit"===r&&(this.printGoodbye(),process.exit(0))}catch(a){n.fail(y.t("wizard.config_unload_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}])}}async restoreConfig(o){const i=c[o]?.displayName||o,{confirm:n}=await e.prompt([{type:"confirm",name:"confirm",message:y.t("wizard.confirm_restore_config",{tool:i}),default:!1}]);if(!n)return;const r=a(y.t("wizard.restoring_config")).start();try{const e=l.restorePrivateConfig(o).filter(e=>e.result.restored);0===e.length?r.warn(y.t("wizard.restore_no_backup")):(r.succeed(y.t("wizard.config_restored",{tool:i})),e.forEach(e=>console.log(t.gray(` ${e.file} ← ${e.result.from}`))),console.log(t.yellow(" ! "+y.t("config.reopen_hint",{tool:i}))))}catch(e){r.fail(y.t("wizard.config_restore_failed")),console.log(t.red(e instanceof Error?e.message:String(e)))}await e.prompt([{type:"input",name:"continue",message:y.t("wizard.press_enter")}])}async run(){await this.showMainMenu()}async showMainMenu(){if(this.hasConfiguredApiKey())for(;;){this.resetScreen();const a=o.getApiKey()||"",i=a.length>4?"sk-****"+a.slice(-4):"****";console.log(t.gray(` 🔑 API Key: ${i}`)+t.green(" ✓")),console.log("");const n=l.getSupportedTools().map(e=>({name:"🛠️ "+e.displayName,value:{type:"tool",tool:e.name}})),r=[new e.Separator(F("── "+y.t("wizard.select_tool")+" ──")),...n,new e.Separator(t.gray("── "+y.t("wizard.settings")+" ──")),{name:"🔑 "+y.t("wizard.menu_change_api_key"),value:{type:"apikey"}},{name:"🔗 "+y.t("wizard.menu_base_url",{url:o.getBaseUrl()}),value:{type:"base"}},{name:"🌐 "+y.t("wizard.menu_config_language"),value:{type:"language"}},new e.Separator,{name:"x "+y.t("wizard.nav_exit"),value:{type:"exit"}}],{action:s}=await this.promptWithHints([{type:"list",name:"action",message:"🛠️ "+y.t("wizard.select_tool"),choices:r}]);"exit"===s.type?(this.printGoodbye(),process.exit(0)):"tool"===s.type?await this.configureTool(s.tool):"apikey"===s.type?await this.configApiKey():"base"===s.type?await this.configBaseUrl():"language"===s.type&&await this.configLanguage()}else await this.runFirstTimeSetup()}}export const wizard=Wizard.getInstance();
|
package/dist/lib/write-plan.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"chalk";import t from"inquirer";import{getAdapter as
|
|
1
|
+
import o from"chalk";import t from"inquirer";import{getAdapter as n}from"./tools/registry.js";import{SUPPORTED_TOOLS as e}from"./tool-manager.js";import{i18n as r}from"./i18n.js";import{isColorEnabled as l,isDryRun as i,isJsonMode as s,isNonInteractive as a,shouldAutoConfirm as c}from"./runtime-options.js";export function toolWritePlan(o){return o.map(o=>{const t=n(o);let e=[];try{e=t?.planNotes?.()??[]}catch{e=[]}return{tool:o,files:t?.backupPaths?.()??(t?[t.configPath]:[]),notes:e}})}export function printWritePlan(t,n){const i=(l()?o.cyan:o=>o)(n.label),s=l()?o.gray:o=>o,a=l()?o.yellow:o=>o;for(const{tool:o,files:n,notes:l}of t)console.log(`${i} ${r.t("setup.dry_run_tool",{tool:e[o]?.displayName??o})}`),n.forEach(o=>console.log(s(` ${o}`))),l.forEach(o=>console.log(a(` ! ${o}`)));for(const o of n.installFirst??[])console.log(`${i} ${r.t("plan.install_first",{tool:e[o]?.displayName??o})}`);n.keyFile&&console.log(`${i} ${r.t("setup.dry_run_key",{file:n.keyFile})}`)}export function asksBeforeWriting(){return Boolean(process.stdin.isTTY&&process.stdout.isTTY)&&!c()&&!a()&&!s()&&!i()}export async function confirmWritePlan(o,n={}){if(!asksBeforeWriting())return!0;if(0===o.length&&!n.keyFile&&!n.installFirst?.length)return!0;console.log("\n"+r.t("plan.title")),printWritePlan(toolWritePlan(o),{label:" •",...n});const{go:e}=await t.prompt([{type:"confirm",name:"go",message:r.t("plan.confirm"),default:!0}]);return e||console.log(r.t("plan.cancelled")),e}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{mkdirSync as e,readFileSync as t,writeFileSync as n}from"fs";import{join as r}from"path";import{configManager as i}from"./config.js";import{logger as o}from"../utils/logger.js";function s(){return r(i.getConfigDir(),"written-values.json")}function l(){try{const e=JSON.parse(t(s(),"utf-8"));return e.values&&"object"==typeof e.values?e.values:{}}catch{return{}}}function u(t){try{e(i.getConfigDir(),{recursive:!0}),n(s(),JSON.stringify({version:1,values:t},null,2)+"\n",{mode:384})}catch(e){o.logError("writtenValues.save",e)}}export function ownsValue(e,t,n=[]){if("string"!=typeof t)return!1;const r=l()[e];return r?r.written===t:n.includes(t)}export function claimField(e,t,n,r={}){const i=l(),o=i[e];let s;return s=null==t||""===t||t===n||"string"==typeof t&&(o?o.written===t||Boolean(r.explicit)&&o.desired!==n:Boolean(r.explicit)||(r.legacy??[]).includes(t)),i[e]=s?{written:n,desired:n}:{desired:n},u(i),s}export function forgetField(e){const t=l();e in t&&(delete t[e],u(t))}const c="gateway_urls";export function noteGatewayUrl(e){const t=l(),n=(t[c]?.desired??"").split("\n").filter(Boolean);n.includes(e)||(t[c]={desired:[...n,e].join("\n")},u(t))}export function wroteGatewayUrl(e){return(l()[c]?.desired??"").split("\n").includes(e)}
|
package/dist/locales/en_US.json
CHANGED
|
@@ -366,7 +366,7 @@
|
|
|
366
366
|
"gui_preconfigured": "{{tool}} is not installed yet; its config is written already, so it works once you install and open it (download: {{install}})",
|
|
367
367
|
"validate_failed": "Couldn't validate the API key for {{label}}: {{reason}}",
|
|
368
368
|
"skip_no_claude_desktop": "This API key has no Claude model group; skipped Claude Code and Claude Desktop",
|
|
369
|
-
"install_app_confirm": "Install {{tools}}? (about
|
|
369
|
+
"install_app_confirm": "Install {{tools}}? (about {{size}} MB from the download site)",
|
|
370
370
|
"install_app_hint": "{{tool}} isn't installed: run {{command}} to install it (its config is ready, so it works once opened)"
|
|
371
371
|
},
|
|
372
372
|
"tools": {
|
|
@@ -380,6 +380,10 @@
|
|
|
380
380
|
"list_separator": ", "
|
|
381
381
|
},
|
|
382
382
|
"codex": {
|
|
383
|
+
"kept_user_settings": "Kept what you set yourself: {{values}}",
|
|
384
|
+
"plan_replace_provider": "Replace model_providers.custom (now pointing at {{url}}, not written by {{product}})",
|
|
385
|
+
"plan_switch_provider": "Codex now uses {{provider}}; it will switch to {{brand}}",
|
|
386
|
+
"provider_replaced": "Replaced the previous custom provider {{url}}; the old file is backed up",
|
|
383
387
|
"sessions_offer": "Move {{count}} earlier Codex sessions over? They're hidden from the list after switching to {{brand}}. They're backed up first and this can be undone.",
|
|
384
388
|
"sessions_hidden": "{{count}} earlier Codex sessions are hidden from the list after switching to {{brand}}: run {{cli}} codex sessions to move them over (backed up first, can be undone)",
|
|
385
389
|
"sessions_hidden_running": "{{count}} earlier Codex sessions are hidden from the list after switching to {{brand}}: quit Codex completely (desktop app included), then run {{cli}} codex sessions",
|
|
@@ -393,6 +397,12 @@
|
|
|
393
397
|
"unload_other_key": "Codex is still signed in with another API key (not the {{brand}} API key, left as is). To use your ChatGPT subscription, run codex logout, then codex login"
|
|
394
398
|
},
|
|
395
399
|
"claude_desktop": {
|
|
400
|
+
"current_official": "the official sign-in",
|
|
401
|
+
"current_entry": "the \"{{name}}\" configuration",
|
|
402
|
+
"plan_switch": "Claude Desktop now uses {{current}}; it will switch to {{brand}}",
|
|
403
|
+
"not_switched": "Claude Desktop uses {{current}}: the {{brand}} configuration is saved but not switched on. To switch, run {{cli}} config claude-desktop --yes",
|
|
404
|
+
"foreign_policy": "The registry key {{key}} holds another service's settings ({{url}}); Claude Desktop uses those and ignores what {{product}} writes. {{product}} left them alone; ask your administrator if needed",
|
|
405
|
+
"plan_foreign_policy": "The registry key {{key}} holds another service's settings ({{url}}); they are kept and Claude Desktop keeps using them",
|
|
396
406
|
"code_cli_downloading": "Downloading Claude Code {{version}} for Claude Desktop's Code tab from the China mirror (about 100 MB)…",
|
|
397
407
|
"code_cli_installed": "Claude Desktop's Code tab has Claude Code {{version}} and no longer needs downloads.claude.ai",
|
|
398
408
|
"code_cli_failed": "Couldn't prepare Claude Code for Claude Desktop's Code tab ({{reason}}); the tab may say it can't download it. Fix the cause above, then run {{cli}} setup --desktopkey <your API key>",
|
|
@@ -414,7 +424,16 @@
|
|
|
414
424
|
"registry_removed": "Removed the old values under {{key}}; Claude Desktop now reads the local config"
|
|
415
425
|
},
|
|
416
426
|
"claude_code": {
|
|
427
|
+
"plan_env_remove": "Remove {{vars}} pointing at this site from {{location}} (backed up first)",
|
|
428
|
+
"env_removed": "Removed {{vars}} pointing at this site from {{location}}; new terminals pick this up (backed up)",
|
|
429
|
+
"env_foreign": "{{vars}} in {{location}} point at another service and override Claude Code's settings; {{product}} left them alone. To use {{brand}}, remove them yourself and open a new terminal",
|
|
430
|
+
"env_foreign_found": "{{vars}} in {{location}} point at another service and override Claude Code's settings",
|
|
431
|
+
"env_foreign_offer": "Remove the environment variables pointing at another service, {{where}}? Claude Code uses {{brand}} only without them (they are backed up first)",
|
|
432
|
+
"env_removed_foreign": "Removed {{vars}} from {{location}} (backed up); open a new terminal for it to take effect",
|
|
433
|
+
"plan_replace_provider": "Replace Claude Code's current endpoint {{url}} (not written by {{product}})",
|
|
434
|
+
"provider_replaced": "Replaced the previous endpoint {{url}}; the old file is backed up",
|
|
417
435
|
"gateway_models": "{{count}} more models added to /model ({{vendors}})",
|
|
436
|
+
"kept_user_models": "Kept the models you set yourself: {{values}}",
|
|
418
437
|
"tier_fallback": "This API key can't use Claude Code's default {{from}}; the {{tier}} alias now uses {{to}}",
|
|
419
438
|
"stable_channel": "Your update channel in settings.json is stable, which may not have reached {{min}} yet; set autoUpdatesChannel to latest, then upgrade",
|
|
420
439
|
"managed_override": "Claude Code managed settings found ({{source}}); {{keys}} there override what {{product}} writes, so this config won't take effect. Managed settings usually come from your company's IT; ask your administrator",
|
|
@@ -462,6 +481,83 @@
|
|
|
462
481
|
"native_mirror_failed": "Couldn't replace from the mirror: {{reason}}",
|
|
463
482
|
"install_label": "{{kind}} {{version}} ({{path}})"
|
|
464
483
|
},
|
|
484
|
+
"components": {
|
|
485
|
+
"category": {
|
|
486
|
+
"runtime": "Runtimes",
|
|
487
|
+
"cli": "Command-line tools",
|
|
488
|
+
"app": "Desktop apps"
|
|
489
|
+
},
|
|
490
|
+
"col": {
|
|
491
|
+
"name": "Component",
|
|
492
|
+
"current": "Installed",
|
|
493
|
+
"latest": "Latest",
|
|
494
|
+
"managed": "Installed by",
|
|
495
|
+
"state": "State"
|
|
496
|
+
},
|
|
497
|
+
"by": {
|
|
498
|
+
"fnm": "fnm",
|
|
499
|
+
"brew": "Homebrew",
|
|
500
|
+
"nvm": "nvm",
|
|
501
|
+
"volta": "Volta",
|
|
502
|
+
"scoop": "Scoop",
|
|
503
|
+
"asdf": "asdf",
|
|
504
|
+
"mise": "mise",
|
|
505
|
+
"system": "system",
|
|
506
|
+
"standalone": "standalone",
|
|
507
|
+
"pipx": "pipx",
|
|
508
|
+
"pip": "pip",
|
|
509
|
+
"winget": "winget",
|
|
510
|
+
"git-for-windows-user": "Git for Windows (this user)",
|
|
511
|
+
"git-for-windows": "Git for Windows",
|
|
512
|
+
"xcode": "Apple Command Line Tools",
|
|
513
|
+
"native": "native",
|
|
514
|
+
"npm": "npm",
|
|
515
|
+
"app": "app",
|
|
516
|
+
"other": "other"
|
|
517
|
+
},
|
|
518
|
+
"state": {
|
|
519
|
+
"unsupported": "not available on this system",
|
|
520
|
+
"missing": "not installed: {{command}}",
|
|
521
|
+
"outdated_auto": "upgrade available: {{command}}",
|
|
522
|
+
"outdated_manual": "upgrade available: {{how}}",
|
|
523
|
+
"latest": "up to date",
|
|
524
|
+
"unknown_latest": "installed"
|
|
525
|
+
},
|
|
526
|
+
"source": "Source: {{source}}",
|
|
527
|
+
"latest_unknown": "Couldn't check the latest version of: {{tools}} (try {{cli}} list --refresh later)",
|
|
528
|
+
"unknown": "Unknown component: {{names}}",
|
|
529
|
+
"known": "Components: {{ids}}",
|
|
530
|
+
"unsupported_platform": "{{tool}} isn't available on this system",
|
|
531
|
+
"blocked_sudo": "Don't install {{tool}} with sudo: it would go into root's home directory and belong to root. Run it again without sudo",
|
|
532
|
+
"blocked_system": "This is the SYSTEM account; {{tool}} would go into the system profile. Run it again signed in as the person who uses it",
|
|
533
|
+
"blocked_unsupported_platform": "{{tool}} isn't available on this system",
|
|
534
|
+
"reason_sudo": "not with sudo",
|
|
535
|
+
"reason_system": "SYSTEM account",
|
|
536
|
+
"reason_unsupported_platform": "not available on this system",
|
|
537
|
+
"no_mirror": "Can't install {{tool}}: no install script location is configured",
|
|
538
|
+
"already_installed": "{{tool}} {{current}} is installed",
|
|
539
|
+
"up_to_date": "{{tool}} {{current}} is up to date",
|
|
540
|
+
"force_hint": "To reinstall it, run {{command}}",
|
|
541
|
+
"outdated_auto": "{{tool}} {{current}} can be upgraded to {{latest}}: run {{command}}",
|
|
542
|
+
"outdated_manual": "{{tool}} {{current}} can be upgraded to {{latest}}. It was installed with {{by}}, which {{cli}} leaves alone: run {{how}}; to add a copy {{cli}} manages, run {{command}}",
|
|
543
|
+
"no_latest": "{{tool}} {{current}} is managed by the system, {{cli}} doesn't upgrade it: {{how}}",
|
|
544
|
+
"how_system": "upgrade it the way it was installed (system package manager or the official installer), or add --force for a copy {{cli}} manages",
|
|
545
|
+
"how_xcode": "update the Command Line Tools in System Settings → General → Software Update",
|
|
546
|
+
"how_other": "upgrade it the way it was installed",
|
|
547
|
+
"force_beside": "{{tool}} is already at {{path}} (installed with {{by}}); --force adds a copy {{cli}} manages",
|
|
548
|
+
"installing": "Installing {{tool}} {{latest}} ({{source}})…",
|
|
549
|
+
"upgrading": "Upgrading {{tool}} to {{latest}} ({{source}})…",
|
|
550
|
+
"script_failed": "{{tool}} wasn't installed; see above. Then run {{command}}",
|
|
551
|
+
"installed": "Installed {{tool}} {{version}}",
|
|
552
|
+
"upgraded": "Upgraded {{tool}} from {{from}} to {{to}}",
|
|
553
|
+
"reinstalled": "Reinstalled {{tool}} {{version}}",
|
|
554
|
+
"reinstalling": "Reinstalling {{tool}} (--force; now {{current}})",
|
|
555
|
+
"path_shadowed": "Your terminal finds {{active}} first, not the {{tool}} {{version}} just installed ({{path}}): put the latter's directory earlier on PATH, or remove the former",
|
|
556
|
+
"capped": "{{tool}} {{latest}} doesn't run on this computer; the install script put in the newest one that does ({{version}}). Upgrades are offered again once a newer version is out",
|
|
557
|
+
"new_terminal": "Open a new terminal window to use it",
|
|
558
|
+
"migrating_globals": "The new Node doesn't have the packages installed globally before; installing the same versions: {{packages}}",
|
|
559
|
+
"migrate_failed": "Not all global packages made it to the new Node; run: {{command}}"
|
|
560
|
+
},
|
|
465
561
|
"install": {
|
|
466
562
|
"permission_unix": "npm probably cannot write its global directory. Either ① sudo {{command}}; or ② run npm config set prefix ~/.npm-global, add export PATH=~/.npm-global/bin:$PATH to ~/.zshrc or ~/.bashrc, open a new terminal and run {{command}}",
|
|
467
563
|
"permission_windows": "Probably missing permissions or a file in use: close the tool if it is running, open an elevated terminal and run {{command}}",
|
|
@@ -851,22 +947,66 @@
|
|
|
851
947
|
"doctor": "Check the common problems first"
|
|
852
948
|
}
|
|
853
949
|
},
|
|
950
|
+
"list": {
|
|
951
|
+
"summary": "List the runtimes, command-line tools and desktop apps {{cli}} can install, and which versions are installed",
|
|
952
|
+
"description": "Lists Node.js, Git, uv, Claude Code, Codex, Grok Build, Antigravity CLI, Claude Desktop and ChatGPT: installed or not, the installed and the latest version, how it was installed and where it comes from. Latest versions are cached for an hour; --refresh checks again now.",
|
|
953
|
+
"when": "To see which tools this computer has and which can be upgraded.",
|
|
954
|
+
"alt": {
|
|
955
|
+
"doctor": "Check the API key and each tool's config"
|
|
956
|
+
},
|
|
957
|
+
"opt": {
|
|
958
|
+
"refresh": "Check the latest versions again instead of using the cache"
|
|
959
|
+
},
|
|
960
|
+
"ex": {
|
|
961
|
+
"all": "List every component",
|
|
962
|
+
"refresh": "Check the latest versions again",
|
|
963
|
+
"json": "JSON output for scripts"
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
"install": {
|
|
967
|
+
"summary": "Install runtimes (Node.js, Git, uv), command-line tools or desktop apps",
|
|
968
|
+
"description": "Installs missing components from China-reachable mirrors, checking checksums (and, for desktop apps, the vendor's signature). One that is already installed is left as it is: its version is shown, with the upgrade command when it is behind; --force reinstalls it.\nNode.js, Git and uv are installed into your own user directory by {{brand}}'s install scripts, no administrator needed; don't use sudo. Several components can be given; what they depend on is installed first.",
|
|
969
|
+
"arg": {
|
|
970
|
+
"components": "node, git, uv, claude-code, codex, grok, agy, claude-desktop, chatgpt; several allowed"
|
|
971
|
+
},
|
|
972
|
+
"opt": {
|
|
973
|
+
"force": "Reinstall even when it is already installed"
|
|
974
|
+
},
|
|
975
|
+
"when": "To add a tool to this computer; other apps' install scripts can call it too (npx {{package}} install …).",
|
|
976
|
+
"needs": "Node.js on this computer ({{cli}} itself runs on Node); without Node, use the one-line installer first",
|
|
977
|
+
"alt": {
|
|
978
|
+
"upgrade": "Upgrade components that are installed",
|
|
979
|
+
"setup": "Then save your API key and configure the tools"
|
|
980
|
+
},
|
|
981
|
+
"ex": {
|
|
982
|
+
"runtimes": "Install Node.js and uv",
|
|
983
|
+
"clis": "Install Claude Code and Codex",
|
|
984
|
+
"app": "Install the ChatGPT desktop app (contains Codex)",
|
|
985
|
+
"force": "Reinstall uv",
|
|
986
|
+
"json": "Install from a script, JSON output"
|
|
987
|
+
}
|
|
988
|
+
},
|
|
854
989
|
"upgrade": {
|
|
855
|
-
"summary": "Upgrade
|
|
856
|
-
"description": "Upgrades each copy the way it was installed: native installs use the tool's own updater, npm installs are reinstalled from the China mirror (npmmirror), Homebrew installs use brew upgrade; if a native or Homebrew upgrade doesn't work, {{brand}}'s install script is used (programs from the China mirror). A named tool that is not installed yet is installed with that script.\nClaude Desktop (macOS / Windows) older than the download site's build
|
|
990
|
+
"summary": "Upgrade coding tools, desktop apps and runtimes (Node.js, Git, uv)",
|
|
991
|
+
"description": "Upgrades each copy the way it was installed: native installs use the tool's own updater, npm installs are reinstalled from the China mirror (npmmirror), Homebrew installs use brew upgrade; if a native or Homebrew upgrade doesn't work, {{brand}}'s install script is used (programs from the China mirror). A named tool that is not installed yet is installed with that script.\nClaude Desktop and ChatGPT (with Codex inside; macOS / Windows) older than the download site's build are upgraded from the official installer there, after checking its checksum and the vendor's (Anthropic / OpenAI) signature; their own auto-update stays on, {{cli}} only steps in when they fall behind. A running app is only closed after a yes at a terminal; with --yes or without a terminal it is left running and only a hint is printed. Add --force to reinstall one that is already the latest. ChatGPT for Mac needs Apple silicon.\nNode.js, Git and uv are only upgraded where {{brand}}'s install scripts manage them (Node under fnm, uv in ~/.local/bin, Git for Windows installed for the current user); a copy from Homebrew, nvm, a system package manager … is left alone and the command that upgrades it is shown; --force adds a copy {{cli}} manages. After fnm's Node is upgraded, the npm packages installed globally before are installed into the new one at the same versions.\nWith nothing named, upgrades every installed coding tool and desktop app, and points out runtimes that are behind.\nTo update {{product}} itself, use {{cli}} update.",
|
|
857
992
|
"arg": {
|
|
858
|
-
"tools": "claude-code, codex, grok, agy, claude-desktop; one or more"
|
|
993
|
+
"tools": "claude-code, codex, grok, agy, claude-desktop, chatgpt, node, git, uv; one or more"
|
|
859
994
|
},
|
|
860
995
|
"ex": {
|
|
861
996
|
"all": "Upgrade every installed tool",
|
|
862
997
|
"one": "Upgrade only Claude Code",
|
|
863
998
|
"many": "Upgrade Codex and Antigravity CLI",
|
|
864
|
-
"desktop": "Install Claude Desktop, or upgrade it to the download site's latest build"
|
|
999
|
+
"desktop": "Install Claude Desktop, or upgrade it to the download site's latest build",
|
|
1000
|
+
"force": "Reinstall ChatGPT even though it is the latest (when the app is broken)",
|
|
1001
|
+
"runtime": "Upgrade Node.js (fnm-managed; otherwise the command that upgrades it)"
|
|
865
1002
|
},
|
|
866
1003
|
"when": "When {{cli}} doctor reports an old version, or the tool's own updater doesn't finish.",
|
|
867
1004
|
"needs": "Without tool names, only installed tools are upgraded",
|
|
868
1005
|
"alt": {
|
|
869
1006
|
"update": "Update {{product}} itself"
|
|
1007
|
+
},
|
|
1008
|
+
"opt": {
|
|
1009
|
+
"force": "Reinstall desktop apps and runtimes that are already the latest; for a runtime installed another way, add a copy {{cli}} manages"
|
|
870
1010
|
}
|
|
871
1011
|
},
|
|
872
1012
|
"refresh": {
|
|
@@ -1061,8 +1201,8 @@
|
|
|
1061
1201
|
"not_installed": "not installed; the download site has {{latest}}",
|
|
1062
1202
|
"outdated": "{{current}} installed, {{latest}} available",
|
|
1063
1203
|
"up_to_date": "{{current}} (latest)",
|
|
1064
|
-
"downloading": "Downloading {{tool}} {{version}} from the download site (about
|
|
1065
|
-
"verifying": "Checking the checksum and
|
|
1204
|
+
"downloading": "Downloading {{tool}} {{version}} from the download site (about {{size}} MB)…",
|
|
1205
|
+
"verifying": "Checking the checksum and {{vendor}}'s signature…",
|
|
1066
1206
|
"installing": "Installing…",
|
|
1067
1207
|
"already_latest": "{{tool}} is up to date ({{current}})",
|
|
1068
1208
|
"latest_unknown": "Couldn't look up the latest {{tool}}: {{reason}}",
|
|
@@ -1070,13 +1210,15 @@
|
|
|
1070
1210
|
"offer_quit": "Quit {{tool}} and upgrade to {{latest}}?",
|
|
1071
1211
|
"declined_hint": "Not upgraded. Run {{command}} later",
|
|
1072
1212
|
"quit_failed": "Couldn't quit {{tool}}, so it wasn't upgraded: quit it yourself, then run {{command}}",
|
|
1213
|
+
"quit_confirm_in_app": "{{tool}} didn't quit: it may have a task running or be asking you to confirm. Switch to {{tool}} and confirm the quit there (or quit it once the task is done); the upgrade goes on here (waiting up to {{seconds}} s)…",
|
|
1214
|
+
"quit_refused": "{{tool}} didn't quit, so it wasn't upgraded: it has a task running or is waiting for you to confirm. Confirm the quit in {{tool}} (or quit it once the task is done), then run {{command}}",
|
|
1073
1215
|
"upgraded": "Upgraded {{tool}} from {{from}} to {{to}}",
|
|
1074
1216
|
"installed": "Installed {{tool}} {{version}}",
|
|
1075
1217
|
"upgrade_failed": "Couldn't upgrade {{tool}}: {{reason}}. {{current}} still works; fix the cause, then run {{command}}",
|
|
1076
1218
|
"install_failed": "Couldn't install {{tool}}: {{reason}}. Fix the cause, then run {{command}}",
|
|
1077
|
-
"blocked_unsupported_platform": "On this computer, install {{tool}} from
|
|
1078
|
-
"blocked_no_mirror": "Install {{tool}} from
|
|
1079
|
-
"blocked_classic_install": "This computer has the classic installer build of {{tool}}, which {{cli}} doesn't replace: check for updates in {{tool}}, or uninstall it and run {{
|
|
1219
|
+
"blocked_unsupported_platform": "On this computer, install {{tool}} from {{url}}",
|
|
1220
|
+
"blocked_no_mirror": "Install {{tool}} from {{url}}",
|
|
1221
|
+
"blocked_classic_install": "This computer has the classic installer build of {{tool}}, which {{cli}} doesn't replace: check for updates in {{tool}}, or uninstall it and run {{command}} to get the current build",
|
|
1080
1222
|
"reason_unsupported_platform": "there is no installer for this system",
|
|
1081
1223
|
"reason_no_mirror": "no download site is configured",
|
|
1082
1224
|
"reason_classic_install": "the classic installer build is installed",
|
|
@@ -1084,11 +1226,32 @@
|
|
|
1084
1226
|
"error_download": "download failed ({{reason}})",
|
|
1085
1227
|
"error_no_checksum": "the download site has no checksum for {{file}}",
|
|
1086
1228
|
"error_checksum": "{{file}} has the wrong checksum (expected {{expected}}…, got {{actual}}…); the download was deleted",
|
|
1087
|
-
"error_signature": "the package
|
|
1229
|
+
"error_signature": "the package's signature is wrong or broken ({{reason}}); nothing was installed",
|
|
1088
1230
|
"error_mount": "couldn't open the package ({{reason}})",
|
|
1089
1231
|
"error_bad_package": "the package has no {{reason}}",
|
|
1090
1232
|
"error_no_permission": "no permission to write {{path}}: run as an administrator, or give {{path}} to this user",
|
|
1091
1233
|
"error_copy": "copying the app failed ({{reason}})",
|
|
1092
|
-
"error_install": "the system installer failed ({{reason}})"
|
|
1234
|
+
"error_install": "the system installer failed ({{reason}})",
|
|
1235
|
+
"blocked_unsupported_arch": "{{tool}} is only built for Apple silicon Macs; this Mac can't run it",
|
|
1236
|
+
"reason_unsupported_arch": "there is no installer for this chip",
|
|
1237
|
+
"reason_unknown": "reason unknown",
|
|
1238
|
+
"blocked_other_app": "The ChatGPT.app in Applications is another app (the earlier ChatGPT without Codex), which {{cli}} doesn't replace: remove or rename it, then run {{command}}",
|
|
1239
|
+
"reason_other_app": "another app with the same name is in the way",
|
|
1240
|
+
"blocked_root": "Don't install {{tool}} with sudo: the app would belong to root and its own updates would fail. Run {{command}} as your usual account",
|
|
1241
|
+
"blocked_system_account": "This is the system account (SYSTEM); {{tool}} would be installed for no real user. Sign in as the account that uses it and run {{command}}",
|
|
1242
|
+
"reason_root": "it can't be installed with sudo",
|
|
1243
|
+
"reason_system_account": "this is the system account (SYSTEM)",
|
|
1244
|
+
"error_app_management": "macOS doesn't let this terminal replace {{path}}: allow it under System Settings → Privacy & Security → App Management, or check for updates in the app",
|
|
1245
|
+
"upgrade_offer": "Upgrade {{tool}} from {{current}} to {{latest}}?",
|
|
1246
|
+
"upgrade_hint": "{{tool}} is at {{current}}, {{latest}} is available: run {{command}}",
|
|
1247
|
+
"reinstalling": "Reinstalling {{tool}} {{latest}} (--force; current {{current}})",
|
|
1248
|
+
"reinstalled": "Reinstalled {{tool}} {{version}}",
|
|
1249
|
+
"force_hint": "To reinstall it, run {{command}} --force",
|
|
1250
|
+
"blocked_remote_session": "This is a remote (SSH) session, where Windows doesn't allow installing {{tool}}: run {{command}} in a terminal on this computer",
|
|
1251
|
+
"reason_remote_session": "Windows apps can't be installed from a remote (SSH) session",
|
|
1252
|
+
"error_needs_admin": "Windows requires administrator rights for this install (0x80073D28); right-click PowerShell, choose \"Run as administrator\" and run it there",
|
|
1253
|
+
"error_other_account": "the prompt was approved with another administrator account, so the app was installed for that account: approve with the current account (make it an administrator), or use the app from that account",
|
|
1254
|
+
"elevate_offer": "Windows requires administrator rights to install {{tool}}. Show the permission prompt now?",
|
|
1255
|
+
"elevating": "Requesting administrator rights: click Yes in the Windows prompt…"
|
|
1093
1256
|
}
|
|
1094
1257
|
}
|