@vibeapi/api-helper 0.0.124 → 0.0.126
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/dist/commands/auth.js +1 -1
- package/dist/commands/base.js +1 -1
- package/dist/commands/bench.js +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/logs.js +1 -1
- package/dist/commands/refresh.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/lib/codex-sessions.d.ts +1 -1
- package/dist/lib/codex-sessions.js +1 -1
- package/dist/lib/command.js +1 -1
- package/dist/lib/model-refresh.d.ts +5 -0
- package/dist/lib/model-refresh.js +1 -1
- package/dist/lib/post-apply.js +1 -1
- package/dist/lib/program.js +1 -1
- package/dist/lib/runtime-options.d.ts +2 -0
- package/dist/lib/runtime-options.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/codex.d.ts +3 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/wizard.js +1 -1
- package/dist/locales/en_US.json +56 -116
- package/dist/locales/zh_CN.json +55 -115
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as a}from"path";import{randomUUID as l}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import p from"chalk";import{logger as u}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m}from"./claude-desktop-cli.js";import{i18n as g}from"../i18n.js";import{BRAND_NAME as y,brand as h,brandEnv as k,CLI_NAME as _}from"../brand.js";import{backupBeforeWrite as b,atomicWriteFile as D}from"./backup.js";import{toolHome as A}from"./types.js";import{canRestartDesktop as C,isDesktopRunning as w,restartDesktop as E,WINDOWS_PACKAGE_FAMILIES as M}from"./desktop-process.js";import{setUserRegistryElevated as v}from"./elevated-reg.js";import{UserActionNeeded as O}from"./types.js";import{baseModelId as x,isClaudeModel as S}from"../model-catalog.js";import{getDefaultModels as P}from"../model-registry.js";const j=y;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const L=/^[a-f0-9-]{36}$/;function I(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=A(),n=Boolean(k("TEST_HOME")?.trim());switch(process.platform){case"darwin":return a(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(o,"AppData","Local");return M.map(t=>a(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??a(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:a(o,".config");return a(e,"Claude-3p")}}}const T=()=>a(claudeDesktopUserDataDir(),"configLibrary"),$=()=>a(T(),"_meta.json"),R=e=>a(T(),`${e}.json`),G=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function N(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return I(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed, back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function U(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),b(n),D(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function K(){const e=N($());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>I(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function F(e){return e?.entries.find(e=>e.name===j&&L.test(e.id))}const H={opus:0,fable:1,sonnet:2,haiku:3};function B(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=B(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function V(e){return B(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>x(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(S)){i=[...new Set(t.models.filter(S).map(x))];for(const e of t.oneMillion)r.add(e)}else{i=[];for(const t of["opus","sonnet","haiku","reasoning"]){const o=(e[t]||"").trim(),n=x(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>H[V(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=a(e)-a(t);if(0!==n)return n;const r=B(e),s=B(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const l=new Set,c=new Map,d=new Set(Object.values(P()).map(e=>x(e||"")));for(const e of n){const t=V(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=V(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||l.has(t)||(o.isFamilyDefault=!0,l.add(t))}return o})}let W=null,J=null,z=null,Z=null;function q(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const X={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}};function Y(e){return Object.fromEntries(Object.entries(X).filter(([t])=>!e(t)))}const Q="SOFTWARE\\Policies\\Claude",ee=`HKCU\\${Q}`,te="HKLM\\SOFTWARE\\Policies\\Claude",oe=`${_}-claude-policy.reg`,ne=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let re=ne;export function setRegRunnerForTests(e){re=e??ne}function se(){return"win32"===process.platform}function ie(e){let t;try{t=re(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function ae(){if(null===ie(ee))return;const e=a(claudeDesktopUserDataDir(),oe);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),b(e),re(["export",ee,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function le(e){ae();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];re(["add",ee,"/v",t,"/t",e,"/d",n,"/f"])}}function ce(e){const t=ie(ee);if(!t)return;ae();let o=t.size;for(const n of e)t.has(n)&&(re(["delete",ee,"/v",n,"/f"]),o-=1);o<=0&&re(["delete",ee,"/f"])}const de=[...Object.keys(q({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(X)];export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return ie(te)?te:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return u.logError("claude-desktop.detectManagedConfig",e),null}}function pe(){const e=A();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",a(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||a(e,"AppData","Local");o=[a(t,"AnthropicClaude"),a(t,"Programs","Claude"),...M.map(e=>a(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",a(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),a(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const ue=/\d+\.\d+\.\d+/;function fe(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}function me(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",a(A(),"Applications","Claude.app")]){const o=a(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?ue.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(A(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return fe(t)}const o=M.map(e=>`'${e}'`).join(",");return fe(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"]}).split(/\r?\n/).flatMap(e=>ue.exec(e)?.[0]??[]))}if("linux"===process.platform)try{const e=c("dpkg-query",["-W","-f=${Version}","claude-desktop"],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]});return ue.exec(e)?.[0]??null}catch{return null}return null}const ge="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",ye="darwin"!==process.platform&&"win32"!==process.platform||!h().installMirror?.claudeDesktop?"https://claude.ai/download":h().installMirror.claudeDesktop,he="darwin"===process.platform?`open ${ye}`:"win32"===process.platform?`start ${ye}`:`xdg-open ${ye}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:ge,installCommand:he,configPath:$(),isInstalled:pe,installedVersion:me,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!pe())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+g.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?me():null,mirrorRepo:h().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null});return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:g.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return u.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:g.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:w,restart:E}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const o=K()??{appliedId:"",entries:[]};let n=F(o);n||(n={id:l(),name:j},o.entries.push(n));const r=q(e);J=!0===r.disableDeploymentModeChooser,W={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=N(R(n.id))??{};U(R(n.id),{...Y(e=>e in s),...s,...r}),o.appliedId=n.id,U($(),o);const i=N(G())??{};if("3p"!==i.deploymentMode&&U(G(),{...i,deploymentMode:"3p"}),z=null,Z=null,se()){const o=ie(ee),n=de.filter(e=>o?.has(e)),s={...Y(e=>o?.has(e)??!1),...r},i=!0===e.settings?.force_registry,l=!i&&function(){const e=!Boolean(k("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(A(),"AppData","Local");return!!t(a(e,"AnthropicClaude"))||M.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{l?ce(de):le(s)}catch(e){u.logError("claude-desktop.policy",e),z=e instanceof Error?e.message.trim():String(e),(n.length>0||i)&&(Z=l?{action:"remove",values:Object.fromEntries(n.map(e=>[e,null])),deleteKey:n.length===o.size}:{action:"write",values:s,deleteKey:!1})}}},pendingElevation(){const e=Z;return e?{prompt:g.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!v(Q,e.values,e.deleteKey))return!1;const t=ie(ee),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(Z=null,z=null),o}}:null},unloadPrivateConfig(){if(se())try{ce(de)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=K(),t=F(e);if(!e||!t)return;b(R(t.id)),s(R(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(b($()),s($(),{force:!0})):U($(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=K(),t=F(e);if(!t||e?.appliedId!==t.id)return null;const o=N(R(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=K(),o=F(t);if(!o||t?.appliedId!==o.id)return;const n=N(R(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(se()&&ie(ee)?.has("inferenceModels"))try{le({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),new O(g.t("tools.claude_desktop.refresh_needs_admin"))}U(R(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(se()){const e=ie(ee)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=F(K());if(!e)return{apiKey:null};const t=N(R(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return u.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=K(),t=F(e);return{meta:e,applied:t?N(R(t.id)):null,desktop:N(G()),...se()?{policy:Object.fromEntries(ie(ee)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;se()&&ie(ee)?.has("inferenceModels")&&(ae(),re(["delete",ee,"/v","inferenceModels","/f"]),e=!0);const t=F(K()),o=t?N(R(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;U(R(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(W&&W.models.length>0){const{models:t,source:o,groups:n}=W;e.push({kind:"summary",text:g.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:g.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==J&&e.push({kind:"detail",text:g.t(J?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!w()||e.push({kind:"action",text:g.t("tools.claude_desktop.restart_hint")}),Z?(e.push({kind:"action",text:g.t(`tools.claude_desktop.policy_stale_${Z.action}`)}),e.push({kind:"detail",text:z??""})):z?(e.push({kind:"detail",text:g.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:z})):se()&&e.push({kind:"detail",text:g.t("tools.claude_desktop.registry_written",{key:ee})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:g.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[$(),G()];try{const t=F(K());t&&e.push(R(t.id))}catch{}return e},backupPaths(){const e=[$(),G()];se()&&e.push(a(claudeDesktopUserDataDir(),oe));try{const t=F(K());t&&e.push(R(t.id))}catch{}return e}};
|
|
1
|
+
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as a}from"path";import{randomUUID as l}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import p from"chalk";import{logger as u}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m}from"./claude-desktop-cli.js";import{i18n as g}from"../i18n.js";import{BRAND_NAME as y,brand as h,brandEnv as k,CLI_NAME as _}from"../brand.js";import{backupBeforeWrite as b,atomicWriteFile as D}from"./backup.js";import{toolHome as A}from"./types.js";import{canRestartDesktop as C,isDesktopRunning as w,restartDesktop as E,WINDOWS_PACKAGE_FAMILIES as M}from"./desktop-process.js";import{setUserRegistryElevated as v}from"./elevated-reg.js";import{UserActionNeeded as O}from"./types.js";import{baseModelId as x,isClaudeModel as S}from"../model-catalog.js";import{getDefaultModels as P}from"../model-registry.js";const j=y;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const L=/^[a-f0-9-]{36}$/;function I(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=A(),n=Boolean(k("TEST_HOME")?.trim());switch(process.platform){case"darwin":return a(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(o,"AppData","Local");return M.map(t=>a(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??a(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:a(o,".config");return a(e,"Claude-3p")}}}const T=()=>a(claudeDesktopUserDataDir(),"configLibrary"),$=()=>a(T(),"_meta.json"),R=e=>a(T(),`${e}.json`),G=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function N(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return I(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed, back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function U(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),b(n),D(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function K(){const e=N($());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>I(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function F(e){return e?.entries.find(e=>e.name===j&&L.test(e.id))}const H={opus:0,fable:1,sonnet:2,haiku:3};function B(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=B(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function V(e){return B(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>x(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(S)){i=[...new Set(t.models.filter(S).map(x))];for(const e of t.oneMillion)r.add(e)}else{i=[];for(const t of["opus","sonnet","haiku","reasoning"]){const o=(e[t]||"").trim(),n=x(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>H[V(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=a(e)-a(t);if(0!==n)return n;const r=B(e),s=B(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const l=new Set,c=new Map,d=new Set(Object.values(P()).map(e=>x(e||"")));for(const e of n){const t=V(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=V(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||l.has(t)||(o.isFamilyDefault=!0,l.add(t))}return o})}let W=null,J=null,z=null,Z=null,q=null;function X(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const Y={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}};function Q(e){return Object.fromEntries(Object.entries(Y).filter(([t])=>!e(t)))}const ee="SOFTWARE\\Policies\\Claude",te=`HKCU\\${ee}`,oe="HKLM\\SOFTWARE\\Policies\\Claude",ne=`${_}-claude-policy.reg`,re=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let se=re;export function setRegRunnerForTests(e){se=e??re}function ie(){return"win32"===process.platform}function ae(e){let t;try{t=se(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function le(){if(null===ae(te))return;const e=a(claudeDesktopUserDataDir(),ne);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),b(e),se(["export",te,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function ce(e){le();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];se(["add",te,"/v",t,"/t",e,"/d",n,"/f"])}}function de(e){const t=ae(te);if(!t)return;le();let o=t.size;for(const n of e)t.has(n)&&(se(["delete",te,"/v",n,"/f"]),o-=1);o<=0&&se(["delete",te,"/f"])}const pe=[...Object.keys(X({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(Y)];export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return ae(oe)?oe:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return u.logError("claude-desktop.detectManagedConfig",e),null}}function ue(){const e=A();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",a(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||a(e,"AppData","Local");o=[a(t,"AnthropicClaude"),a(t,"Programs","Claude"),...M.map(e=>a(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",a(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),a(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const fe=/\d+\.\d+\.\d+/;function me(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}function ge(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",a(A(),"Applications","Claude.app")]){const o=a(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?fe.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(A(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return me(t)}const o=M.map(e=>`'${e}'`).join(",");return me(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"]}).split(/\r?\n/).flatMap(e=>fe.exec(e)?.[0]??[]))}if("linux"===process.platform)try{const e=c("dpkg-query",["-W","-f=${Version}","claude-desktop"],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]});return fe.exec(e)?.[0]??null}catch{return null}return null}const ye="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",he="darwin"!==process.platform&&"win32"!==process.platform||!h().installMirror?.claudeDesktop?"https://claude.ai/download":h().installMirror.claudeDesktop,ke="darwin"===process.platform?`open ${he}`:"win32"===process.platform?`start ${he}`:`xdg-open ${he}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:ye,installCommand:ke,configPath:$(),isInstalled:ue,installedVersion:ge,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!ue())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+g.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?ge():null,mirrorRepo:h().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null});return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:g.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return u.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:g.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:w,restart:E}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const o=K()??{appliedId:"",entries:[]};let n=F(o);n||(n={id:l(),name:j},o.entries.push(n));const r=X(e);J=!0===r.disableDeploymentModeChooser,W={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=N(R(n.id))??{};U(R(n.id),{...Q(e=>e in s),...s,...r}),o.appliedId=n.id,U($(),o);const i=N(G())??{};if("3p"!==i.deploymentMode&&U(G(),{...i,deploymentMode:"3p"}),Z=null,q=null,z=null,ie()){const o=ae(te),n=pe.filter(e=>o?.has(e)),s={...Q(e=>o?.has(e)??!1),...r},i=!0===e.settings?.force_registry,l=!i&&function(){const e=!Boolean(k("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(A(),"AppData","Local");return!!t(a(e,"AnthropicClaude"))||M.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{l?de(pe):ce(s),z=l?"removed":"written"}catch(e){u.logError("claude-desktop.policy",e),Z=e instanceof Error?e.message.trim():String(e),(n.length>0||i)&&(q=l?{action:"remove",values:Object.fromEntries(n.map(e=>[e,null])),deleteKey:n.length===o.size}:{action:"write",values:s,deleteKey:!1})}}},pendingElevation(){const e=q;return e?{prompt:g.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!v(ee,e.values,e.deleteKey))return!1;const t=ae(te),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(q=null,Z=null),o}}:null},unloadPrivateConfig(){if(ie())try{de(pe)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=K(),t=F(e);if(!e||!t)return;b(R(t.id)),s(R(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(b($()),s($(),{force:!0})):U($(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=K(),t=F(e);if(!t||e?.appliedId!==t.id)return null;const o=N(R(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=K(),o=F(t);if(!o||t?.appliedId!==o.id)return;const n=N(R(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(ie()&&ae(te)?.has("inferenceModels"))try{ce({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),new O(g.t("tools.claude_desktop.refresh_needs_admin"))}U(R(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(ie()){const e=ae(te)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=F(K());if(!e)return{apiKey:null};const t=N(R(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return u.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=K(),t=F(e);return{meta:e,applied:t?N(R(t.id)):null,desktop:N(G()),...ie()?{policy:Object.fromEntries(ae(te)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;ie()&&ae(te)?.has("inferenceModels")&&(le(),se(["delete",te,"/v","inferenceModels","/f"]),e=!0);const t=F(K()),o=t?N(R(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;U(R(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(W&&W.models.length>0){const{models:t,source:o,groups:n}=W;e.push({kind:"summary",text:g.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:g.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==J&&e.push({kind:"detail",text:g.t(J?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!w()||e.push({kind:"action",text:g.t("tools.claude_desktop.restart_hint")}),q?(e.push({kind:"action",text:g.t(`tools.claude_desktop.policy_stale_${q.action}`)}),e.push({kind:"detail",text:Z??""})):Z?(e.push({kind:"detail",text:g.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:Z})):ie()&&z&&e.push({kind:"detail",text:g.t(`tools.claude_desktop.registry_${z}`,{key:te})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:g.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[$(),G()];try{const t=F(K());t&&e.push(R(t.id))}catch{}return e},backupPaths(){const e=[$(),G()];ie()&&e.push(a(claudeDesktopUserDataDir(),ne));try{const t=F(K());t&&e.push(R(t.id))}catch{}return e}};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type ToolAdapter } from './types.js';
|
|
2
2
|
import type { ModelCatalog } from '../model-catalog.js';
|
|
3
3
|
import { type CatalogRejection } from './codex-catalog.js';
|
|
4
|
-
/** The desktop app is in ChatGPT Work mode,
|
|
4
|
+
/** The desktop app is in ChatGPT Work mode on our key, where it may refuse to start a thread. */
|
|
5
5
|
export declare function codexWorkModeOn(): boolean;
|
|
6
|
+
/** Where Codex reads its config, for messages that name the file. */
|
|
7
|
+
export declare function codexConfigPath(): string;
|
|
6
8
|
export declare const CODEX_ONE_MILLION_CONTEXT_SETTING = "one_million_context";
|
|
7
9
|
/** For doctor: a local Codex that cannot load the catalog `config.toml` points at (checked afresh, no cache). */
|
|
8
10
|
export declare function codexCatalogRejection(): CatalogRejection | null;
|
package/dist/lib/tools/codex.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,
|
|
1
|
+
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as i,statSync as s,writeFileSync as l}from"fs";import{join as a}from"path";import*as c from"@iarna/toml";import{logger as d}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{backupBeforeWrite as m,atomicWriteFile as p}from"./backup.js";import{codexHome as f,pickModel as g,toolHome as _,withV1 as x}from"./types.js";import{moveSessionsToProvider as h,NO_STATE_DB as y,runningCodexPids as k}from"../codex-sessions.js";import{getToolDefaultModel as b}from"../model-registry.js";import{configManager as v}from"../config.js";import{maskHome as w,track as j}from"../telemetry.js";import{buildCodexCatalog as C,catalogRejections as O,codexCatalogPath as S,fillFromOlderEntries as M,installedCodexBinaries as A,loadBundledCodexModels as E,loadPreviousCodexModels as N,previousGatewayModelIds as P}from"./codex-catalog.js";import{gatewayModelSpecs as T,modelFamily as D}from"../gateway-models.js";import{findInstalls as I,mirrorInstallCommand as L,brandInstallScripts as $}from"./tool-installs.js";const J=()=>f(),G=()=>a(J(),"config.toml"),R="sessions_move_declined",K=["browser_use","browser_use_external","computer_use"];function X(e){const t=e.features;if(!F(t)||!K.every(e=>!1===t[e]))return!1;for(const e of K)delete t[e];return!0}export function codexWorkModeOn(){try{const e=Q();return e.model_provider===U&&F(e.desktop)&&"STEPS_PROSE"===e.desktop.conversationDetailMode}catch{return!1}}function B(){try{if(F(Q().desktop))return!0}catch{}if("darwin"===process.platform)return["/Applications",a(_(),"Applications")].some(e=>["ChatGPT.app","Codex.app"].some(o=>t(a(e,o))));if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(_(),"AppData","Local"),"Packages");try{return n(e).some(e=>/^OpenAI\.(Codex|ChatGPT)/i.test(e))}catch{return!1}}return t("/usr/lib/chatgpt/ChatGPT")}export function codexConfigPath(){return G()}const W=()=>a(J(),"auth.json"),q="OPENAI_API_KEY",U="custom",z=1e6,Y=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function F(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function H(e,t){return F(e[t])||(e[t]={}),e[t]}function Q(){if(!t(G()))return{};const e=r(G(),"utf-8");if(!e.trim())return{};try{const t=c.parse(e);if(!F(t))throw new Error("config.toml root must be a TOML table");return t}catch(e){throw new Error(`Existing ~/.codex/config.toml cannot be parsed, back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function V(){if(!t(W()))return{};try{const e=JSON.parse(r(W(),"utf-8"));return F(e)?e:{}}catch{return{}}}let Z=null;function ee(e){const t=e.profiles;if(F(t)){for(const[e,o]of Object.entries(t))F(o)&&2===Object.keys(o).length&&o.model_provider===U&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let te=null;const oe=()=>a(v.getConfigDir(),"codex-catalog-check.json");function ne(e){const o=S();t(o)&&r(o,"utf-8")===e||(m(o),p(o,e))}function re(t,n){if(0===n.length)return[];const i=function(t,o){const n=e("sha256").update(t);for(const e of o)try{const t=s(e);n.update(`\0${e}\0${t.size}\0${t.mtimeMs}`)}catch{n.update(`\0${e}`)}return n.digest("hex")}(t,n);if(function(e){try{return JSON.parse(r(oe(),"utf-8")).signature===e}catch{return!1}}(i))return[];const a=O(S(),n);return 0===a.length&&function(e){try{o(v.getConfigDir(),{recursive:!0}),l(oe(),JSON.stringify({signature:e})+"\n")}catch(e){d.logError("codexAdapter.rememberAccepted",e)}}(i),a}function ie(e,t,o){const n=!1!==t.settings?.one_million_context;!function(e){e.model_context_window===z&&delete e.model_context_window,e.model_auto_compact_token_limit===Y&&delete e.model_auto_compact_token_limit}(e);const r=()=>{e.model_catalog_json===S()&&delete e.model_catalog_json,n&&(e.model_context_window=z,e.model_auto_compact_token_limit=Y)},s=E()??N();if(!s)return d.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),te="skipped",void r();const l=t.catalog,a=e=>C({bundled:e,specs:T("codex",l?.clientModels),...l?{keyModels:l.models}:{},gatewayAvailable:l?.models??P(),oneMillion:n,selectedModel:o,..."gateway"===l?.oneMillionSource?{claudeOneMillion:l.oneMillion}:{}}),c=e=>JSON.stringify(e,null,2)+"\n";let u=a(s);ne(c(u));const m=A(),p=re(c(u),m);if(p.length>0){const e=Date.now();let t=!1;for(const e of p){const o=E(e.bin);if(o){for(const e of[{models:M(u.models,o)},{models:M(a(o).models,o)}])if(ne(c(e)),0===re(c(e),m).length){u=e,t=!0;break}if(t)break}}if(j("codex-catalog",t?"fallback":"fail",{duration_ms:Date.now()-e,error:p[0].error,detail:{rejected_by:p.map(e=>({version:e.version,path:w(e.bin)}))}}),!t)return te={rejectedBy:p[0]},i(S(),{force:!0}),void r()}te={listed:u.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))},e.model_catalog_json=S()}export function codexCatalogRejection(){let e;try{e=Q()}catch{return null}return e.model_catalog_json===S()&&t(S())?O(S())[0]??null:null}export function setCodexOneMillionContext(e,t){const o=Q(),n=c.stringify(o),r="string"==typeof o.model?o.model:b("codex");ie(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},r);const i=c.stringify(o);i!==n&&(m(G()),p(G(),i))}const se={command:"codex",npmPackage:"@openai/codex",native:{binDir:"win32"===process.platform?["AppData","Local","Programs","OpenAI","Codex","bin"]:[".local","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".codex","packages","standalone"]]},mirrorScript:$("codex"),brew:"codex"};export const codexAdapter={name:"codex",displayName:"Codex",command:"codex",installCommand:L(se),installSpec:se,configPath:G(),wantsModelCatalog:!0,listedModels(){if(Q().model_catalog_json!==S())return null;try{return(JSON.parse(r(S(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){if(Q().model_catalog_json!==S())return;setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog);const t=Q();X(t)&&(m(G()),p(G(),c.stringify(t)))},async followUp(){if(Q().model_provider!==U)return null;const e=await h(U,{dryRun:!0}),t=Math.max(e.moved.length,e.dbRows);if(0===t)return null;const o=v.getToolSettings("codex")[R];if("number"==typeof o&&t<=o)return null;const n={count:String(t)};return k().length>0?{hint:u.t("tools.codex.sessions_hidden_running",n)}:{prompt:u.t("tools.codex.sessions_offer",n),hint:u.t("tools.codex.sessions_hidden",n),async run(){const e=await h(U),t=[...new Set(e.moved.map(e=>e.from))].join("、")||"-",o=String(Math.max(e.moved.length,e.dbRows)),n=[{kind:"summary",text:u.t("codex_sessions.moved",{count:o,from:t,target:U})},{kind:"summary",text:u.t("codex_sessions.backup",{dir:e.backupDir??""})}];return e.dbSkipped&&e.dbSkipped!==y&&n.push({kind:"action",text:u.t("codex_sessions.db_skipped",{reason:e.dbSkipped})}),n},decline(){v.setToolSetting("codex",R,t)}}},applyNotes(){if("skipped"===te)return 0===I(se).length?[]:[{kind:"action",text:u.t("tools.codex.catalog_skipped")}];if(!te)return[];if("rejectedBy"in te){const{bin:e,version:t}=te.rejectedBy;return[{kind:"action",text:u.t("tools.codex.catalog_rejected",{path:e,version:t??"?"})}]}const e=new Map;for(const t of te.listed)e.set(D(t.id),(e.get(D(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${u.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:u.t("tools.codex.catalog_written",{count:String(te.listed.length),breakdown:t})},{kind:"detail",text:te.listed.map(e=>e.name).join(", ")},...codexWorkModeOn()||B()?[{kind:"action",text:u.t(codexWorkModeOn()?"tools.codex.work_mode_on":"tools.codex.work_mode_hint")}]:[]]},loadPrivateConfig(e){const t=b("codex"),o=g(e.models,t),n=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,r=x(e.baseUrl),i=Q();i.model=n,i.model_provider=U,i.model_reasoning_effort="high",ie(i,e,n);const s=H(i,"model_providers"),l=F(s[U])?{...s[U]}:{};delete l.env_key;const{experimental_bearer_token:a,...d}=l;s[U]={...d,name:"custom",wire_api:"responses",requires_openai_auth:!0,base_url:r},ee(i),H(H(i,"tui"),"model_availability_nux")[n]=4;const u=H(i,"features");u.goals=!0,u.js_repl=!1,X(i),m(G()),p(G(),c.stringify(i)),function(e){const t=e.trim();if(!t)return;const o={...V(),auth_mode:"apikey",[q]:t};m(W()),p(W(),JSON.stringify(o,null,2)+"\n",384)}(e.apiKey)},unloadPrivateConfig(e){if(Z=function(e){const t=V(),o="string"==typeof t[q]?t[q].trim():"";if(!o)return F(t.tokens)?"chatgpt":null;if(!e.includes(o))return"other_key";const{[q]:n,auth_mode:r,...s}=t;return m(W()),F(s.tokens)?(p(W(),JSON.stringify({...s,auth_mode:"chatgpt"},null,2)+"\n",384),"chatgpt"):(i(W(),{force:!0}),"signed_out")}(e?.savedKeys??[]),!t(G()))return;let o;try{o=Q()}catch(e){return void d.logError("codexAdapter.unloadPrivateConfig",e)}const n=o.model_providers;F(n)&&(delete n[U],0===Object.keys(n).length&&delete o.model_providers),o.model_provider===U&&delete o.model_provider,o.model_catalog_json===S()&&delete o.model_catalog_json,X(o),ee(o),m(G()),p(G(),c.stringify(o))},unloadNotes(){switch(Z){case"chatgpt":return[{kind:"action",text:u.t("tools.codex.unload_chatgpt_restored")}];case"other_key":return[{kind:"action",text:u.t("tools.codex.unload_other_key")}];default:return[{kind:"action",text:u.t("tools.codex.unload_sign_in")}]}},detectCurrentConfig(){const e=V()[q];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return Q()}catch(e){return d.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[G(),W(),S()]};export function codexAuthProblem(){try{const e=Q(),t=e.model_providers?.[U];if(e.model_provider!==U||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=V();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
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{postApplyPrompts as d}from"./post-apply.js";import{i18n as p,detectSystemLang as m}from"./i18n.js";import{createBorderLine as u,createContentLine as _}from"../utils/string-width.js";import{validateApiKey as g,fetchModels as w}from"./api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as f}from"./tools/codex.js";import{CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as y}from"./tools/claude-desktop.js";import{addressesWithCurrent as h,ensureReachableGatewayAddress as z,fastestIndex as v,probeAll as k,probeSummary as x,reasonText as b,savedApiKey as S,switchGatewayAddress as C}from"../commands/base.js";import{readFileSync as M}from"fs";import{dirname as T,join as A}from"path";import{fileURLToPath as K}from"url";import{brand as N}from"./brand.js";const B=T(K(import.meta.url)),H=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(H.bold("\n"+u("╔","╗","═",this.BOX_WIDTH))),console.log(H.bold(_(e,"║","║",this.BOX_WIDTH,"center"))),console.log(H.bold(u("╚","╝","═",this.BOX_WIDTH))),console.log("")}showOperationHints(){const e=[t.gray(p.t("wizard.hint_navigate")),t.gray(p.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=p.t("wizard.banner_subtitle"),a=_(t,"║","║",e,"center"),o=_("","║","║",e,"center"),i=_(`${N().productName} v${function(){try{return JSON.parse(M(A(B,"..","..","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=>_(s+t,"║","║",e,"left")),c=[u("╔","╗","═",e),o,...l,o,i,a,u("╚","╝","═",e)];console.log(H.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=p.t("wizard.goodbye_message_tools",{commands:t}),e.some(e=>"claude-code"===e.name)&&(a+=" "+p.t("wizard.goodbye_claude_hint"))}else a=p.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(" ! "+p.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:o})))}async runFirstTimeSetup(){const e="zh_CN"===m();e&&(o.setLang("zh_CN"),p.setLocale("zh_CN")),this.resetScreen(),console.log(H.bold("\n"+p.t("wizard.welcome"))),console.log(t.gray(p.t("wizard.privacy_note")+"\n")),e?console.log(t.gray(p.t("wizard.lang_auto_zh")+"\n")):await this.configLanguage(),await z(),await this.configApiKey()&&await this.selectAndConfigureTool(!0)}async configLanguage(){for(;;){this.resetScreen(),this.createBox(p.t("wizard.select_language"));const a=p.getLocale(),{language:i}=await this.promptWithHints([{type:"list",name:"language",message:"✨ "+p.t("wizard.select_language"),choices:[{name:"[EN] English"+("en_US"===a?t.green(" ✓ ("+p.t("wizard.current_active")+")"):""),value:"en_US"},{name:"[CN] 中文"+("zh_CN"===a?t.green(" ✓ ("+p.t("wizard.current_active")+")"):""),value:"zh_CN"},new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"back"},{name:"x "+p.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 p.setLocale(i)}}buildPresetChoices(){const a=n(),o=a.filter(e=>e.recommended),i=a.filter(e=>!e.recommended),r=e=>({name:(p.t(e.name)!==e.name?p.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")("── "+p.t("wizard.recommended")+" ──"))),s.push(...o.map(r))),i.length>0&&(s.push(new e.Separator(t.gray("── "+p.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:p.t("wizard.custom_model_mode"),choices:[{name:p.t("wizard.custom_model_single"),value:"single"},{name:p.t("wizard.custom_model_per_role"),value:"per_role"}]}]);if("single"===n){const{customModel:t}=await e.prompt([{type:"input",name:"customModel",message:p.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:p.t("wizard.model_haiku"),default:a.haiku},{type:"input",name:"sonnet",message:p.t("wizard.model_sonnet"),default:a.sonnet},{type:"input",name:"opus",message:p.t("wizard.model_opus"),default:a.opus},{type:"input",name:"reasoning",message:p.t("wizard.model_reasoning"),default:a.reasoning}]);o.setModels(t)}console.log(t.green("\n✓ "+p.t("wizard.models_saved")))}async configModels(a){const i=o.getApiKey();if(await this.validatedKeyForConfiguration(i))for(;;){this.resetScreen(),this.createBox(p.t("wizard.config_models"));const i=[...this.buildPresetChoices()];i.push(new e.Separator),i.push({name:"✏️ "+p.t("wizard.custom_model_input"),value:{type:"custom_input"}}),i.push(new e.Separator),i.push({name:"<- "+p.t("wizard.nav_return"),value:{type:"back"}}),i.push({name:"x "+p.t("wizard.nav_exit"),value:{type:"exit"}});const{modelChoice:n}=await this.promptWithHints([{type:"list",name:"modelChoice",message:p.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✓ "+p.t("wizard.models_saved"))),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig())}}}else await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}async promptLoadAfterModelConfig(){const{shouldLoad:t}=await e.prompt([{type:"list",name:"shouldLoad",message:p.t("wizard.load_config_now"),choices:[{name:p.t("wizard.load_config_yes"),value:!0},{name:p.t("wizard.load_config_later"),value:!1}]}]);t&&await this.selectAndConfigureTool()}async configBaseUrl(){const i=o.getBaseUrl(),n=h(),r=a(p.t("wizard.base_testing")).start(),s=await k(n,{apiKey:S(),samples:3});r.stop();const l=v(s),c=n.map((e,a)=>{const o=e.url===i?t.cyan(` ← ${p.t("base.current_mark")}`):"";return{name:`${e.url} ${t.gray(e.label)} ${x(s[a],a===l)}${o}`,value:e.url}});c.push(new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"__back__"});const{url:d}=await this.promptWithHints([{type:"list",name:"url",message:p.t("wizard.base_select"),choices:c,default:i}]);if("__back__"===d)return;const m=s[n.findIndex(e=>e.url===d)];m.ok?await C(d):console.log(t.red(p.t("base.unreachable",{url:d,reason:b(m)}))),await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}async configApiKey(){for(;;){this.resetScreen(),this.createBox(p.t("wizard.input_api_key")),console.log(t.gray("\n💡 "+p.t("wizard.api_key_input_hint"))),console.log(t.gray(" "+p.t("wizard.api_key_get_hint",{url:N().links.tokenPage}))),console.log();const{apiKey:i}=await e.prompt([{type:"password",name:"apiKey",message:p.t("wizard.input_your_api_key"),mask:"*"}]);if(!i||""===i.trim()){const{action:t}=await e.prompt([{type:"list",name:"action",message:p.t("wizard.select_action"),choices:[{name:p.t("wizard.retry_input"),value:"retry"},{name:"<- "+p.t("wizard.nav_return"),value:"back"}]}]);if("back"===t)return!1;continue}const n=a(p.t("wizard.validating_api_key")).start(),r=await g(i.trim());if(n.stop(),r.valid)return o.setApiKey(i.trim()),this.validatedApiKeys.add(i.trim()),console.log(t.green("\n✓ "+p.t("wizard.api_key_valid"))),!0;{this.validatedApiKeys.delete(i.trim()),"invalid_api_key"===r.error?console.log(t.red("\n✗ "+p.t("wizard.api_key_invalid"))):console.log(t.red("\n✗ "+p.t("wizard.api_key_network_error")));const{action:a}=await e.prompt([{type:"list",name:"action",message:p.t("wizard.select_action"),choices:[{name:p.t("wizard.retry_input"),value:"retry"},{name:"<- "+p.t("wizard.nav_return"),value:"back"}]}]);if("back"===a)return!1}}}async selectAndConfigureTool(t=!1){for(;;){this.resetScreen(),this.createBox(p.t("wizard.select_tool"));const a=l.getSupportedTools().map(e=>({name:e.displayName,value:e.name})),{tool:o}=await this.promptWithHints([{type:"list",name:"tool",message:"🛠️ "+p.t("wizard.select_tool"),choices:[...a,new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"back"},{name:"x "+p.t("wizard.nav_exit"),value:"exit"}]}]);if("exit"===o)this.printGoodbye(),process.exit(0);else if("back"===o)return;await this.configureTool(o,t)}}async configureTool(a,o=!1){const i=c[a];if(i){if(!l.isToolInstalled(a)){console.log(t.yellow("\n"+p.t("wizard.tool_not_installed",{tool:i.displayName})));const{install:o}=await e.prompt([{type:"confirm",name:"install",message:p.t("wizard.install_tool_confirm"),default:!0}]);if(!o)return;try{await l.installTool(a)}catch{return void console.log(t.red(p.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+" "+p.t("wizard.menu_title"));const o=[{name:"📥 "+p.t("wizard.action_load_config",{tool:a.displayName}),value:"load"},{name:"📤 "+p.t("wizard.action_unload_config",{tool:a.displayName}),value:"unload"}];l.supportsClearPinnedModels(t)&&o.push({name:"🧹 "+p.t("wizard.action_clear_model",{tool:a.displayName}),value:"clear-model"}),o.push({name:"🧨 "+p.t("wizard.action_force_config",{tool:a.displayName}),value:"force"},{name:"↩️ "+p.t("wizard.action_restore_config",{tool:a.displayName}),value:"restore"},new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"back"},{name:"x "+p.t("wizard.nav_exit"),value:"exit"});const{action:i}=await this.promptWithHints([{type:"list",name:"action",message:"⚙️ "+p.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):"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"+p.t("wizard.api_key_required"))),console.log(t.yellow(p.t("wizard.please_config_api_key_first"))),null;if(this.validatedApiKeys.has(o))return o;const i=a(p.t("wizard.validating_api_key")).start(),n=await g(o);if(n.valid)return this.validatedApiKeys.add(o),i.succeed(p.t("wizard.api_key_valid")),o;this.validatedApiKeys.delete(o);const r="invalid_api_key"===n.error?p.t("wizard.api_key_invalid"):p.t("wizard.api_key_network_error");return i.fail(r),console.log(t.red("\n"+p.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:p.t("wizard.press_enter")}]),!1;const d="claude-code"===i,m=s(i),u=d||!m?p.t("wizard.model_builtin_default"):m;this.resetScreen(),this.createBox(n.displayName+" · "+p.t("wizard.config_models"));const _=[{name:"✅ "+p.t("wizard.use_default_model",{model:u}),value:{type:"default"}},{name:"🌐 "+p.t("wizard.fetch_models_from_api"),value:{type:"fetch"}},...this.buildPresetChoices(),new e.Separator,{name:"✏️ "+p.t("wizard.input_custom_model"),value:{type:"custom"}},new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:{type:"back"}}],{choice:g}=await this.promptWithHints([{type:"list",name:"choice",message:p.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:p.t("wizard.input_custom_model"),default:!d&&m?m:void 0}]),a=(t||"").trim();o.setToolModel(i,a?this.singleModelOverride(a):null)}else if("fetch"===g.type){const n=a(p.t("wizard.fetching_models")).start(),r=await w(l);let s;if(n.stop(),r.ok&&r.models.length>0){const{model:t}=await e.prompt([{type:"list",name:"model",message:p.t("wizard.select_fetched_model"),pageSize:20,choices:[...r.models,new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"__back__"}]}]);if("__back__"===t)return!1;s=t}else{console.log(t.yellow("\n"+p.t("wizard.fetch_models_failed")));const{model:a}=await e.prompt([{type:"input",name:"model",message:p.t("wizard.input_custom_model"),default:!d&&m?m:void 0}]);s=(a||"").trim()}o.setToolModel(i,s?this.singleModelOverride(s):null)}if("codex"===i){const t=o.getToolSetting(i,f),{enableOneMillionContext:a}=await e.prompt([{type:"confirm",name:"enableOneMillionContext",message:p.t("wizard.codex_enable_1m_context"),default:!1!==t}]);o.setToolSetting(i,f,Boolean(a))}if("claude-desktop"===i){const t=o.getToolSetting(i,y),{hideOfficialLogin:a}=await e.prompt([{type:"confirm",name:"hideOfficialLogin",message:p.t("wizard.desktop_hide_official_login"),default:!1!==t}]);o.setToolSetting(i,y,Boolean(a))}return console.log(t.green("\n✓ "+p.t("wizard.models_saved"))),d&&console.log(t.gray("💡 "+p.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:p.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:p.t("wizard.press_enter")}]);const m=a(p.t("wizard.loading_config")).start();try{await l.applyPrivateConfig(i,s,r,n),m.stop(),l.printApplied(i),await d([i]),n.force&&console.log(t.yellow(p.t("config.force_done",{tool:c[i]?.displayName||i})));const a=c[i];a&&!a.gui&&(console.log(t.green("\n"+p.t("wizard.run_tool_hint",{command:a.command}))),this.printPathReloadHint([i]));const{nextAction:o}=await e.prompt([{type:"list",name:"nextAction",message:p.t("wizard.what_next"),choices:[{name:p.t("wizard.exit_and_start"),value:"exit"},{name:p.t("wizard.continue_config"),value:"continue"}]}]);"exit"===o&&(this.printGoodbye(),process.exit(0))}catch(a){m.fail(p.t("wizard.config_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}}async clearPinnedModels(a){const o=c[a]?.displayName||a,{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:p.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"+p.t("config.clear_model_none",{tool:o}))):(console.log(t.green("\n✓ "+p.t("config.clear_model_done",{tool:o}))),e.forEach(e=>console.log(t.gray(` - ${e}`))),console.log(t.gray(p.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:p.t("wizard.press_enter")}])}}async unloadConfig(o){const{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:p.t("wizard.confirm_unload_config",{tool:c[o]?.displayName||o}),default:!1}]);if(!i)return;const n=a(p.t("wizard.unloading_config")).start();try{const a=l.unloadPrivateConfig(o);n.succeed(p.t("wizard.config_unloaded")),a.forEach(e=>console.log(t.yellow(" ! "+e.text)));const{nextAction:i}=await e.prompt([{type:"list",name:"nextAction",message:p.t("wizard.what_next"),choices:[{name:p.t("wizard.nav_exit"),value:"exit"},{name:p.t("wizard.continue_config"),value:"continue"}]}]);"exit"===i&&(this.printGoodbye(),process.exit(0))}catch(a){n.fail(p.t("wizard.config_unload_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}}async restoreConfig(o){const i=c[o]?.displayName||o,{confirm:n}=await e.prompt([{type:"confirm",name:"confirm",message:p.t("wizard.confirm_restore_config",{tool:i}),default:!1}]);if(!n)return;const r=a(p.t("wizard.restoring_config")).start();try{const e=l.restorePrivateConfig(o).filter(e=>e.result.restored);0===e.length?r.warn(p.t("wizard.restore_no_backup")):(r.succeed(p.t("wizard.config_restored",{tool:i})),e.forEach(e=>console.log(t.gray(` ${e.file} ← ${e.result.from}`))),console.log(t.yellow(" ! "+p.t("config.reopen_hint",{tool:i}))))}catch(e){r.fail(p.t("wizard.config_restore_failed")),console.log(t.red(e instanceof Error?e.message:String(e)))}await e.prompt([{type:"input",name:"continue",message:p.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(H("── "+p.t("wizard.select_tool")+" ──")),...n,new e.Separator(t.gray("── "+p.t("wizard.settings")+" ──")),{name:"🔑 "+p.t("wizard.menu_change_api_key"),value:{type:"apikey"}},{name:"🔗 "+p.t("wizard.menu_base_url",{url:o.getBaseUrl()}),value:{type:"base"}},{name:"🌐 "+p.t("wizard.menu_config_language"),value:{type:"language"}},new e.Separator,{name:"x "+p.t("wizard.nav_exit"),value:{type:"exit"}}],{action:s}=await this.promptWithHints([{type:"list",name:"action",message:"🛠️ "+p.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{postApplyPrompts as d}from"./post-apply.js";import{i18n as p,detectSystemLang as m}from"./i18n.js";import{createBorderLine as u,createContentLine as _}from"../utils/string-width.js";import{validateApiKey as g,fetchModels as w}from"./api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as f}from"./tools/codex.js";import{CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as y}from"./tools/claude-desktop.js";import{addressesWithCurrent as h,ensureReachableGatewayAddress as z,fastestIndex as v,probeAll as k,probeSummary as x,reasonText as b,savedApiKey as S,switchGatewayAddress as C}from"../commands/base.js";import{readFileSync as M}from"fs";import{dirname as T,join as A}from"path";import{fileURLToPath as K}from"url";import{brand as N}from"./brand.js";const B=T(K(import.meta.url)),P=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(P.bold("\n"+u("╔","╗","═",this.BOX_WIDTH))),console.log(P.bold(_(e,"║","║",this.BOX_WIDTH,"center"))),console.log(P.bold(u("╚","╝","═",this.BOX_WIDTH))),console.log("")}showOperationHints(){const e=[t.gray(p.t("wizard.hint_navigate")),t.gray(p.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=p.t("wizard.banner_subtitle"),a=_(t,"║","║",e,"center"),o=_("","║","║",e,"center"),i=_(`${N().productName} v${function(){try{return JSON.parse(M(A(B,"..","..","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=>_(s+t,"║","║",e,"left")),c=[u("╔","╗","═",e),o,...l,o,i,a,u("╚","╝","═",e)];console.log(P.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=p.t("wizard.goodbye_message_tools",{commands:t}),e.some(e=>"claude-code"===e.name)&&(a+=" "+p.t("wizard.goodbye_claude_hint"))}else a=p.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(" ! "+p.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:o})))}async runFirstTimeSetup(){const e="zh_CN"===m();e&&(o.setLang("zh_CN"),p.setLocale("zh_CN")),this.resetScreen(),console.log(P.bold("\n"+p.t("wizard.welcome"))),console.log(t.gray(p.t("wizard.privacy_note")+"\n")),e?console.log(t.gray(p.t("wizard.lang_auto_zh")+"\n")):await this.configLanguage(),await z(),await this.configApiKey()&&await this.selectAndConfigureTool(!0)}async configLanguage(){for(;;){this.resetScreen(),this.createBox(p.t("wizard.select_language"));const a=p.getLocale(),{language:i}=await this.promptWithHints([{type:"list",name:"language",message:"✨ "+p.t("wizard.select_language"),choices:[{name:"[EN] English"+("en_US"===a?t.green(" ✓ ("+p.t("wizard.current_active")+")"):""),value:"en_US"},{name:"[CN] 中文"+("zh_CN"===a?t.green(" ✓ ("+p.t("wizard.current_active")+")"):""),value:"zh_CN"},new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"back"},{name:"x "+p.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 p.setLocale(i)}}buildPresetChoices(){const a=n(),o=a.filter(e=>e.recommended),i=a.filter(e=>!e.recommended),r=e=>({name:(p.t(e.name)!==e.name?p.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")("── "+p.t("wizard.recommended")+" ──"))),s.push(...o.map(r))),i.length>0&&(s.push(new e.Separator(t.gray("── "+p.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:p.t("wizard.custom_model_mode"),choices:[{name:p.t("wizard.custom_model_single"),value:"single"},{name:p.t("wizard.custom_model_per_role"),value:"per_role"}]}]);if("single"===n){const{customModel:t}=await e.prompt([{type:"input",name:"customModel",message:p.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:p.t("wizard.model_haiku"),default:a.haiku},{type:"input",name:"sonnet",message:p.t("wizard.model_sonnet"),default:a.sonnet},{type:"input",name:"opus",message:p.t("wizard.model_opus"),default:a.opus},{type:"input",name:"reasoning",message:p.t("wizard.model_reasoning"),default:a.reasoning}]);o.setModels(t)}console.log(t.green("\n✓ "+p.t("wizard.models_saved")))}async configModels(a){const i=o.getApiKey();if(await this.validatedKeyForConfiguration(i))for(;;){this.resetScreen(),this.createBox(p.t("wizard.config_models"));const i=[...this.buildPresetChoices()];i.push(new e.Separator),i.push({name:"✏️ "+p.t("wizard.custom_model_input"),value:{type:"custom_input"}}),i.push(new e.Separator),i.push({name:"<- "+p.t("wizard.nav_return"),value:{type:"back"}}),i.push({name:"x "+p.t("wizard.nav_exit"),value:{type:"exit"}});const{modelChoice:n}=await this.promptWithHints([{type:"list",name:"modelChoice",message:p.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✓ "+p.t("wizard.models_saved"))),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig())}}}else await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}async promptLoadAfterModelConfig(){const{shouldLoad:t}=await e.prompt([{type:"list",name:"shouldLoad",message:p.t("wizard.load_config_now"),choices:[{name:p.t("wizard.load_config_yes"),value:!0},{name:p.t("wizard.load_config_later"),value:!1}]}]);t&&await this.selectAndConfigureTool()}async configBaseUrl(){const i=o.getBaseUrl(),n=h(),r=a(p.t("wizard.base_testing")).start(),s=await k(n,{apiKey:S(),samples:3});r.stop();const l=v(s),c=n.map((e,a)=>{const o=e.url===i?t.cyan(` ← ${p.t("base.current_mark")}`):"";return{name:`${e.url} ${t.gray(e.label)} ${x(s[a],a===l)}${o}`,value:e.url}});c.push(new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"__back__"});const{url:d}=await this.promptWithHints([{type:"list",name:"url",message:p.t("wizard.base_select"),choices:c,default:i}]);if("__back__"===d)return;const m=s[n.findIndex(e=>e.url===d)];m.ok?await C(d):console.log(t.red(p.t("base.unreachable",{url:d,reason:b(m)}))),await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}async configApiKey(){for(;;){this.resetScreen(),this.createBox(p.t("wizard.input_api_key")),console.log(t.gray("\n💡 "+p.t("wizard.api_key_input_hint"))),console.log(t.gray(" "+p.t("wizard.api_key_get_hint",{url:N().links.tokenPage}))),console.log();const{apiKey:i}=await e.prompt([{type:"password",name:"apiKey",message:p.t("wizard.input_your_api_key"),mask:"*"}]);if(!i||""===i.trim()){const{action:t}=await e.prompt([{type:"list",name:"action",message:p.t("wizard.select_action"),choices:[{name:p.t("wizard.retry_input"),value:"retry"},{name:"<- "+p.t("wizard.nav_return"),value:"back"}]}]);if("back"===t)return!1;continue}const n=a(p.t("wizard.validating_api_key")).start(),r=await g(i.trim());if(n.stop(),r.valid)return o.setApiKey(i.trim()),this.validatedApiKeys.add(i.trim()),console.log(t.green("\n✓ "+p.t("wizard.api_key_valid"))),!0;{this.validatedApiKeys.delete(i.trim()),"invalid_api_key"===r.error?console.log(t.red("\n✗ "+p.t("wizard.api_key_invalid"))):console.log(t.red("\n✗ "+p.t("wizard.api_key_network_error")));const{action:a}=await e.prompt([{type:"list",name:"action",message:p.t("wizard.select_action"),choices:[{name:p.t("wizard.retry_input"),value:"retry"},{name:"<- "+p.t("wizard.nav_return"),value:"back"}]}]);if("back"===a)return!1}}}async selectAndConfigureTool(t=!1){for(;;){this.resetScreen(),this.createBox(p.t("wizard.select_tool"));const a=l.getSupportedTools().map(e=>({name:e.displayName,value:e.name})),{tool:o}=await this.promptWithHints([{type:"list",name:"tool",message:"🛠️ "+p.t("wizard.select_tool"),choices:[...a,new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"back"},{name:"x "+p.t("wizard.nav_exit"),value:"exit"}]}]);if("exit"===o)this.printGoodbye(),process.exit(0);else if("back"===o)return;await this.configureTool(o,t)}}async configureTool(a,o=!1){const i=c[a];if(i){if(!l.isToolInstalled(a)){console.log(t.yellow("\n"+p.t("wizard.tool_not_installed",{tool:i.displayName})));const{install:o}=await e.prompt([{type:"confirm",name:"install",message:p.t("wizard.install_tool_confirm"),default:!0}]);if(!o)return;try{await l.installTool(a)}catch{return void console.log(t.red(p.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+" "+p.t("wizard.menu_title"));const o=[{name:"📥 "+p.t("wizard.action_load_config",{tool:a.displayName}),value:"load"},{name:"📤 "+p.t("wizard.action_unload_config",{tool:a.displayName}),value:"unload"}];l.supportsClearPinnedModels(t)&&o.push({name:"🧹 "+p.t("wizard.action_clear_model",{tool:a.displayName}),value:"clear-model"}),o.push({name:"🧨 "+p.t("wizard.action_force_config",{tool:a.displayName}),value:"force"},{name:"↩️ "+p.t("wizard.action_restore_config",{tool:a.displayName}),value:"restore"},new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"back"},{name:"x "+p.t("wizard.nav_exit"),value:"exit"});const{action:i}=await this.promptWithHints([{type:"list",name:"action",message:"⚙️ "+p.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):"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"+p.t("wizard.api_key_required"))),console.log(t.yellow(p.t("wizard.please_config_api_key_first"))),null;if(this.validatedApiKeys.has(o))return o;const i=a(p.t("wizard.validating_api_key")).start(),n=await g(o);if(n.valid)return this.validatedApiKeys.add(o),i.succeed(p.t("wizard.api_key_valid")),o;this.validatedApiKeys.delete(o);const r="invalid_api_key"===n.error?p.t("wizard.api_key_invalid"):p.t("wizard.api_key_network_error");return i.fail(r),console.log(t.red("\n"+p.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:p.t("wizard.press_enter")}]),!1;const d="claude-code"===i,m=d||"claude-desktop"===i||"agy"===i,u=s(i),_=m||!u?p.t("wizard.model_builtin_default"):u;this.resetScreen(),this.createBox(n.displayName+" · "+p.t("wizard.config_models"));const g=[{name:"✅ "+p.t("wizard.use_default_model",{model:_}),value:{type:"default"}},{name:"🌐 "+p.t("wizard.fetch_models_from_api"),value:{type:"fetch"}},...this.buildPresetChoices(),new e.Separator,{name:"✏️ "+p.t("wizard.input_custom_model"),value:{type:"custom"}},new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:{type:"back"}}],{choice:h}=await this.promptWithHints([{type:"list",name:"choice",message:p.t("wizard.select_tool_model",{tool:n.displayName}),choices:g}]);if("back"===h.type)return!1;if("default"===h.type)o.setToolModel(i,null);else if("preset"===h.type)o.setToolModel(i,r(h.preset));else if("custom"===h.type){const{model:t}=await e.prompt([{type:"input",name:"model",message:p.t("wizard.input_custom_model"),default:!m&&u?u:void 0}]),a=(t||"").trim();o.setToolModel(i,a?this.singleModelOverride(a):null)}else if("fetch"===h.type){const n=a(p.t("wizard.fetching_models")).start(),r=await w(l);let s;if(n.stop(),r.ok&&r.models.length>0){const{model:t}=await e.prompt([{type:"list",name:"model",message:p.t("wizard.select_fetched_model"),pageSize:20,choices:[...r.models,new e.Separator,{name:"<- "+p.t("wizard.nav_return"),value:"__back__"}]}]);if("__back__"===t)return!1;s=t}else{console.log(t.yellow("\n"+p.t("wizard.fetch_models_failed")));const{model:a}=await e.prompt([{type:"input",name:"model",message:p.t("wizard.input_custom_model"),default:!m&&u?u:void 0}]);s=(a||"").trim()}o.setToolModel(i,s?this.singleModelOverride(s):null)}if("codex"===i){const t=o.getToolSetting(i,f),{enableOneMillionContext:a}=await e.prompt([{type:"confirm",name:"enableOneMillionContext",message:p.t("wizard.codex_enable_1m_context"),default:!1!==t}]);o.setToolSetting(i,f,Boolean(a))}if("claude-desktop"===i){const t=o.getToolSetting(i,y),{hideOfficialLogin:a}=await e.prompt([{type:"confirm",name:"hideOfficialLogin",message:p.t("wizard.desktop_hide_official_login"),default:!1!==t}]);o.setToolSetting(i,y,Boolean(a))}return console.log(t.green("\n✓ "+p.t("wizard.models_saved"))),d&&console.log(t.gray("💡 "+p.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:p.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:p.t("wizard.press_enter")}]);const m=a(p.t("wizard.loading_config")).start();try{await l.applyPrivateConfig(i,s,r,n),m.stop(),l.printApplied(i),await d([i]),n.force&&console.log(t.yellow(p.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"+p.t("wizard.run_tool_hint",{command:a.command}))),this.printPathReloadHint([i]));const{nextAction:o}=await e.prompt([{type:"list",name:"nextAction",message:p.t("wizard.what_next"),choices:[{name:p.t("wizard.exit_and_start"),value:"exit"},{name:p.t("wizard.continue_config"),value:"continue"}]}]);"exit"===o&&(this.printGoodbye(),process.exit(0))}catch(a){m.fail(p.t("wizard.config_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}}async clearPinnedModels(a){const o=c[a]?.displayName||a,{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:p.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"+p.t("config.clear_model_none",{tool:o}))):(console.log(t.green("\n✓ "+p.t("config.clear_model_done",{tool:o}))),e.forEach(e=>console.log(t.gray(` - ${e}`))),console.log(t.gray(p.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:p.t("wizard.press_enter")}])}}async unloadConfig(o){const{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:p.t("wizard.confirm_unload_config",{tool:c[o]?.displayName||o}),default:!1}]);if(!i)return;const n=a(p.t("wizard.unloading_config")).start();try{const a=Boolean(l.detectCurrentConfig(o).apiKey),i=l.unloadPrivateConfig(o);if(!a)return void n.info(p.t("config.remove_nothing",{tool:c[o]?.displayName||o}));n.succeed(p.t("wizard.config_unloaded")),i.forEach(e=>console.log(t.yellow(" ! "+e.text)));const{nextAction:r}=await e.prompt([{type:"list",name:"nextAction",message:p.t("wizard.what_next"),choices:[{name:p.t("wizard.nav_exit"),value:"exit"},{name:p.t("wizard.continue_config"),value:"continue"}]}]);"exit"===r&&(this.printGoodbye(),process.exit(0))}catch(a){n.fail(p.t("wizard.config_unload_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:p.t("wizard.press_enter")}])}}async restoreConfig(o){const i=c[o]?.displayName||o,{confirm:n}=await e.prompt([{type:"confirm",name:"confirm",message:p.t("wizard.confirm_restore_config",{tool:i}),default:!1}]);if(!n)return;const r=a(p.t("wizard.restoring_config")).start();try{const e=l.restorePrivateConfig(o).filter(e=>e.result.restored);0===e.length?r.warn(p.t("wizard.restore_no_backup")):(r.succeed(p.t("wizard.config_restored",{tool:i})),e.forEach(e=>console.log(t.gray(` ${e.file} ← ${e.result.from}`))),console.log(t.yellow(" ! "+p.t("config.reopen_hint",{tool:i}))))}catch(e){r.fail(p.t("wizard.config_restore_failed")),console.log(t.red(e instanceof Error?e.message:String(e)))}await e.prompt([{type:"input",name:"continue",message:p.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(P("── "+p.t("wizard.select_tool")+" ──")),...n,new e.Separator(t.gray("── "+p.t("wizard.settings")+" ──")),{name:"🔑 "+p.t("wizard.menu_change_api_key"),value:{type:"apikey"}},{name:"🔗 "+p.t("wizard.menu_base_url",{url:o.getBaseUrl()}),value:{type:"base"}},{name:"🌐 "+p.t("wizard.menu_config_language"),value:{type:"language"}},new e.Separator,{name:"x "+p.t("wizard.nav_exit"),value:{type:"exit"}}],{action:s}=await this.promptWithHints([{type:"list",name:"action",message:"🛠️ "+p.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();
|