@vibeapi/api-helper 0.0.148 → 0.0.149
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/components.json +157 -0
- package/dist/commands/components.d.ts +26 -0
- package/dist/commands/components.js +1 -0
- package/dist/commands/upgrade.d.ts +4 -2
- package/dist/commands/upgrade.js +1 -1
- package/dist/components.json +157 -0
- package/dist/lib/app-update.d.ts +20 -0
- package/dist/lib/app-update.js +1 -1
- package/dist/lib/brand.js +1 -1
- package/dist/lib/components.d.ts +204 -0
- package/dist/lib/components.js +1 -0
- package/dist/lib/dry-run.js +1 -1
- package/dist/lib/program.js +1 -1
- package/dist/lib/runtime-options.d.ts +5 -0
- package/dist/lib/runtime-options.js +1 -1
- package/dist/lib/tool-upgrade.d.ts +2 -0
- package/dist/lib/tool-upgrade.js +1 -1
- package/dist/lib/tools/chatgpt-desktop.d.ts +14 -1
- package/dist/lib/tools/chatgpt-desktop.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/desktop-process.d.ts +4 -1
- package/dist/lib/tools/desktop-process.js +1 -1
- package/dist/lib/tools/tool-installs.d.ts +8 -0
- package/dist/lib/tools/tool-installs.js +1 -1
- package/dist/lib/tools/types.d.ts +13 -9
- package/dist/locales/en_US.json +124 -5
- package/dist/locales/zh_CN.json +124 -5
- package/package.json +2 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The components vibecli installs and upgrades (`vibecli list` / `install` / `upgrade`): runtimes (Node, Git, uv),
|
|
3
|
+
* coding CLIs (Claude Code, Codex, Grok Build, agy) and desktop apps (Claude Desktop, ChatGPT). What each one is,
|
|
4
|
+
* where it comes from and how it is checked is declared once in `components.json` (repo root, shipped with the
|
|
5
|
+
* package); the docs and the install scripts' README are generated from the same file
|
|
6
|
+
* (`scripts/gen-components-doc.mjs`).
|
|
7
|
+
*
|
|
8
|
+
* - CLIs and apps are driven by their tool adapter (`installSpec` / `appInstaller`), as before.
|
|
9
|
+
* - Runtimes are installed by the brand's install scripts (`node.sh` / `node.ps1` …), which already find an
|
|
10
|
+
* existing copy, pick a mirror and check sha256. vibecli only upgrades a copy that one of those scripts (or the
|
|
11
|
+
* vendor's own standalone installer at the same place) manages: fnm's Node, uv in ~/.local/bin, the per-user
|
|
12
|
+
* Git for Windows. A copy from Homebrew, nvm, the system … is reported with the command that upgrades it; `--force`
|
|
13
|
+
* installs our own copy anyway.
|
|
14
|
+
* - Already installed + `install`: only the state and the upgrade command, never overwritten (user, 11-01); `--force`
|
|
15
|
+
* reinstalls.
|
|
16
|
+
*/
|
|
17
|
+
export type ComponentCategory = 'runtime' | 'cli' | 'app';
|
|
18
|
+
export interface ComponentSpec {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
category: ComponentCategory;
|
|
22
|
+
aliases?: string[];
|
|
23
|
+
platforms: NodeJS.Platform[];
|
|
24
|
+
/** Runtimes: the command and how to read its version out of `<command> --version`. */
|
|
25
|
+
detect?: {
|
|
26
|
+
command: string;
|
|
27
|
+
pattern: string;
|
|
28
|
+
};
|
|
29
|
+
latest: {
|
|
30
|
+
type: 'node-lts';
|
|
31
|
+
url: string;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'devtools';
|
|
34
|
+
key: string;
|
|
35
|
+
platforms?: NodeJS.Platform[];
|
|
36
|
+
} | {
|
|
37
|
+
type: 'npm';
|
|
38
|
+
package: string;
|
|
39
|
+
staleTag?: boolean;
|
|
40
|
+
} | {
|
|
41
|
+
type: 'version-file';
|
|
42
|
+
url: string;
|
|
43
|
+
} | {
|
|
44
|
+
type: 'app';
|
|
45
|
+
};
|
|
46
|
+
/** Where it is downloaded from, per platform (`all` for every one); `{scripts}`, `{agy}`, `{devtools}` expand. */
|
|
47
|
+
sources: Partial<Record<NodeJS.Platform | 'all', string>>;
|
|
48
|
+
verify: {
|
|
49
|
+
checksum: string;
|
|
50
|
+
signature: string;
|
|
51
|
+
};
|
|
52
|
+
install: {
|
|
53
|
+
type: 'script';
|
|
54
|
+
script: string;
|
|
55
|
+
forceEnv?: Record<string, string>;
|
|
56
|
+
} | {
|
|
57
|
+
type: 'adapter';
|
|
58
|
+
} | {
|
|
59
|
+
type: 'app';
|
|
60
|
+
};
|
|
61
|
+
upgrade?: {
|
|
62
|
+
managedBy: string;
|
|
63
|
+
migrateGlobalPackages?: boolean;
|
|
64
|
+
};
|
|
65
|
+
/** Tool adapter for CLIs, app id for desktop apps. */
|
|
66
|
+
adapter?: string;
|
|
67
|
+
app?: string;
|
|
68
|
+
/** Command that shows it works after installing. */
|
|
69
|
+
check?: string[];
|
|
70
|
+
/** Components installed first when missing. */
|
|
71
|
+
requires: string[];
|
|
72
|
+
}
|
|
73
|
+
interface Manifest {
|
|
74
|
+
schema: number;
|
|
75
|
+
devtools: string;
|
|
76
|
+
components: ComponentSpec[];
|
|
77
|
+
}
|
|
78
|
+
/** Validates the shape the code relies on; a broken manifest is a build error, caught by the unit tests. */
|
|
79
|
+
export declare function parseManifest(text: string): Manifest;
|
|
80
|
+
/** Tests swap in their own manifest (null = the shipped one). */
|
|
81
|
+
export declare function setComponentManifestForTests(text: string | null): void;
|
|
82
|
+
export declare function listComponents(): ComponentSpec[];
|
|
83
|
+
/** By id or alias, case-insensitive. */
|
|
84
|
+
export declare function resolveComponent(name: string): ComponentSpec | undefined;
|
|
85
|
+
export declare function componentPlatform(): NodeJS.Platform;
|
|
86
|
+
/** `{scripts}` / `{agy}` / `{devtools}` → this brand's mirrors; null when the brand has no such mirror. */
|
|
87
|
+
export declare function expandUrl(text: string): string | null;
|
|
88
|
+
export declare function componentSource(spec: ComponentSpec, platform?: NodeJS.Platform): string;
|
|
89
|
+
/**
|
|
90
|
+
* Why components can't be installed for this account, null when they can. Everything goes into the user's own
|
|
91
|
+
* home directory: under sudo it would land in root's (and belong to root), as SYSTEM in the system profile.
|
|
92
|
+
* Plain root (a container, a server) is its own user and is fine.
|
|
93
|
+
*/
|
|
94
|
+
export declare function installBlocker(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): 'sudo' | 'system' | null;
|
|
95
|
+
export interface Probe {
|
|
96
|
+
path: string;
|
|
97
|
+
version: string | null;
|
|
98
|
+
}
|
|
99
|
+
/** Where our scripts (or the vendor's standalone installer) put the runtime, checked when PATH doesn't have it. */
|
|
100
|
+
export declare function knownRuntimePaths(id: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string[];
|
|
101
|
+
/** Every working copy: PATH order first (the first one is what a command runs), then the known places. */
|
|
102
|
+
export declare function probeRuntime(spec: ComponentSpec, platform?: NodeJS.Platform): Probe[];
|
|
103
|
+
/** Where the install script puts the runtime (fnm's default alias, ~/.local/bin, the per-user Git for Windows). */
|
|
104
|
+
export declare function scriptTarget(id: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string | null;
|
|
105
|
+
/**
|
|
106
|
+
* Who looks after this copy, and whether vibecli may upgrade it in place: `auto` = one of our install scripts
|
|
107
|
+
* (or the vendor's standalone installer at the same place) manages it; otherwise a hint names the right command.
|
|
108
|
+
*/
|
|
109
|
+
export interface RuntimeManager {
|
|
110
|
+
by: string;
|
|
111
|
+
auto: boolean;
|
|
112
|
+
/** The command that upgrades it, for copies vibecli leaves alone. */
|
|
113
|
+
hint?: string;
|
|
114
|
+
}
|
|
115
|
+
export declare function runtimeManager(id: string, path: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): RuntimeManager;
|
|
116
|
+
/** The newest LTS in Node's dist index (newest first; `lts` is false or the line's codename). */
|
|
117
|
+
export declare function latestNodeLts(indexJson: string): string;
|
|
118
|
+
/** `key=value` lines of the devtools mirror's versions.txt; versions come back as x.y.z (`v2.56.0.windows.4` → 2.56.0). */
|
|
119
|
+
export declare function devtoolsVersion(text: string, key: string): string;
|
|
120
|
+
/** The newest version (cached an hour, failures ten minutes; `refresh` reads it again). Null when there is none to compare with. */
|
|
121
|
+
export declare function latestVersion(spec: ComponentSpec, options?: {
|
|
122
|
+
refresh?: boolean;
|
|
123
|
+
}): Promise<{
|
|
124
|
+
version: string | null;
|
|
125
|
+
error?: string;
|
|
126
|
+
}>;
|
|
127
|
+
export interface ComponentStatus {
|
|
128
|
+
id: string;
|
|
129
|
+
name: string;
|
|
130
|
+
category: ComponentCategory;
|
|
131
|
+
/** This platform has it at all (Claude Desktop / ChatGPT: macOS and Windows). */
|
|
132
|
+
supported: boolean;
|
|
133
|
+
installed: boolean;
|
|
134
|
+
current: string | null;
|
|
135
|
+
latest: string | null;
|
|
136
|
+
outdated: boolean;
|
|
137
|
+
path: string | null;
|
|
138
|
+
/** fnm / brew / native / npm …; null when not installed. */
|
|
139
|
+
managed_by: string | null;
|
|
140
|
+
/** vibecli upgrades it in place (`vibecli upgrade <id>`); false = `hint` names how. */
|
|
141
|
+
auto_upgrade: boolean;
|
|
142
|
+
hint?: string;
|
|
143
|
+
source: string;
|
|
144
|
+
/** Why vibecli can't install it here (sudo, SYSTEM, a desktop app's blocker), null when it can. */
|
|
145
|
+
blocker: string | null;
|
|
146
|
+
/** The latest version doesn't run on this machine; this is the newest that does (found by the last upgrade). */
|
|
147
|
+
capped_at?: string;
|
|
148
|
+
error?: string;
|
|
149
|
+
}
|
|
150
|
+
export type LatestInfo = {
|
|
151
|
+
version: string | null;
|
|
152
|
+
error?: string;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Latest versions of several components at once, before any local probing: `list` checks them all, and on
|
|
156
|
+
* Windows the probes (PowerShell for app versions and processes) are synchronous, so fetches left running
|
|
157
|
+
* across them hit their timeouts. Pass the result to `componentStatus({ latest })`.
|
|
158
|
+
*/
|
|
159
|
+
export declare function prefetchLatest(specs: ComponentSpec[], options?: {
|
|
160
|
+
refresh?: boolean;
|
|
161
|
+
}): Promise<Map<string, LatestInfo>>;
|
|
162
|
+
export declare function componentStatus(spec: ComponentSpec, options?: {
|
|
163
|
+
refresh?: boolean;
|
|
164
|
+
offline?: boolean;
|
|
165
|
+
latest?: LatestInfo;
|
|
166
|
+
}): Promise<ComponentStatus>;
|
|
167
|
+
/** Globally installed npm packages of the Node at `nodePath` (fnm keeps them per Node version). */
|
|
168
|
+
export declare function globalPackages(nodePath: string, platform?: NodeJS.Platform): Array<{
|
|
169
|
+
name: string;
|
|
170
|
+
version: string;
|
|
171
|
+
}>;
|
|
172
|
+
export type ComponentOutcome = 'installed' | 'upgraded' | 'reinstalled' | 'up_to_date' | 'already_installed' | 'manual' | 'unavailable' | 'failed';
|
|
173
|
+
export interface ComponentResult {
|
|
174
|
+
tool: string;
|
|
175
|
+
category: ComponentCategory;
|
|
176
|
+
current: string | null;
|
|
177
|
+
latest: string | null;
|
|
178
|
+
result: ComponentOutcome;
|
|
179
|
+
version_after: string | null;
|
|
180
|
+
ok: boolean;
|
|
181
|
+
reason?: string;
|
|
182
|
+
hint?: string;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Install (`mode: 'install'`) or upgrade a runtime. Installing one that is there only reports it (`--force`
|
|
186
|
+
* reinstalls); upgrading one another manager owns names that manager's command (`--force` installs ours).
|
|
187
|
+
*/
|
|
188
|
+
export declare function runRuntime(spec: ComponentSpec, mode: 'install' | 'upgrade', options?: {
|
|
189
|
+
force?: boolean;
|
|
190
|
+
}): Promise<ComponentResult>;
|
|
191
|
+
/** "x a → b: run …" for an outdated copy. */
|
|
192
|
+
export declare function upgradeAdvice(status: ComponentStatus): string;
|
|
193
|
+
export declare function setComponentDepsForTests(deps: {
|
|
194
|
+
platform?: NodeJS.Platform | null;
|
|
195
|
+
uid?: number | null;
|
|
196
|
+
systemPaths?: boolean;
|
|
197
|
+
registryPath?: () => string[];
|
|
198
|
+
versionRunner?: (path: string) => string;
|
|
199
|
+
macDeveloperTools?: () => boolean;
|
|
200
|
+
fetchText?: (url: string) => Promise<string>;
|
|
201
|
+
scriptRunner?: (url: string, env: Record<string, string>) => Promise<boolean>;
|
|
202
|
+
commandRunner?: (command: string, args: string[]) => Promise<boolean>;
|
|
203
|
+
}): void;
|
|
204
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{spawnSync as t}from"child_process";import{existsSync as e,mkdirSync as n,readFileSync as o,readdirSync as r,realpathSync as s,statSync as a,writeFileSync as i}from"fs";import{delimiter as l,dirname as c,isAbsolute as u,join as p,sep as d}from"path";import{fileURLToPath as m}from"url";import f from"chalk";import{brand as g,CLI_NAME as h}from"./brand.js";import{configManager as w}from"./config.js";import{i18n as v}from"./i18n.js";import{appLatest as y,appStatus as b,appStatusWith as $,cachedAppStatus as _,getApp as P}from"./app-update.js";import{compareVersions as x}from"./model-registry.js";import{isJsonMode as A}from"./runtime-options.js";import{track as k}from"./telemetry.js";import{runWatched as S}from"./tool-upgrade.js";import{getAdapter as D}from"./tools/registry.js";import{findInstallsIncludingNative as L,forgetInstalls as j,NPM_MIRROR as E,npmMirrorVersion as R}from"./tools/tool-installs.js";import{toolHome as C}from"./tools/types.js";import{logger as T}from"../utils/logger.js";let M=null;export function parseManifest(t){const e=JSON.parse(t);if(1!==e.schema||!Array.isArray(e.components))throw new Error("components.json: schema must be 1 with a components list");const n=new Set;for(const t of e.components){if(!t.id||!t.name||!["runtime","cli","app"].includes(t.category))throw new Error(`components.json: bad entry ${JSON.stringify(t.id)}`);for(const e of[t.id,...t.aliases??[]]){if(n.has(e))throw new Error(`components.json: duplicate name ${e}`);n.add(e)}if("runtime"===t.category&&(!t.detect||"script"!==t.install.type))throw new Error(`components.json: runtime ${t.id} needs detect + a script`);if("cli"===t.category&&!t.adapter)throw new Error(`components.json: cli ${t.id} needs an adapter`);if("app"===t.category&&!t.app)throw new Error(`components.json: app ${t.id} needs an app id`)}for(const t of e.components)for(const e of t.requires)if(!n.has(e))throw new Error(`components.json: ${t.id} requires unknown ${e}`);return e}function N(){return M||(M=parseManifest(o(function(){const t=c(m(import.meta.url)),n=[p(t,"..","..","components.json"),p(t,"..","components.json"),p(t,"components.json")],o=n.find(t=>e(t));if(!o)throw new Error(`components.json not found, searched: ${n.join(", ")}`);return o}(),"utf-8"))),M}export function setComponentManifestForTests(t){M=null===t?null:parseManifest(t)}export function listComponents(){return N().components}export function resolveComponent(t){const e=t.trim().toLowerCase();return listComponents().find(t=>t.id===e||(t.aliases??[]).includes(e))}let O=null;export function componentPlatform(){return O??process.platform}export function expandUrl(t){const e=g().installMirror??{};let n=!1;const o=t.replace(/\{(scripts|agy|devtools)\}/g,(t,o)=>{const r="devtools"===o?N().devtools:e[o];return r||(n=!0),r??""});return n?null:o}export function componentSource(t,e=componentPlatform()){return(t.sources[e]??t.sources.all??"").replace(/\{(scripts|agy|devtools)\}/g,(t,e)=>("devtools"===e?N().devtools:g().installMirror?.[e])??t)}export function installBlocker(t=process.env,e=componentPlatform()){return"win32"===e?/\\system32\\config\\systemprofile/i.test(t.USERPROFILE??"")||t.USERNAME?.endsWith("$")?"system":null:0===(U??process.getuid?.())&&t.SUDO_USER&&"root"!==t.SUDO_USER?"sudo":null}let U=null,I=!0,B=e=>{const n=/\.(cmd|bat)$/i.test(e)?t(`"${e}" --version`,{encoding:"utf-8",timeout:1e4,windowsHide:!0,shell:!0,stdio:["ignore","pipe","pipe"]}):t(e,["--version"],{encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]});return`${n.stdout??""}${n.stderr??""}`},F=()=>0===t("xcode-select",["-p"],{stdio:"ignore",timeout:1e4}).status;function V(t){try{return s(t)}catch{return t}}function H(t,e){return"win32"===e?[`${t}.exe`,`${t}.cmd`]:[t]}export function knownRuntimePaths(t,e=componentPlatform(),n=process.env){const o=C();if("node"===t){if("win32"===e){const t=n.FNM_DIR||p(n.APPDATA||p(o,"AppData","Roaming"),"fnm");return[p(t,"aliases","default","node.exe"),p(n.LOCALAPPDATA||p(o,"AppData","Local"),"Programs","nodejs","node.exe")]}return[p(W(e,n),"aliases","default","bin","node"),"/opt/homebrew/bin/node","/usr/local/bin/node","/usr/bin/node"]}if("uv"===t)return"win32"===e?[p(o,".local","bin","uv.exe"),p(o,".cargo","bin","uv.exe")]:[p(n.UV_INSTALL_DIR||p(o,".local","bin"),"uv"),p(o,".cargo","bin","uv"),"/opt/homebrew/bin/uv","/usr/local/bin/uv"];if("git"===t){if("win32"===e){const t=n.LOCALAPPDATA||p(o,"AppData","Local");return[p(t,"Programs","Git","cmd","git.exe"),p(n.ProgramFiles||"C:\\Program Files","Git","cmd","git.exe")]}return["/opt/homebrew/bin/git","/usr/local/bin/git","/usr/bin/git"]}return[]}function W(t,n){if(n.FNM_DIR)return n.FNM_DIR;const o=C();if("win32"===t)return p(n.APPDATA||p(o,"AppData","Roaming"),"fnm");const r=p(o,".local","share","fnm"),s=p(o,"Library","Application Support","fnm");return"darwin"===t&&!e(r)&&e(s)?s:r}let G=()=>{const e=e=>{const n=`${t("reg",["query",e,"/v","Path"],{encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","ignore"]}).stdout??""}`.split(/\r?\n/).find(t=>/\sREG_(EXPAND_)?SZ\s/.test(t));return n?n.replace(/^.*?REG_(EXPAND_)?SZ\s+/,""):""};return[e("HKCU\\Environment"),e("HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment")].flatMap(t=>{return(e=t,e.replace(/%([^%]+)%/g,(t,e)=>process.env[e]??t)).split(";");var e}).map(t=>t.trim().replace(/^"|"$/g,"")).filter(Boolean)},J=null;export function probeRuntime(t,e=componentPlatform()){const n=t.detect,o=new RegExp(n.pattern),r=new Set,s=[],i=n=>{if(!function(t){try{return a(t).isFile()}catch{return!1}}(n))return;if("darwin"===e&&"git"===t.id&&"/usr/bin/git"===n&&!F())return;const i=V(n),l="win32"===e?i.toLowerCase():i;if(r.has(l))return;r.add(l);const c=o.exec(B(n));c&&s.push({path:n,version:c[1]??null})},c=(process.env.PATH??"").split("win32"===e?";":l);"win32"===e&&c.push(...J??=z(()=>G())??[]);for(const t of c)if(t&&u(t))for(const o of H(n.command,e))i(p(t,o));for(const n of knownRuntimePaths(t.id,e))(I||n.startsWith(C()))&&i(n);return s}export function scriptTarget(t,e=componentPlatform(),n=process.env){const o=C();return"node"===t?"win32"===e?p(W(e,n),"aliases","default","node.exe"):p(W(e,n),"aliases","default","bin","node"):"uv"===t?p(n.UV_INSTALL_DIR||p(o,".local","bin"),"win32"===e?"uv.exe":"uv"):"git"===t&&"win32"===e?p(n.LOCALAPPDATA||p(o,"AppData","Local"),"Programs","Git","cmd","git.exe"):null}export function runtimeManager(t,e,n=componentPlatform(),o=process.env){const r=V(e),s=t=>"win32"===n?t.replace(/\//g,"\\").toLowerCase():t,a=s(r),i=s(e),l="win32"===n?"\\":"\\"===d?"/":d,u=t=>a.includes(s(t))||i.includes(s(t)),m=t=>a.startsWith(s(t)+l)||i.startsWith(s(t)+l),f=C(),g=/[\\/](Cellar|Caskroom|homebrew)[\\/]/i.test(r)||/^\/opt\/homebrew\//.test(e)||/^\/usr\/local\/(Cellar|opt)\//.test(r);if("node"===t)return u(`${l}fnm${l}`)||m(W(n,o))?{by:"fnm",auto:!0}:g?{by:"brew",auto:!1,hint:"brew upgrade node"}:u(`${l}.nvm${l}`)?{by:"nvm",auto:!1,hint:"nvm install --lts --reinstall-packages-from=current"}:u(`${l}nvm${l}`)&&"win32"===n?{by:"nvm",auto:!1,hint:"nvm install lts"}:u(`${l}.volta${l}`)||u(`${l}volta${l}`)?{by:"volta",auto:!1,hint:"volta install node@lts"}:u(`${l}scoop${l}`)?{by:"scoop",auto:!1,hint:"scoop update nodejs-lts"}:u(`${l}.asdf${l}`)?{by:"asdf",auto:!1,hint:"asdf install nodejs latest"}:u(`${l}mise${l}`)?{by:"mise",auto:!1,hint:"mise use -g node@lts"}:{by:"system",auto:!1};if("uv"===t)return[o.UV_INSTALL_DIR,p(f,".local","bin"),p(f,".cargo","bin")].filter(Boolean).some(t=>s(c(e))===s(t)||s(c(r))===s(t))?{by:"standalone",auto:!0}:g?{by:"brew",auto:!1,hint:"brew upgrade uv"}:u("pipx")?{by:"pipx",auto:!1,hint:"pipx upgrade uv"}:u(`${l}scoop${l}`)?{by:"scoop",auto:!1,hint:"scoop update uv"}:u("winget")?{by:"winget",auto:!1,hint:"winget upgrade astral-sh.uv"}:u("site-packages")||u(`${l}python`)?{by:"pip",auto:!1,hint:"pip install -U uv"}:{by:"other",auto:!1};if("git"===t){if("win32"===n){const t=o.LOCALAPPDATA||p(f,"AppData","Local");return m(p(t,"Programs","Git"))?{by:"git-for-windows-user",auto:!0}:u(`${l}scoop${l}`)?{by:"scoop",auto:!1,hint:"scoop update git"}:{by:"git-for-windows",auto:!1,hint:"git update-git-for-windows"}}return g?{by:"brew",auto:!1,hint:"brew upgrade git"}:"darwin"===n?{by:"xcode",auto:!1,hint:"softwareupdate --list"}:{by:"system",auto:!1}}return{by:"other",auto:!1}}function q(){return p(w.getConfigDir(),"component-releases.json")}function K(){try{const t=JSON.parse(o(q(),"utf-8"));return t&&"object"==typeof t?t:{}}catch{return{}}}function X(t,e){try{n(w.getConfigDir(),{recursive:!0}),i(q(),JSON.stringify({...K(),[t]:e},null,2))}catch(t){T.logError("components.writeCache",t)}}let Z=async(t,e=15e3)=>{const n=await fetch(t,{signal:AbortSignal.timeout(e)});if(!n.ok)throw new Error(`HTTP ${n.status} ${t}`);return n.text()};const Y=/(\d+\.\d+\.\d+)/;export function latestNodeLts(t){const e=JSON.parse(t).find(t=>"string"==typeof t.lts&&t.lts&&"string"==typeof t.version);if(!e)throw new Error("no LTS release in the Node index");return e.version.replace(/^v/,"")}export function devtoolsVersion(t,e){const n=t.split(/\r?\n/).find(t=>t.startsWith(`${e}=`)),o=n?Y.exec(n.slice(e.length+1)):null;if(!o)throw new Error(`${e} is not in versions.txt`);return o[1]}export async function latestVersion(t,e={}){const n=componentPlatform(),o=`${t.id}:${n}`,r=K()[o],s=r&&Date.now()-r.checked_at<(r.version?36e5:6e5);if(r&&s&&!e.refresh)return{version:r.version??null,...r.error?{error:r.error}:{}};try{const e=await async function(t,e){const n=t.latest;switch(n.type){case"node-lts":return latestNodeLts(await Z(n.url));case"devtools":return n.platforms&&!n.platforms.includes(e)?null:devtoolsVersion(await Z(`${N().devtools}/versions.txt`),n.key);case"npm":{if(n.staleTag){const e=D(t.adapter??"")?.installSpec,n=e?await R(e):"latest";if("latest"!==n)return n}const e=JSON.parse(await Z(`${E}/${n.package}/latest`));if(!e.version)throw new Error(`no version for ${n.package}`);return e.version}case"version-file":{const t=expandUrl(n.url);if(!t)return null;const e=Y.exec(await Z(t));if(!e)throw new Error(`no version in ${t}`);return e[1]}default:return null}}(t,n);return e&&X(o,{version:e,checked_at:Date.now()}),{version:e}}catch(e){const n=e instanceof Error?e.message:String(e);return T.logError(`components.latest(${t.id})`,e),X(o,{error:n,checked_at:Date.now()}),{version:r?.version??null,error:n}}}export async function prefetchLatest(t,e={}){const n=componentPlatform(),o=await Promise.all(t.map(async t=>t.platforms.includes(n)?"app"===t.category?[t.id,P(t.app)?await y(t.app,e):{version:null}]:[t.id,await latestVersion(t,e)]:[t.id,{version:null}]));return new Map(o)}export async function componentStatus(t,e={}){const n=componentPlatform(),o={id:t.id,name:t.name,category:t.category,supported:t.platforms.includes(n),source:componentSource(t,n)},r={...o,installed:!1,current:null,latest:null,outdated:!1,path:null,managed_by:null,auto_upgrade:!1,blocker:o.supported?installBlocker():"unsupported_platform"};if(!o.supported)return r;if("app"===t.category){const n=P(t.app);if(!n)return{...r,blocker:"unsupported_platform"};const o=e.latest?$(t.app,e.latest):e.offline?_(t.app):await b(t.app,{refresh:e.refresh});return{...r,installed:o.installed,current:o.current,latest:o.latest,outdated:o.outdated,path:o.installed?z(()=>n.appInstaller.installedPath()):null,managed_by:o.installed?"app":null,auto_upgrade:o.installed&&!o.blocker,blocker:o.blocker??installBlocker(),...o.error?{error:o.error}:{}}}let s=null,a=null,i=null;if("cli"===t.category){const e=D(t.adapter)?.installSpec,n=e?L(e)[0]:void 0;n&&(s=n.version,a=n.path,i={by:n.kind,auto:!0})}else{const e=probeRuntime(t,n)[0];e&&(s=e.version,a=e.path,i=runtimeManager(t.id,e.path,n))}const{version:l,error:c}=e.latest?e.latest:e.offline?{version:K()[`${t.id}:${n}`]?.version??null,error:void 0}:await latestVersion(t,{refresh:e.refresh}),u=l?K()[`${t.id}:${n}:ceiling`]:void 0,p=Boolean(u?.version&&u.error===l&&s&&x(s,u.version)>=0);return{...r,installed:Boolean(a),current:s,latest:l,outdated:Boolean(s&&l&&x(s,l)<0&&!p),...p?{capped_at:u.version}:{},path:a,managed_by:i?.by??null,auto_upgrade:i?.auto??!1,...i?.hint?{hint:i.hint}:{},...c?{error:c}:{}}}function z(t){try{return t()}catch{return null}}const Q={idleMs:18e4,timeoutMs:36e5};let tt=async(t,e)=>{const n={...Q,env:e};return"ok"===("win32"===componentPlatform()?await S("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${t} -TimeoutSec 30 | iex`],n):await S("sh",["-c",'script=$(curl -fsSL --connect-timeout 15 --max-time 60 "$0") && printf \'%s\\n\' "$script" | sh',t],n))},et=async(t,e)=>"ok"===await S(t,e,Q);function nt(t){A()?process.stderr.write(t+"\n"):console.log(t)}export function globalPackages(t,e=componentPlatform()){const n=c(V(t)),s="win32"===e?p(n,"node_modules"):p(c(n),"lib","node_modules"),a=[],i=(t,e)=>{try{const n=JSON.parse(o(p(t,"package.json"),"utf-8"));n.version&&a.push({name:e,version:n.version})}catch{}};let l=[];try{l=r(s)}catch{return a}for(const t of l)if(!t.startsWith(".")&&"npm"!==t&&"corepack"!==t)if(t.startsWith("@"))try{for(const e of r(p(s,t)))e.startsWith(".")||i(p(s,t,e),`${t}/${e}`)}catch{}else i(p(s,t),t);return a}function ot(t,e,n={}){const o=["installed","upgraded","reinstalled","up_to_date","already_installed"].includes(e);return{tool:t.id,category:t.category,current:t.current,latest:t.latest,result:e,version_after:null,ok:o,...n}}function rt(t){return`${h} upgrade ${t}`}export async function runRuntime(t,e,n={}){const o=Date.now(),r=componentPlatform(),s=await componentStatus(t,{refresh:!0}),a=t.name;if(!s.supported)return nt(f.yellow(" ! "+v.t("components.unsupported_platform",{tool:a}))),ot(s,"unavailable",{reason:"unsupported_platform"});if(s.blocker)return nt(f.yellow(" ! "+function(t,e){return v.t(`components.blocked_${t}`,{tool:e})}(s.blocker,a))),ot(s,"unavailable",{reason:s.blocker});const i=function(t){if("script"!==t.install.type)return null;const e=g().installMirror?.scripts;return e?`${e}/${t.install.script}.${"win32"===componentPlatform()?"ps1":"sh"}`:null}(t);if(s.installed&&!n.force){const n=f.gray(`(${s.path})`);if(s.latest&&!s.outdated)return nt(f.green(" √ "+v.t("components.up_to_date",{tool:a,current:s.current??"?"}))+n),"upgrade"===e&&nt(f.gray(" "+v.t("components.force_hint",{command:`${rt(t.id)} --force`}))),ot(s,"install"===e?"already_installed":"up_to_date");if("install"===e)return nt(f.green(" √ "+v.t("components.already_installed",{tool:a,current:s.current??"?"}))+n),s.outdated&&nt(f.yellow(" ! "+upgradeAdvice(s))),ot(s,"already_installed",s.outdated?{hint:upgradeAdvice(s)}:{});if(!s.latest)return nt(f.yellow(" ! "+v.t("components.no_latest",{tool:a,current:s.current??"?",how:at(s)}))),ot(s,"manual",{reason:s.error??"no_latest",hint:s.hint});if(!s.auto_upgrade)return nt(f.yellow(" ! "+upgradeAdvice(s))),ot(s,"manual",{hint:s.hint})}if(!i)return nt(f.yellow(" ! "+v.t("components.no_mirror",{tool:a}))),ot(s,"unavailable",{reason:"no_mirror"});s.installed&&!s.auto_upgrade&&nt(f.yellow(" ! "+v.t("components.force_beside",{tool:a,path:s.path??"?",by:s.managed_by??"?"})));const u={};s.installed&&"script"===t.install.type&&Object.assign(u,t.install.forceEnv??{}),"uv"===t.id&&s.installed&&s.auto_upgrade&&s.path&&(u.UV_INSTALL_DIR=c(s.path));const d=t.upgrade?.migrateGlobalPackages&&s.installed&&"fnm"===s.managed_by&&s.path,m=d?globalPackages(s.path,r):[],h=d?V(s.path):null;nt(f.gray(" "+v.t(s.installed?"components.upgrading":"components.installing",{tool:a,latest:s.latest??"",source:s.source}))),k(`component:${t.id}`,"start",{detail:{mode:e,force:Boolean(n.force),current:s.current}});const w=await tt(i,u);j(),J=null;const y=probeRuntime(t,r),b=scriptTarget(t.id,r,{...process.env,...u}),$=(b?y.find(t=>{return e=t.path,n=b,"win32"===r?V(e).toLowerCase()===V(n).toLowerCase():V(e)===V(n);var e,n}):void 0)??y.find(e=>runtimeManager(t.id,e.path,r).auto)??y[0];if(!w||!$)return k(`component:${t.id}`,"fail",{duration_ms:Date.now()-o}),nt(f.red(" × "+v.t("components.script_failed",{tool:a,command:(s.installed?rt:st)(t.id)}))),ot(s,"failed",{reason:w?"not_found_after":"script_failed"});d&&m.length&&h&&V($.path)!==h&&await async function(t,e,n){const o=new Set(globalPackages(e,n).map(t=>t.name)),r=t.filter(t=>!o.has(t.name));if(!r.length)return;nt(f.gray(" "+v.t("components.migrating_globals",{packages:r.map(t=>t.name).join("、")})));const s=function(t,e){const n=c(V(t));return p(n,"win32"===e?"npm.cmd":"npm")}(e,n),a=["install","-g",...r.map(t=>`${t.name}@${t.version}`),`--registry=${E}`,"--no-fund","--no-audit","--loglevel=error"];await et(s,a)||nt(f.yellow(" ! "+v.t("components.migrate_failed",{command:[s,...a].join(" ")})))}(m,$.path,r);const _=y[0];_&&_.path!==$.path&&_.version&&$.version&&x(_.version,$.version)<0&&nt(f.yellow(" ! "+v.t("components.path_shadowed",{tool:a,active:_.path,version:$.version,path:$.path}))),s.latest&&$.version&&x($.version,s.latest)<0&&(X(`${t.id}:${r}:ceiling`,{version:$.version,error:s.latest,checked_at:Date.now()}),nt(f.yellow(" ! "+v.t("components.capped",{tool:a,latest:s.latest,version:$.version})))),k(`component:${t.id}`,"ok",{duration_ms:Date.now()-o,detail:{version:$.version}});const P=s.installed?n.force&&!s.outdated?"reinstalled":"upgraded":"installed";var A;return nt(f.green(" √ "+("installed"===P?v.t("components.installed",{tool:a,version:$.version??"?"}):"reinstalled"===P?v.t("components.reinstalled",{tool:a,version:$.version??"?"}):v.t("components.upgraded",{tool:a,from:s.current??"?",to:$.version??"?"})))+f.gray(`(${$.path})`)),A=c($.path),(process.env.PATH??"").split("win32"===componentPlatform()?";":l).some(t=>"win32"===componentPlatform()?t.toLowerCase()===A.toLowerCase():t===A)||nt(f.gray(" "+v.t("components.new_terminal"))),ot(s,P,{version_after:$.version})}function st(t){return`${h} install ${t}`}function at(t){return t.hint?t.hint:v.t(`components.how_${t.managed_by??"other"}`,{tool:t.name})}export function upgradeAdvice(t){return t.auto_upgrade?v.t("components.outdated_auto",{tool:t.name,current:t.current??"?",latest:t.latest??"?",command:rt(t.id)}):v.t("components.outdated_manual",{tool:t.name,current:t.current??"?",latest:t.latest??"?",by:t.managed_by??"?",how:at(t),command:`${rt(t.id)} --force`})}export function setComponentDepsForTests(t){void 0!==t.platform&&(O=t.platform),void 0!==t.uid&&(U=t.uid),void 0!==t.systemPaths&&(I=t.systemPaths),t.registryPath&&(G=t.registryPath,J=null),t.versionRunner&&(B=t.versionRunner),t.macDeveloperTools&&(F=t.macDeveloperTools),t.fetchText&&(Z=t.fetchText),t.scriptRunner&&(tt=t.scriptRunner),t.commandRunner&&(et=t.commandRunner)}
|
package/dist/lib/dry-run.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{firstCommandWord as e}from"./cli-help.js";export function dryRunUnsupportedCommand(s){const n=e(s);if(void 0===n)return"(wizard)";const r=s.filter(e=>!e.startsWith("-")),o=r[r.indexOf(n)+1];switch(n){case"setup":case"config":case"status":case"bench":case"logs":case"completion":case"help":return null;case"doctor":return s.includes("--report")?"doctor --report":null;case"base":return void 0===o?null:`base ${o}`;case"lang":return void 0===o||"show"===o?null:`lang ${o}`;case"codex":return s.includes("--undo")?"codex sessions --undo":null;case"sessions":return"export"===o?"sessions export":"resume"===o&&s.includes("--run")?"sessions resume --run":null;default:return n}}
|
|
1
|
+
import{firstCommandWord as e}from"./cli-help.js";export function dryRunUnsupportedCommand(s){const n=e(s);if(void 0===n)return"(wizard)";const r=s.filter(e=>!e.startsWith("-")),o=r[r.indexOf(n)+1];switch(n){case"setup":case"config":case"status":case"bench":case"logs":case"list":case"completion":case"help":return null;case"doctor":return s.includes("--report")?"doctor --report":null;case"base":return void 0===o?null:`base ${o}`;case"lang":return void 0===o||"show"===o?null:`lang ${o}`;case"codex":return s.includes("--undo")?"codex sessions --undo":null;case"sessions":return"export"===o?"sessions export":"resume"===o&&s.includes("--run")?"sessions resume --run":null;default:return n}}
|
package/dist/lib/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as y}from"../commands/logs.js";import{completionCommand as $}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{codexSessionsCommand as w}from"../commands/codex-sessions.js";import{sessionsExportCommand as v,sessionsListCommand as j,sessionsResumeCommand as O,sessionsShowCommand as S}from"../commands/sessions.js";import{setupCommand as A,DEDICATED_KEYS as E}from"../commands/setup.js";import{baseCommand as G}from"../commands/base.js";import{usageError as z}from"./errors.js";import{requireTerminal as C}from"./confirm.js";import{brand as R,brandEnv as B,CLI_NAME as I}from"./brand.js";const L=(R().gatewayAddresses[1]??R().gatewayAddresses[0]).url,N=(R().gatewayAddresses[2]??R().gatewayAddresses[0]).url;function P(e,o){return i.t(`help.${e}`,o)}function T(e,o){return{command:e,note:P(o)}}function U(e){const o=P(e);return o===`help.${e}`?"":o}function H(e,o=[]){return{when:U(`${e}.when`),prerequisites:U(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>T(e,o))}}function K(e){return e.helpCommand("help [command]",P("help_command"))}export function buildProgram(){const R=new e;R.name(`${I}`).summary(P("root.summary")).description(P("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(P("group.global_options")).helpOption("-h, --help",P("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",P("global.version")).option("--base <url>",P("global.base")).option("--non-interactive",P("global.non_interactive")).option("--json",P("global.json")).option("-y, --yes",P("global.yes")).option("--dry-run",P("global.dry_run")).option("--no-color",P("global.no_color")),R.configureOutput({writeErr:()=>{},outputError:()=>{}}),R.showSuggestionAfterError(),R.exitOverride(e=>{throw e}),R.commandsGroup(P("group.configure"));const U=R.command("setup").summary(P("setup.summary")).description(P("setup.description")).option("--key <key>",P("setup.opt.key"));for(const e of E){const s=new o(`--${e.option} <key>`,P(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),U.addOption(s)}U.option("--1m",P("setup.opt.one_m")).option("--no-1m",P("setup.opt.no_one_m")).option("--claude-official <on|off>",P("setup.opt.claude_official")).option("--desktop-registry <on|off>",P("setup.opt.desktop_registry")).option("--force",P("setup.opt.force")).option("--install",P("setup.opt.install")).option("--no-install",P("setup.opt.no_install")).option("--all",P("setup.opt.all")).action(async e=>{e.key||E.some(o=>e[o.option])||(e.key=B("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||E.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw z(i.t("setup.usage"),`${I} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw z(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${I} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw z(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${I} setup --desktop-registry on|off`,"invalid_value");await A({key:e.key,...Object.fromEntries(E.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(U,{...H("setup",[[`${I} init`,"setup.alt.init"],[`${I} config <tool>`,"setup.alt.config"],[`${I} auth <key>`,"setup.alt.auth"]]),sections:[{title:P("setup.autodetect_title"),rows:[["Claude",P("setup.autodetect.claude")],["GPT",P("setup.autodetect.gpt")],["Grok",P("setup.autodetect.grok")],["Gemini",P("setup.autodetect.gemini")]]}],examples:[T(`${I} setup --key sk-xxx`,"setup.ex.key"),T(`${I} setup --install --key sk-xxx`,"setup.ex.install"),T(`${I} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),T(`${I} setup --force --key sk-xxx`,"setup.ex.force"),T(`${I} setup --base ${L} --key sk-xxx`,"setup.ex.base")]});const M=R.command("init").summary(P("init.summary")).description(P("init.description")).action(async()=>{C(),await r.runFirstTimeSetup()});p(M,{...H("init",[[`${I} setup --key <key>`,"init.alt.setup"],[`${I}`,"init.alt.menu"]]),examples:[T(`${I} init`,"init.ex.run"),T(`${I} init --base ${L}`,"init.ex.base"),T(`${I}`,"init.ex.menu")]});const q=R.command("auth").summary(P("auth.summary")).description(P("auth.description")).argument("[token]",P("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});K(q);const D=q.command("revoke").description(P("auth.revoke")).action(async()=>{await d(["revoke"])});p(D,{examples:[T(`${I} auth revoke`,"auth.ex.revoke_ask"),T(`${I} auth revoke --yes`,"auth.ex.revoke")]});const F=q.command("reload <tool>").description(P("auth.reload")).action(async e=>{await d(["reload",e])});p(F,{examples:[T(`${I} auth reload claude-code`,"auth.ex.reload"),T(`${I} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(q,{...H("auth",[[`${I} setup --key <key>`,"auth.alt.setup"]]),examples:[T(`${I} auth`,"auth.ex.prompt"),T(`${I} auth sk-xxx --non-interactive`,"auth.ex.save"),T(`${I} auth revoke --yes`,"auth.ex.revoke"),T(`${I} auth reload claude-code`,"auth.ex.reload")]});const J=R.command("config").summary(P("config.summary")).description(P("config.description")).argument("[args...]",P("config.arg.args")).option("-f, --force",P("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(J,{...H("config",[[`${I} setup --force --key <key>`,"config.alt.setup"],[`${I} status`,"config.alt.status"]]),sections:[{title:P("config.subcommands_title"),rows:[["<tool>",P("config.sub.tool")],["<tool> --force",P("config.sub.tool_force")],["<tool> --non-interactive",P("config.sub.tool_non_interactive")],["<tool> remove",P("config.sub.tool_remove")],["<tool> restore",P("config.sub.tool_restore")],["<tool> backups",P("config.sub.tool_backups")],["<tool> clear-model",P("config.sub.tool_clear_model")],["tool-model list",P("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",P("config.sub.tool_model_set")],["tool-model clear <tool>",P("config.sub.tool_model_clear")],["profile list",P("config.sub.profile_list")],["profile create <name>",P("config.sub.profile_create")],["profile use <name>",P("config.sub.profile_use")],["profile delete <name>",P("config.sub.profile_delete")],["preset list",P("config.sub.preset_list")],["preset save <name>",P("config.sub.preset_save")],["preset use <name>",P("config.sub.preset_use")],["preset delete <name>",P("config.sub.preset_delete")],["backup list",P("config.sub.backup_list")],["backup create [label]",P("config.sub.backup_create")],["backup restore <name>",P("config.sub.backup_restore")]]},{title:P("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[T(`${I} config codex`,"config.ex.menu"),T(`${I} config claude-code --force`,"config.ex.force"),T(`${I} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),T(`${I} config profile create work`,"config.ex.profile"),T(`${I} config codex remove`,"config.ex.remove")]});const Y=R.command("base").summary(P("base.summary")).description(P("base.description")).argument("[target]",P("base.arg.target")).action(async e=>{await G(e)});p(Y,{...H("base",[[`${I} doctor`,"base.alt.doctor"],[`${I} bench`,"base.alt.bench"]]),sections:[{title:P("base.targets_title"),rows:[[P("base.target.none_term"),P("base.target.none")],[P("base.target.index_term"),P("base.target.index")],[P("base.target.url_term"),P("base.target.url")],["auto",P("base.target.auto")],["default",P("base.target.default",{url:l})]]}],examples:[T(`${I} base`,"base.ex.list"),T(`${I} base auto`,"base.ex.auto"),T(`${I} base 2`,"base.ex.index"),T(`${I} base ${L}`,"base.ex.url"),T(`${I} base default`,"base.ex.default")]}),R.commandsGroup(P("group.diagnose"));const Q=R.command("status").summary(P("status.summary")).description(P("status.description")).action(async()=>{await x()});p(Q,{...H("status",[[`${I} doctor`,"status.alt.doctor"]]),examples:[T(`${I} status`,"status.ex.show"),T(`${I} status --json`,"status.ex.json")]});const V=R.command("doctor").summary(P("doctor.summary")).description(P("doctor.description")).option("--deep",P("doctor.opt.deep")).option("--report",P("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(V,{...H("doctor",[[`${I} base auto`,"doctor.alt.base"],[`${I} logs tail`,"doctor.alt.logs"]]),examples:[T(`${I} doctor`,"doctor.ex.run"),T(`${I} doctor --deep`,"doctor.ex.deep"),T(`${I} doctor --report`,"doctor.ex.report")]});const W=R.command("bench").summary(P("bench.summary")).description(P("bench.description")).option("--samples <n>",P("bench.opt.samples"),"5").option("--stream",P("bench.opt.stream")).option("--model <model>",P("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(W,{...H("bench",[[`${I} base`,"bench.alt.base"]]),examples:[T(`${I} bench`,"bench.ex.run"),T(`${I} bench --samples 3`,"bench.ex.samples"),T(`${I} bench --stream`,"bench.ex.stream"),T(`${I} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),T(`${I} bench --json`,"bench.ex.json")]});const X=R.command("logs").summary(P("logs.summary")).description(P("logs.description")).argument("[action]",P("logs.arg.action")).argument("[file]",P("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await y(s)});p(X,{...H("logs",[[`${I} doctor`,"logs.alt.doctor"]]),sections:[{title:P("logs.actions_title"),rows:[["list",P("logs.action.list")],["tail [file]",P("logs.action.tail")],["path",P("logs.action.path")]]}],examples:[T(`${I} logs`,"logs.ex.list"),T(`${I} logs tail`,"logs.ex.tail"),T(`${I} logs path`,"logs.ex.path")]}),R.commandsGroup(P("group.maintain"));const Z=R.command("upgrade").summary(P("upgrade.summary")).description(P("upgrade.description")).argument("[tools...]",P("upgrade.arg.tools")).option("--force",P("upgrade.opt.force")).action(async(e=[],o={})=>{await _(e,{force:o.force})});p(Z,{...H("upgrade",[[`${I} update`,"upgrade.alt.update"]]),examples:[T(`${I} upgrade`,"upgrade.ex.all"),T(`${I} upgrade claude-code`,"upgrade.ex.one"),T(`${I} upgrade codex agy`,"upgrade.ex.many"),T(`${I} upgrade claude-desktop`,"upgrade.ex.desktop"),T(`${I} upgrade chatgpt --force`,"upgrade.ex.force")]});const ee=R.command("refresh").summary(P("refresh.summary")).description(P("refresh.description")).action(async()=>{await h()});p(ee,{...H("refresh",[[`${I} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[T(`${I} refresh`,"refresh.ex.run"),T(`${I} refresh --base ${N}`,"refresh.ex.base")]});const oe=R.command("update").summary(P("update.summary")).description(P("update.description")).action(async()=>{await k()});p(oe,{...H("update",[[`${I} upgrade`,"update.alt.upgrade"]]),examples:[T(`${I} update`,"update.ex.check"),T(`${I} update --json`,"update.ex.json")]});const se=R.command("codex").summary(P("codex.summary")).description(P("codex.description"));K(se);const te=se.command("sessions").summary(P("codex_sessions.summary")).description(P("codex_sessions.description")).option("--to <provider>",P("codex_sessions.opt.to")).option("--undo <dir>",P("codex_sessions.opt.undo")).action(async e=>{await w(e)});p(se,{...H("codex"),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(te,{...H("codex_sessions",[[`${I} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --to custom`,"codex_sessions.ex.to"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ne=R.command("sessions").summary(P("sessions.summary")).description(P("sessions.description"));K(ne);const ae=ne.command("list",{isDefault:!0}).description(P("sessions.list")).option("--tool <tool>",P("sessions.opt.tool")).option("--dir <path>",P("sessions.opt.dir")).option("--here",P("sessions.opt.here")).option("-n, --limit <count>",P("sessions.opt.limit")).option("--all",P("sessions.opt.all")).action(async e=>{await j(e)}),ie=ne.command("show <id>").description(P("sessions.show")).option("-m, --messages <count>",P("sessions.opt.messages")).action(async(e,o)=>{await S(e,o)}),re=ne.command("resume <id>").description(P("sessions.resume")).option("--run",P("sessions.opt.run")).action(async(e,o)=>{await O(e,o)}),ce=ne.command("export <ids...>").description(P("sessions.export")).option("-o, --output <dir>",P("sessions.opt.output")).option("--tools",P("sessions.opt.tools")).action(async(e,o)=>{await v(e,o)});p(ae,{examples:[T(`${I} sessions list`,"sessions.ex.list"),T(`${I} sessions list --tool codex`,"sessions.ex.codex"),T(`${I} sessions list --here --all`,"sessions.ex.here"),T(`${I} sessions list --json`,"sessions.ex.json")]}),p(ie,{examples:[T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(re,{examples:[T(`${I} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ce,{examples:[T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),T(`${I} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ne,{...H("sessions",[[`${I} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[T(`${I} sessions`,"sessions.ex.list"),T(`${I} sessions --tool codex --here`,"sessions.ex.here"),T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const le=R.command("lang").summary(P("lang.summary")).description(P("lang.description"));K(le);const pe=le.command("show").description(P("lang.show")).action(async()=>{await u(["show"])}),me=le.command("set <locale>").description(P("lang.set")).action(async e=>{await u(["set",e])}),ue=[T(`${I} lang show`,"lang.ex.show"),T(`${I} lang set en_US`,"lang.ex.set_en"),T(`${I} lang set zh_CN`,"lang.ex.set_zh")];p(le,{...H("lang",[[`${I} enter lang`,"lang.alt.enter"]]),examples:ue}),p(pe,{examples:[ue[0],T(`${I} lang show --json`,"lang.ex.show_json")]}),p(me,{examples:ue.slice(1)});const de=R.command("completion").summary(P("completion.summary")).description(P("completion.description")).argument("<shell>",P("completion.arg.shell")).action(async e=>{await $([e])});p(de,{...H("completion"),examples:[T(`${I} completion bash > ~/.${I}-completion.bash`,"completion.ex.bash"),T(`${I} completion zsh > ~/.${I}-completion.zsh`,"completion.ex.zsh"),T(`${I} completion fish > ~/.config/fish/completions/${I}.fish`,"completion.ex.fish")]});const fe=R.command("enter").summary(P("enter.summary")).description(P("enter.description")).argument("[option]",P("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||C(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p(fe,{...H("enter",[[`${I}`,"enter.alt.menu"],[`${I} config <tool>`,"enter.alt.config"]]),sections:[{title:P("enter.options_title"),rows:[[P("enter.option.none_term"),P("enter.option.none")],["lang",P("enter.option.lang")],["apikey",P("enter.option.apikey")],["models",P("enter.option.models")],["<tool>",P("enter.option.tool")]]}],examples:[T(`${I} enter`,"enter.ex.menu"),T(`${I} enter models`,"enter.ex.models"),T(`${I} enter codex`,"enter.ex.tool")]}),K(R),R.action(async()=>{C(),await r.run()}),p(R,{examples:[T(`${I}`,"root.ex.menu"),T(`${I} setup --key sk-xxx`,"root.ex.setup"),T(`${I} doctor`,"root.ex.doctor"),T(`${I} base auto`,"root.ex.base"),T(`${I} config codex`,"root.ex.config")]});const ge=e=>{for(const o of e.commands)o.helpOption("-h, --help",P("global.help")),ge(o)};return ge(R),R}
|
|
1
|
+
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as $}from"../commands/logs.js";import{completionCommand as y}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{installCommand as w,listCommand as v}from"../commands/components.js";import{codexSessionsCommand as j}from"../commands/codex-sessions.js";import{sessionsExportCommand as O,sessionsListCommand as S,sessionsResumeCommand as A,sessionsShowCommand as E}from"../commands/sessions.js";import{setupCommand as G,DEDICATED_KEYS as z}from"../commands/setup.js";import{baseCommand as C}from"../commands/base.js";import{usageError as R}from"./errors.js";import{requireTerminal as B}from"./confirm.js";import{brand as I,brandEnv as L,CLI_NAME as N}from"./brand.js";const P=(I().gatewayAddresses[1]??I().gatewayAddresses[0]).url,T=(I().gatewayAddresses[2]??I().gatewayAddresses[0]).url;function U(e,o){return i.t(`help.${e}`,o)}function H(e,o){return{command:e,note:U(o)}}function K(e){const o=U(e);return o===`help.${e}`?"":o}function M(e,o=[]){return{when:K(`${e}.when`),prerequisites:K(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>H(e,o))}}function q(e){return e.helpCommand("help [command]",U("help_command"))}export function buildProgram(){const I=new e;I.name(`${N}`).summary(U("root.summary")).description(U("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(U("group.global_options")).helpOption("-h, --help",U("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",U("global.version")).option("--base <url>",U("global.base")).option("--non-interactive",U("global.non_interactive")).option("--json",U("global.json")).option("-y, --yes",U("global.yes")).option("--dry-run",U("global.dry_run")).option("--no-color",U("global.no_color")),I.configureOutput({writeErr:()=>{},outputError:()=>{}}),I.showSuggestionAfterError(),I.exitOverride(e=>{throw e}),I.commandsGroup(U("group.configure"));const K=I.command("setup").summary(U("setup.summary")).description(U("setup.description")).option("--key <key>",U("setup.opt.key"));for(const e of z){const s=new o(`--${e.option} <key>`,U(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),K.addOption(s)}K.option("--1m",U("setup.opt.one_m")).option("--no-1m",U("setup.opt.no_one_m")).option("--claude-official <on|off>",U("setup.opt.claude_official")).option("--desktop-registry <on|off>",U("setup.opt.desktop_registry")).option("--force",U("setup.opt.force")).option("--install",U("setup.opt.install")).option("--no-install",U("setup.opt.no_install")).option("--all",U("setup.opt.all")).action(async e=>{e.key||z.some(o=>e[o.option])||(e.key=L("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||z.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw R(i.t("setup.usage"),`${N} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw R(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${N} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw R(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${N} setup --desktop-registry on|off`,"invalid_value");await G({key:e.key,...Object.fromEntries(z.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(K,{...M("setup",[[`${N} init`,"setup.alt.init"],[`${N} config <tool>`,"setup.alt.config"],[`${N} auth <key>`,"setup.alt.auth"]]),sections:[{title:U("setup.autodetect_title"),rows:[["Claude",U("setup.autodetect.claude")],["GPT",U("setup.autodetect.gpt")],["Grok",U("setup.autodetect.grok")],["Gemini",U("setup.autodetect.gemini")]]}],examples:[H(`${N} setup --key sk-xxx`,"setup.ex.key"),H(`${N} setup --install --key sk-xxx`,"setup.ex.install"),H(`${N} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),H(`${N} setup --force --key sk-xxx`,"setup.ex.force"),H(`${N} setup --base ${P} --key sk-xxx`,"setup.ex.base")]});const D=I.command("init").summary(U("init.summary")).description(U("init.description")).action(async()=>{B(),await r.runFirstTimeSetup()});p(D,{...M("init",[[`${N} setup --key <key>`,"init.alt.setup"],[`${N}`,"init.alt.menu"]]),examples:[H(`${N} init`,"init.ex.run"),H(`${N} init --base ${P}`,"init.ex.base"),H(`${N}`,"init.ex.menu")]});const F=I.command("auth").summary(U("auth.summary")).description(U("auth.description")).argument("[token]",U("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});q(F);const J=F.command("revoke").description(U("auth.revoke")).action(async()=>{await d(["revoke"])});p(J,{examples:[H(`${N} auth revoke`,"auth.ex.revoke_ask"),H(`${N} auth revoke --yes`,"auth.ex.revoke")]});const Y=F.command("reload <tool>").description(U("auth.reload")).action(async e=>{await d(["reload",e])});p(Y,{examples:[H(`${N} auth reload claude-code`,"auth.ex.reload"),H(`${N} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(F,{...M("auth",[[`${N} setup --key <key>`,"auth.alt.setup"]]),examples:[H(`${N} auth`,"auth.ex.prompt"),H(`${N} auth sk-xxx --non-interactive`,"auth.ex.save"),H(`${N} auth revoke --yes`,"auth.ex.revoke"),H(`${N} auth reload claude-code`,"auth.ex.reload")]});const Q=I.command("config").summary(U("config.summary")).description(U("config.description")).argument("[args...]",U("config.arg.args")).option("-f, --force",U("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(Q,{...M("config",[[`${N} setup --force --key <key>`,"config.alt.setup"],[`${N} status`,"config.alt.status"]]),sections:[{title:U("config.subcommands_title"),rows:[["<tool>",U("config.sub.tool")],["<tool> --force",U("config.sub.tool_force")],["<tool> --non-interactive",U("config.sub.tool_non_interactive")],["<tool> remove",U("config.sub.tool_remove")],["<tool> restore",U("config.sub.tool_restore")],["<tool> backups",U("config.sub.tool_backups")],["<tool> clear-model",U("config.sub.tool_clear_model")],["tool-model list",U("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",U("config.sub.tool_model_set")],["tool-model clear <tool>",U("config.sub.tool_model_clear")],["profile list",U("config.sub.profile_list")],["profile create <name>",U("config.sub.profile_create")],["profile use <name>",U("config.sub.profile_use")],["profile delete <name>",U("config.sub.profile_delete")],["preset list",U("config.sub.preset_list")],["preset save <name>",U("config.sub.preset_save")],["preset use <name>",U("config.sub.preset_use")],["preset delete <name>",U("config.sub.preset_delete")],["backup list",U("config.sub.backup_list")],["backup create [label]",U("config.sub.backup_create")],["backup restore <name>",U("config.sub.backup_restore")]]},{title:U("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[H(`${N} config codex`,"config.ex.menu"),H(`${N} config claude-code --force`,"config.ex.force"),H(`${N} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),H(`${N} config profile create work`,"config.ex.profile"),H(`${N} config codex remove`,"config.ex.remove")]});const V=I.command("base").summary(U("base.summary")).description(U("base.description")).argument("[target]",U("base.arg.target")).action(async e=>{await C(e)});p(V,{...M("base",[[`${N} doctor`,"base.alt.doctor"],[`${N} bench`,"base.alt.bench"]]),sections:[{title:U("base.targets_title"),rows:[[U("base.target.none_term"),U("base.target.none")],[U("base.target.index_term"),U("base.target.index")],[U("base.target.url_term"),U("base.target.url")],["auto",U("base.target.auto")],["default",U("base.target.default",{url:l})]]}],examples:[H(`${N} base`,"base.ex.list"),H(`${N} base auto`,"base.ex.auto"),H(`${N} base 2`,"base.ex.index"),H(`${N} base ${P}`,"base.ex.url"),H(`${N} base default`,"base.ex.default")]}),I.commandsGroup(U("group.diagnose"));const W=I.command("status").summary(U("status.summary")).description(U("status.description")).action(async()=>{await x()});p(W,{...M("status",[[`${N} doctor`,"status.alt.doctor"]]),examples:[H(`${N} status`,"status.ex.show"),H(`${N} status --json`,"status.ex.json")]});const X=I.command("doctor").summary(U("doctor.summary")).description(U("doctor.description")).option("--deep",U("doctor.opt.deep")).option("--report",U("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(X,{...M("doctor",[[`${N} base auto`,"doctor.alt.base"],[`${N} logs tail`,"doctor.alt.logs"]]),examples:[H(`${N} doctor`,"doctor.ex.run"),H(`${N} doctor --deep`,"doctor.ex.deep"),H(`${N} doctor --report`,"doctor.ex.report")]});const Z=I.command("bench").summary(U("bench.summary")).description(U("bench.description")).option("--samples <n>",U("bench.opt.samples"),"5").option("--stream",U("bench.opt.stream")).option("--model <model>",U("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(Z,{...M("bench",[[`${N} base`,"bench.alt.base"]]),examples:[H(`${N} bench`,"bench.ex.run"),H(`${N} bench --samples 3`,"bench.ex.samples"),H(`${N} bench --stream`,"bench.ex.stream"),H(`${N} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),H(`${N} bench --json`,"bench.ex.json")]});const ee=I.command("logs").summary(U("logs.summary")).description(U("logs.description")).argument("[action]",U("logs.arg.action")).argument("[file]",U("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await $(s)});p(ee,{...M("logs",[[`${N} doctor`,"logs.alt.doctor"]]),sections:[{title:U("logs.actions_title"),rows:[["list",U("logs.action.list")],["tail [file]",U("logs.action.tail")],["path",U("logs.action.path")]]}],examples:[H(`${N} logs`,"logs.ex.list"),H(`${N} logs tail`,"logs.ex.tail"),H(`${N} logs path`,"logs.ex.path")]}),I.commandsGroup(U("group.maintain"));const oe=I.command("list").summary(U("list.summary")).description(U("list.description")).option("--refresh",U("list.opt.refresh")).action(async(e={})=>{await v({refresh:e.refresh})});p(oe,{...M("list",[[`${N} doctor`,"list.alt.doctor"]]),examples:[H(`${N} list`,"list.ex.all"),H(`${N} list --refresh`,"list.ex.refresh"),H(`${N} list --json`,"list.ex.json")]});const se=I.command("install").summary(U("install.summary")).description(U("install.description")).argument("<components...>",U("install.arg.components")).option("--force",U("install.opt.force")).action(async(e,o={})=>{await w(e,{force:o.force})});p(se,{...M("install",[[`${N} upgrade`,"install.alt.upgrade"],[`${N} setup --key ${i.t("errors.key_placeholder")}`,"install.alt.setup"]]),examples:[H(`${N} install node uv`,"install.ex.runtimes"),H(`${N} install claude-code codex`,"install.ex.clis"),H(`${N} install chatgpt`,"install.ex.app"),H(`${N} install uv --force`,"install.ex.force"),H(`${N} install node uv --yes --json`,"install.ex.json")]});const te=I.command("upgrade").summary(U("upgrade.summary")).description(U("upgrade.description")).argument("[tools...]",U("upgrade.arg.tools")).option("--force",U("upgrade.opt.force")).action(async(e=[],o={})=>{await _(e,{force:o.force})});p(te,{...M("upgrade",[[`${N} update`,"upgrade.alt.update"]]),examples:[H(`${N} upgrade`,"upgrade.ex.all"),H(`${N} upgrade codex agy`,"upgrade.ex.many"),H(`${N} upgrade claude-desktop`,"upgrade.ex.desktop"),H(`${N} upgrade chatgpt --force`,"upgrade.ex.force"),H(`${N} upgrade node`,"upgrade.ex.runtime")]});const ne=I.command("refresh").summary(U("refresh.summary")).description(U("refresh.description")).action(async()=>{await h()});p(ne,{...M("refresh",[[`${N} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[H(`${N} refresh`,"refresh.ex.run"),H(`${N} refresh --base ${T}`,"refresh.ex.base")]});const ae=I.command("update").summary(U("update.summary")).description(U("update.description")).action(async()=>{await k()});p(ae,{...M("update",[[`${N} upgrade`,"update.alt.upgrade"]]),examples:[H(`${N} update`,"update.ex.check"),H(`${N} update --json`,"update.ex.json")]});const ie=I.command("codex").summary(U("codex.summary")).description(U("codex.description"));q(ie);const re=ie.command("sessions").summary(U("codex_sessions.summary")).description(U("codex_sessions.description")).option("--to <provider>",U("codex_sessions.opt.to")).option("--undo <dir>",U("codex_sessions.opt.undo")).action(async e=>{await j(e)});p(ie,{...M("codex"),examples:[H(`${N} codex sessions`,"codex_sessions.ex.move"),H(`${N} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(re,{...M("codex_sessions",[[`${N} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[H(`${N} codex sessions`,"codex_sessions.ex.move"),H(`${N} codex sessions --to custom`,"codex_sessions.ex.to"),H(`${N} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ce=I.command("sessions").summary(U("sessions.summary")).description(U("sessions.description"));q(ce);const le=ce.command("list",{isDefault:!0}).description(U("sessions.list")).option("--tool <tool>",U("sessions.opt.tool")).option("--dir <path>",U("sessions.opt.dir")).option("--here",U("sessions.opt.here")).option("-n, --limit <count>",U("sessions.opt.limit")).option("--all",U("sessions.opt.all")).action(async e=>{await S(e)}),pe=ce.command("show <id>").description(U("sessions.show")).option("-m, --messages <count>",U("sessions.opt.messages")).action(async(e,o)=>{await E(e,o)}),me=ce.command("resume <id>").description(U("sessions.resume")).option("--run",U("sessions.opt.run")).action(async(e,o)=>{await A(e,o)}),ue=ce.command("export <ids...>").description(U("sessions.export")).option("-o, --output <dir>",U("sessions.opt.output")).option("--tools",U("sessions.opt.tools")).action(async(e,o)=>{await O(e,o)});p(le,{examples:[H(`${N} sessions list`,"sessions.ex.list"),H(`${N} sessions list --tool codex`,"sessions.ex.codex"),H(`${N} sessions list --here --all`,"sessions.ex.here"),H(`${N} sessions list --json`,"sessions.ex.json")]}),p(pe,{examples:[H(`${N} sessions show 01a0f5fe`,"sessions.ex.show"),H(`${N} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(me,{examples:[H(`${N} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),H(`${N} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ue,{examples:[H(`${N} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),H(`${N} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ce,{...M("sessions",[[`${N} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[H(`${N} sessions`,"sessions.ex.list"),H(`${N} sessions --tool codex --here`,"sessions.ex.here"),H(`${N} sessions show 01a0f5fe`,"sessions.ex.show"),H(`${N} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),H(`${N} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const de=I.command("lang").summary(U("lang.summary")).description(U("lang.description"));q(de);const fe=de.command("show").description(U("lang.show")).action(async()=>{await u(["show"])}),ge=de.command("set <locale>").description(U("lang.set")).action(async e=>{await u(["set",e])}),xe=[H(`${N} lang show`,"lang.ex.show"),H(`${N} lang set en_US`,"lang.ex.set_en"),H(`${N} lang set zh_CN`,"lang.ex.set_zh")];p(de,{...M("lang",[[`${N} enter lang`,"lang.alt.enter"]]),examples:xe}),p(fe,{examples:[xe[0],H(`${N} lang show --json`,"lang.ex.show_json")]}),p(ge,{examples:xe.slice(1)});const he=I.command("completion").summary(U("completion.summary")).description(U("completion.description")).argument("<shell>",U("completion.arg.shell")).action(async e=>{await y([e])});p(he,{...M("completion"),examples:[H(`${N} completion bash > ~/.${N}-completion.bash`,"completion.ex.bash"),H(`${N} completion zsh > ~/.${N}-completion.zsh`,"completion.ex.zsh"),H(`${N} completion fish > ~/.config/fish/completions/${N}.fish`,"completion.ex.fish")]});const $e=I.command("enter").summary(U("enter.summary")).description(U("enter.description")).argument("[option]",U("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||B(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p($e,{...M("enter",[[`${N}`,"enter.alt.menu"],[`${N} config <tool>`,"enter.alt.config"]]),sections:[{title:U("enter.options_title"),rows:[[U("enter.option.none_term"),U("enter.option.none")],["lang",U("enter.option.lang")],["apikey",U("enter.option.apikey")],["models",U("enter.option.models")],["<tool>",U("enter.option.tool")]]}],examples:[H(`${N} enter`,"enter.ex.menu"),H(`${N} enter models`,"enter.ex.models"),H(`${N} enter codex`,"enter.ex.tool")]}),q(I),I.action(async()=>{B(),await r.run()}),p(I,{examples:[H(`${N}`,"root.ex.menu"),H(`${N} setup --key sk-xxx`,"root.ex.setup"),H(`${N} doctor`,"root.ex.doctor"),H(`${N} base auto`,"root.ex.base"),H(`${N} config codex`,"root.ex.config")]});const ye=e=>{for(const o of e.commands)o.helpOption("-h, --help",U("global.help")),ye(o)};return ye(I),I}
|
|
@@ -23,3 +23,8 @@ export declare function isColorEnabled(): boolean;
|
|
|
23
23
|
export declare function resetRuntimeOptions(): void;
|
|
24
24
|
export declare function detectColorPreferenceFromEnv(env?: NodeJS.ProcessEnv): boolean;
|
|
25
25
|
export declare function emitJson(data: unknown, output?: (line: string) => void): void;
|
|
26
|
+
/**
|
|
27
|
+
* Under `--json`, everything `fn` prints with console.log goes to stderr, so stdout stays the one JSON document the
|
|
28
|
+
* command emits afterwards (install / upgrade reuse code that reports progress on stdout).
|
|
29
|
+
*/
|
|
30
|
+
export declare function progressToStderr<T>(fn: () => Promise<T>): Promise<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const n={nonInteractive:!1,json:!1,yes:!1,dryRun:!1,color:!0};let
|
|
1
|
+
const n={nonInteractive:!1,json:!1,yes:!1,dryRun:!1,color:!0};let o={...n};export function setRuntimeOptions(n){o={...o,...n}}export function getRuntimeOptions(){return{...o}}export function isJsonMode(){return o.json}export function isNonInteractive(){return o.nonInteractive||o.json}export function isDryRun(){return o.dryRun}export function shouldAutoConfirm(){return o.yes||o.nonInteractive||o.json}export function canPrompt(){return!isNonInteractive()&&Boolean(process.stdin.isTTY)}export function hasExplicitYes(){return o.yes}export function isColorEnabled(){return o.color}export function resetRuntimeOptions(){o={...n}}export function detectColorPreferenceFromEnv(n=process.env){return(!n.NO_COLOR||"0"===n.NO_COLOR)&&"0"!==n.FORCE_COLOR&&"false"!==n.FORCE_COLOR}export function emitJson(n,o=n=>process.stdout.write(n+"\n")){o(JSON.stringify(n,null,2))}export async function progressToStderr(n){if(!isJsonMode())return n();const o=console.log;console.log=(...n)=>console.error(...n);try{return await n()}finally{console.log=o}}
|
|
@@ -6,6 +6,8 @@ export interface RunLimits {
|
|
|
6
6
|
timeoutMs?: number;
|
|
7
7
|
/** Stop once the command has printed nothing for this long (download progress counts as output). */
|
|
8
8
|
idleMs?: number;
|
|
9
|
+
/** Extra environment variables for the command (install scripts' NODE_INSTALL_FORCE …). */
|
|
10
|
+
env?: Record<string, string>;
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* Runs a command with its output passed through to the terminal, stopping it once it goes quiet
|
package/dist/lib/tool-upgrade.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as s}from"./i18n.js";import{logger as a}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as u,forgetInstalls as
|
|
1
|
+
import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as s}from"./i18n.js";import{logger as a}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as m,findInstallsIncludingNative as u,forgetInstalls as d,installLabel as g,npmMirrorInstallCommand as f,npmMirrorVersion as w,npmUninstallCommand as h}from"./tools/tool-installs.js";import{toolHome as y}from"./tools/types.js";import{isJsonMode as v,isNonInteractive as _,shouldAutoConfirm as k}from"./runtime-options.js";import{track as b}from"./telemetry.js";import{isWindowsPowerShell as $,powerShellEnv as j}from"./powershell-env.js";let T="ok",M=async(t,o,r={})=>(console.log(n.gray("$ ")+[t,...o].join(" ")),T=r.idleMs?await runWatched(t,o,r):function(t,o,r){const n=D(t)?e(E(t,o),{stdio:S(),shell:!0,timeout:r}):e(t,o,{stdio:S(),timeout:r,env:x(t)});return n.error&&a.logError(`upgrade: ${t}`,n.error),"ETIMEDOUT"===n.error?.code?"timeout":0===n.status?"ok":"fail"}(t,o,r.timeoutMs),"ok"===T);const D=t=>"win32"===process.platform&&!/\.exe$/i.test(t),x=t=>$(t)?j():process.env,E=(t,e)=>[t,...e].map(t=>/\s/.test(t)?`"${t}"`:t).join(" "),S=()=>["inherit",v()?2:"inherit","inherit"];export function runWatched(e,o,r){return new Promise(n=>{const i=r.env?{...x(e),...r.env}:x(e),s=D(e)?t(E(e,o),{stdio:["inherit","pipe","pipe"],shell:!0,env:i}):t(e,o,{stdio:["inherit","pipe","pipe"],env:i});let l;const c=t=>{l=t,s.kill()};let p;const m=()=>{clearTimeout(p),r.idleMs&&(p=setTimeout(()=>c("stalled"),r.idleMs))},u=r.timeoutMs?setTimeout(()=>c("timeout"),r.timeoutMs):void 0;m(),s.stdout?.on("data",t=>{(v()?process.stderr:process.stdout).write(t),m()}),s.stderr?.on("data",t=>{process.stderr.write(t),m()});const d=t=>{clearTimeout(p),clearTimeout(u),n(t)};s.on("error",t=>{a.logError(`upgrade: ${e}`,t),d(l??"fail")}),s.on("close",t=>{l&&(v()?process.stderr:process.stdout).write("\n"),d(l??(0===t?"ok":"fail"))})})}export function setUpgradeRunnerForTests(t){M=async(e,o,r)=>{const n=await t(e,o,r);return T="string"==typeof n?n:n?"ok":"fail","ok"===T}}const P={ok:"install.script_failed_npm",fail:"install.script_failed_npm",stalled:"install.script_stalled_npm",timeout:"install.script_timeout_npm"};export async function mirrorInstall(t){if(!t.mirrorScript)return I(t);console.log(n.gray(s.t("install.downloading")));const e=`install-script:${t.command}`,o=Date.now();b(e,"start");const r={idleMs:18e4,timeoutMs:36e5},i="win32"===process.platform?await M("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${t.mirrorScript.ps1} -TimeoutSec 30 | iex`],r):await M("sh",["-c",`script=$(curl -fsSL --connect-timeout 15 --max-time 60 ${t.mirrorScript.sh}) && printf '%s\\n' "$script" | sh`],r),a=T;return b(e,"stalled"===a?"timeout":a,{duration_ms:Date.now()-o,..."stalled"===a||"timeout"===a?{detail:{reason:a}}:{}}),i||!t.npmPackage?i:(console.log(n.yellow(" ! "+s.t(P[a],{minutes:String(3)}))),b(e,"fallback"),I(t))}async function I(t){const e=f(t,await w(t)),[o,...r]=e.split(" "),i=`install-npm:${t.command}`,a=Date.now();b(i,"start");const l=await M(o,r);return b(i,l?"ok":"fail",{duration_ms:Date.now()-a}),l||"win32"===process.platform||console.log(n.yellow(" ! "+s.t("upgrade.npm_permission",{command:e}))),l}async function U(t,e){switch(e.kind){case"npm":t.npmPackage&&await M("npm",["uninstall","-g",t.npmPackage]);break;case"brew":t.brew&&await M("brew",["uninstall",t.brew]);break;case"native":try{o(e.path,{force:!0});for(const e of t.native?.dataDirs??[])o(r(y(),...e),{recursive:!0,force:!0})}catch(t){a.logError("upgrade: remove native copy",t)}break;default:return!1}return d(),!m(t).some(t=>t.path===e.path)}function N(t,e){switch(e.kind){case"npm":return h(t);case"brew":return`brew uninstall ${t.brew}`;case"native":return s.t("upgrade.delete_paths",{paths:[e.path,...(t.native?.dataDirs??[]).map(t=>r(y(),...t))].join("、")});default:return s.t("upgrade.delete_paths",{paths:e.path})}}export async function upgradeTool(t){const e=Date.now();b(`upgrade:${t}`,"start");try{const o=await async function(t){const e=p(t),o=e?.installSpec;if(!e||!o)throw new Error(s.t("upgrade.unsupported",{tool:t}));const r=e.displayName;d();const f=m(o);if(console.log(n.bold(`\n${r}`)),0===f.length)console.log(s.t("upgrade.not_installed_installing",{tool:r})),await mirrorInstall(o);else{const t=f[0];console.log(n.gray(" "+s.t("upgrade.current",{copy:g(t)})));const e=await async function(t,e){switch(e.kind){case"native":return M(e.path,t.native?.updateArgs??["update"],{timeoutMs:t.native?.updateTimeoutMs});case"npm":return I(t);case"brew":return!!t.brew&&M("brew",["upgrade",t.brew]);default:return!1}}(o,t);e||"other"!==t.kind?e||"npm"===t.kind||"native"===t.kind&&await async function(t){const e=t.native?.mirrorUpdate;if(!e)return!1;console.log(n.yellow(" ! "+s.t("upgrade.native_mirror_trying")));try{const{version:t,manifestVerified:o}=await e();return console.log(n.green(" √ "+s.t(o?"upgrade.native_mirror_done_verified":"upgrade.native_mirror_done",{version:t}))),!0}catch(t){return a.logError("upgrade: native mirror",t),console.log(n.yellow(" ! "+s.t("upgrade.native_mirror_failed",{reason:t instanceof Error?t.message:String(t)}))),!1}}(o)||(console.log(n.yellow(" ! "+s.t("upgrade.fallback_mirror"))),await mirrorInstall(o)):console.log(n.yellow(" ! "+s.t("upgrade.unknown_install",{path:t.path})))}d(),await async function(t,e){const o=m(t);if(o.length<2)return;const r=function(t){return t.reduce((t,e)=>e.version&&(!t.version||l(e.version,t.version)>0)?e:t)}(o),a=o.filter(t=>t!==r);console.log(n.yellow(" ! "+s.t("upgrade.duplicates",{tool:e,keep:g(r),others:a.map(g).join("、")})));let c=k();c||_()||!process.stdin.isTTY||(c=(await i.prompt([{type:"confirm",name:"remove",message:s.t("upgrade.confirm_remove"),default:!0}])).remove);for(const e of a)c&&await U(t,e)?console.log(n.green(" √ "+s.t("upgrade.removed",{copy:g(e)}))):console.log(n.yellow(" ! "+s.t("upgrade.remove_by_hand",{how:N(t,e)})))}(o,r),d();const w=u(o)[0];if(!w)return console.log(n.red(" × "+s.t("upgrade.still_missing",{tool:r}))),!1;w.onPath||console.log(n.gray(" "+s.t("components.new_terminal")));const h=c(t);if(h&&w.version&&l(w.version,h)<0){console.log(n.yellow(" ! "+s.t("upgrade.still_old",{copy:g(w),min:h})));for(const t of e.upgradeHints?.(h)??[])console.log(n.yellow(" ! "+t));return!1}return console.log(n.green(" √ "+s.t("upgrade.done",{copy:g(w)}))),!0}(t);return b(`upgrade:${t}`,o?"ok":"fail",{duration_ms:Date.now()-e}),o}catch(o){throw b(`upgrade:${t}`,"fail",{duration_ms:Date.now()-e,error:o}),o}}
|
|
@@ -19,14 +19,27 @@ export declare const chatgptInstaller: import("./desktop-app-installer.js").Desk
|
|
|
19
19
|
declare let run: (command: string, args: string[], timeout?: number) => {
|
|
20
20
|
status: number | null;
|
|
21
21
|
stdout: string;
|
|
22
|
+
stderr?: string;
|
|
22
23
|
};
|
|
23
24
|
/** Tests replace the process runner. */
|
|
24
25
|
export declare function setChatgptProcessRunnerForTests(fake: typeof run): void;
|
|
25
26
|
/** Only the installed copy's main process counts (not another app that happens to be called ChatGPT). */
|
|
26
27
|
export declare function isChatgptRunning(): boolean;
|
|
27
|
-
/**
|
|
28
|
+
/** The last `quitChatgpt()` was turned down by the app (see there); it is still running. */
|
|
29
|
+
export declare function chatgptQuitRefused(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Quit (gracefully, then forcibly); true when no instance is left. On macOS ChatGPT can turn the quit down: with a
|
|
32
|
+
* task running or a confirmation open, AppleScript's `quit` comes back with -128 ("User canceled"), or doesn't come
|
|
33
|
+
* back before the timeout while the app asks. Then it is left running, never killed (unsaved work, a running
|
|
34
|
+
* task), and `chatgptQuitRefused()` is true so the caller can ask the user to confirm the quit in the app.
|
|
35
|
+
*/
|
|
28
36
|
export declare function quitChatgpt(): boolean;
|
|
29
37
|
/** Start the installed app; true when it is running afterwards. */
|
|
30
38
|
export declare function launchChatgpt(): boolean;
|
|
39
|
+
/** osascript's answer to `quit`: -128 = the app (or the user, in its dialog) cancelled it; no answer = the app is still asking. */
|
|
40
|
+
export declare function macQuitRefused(answer: {
|
|
41
|
+
status: number | null;
|
|
42
|
+
stderr?: string;
|
|
43
|
+
}): boolean;
|
|
31
44
|
export declare const chatgptDesktopApp: CompanionApp;
|
|
32
45
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{logger as n}from"../../utils/logger.js";import{brand as e}from"../brand.js";import{powerShellEnv as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{logger as n}from"../../utils/logger.js";import{brand as e}from"../brand.js";import{powerShellEnv as r}from"../powershell-env.js";import{existsSync as i}from"fs";import{join as o}from"path";import{appPlatform as s,createDesktopAppInstaller as a,isArm64Machine as p,macAppVersion as l,macBundleId as c}from"./desktop-app-installer.js";import{toolHome as u}from"./types.js";export const OPENAI_TEAM_ID="2DC432GLL2";const d="com.openai.codex";export const CHATGPT_PACKAGE_FAMILY="OpenAI.Codex_2p2nqsd0c76g0";const g=a({id:"chatgpt-desktop",mirror:()=>e().installMirror?.chatgptDesktop,asset:(t,n)=>"darwin"===t?n?"ChatGPT-mac-arm64.dmg":null:"win32"===t?n?"ChatGPT-win-arm64.msix":"ChatGPT-win-x64.msix":null,versionFile:(t,n)=>"win32"===t?`version-win-${n?"arm64":"x64"}.txt`:"version.txt",macApp:{source:"ChatGPT.app",installedNames:["ChatGPT.app","Codex.app"],bundleId:d,teamId:"2DC432GLL2"},windows:{signer:new RegExp("^CN=50BDFD77-8903-4850-9FFE-6E8522F64D5B$"),packageFilter:`$_.PackageFamilyName -eq '${CHATGPT_PACKAGE_FAMILY}'`},extraBlocker:t=>"darwin"===t&&!g.installedMacApp()&&["/Applications",o(u(),"Applications")].some(t=>{const n=o(t,"ChatGPT.app");return i(o(n,"Contents","Info.plist"))&&c(n)!==d})?"other_app":null});export const chatgptInstaller=g;let h=(e,i,o=3e4)=>{const s=t(e,i,{encoding:"utf-8",timeout:o,windowsHide:!0,stdio:["ignore","pipe","pipe"],env:r()});return s.error&&n.logError(`chatgpt-desktop: ${e}`,s.error),{status:s.status,stdout:`${s.stdout??""}`,stderr:`${s.stderr??""}`}};export function setChatgptProcessRunnerForTests(t){h=t}function m(t,n){return h("powershell.exe",["-NoProfile","-NonInteractive","-Command",t],n)}const f=t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),C="Get-Process -ErrorAction SilentlyContinue | Where-Object { $_.Path -like '*\\WindowsApps\\OpenAI.Codex_*\\app\\ChatGPT.exe' }";function w(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}export function isChatgptRunning(){if("darwin"===s()){const t=g.installedMacApp();return Boolean(t)&&0===h("pgrep",["-f",`^${f(t)}/Contents/MacOS/`]).status}return"win32"===s()&&Number(m(`@(${C}).Count`).stdout.trim())>0}let A=!1;export function chatgptQuitRefused(){return A}export function quitChatgpt(){if(A=!1,"darwin"===s()){const t=g.installedMacApp();if(macQuitRefused(h("osascript",["-e",`tell application id "${d}" to quit`]))&&(A=isChatgptRunning(),A))return!1;for(let t=0;t<30&&isChatgptRunning();t++)w(500);t&&isChatgptRunning()&&h("pkill",["-f",`^${f(t)}/Contents/MacOS/`]),w(1e3)}else{if("win32"!==s())return!1;m([`$p = @(${C})`,"$p | ForEach-Object { [void]$_.CloseMainWindow() }","Start-Sleep -Seconds 3",`@(${C}) | Stop-Process -Force -ErrorAction SilentlyContinue`,"Start-Sleep -Seconds 1"].join("\n"),6e4)}return!isChatgptRunning()}export function launchChatgpt(){if("darwin"===s()){const t=g.installedMacApp();if(!t)return!1;h("open",[t])}else{if("win32"!==s())return!1;m(`Start-Process 'shell:AppsFolder\\${CHATGPT_PACKAGE_FAMILY}!App'`,6e4)}for(let t=0;t<20;t++){if(isChatgptRunning())return!0;w(500)}return!1}export function macQuitRefused(t){return null===t.status||/\(-128\)|-1712/.test(t.stderr??"")}export const chatgptDesktopApp={name:"chatgpt",displayName:"ChatGPT",installedVersion:function(){if("darwin"===s()){const t=g.installedMacApp();return t?l(t):null}return"win32"===s()?g.windowsPackageVersion():null},runningApp:{isRunning:isChatgptRunning,quit:quitChatgpt,quitRefused:chatgptQuitRefused,launch:launchChatgpt},appInstaller:{vendor:"OpenAI",sizeMb:()=>"darwin"===s()?800:p()?1050:1e3,downloadPage:"https://chatgpt.com/download",blocker:g.blocker,latestVersion:()=>g.latestVersion(),installedPath:()=>"darwin"===s()?g.installedMacApp():"win32"!==s()?null:g.windowsPackageVersion()?"MSIX":null,install:t=>g.install(t)}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{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 l}from"path";import{randomUUID as a}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,installedDesktopAsarPath as g}from"./claude-desktop-cli.js";import{i18n as y}from"../i18n.js";import{BRAND_NAME as h,brand as k,brandEnv as _,CLI_NAME as b}from"../brand.js";import{backupBeforeWrite as D,atomicWriteFile as w}from"./backup.js";import{toolHome as A}from"./types.js";import{canRestartDesktop as C,isDesktopRunning as E,launchDesktop as v,quitDesktop as M,restartDesktop as O,WINDOWS_PACKAGE_FAMILIES as S}from"./desktop-process.js";import{desktopInstallBlocker as x,fetchLatestDesktopVersion as P,installedMacApp as j,installLatestDesktop as I}from"./claude-desktop-app.js";import{setUserRegistryElevated as L}from"./elevated-reg.js";import{UserActionNeeded as T}from"./types.js";import{baseModelId as $,isClaudeModel as N}from"../model-catalog.js";import{getDefaultModels as R}from"../model-registry.js";import{claudeFormat as G,nestedClaudeProjectFiles as K}from"../sessions/formats.js";import{powerShellEnv as U}from"../powershell-env.js";const F=h;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const H=/^[a-f0-9-]{36}$/;function J(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(_("TEST_HOME")?.trim());switch(process.platform){case"darwin":return l(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(o,"AppData","Local");return S.map(t=>l(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??l(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:l(o,".config");return l(e,"Claude-3p")}}}const V=()=>l(claudeDesktopUserDataDir(),"configLibrary"),B=()=>l(V(),"_meta.json"),W=e=>l(V(),`${e}.json`),z=()=>l(claudeDesktopUserDataDir(),"claude_desktop_config.json");function q(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return J(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 X(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),D(n),w(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function Z(){const e=q(B());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>J(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function Y(e){return e?.entries.find(e=>e.name===F&&H.test(e.id))}const Q={opus:0,fable:1,sonnet:2,haiku:3};function ee(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=ee(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function te(e){return ee(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>$(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(N)){i=[...new Set(t.models.filter(N).map($))];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=$(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const l=e=>Q[te(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=l(e)-l(t);if(0!==n)return n;const r=ee(e),s=ee(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 a=new Set,c=new Map,d=new Set(Object.values(R()).map(e=>$(e||"")));for(const e of n){const t=te(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=te(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||a.has(t)||(o.isFamilyDefault=!0,a.add(t))}return o})}let oe=null,ne=null,re=null,se=null,ie=null;function le(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 ae={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}},ce=()=>{if(_("TEST_HOME")?.trim())return null;const e=g();return e?r(e):null};let de=ce,pe=null;export function setDesktopAsarForTests(e){de=void 0===e?ce:()=>e,pe=null}function ue(){if(pe)return pe;let e=null;try{e=de()}catch(e){u.logError("claude-desktop.unsupportedDefaults",e)}return pe=new Set(e?Object.keys(ae).filter(t=>!e.includes(t)):[]),pe}function fe(e){const t=ue();return Object.fromEntries(Object.entries(ae).filter(([o])=>!e(o)&&!t.has(o)))}function me(e){const t={...fe(t=>t in e),...e};for(const e of ue())e in t&&JSON.stringify(t[e])===JSON.stringify(ae[e])&&delete t[e];return t}const ge="SOFTWARE\\Policies\\Claude",ye=`HKCU\\${ge}`,he="HKLM\\SOFTWARE\\Policies\\Claude",ke=`${b}-claude-policy.reg`,_e=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let be=_e;export function setRegRunnerForTests(e){be=e??_e}function De(){return"win32"===process.platform}function we(e){let t;try{t=be(["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===we(ye))return;const e=l(claudeDesktopUserDataDir(),ke);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),D(e),be(["export",ye,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function Ce(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)];be(["add",ye,"/v",t,"/t",e,"/d",n,"/f"])}}function Ee(e){const t=we(ye);if(!t)return;Ae();let o=t.size;for(const n of e)t.has(n)&&(be(["delete",ye,"/v",n,"/f"]),o-=1);o<=0&&be(["delete",ye,"/f"])}function ve(){const e=!Boolean(_("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(A(),"AppData","Local");return!!t(l(e,"AnthropicClaude"))||S.some(o=>t(l(e,"Packages",o,"LocalCache","Local","Claude-3p")))}const Me=[...Object.keys(le({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(ae)];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 we(he)?he: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 Oe(){const e=A();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",l(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||l(e,"AppData","Local");o=[l(t,"AnthropicClaude"),l(t,"Programs","Claude"),...S.map(e=>l(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",l(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),l(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const Se=/\d+\.\d+\.\d+/;function xe(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 Pe(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",l(A(),"Applications","Claude.app")]){const o=l(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?Se.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(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 xe(t)}const o=S.map(e=>`'${e}'`).join(",");return xe(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"],env:U()}).split(/\r?\n/).flatMap(e=>Se.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 Se.exec(e)?.[0]??null}catch{return null}return null}const je="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",Ie="darwin"!==process.platform&&"win32"!==process.platform||!k().installMirror?.claudeDesktop?"https://claude.ai/download":k().installMirror.claudeDesktop,Le="darwin"===process.platform?`open ${Ie}`:"win32"===process.platform?`start ${Ie}`:`xdg-open ${Ie}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:je,installCommand:Le,configPath:B(),sessions:{format:G,files:()=>K(l(claudeDesktopUserDataDir(),"local-agent-mode-sessions"))},isInstalled:Oe,installedVersion:Pe,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!Oe())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+y.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?Pe():null,mirrorRepo:k().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:y.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:y.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:E,restart:O,quit:M,launch:v}:void 0,appInstaller:{vendor:"Anthropic",sizeMb:()=>300,downloadPage:"https://claude.ai/download",blocker:x,latestVersion:()=>P(),installedPath(){if("darwin"===process.platform)return j();if("win32"!==process.platform)return null;try{return Pe()?"MSIX":null}catch(e){return u.logError("claude-desktop.installedPath",e),null}},install:e=>I(e)},wantsModelCatalog:!0,loadPrivateConfig(e){const t=Z()??{appliedId:"",entries:[]};let o=Y(t);o||(o={id:a(),name:F},t.entries.push(o));const n=le(e);ne=!0===n.disableDeploymentModeChooser,oe={models:n.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const r=q(W(o.id))??{};X(W(o.id),{...me(r),...n}),t.appliedId=o.id,X(B(),t);const s=q(z())??{};if("3p"!==s.deploymentMode&&X(z(),{...s,deploymentMode:"3p"}),se=null,ie=null,re=null,De()){const t=we(ye),o=Me.filter(e=>t?.has(e)),r={...fe(e=>t?.has(e)??!1),...n},s=!0===e.settings?.force_registry,i=!s&&ve();try{i?Ee(Me):Ce(r),re=i?"removed":"written"}catch(e){u.logError("claude-desktop.policy",e),se=e instanceof Error?e.message.trim():String(e),(o.length>0||s)&&(ie=i?{action:"remove",values:Object.fromEntries(o.map(e=>[e,null])),deleteKey:o.length===t.size}:{action:"write",values:r,deleteKey:!1})}}},pendingElevation(){const e=ie;return e?{prompt:y.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!L(ge,e.values,e.deleteKey))return!1;const t=we(ye),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(ie=null,se=null),o}}:null},unloadPrivateConfig(){if(De())try{Ee(Me)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=Z(),t=Y(e);if(!e||!t)return;D(W(t.id)),s(W(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(D(B()),s(B(),{force:!0})):X(B(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=Z(),t=Y(e);if(!t||e?.appliedId!==t.id)return null;const o=q(W(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=Z(),o=Y(t);if(!o||t?.appliedId!==o.id)return;const n=q(W(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog),s=JSON.stringify(n.inferenceModels)!==JSON.stringify(r),i={...me(n),inferenceModels:r},l=JSON.stringify(i)!==JSON.stringify(n);ie=null;const a=De()?we(ye):null;if(!a?.has("inferenceModels"))return void(l&&X(W(o.id),i));const c=Me.filter(e=>a.has(e)),d=!0!==e.settings?.force_registry&&ve();if(l&&X(W(o.id),i),d||s)try{d?Ee(Me):Ce({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),ie=d?{action:"remove",values:Object.fromEntries(c.map(e=>[e,null])),deleteKey:c.length===a.size}:{action:"write",values:{inferenceModels:r},deleteKey:!1},new T(y.t("tools.claude_desktop.refresh_needs_admin"))}},detectCurrentConfig(){try{if(De()){const e=we(ye)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=Y(Z());if(!e)return{apiKey:null};const t=q(W(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=Z(),t=Y(e);return{meta:e,applied:t?q(W(t.id)):null,desktop:q(z()),...De()?{policy:Object.fromEntries(we(ye)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;De()&&we(ye)?.has("inferenceModels")&&(Ae(),be(["delete",ye,"/v","inferenceModels","/f"]),e=!0);const t=Y(Z()),o=t?q(W(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;X(W(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(oe&&oe.models.length>0){const{models:t,source:o,groups:n}=oe;e.push({kind:"summary",text:y.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:y.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!==ne&&e.push({kind:"detail",text:y.t(ne?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!E()||e.push({kind:"action",text:y.t("tools.claude_desktop.restart_hint")}),ie?(e.push({kind:"action",text:y.t(`tools.claude_desktop.policy_stale_${ie.action}`)}),e.push({kind:"detail",text:se??""})):se?(e.push({kind:"detail",text:y.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:se})):De()&&re&&e.push({kind:"detail",text:y.t(`tools.claude_desktop.registry_${re}`,{key:ye})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:y.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[B(),z()];try{const t=Y(Z());t&&e.push(W(t.id))}catch{}return e},backupPaths(){const e=[B(),z()];De()&&e.push(l(claudeDesktopUserDataDir(),ke));try{const t=Y(Z());t&&e.push(W(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 l}from"path";import{randomUUID as a}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,installedDesktopAsarPath as g}from"./claude-desktop-cli.js";import{i18n as y}from"../i18n.js";import{BRAND_NAME as h,brand as k,brandEnv as _,CLI_NAME as b}from"../brand.js";import{backupBeforeWrite as D,atomicWriteFile as w}from"./backup.js";import{toolHome as A}from"./types.js";import{canRestartDesktop as C,desktopQuitRefused as E,isDesktopRunning as v,launchDesktop as M,quitDesktop as O,restartDesktop as S,WINDOWS_PACKAGE_FAMILIES as x}from"./desktop-process.js";import{desktopInstallBlocker as P,fetchLatestDesktopVersion as j,installedMacApp as I,installLatestDesktop as L}from"./claude-desktop-app.js";import{setUserRegistryElevated as T}from"./elevated-reg.js";import{UserActionNeeded as $}from"./types.js";import{baseModelId as N,isClaudeModel as R}from"../model-catalog.js";import{getDefaultModels as G}from"../model-registry.js";import{claudeFormat as K,nestedClaudeProjectFiles as U}from"../sessions/formats.js";import{powerShellEnv as F}from"../powershell-env.js";const H=h;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const J=/^[a-f0-9-]{36}$/;function V(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(_("TEST_HOME")?.trim());switch(process.platform){case"darwin":return l(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(o,"AppData","Local");return x.map(t=>l(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??l(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:l(o,".config");return l(e,"Claude-3p")}}}const B=()=>l(claudeDesktopUserDataDir(),"configLibrary"),W=()=>l(B(),"_meta.json"),z=e=>l(B(),`${e}.json`),q=()=>l(claudeDesktopUserDataDir(),"claude_desktop_config.json");function X(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return V(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 Z(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),D(n),w(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function Y(){const e=X(W());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>V(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function Q(e){return e?.entries.find(e=>e.name===H&&J.test(e.id))}const ee={opus:0,fable:1,sonnet:2,haiku:3};function te(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=te(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function oe(e){return te(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>N(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(R)){i=[...new Set(t.models.filter(R).map(N))];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=N(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const l=e=>ee[oe(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=l(e)-l(t);if(0!==n)return n;const r=te(e),s=te(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 a=new Set,c=new Map,d=new Set(Object.values(G()).map(e=>N(e||"")));for(const e of n){const t=oe(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=oe(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||a.has(t)||(o.isFamilyDefault=!0,a.add(t))}return o})}let ne=null,re=null,se=null,ie=null,le=null;function ae(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 ce={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}},de=()=>{if(_("TEST_HOME")?.trim())return null;const e=g();return e?r(e):null};let pe=de,ue=null;export function setDesktopAsarForTests(e){pe=void 0===e?de:()=>e,ue=null}function fe(){if(ue)return ue;let e=null;try{e=pe()}catch(e){u.logError("claude-desktop.unsupportedDefaults",e)}return ue=new Set(e?Object.keys(ce).filter(t=>!e.includes(t)):[]),ue}function me(e){const t=fe();return Object.fromEntries(Object.entries(ce).filter(([o])=>!e(o)&&!t.has(o)))}function ge(e){const t={...me(t=>t in e),...e};for(const e of fe())e in t&&JSON.stringify(t[e])===JSON.stringify(ce[e])&&delete t[e];return t}const ye="SOFTWARE\\Policies\\Claude",he=`HKCU\\${ye}`,ke="HKLM\\SOFTWARE\\Policies\\Claude",_e=`${b}-claude-policy.reg`,be=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let De=be;export function setRegRunnerForTests(e){De=e??be}function we(){return"win32"===process.platform}function Ae(e){let t;try{t=De(["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 Ce(){if(null===Ae(he))return;const e=l(claudeDesktopUserDataDir(),_e);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),D(e),De(["export",he,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function Ee(e){Ce();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)];De(["add",he,"/v",t,"/t",e,"/d",n,"/f"])}}function ve(e){const t=Ae(he);if(!t)return;Ce();let o=t.size;for(const n of e)t.has(n)&&(De(["delete",he,"/v",n,"/f"]),o-=1);o<=0&&De(["delete",he,"/f"])}function Me(){const e=!Boolean(_("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(A(),"AppData","Local");return!!t(l(e,"AnthropicClaude"))||x.some(o=>t(l(e,"Packages",o,"LocalCache","Local","Claude-3p")))}const Oe=[...Object.keys(ae({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(ce)];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(ke)?ke: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 Se(){const e=A();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",l(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||l(e,"AppData","Local");o=[l(t,"AnthropicClaude"),l(t,"Programs","Claude"),...x.map(e=>l(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",l(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),l(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const xe=/\d+\.\d+\.\d+/;function Pe(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 je(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",l(A(),"Applications","Claude.app")]){const o=l(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?xe.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(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 Pe(t)}const o=x.map(e=>`'${e}'`).join(",");return Pe(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"],env:F()}).split(/\r?\n/).flatMap(e=>xe.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 xe.exec(e)?.[0]??null}catch{return null}return null}const Ie="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",Le="darwin"!==process.platform&&"win32"!==process.platform||!k().installMirror?.claudeDesktop?"https://claude.ai/download":k().installMirror.claudeDesktop,Te="darwin"===process.platform?`open ${Le}`:"win32"===process.platform?`start ${Le}`:`xdg-open ${Le}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:Ie,installCommand:Te,configPath:W(),sessions:{format:K,files:()=>U(l(claudeDesktopUserDataDir(),"local-agent-mode-sessions"))},isInstalled:Se,installedVersion:je,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!Se())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+y.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?je():null,mirrorRepo:k().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:y.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:y.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:v,restart:S,quit:O,quitRefused:E,launch:M}:void 0,appInstaller:{vendor:"Anthropic",sizeMb:()=>300,downloadPage:"https://claude.ai/download",blocker:P,latestVersion:()=>j(),installedPath(){if("darwin"===process.platform)return I();if("win32"!==process.platform)return null;try{return je()?"MSIX":null}catch(e){return u.logError("claude-desktop.installedPath",e),null}},install:e=>L(e)},wantsModelCatalog:!0,loadPrivateConfig(e){const t=Y()??{appliedId:"",entries:[]};let o=Q(t);o||(o={id:a(),name:H},t.entries.push(o));const n=ae(e);re=!0===n.disableDeploymentModeChooser,ne={models:n.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const r=X(z(o.id))??{};Z(z(o.id),{...ge(r),...n}),t.appliedId=o.id,Z(W(),t);const s=X(q())??{};if("3p"!==s.deploymentMode&&Z(q(),{...s,deploymentMode:"3p"}),ie=null,le=null,se=null,we()){const t=Ae(he),o=Oe.filter(e=>t?.has(e)),r={...me(e=>t?.has(e)??!1),...n},s=!0===e.settings?.force_registry,i=!s&&Me();try{i?ve(Oe):Ee(r),se=i?"removed":"written"}catch(e){u.logError("claude-desktop.policy",e),ie=e instanceof Error?e.message.trim():String(e),(o.length>0||s)&&(le=i?{action:"remove",values:Object.fromEntries(o.map(e=>[e,null])),deleteKey:o.length===t.size}:{action:"write",values:r,deleteKey:!1})}}},pendingElevation(){const e=le;return e?{prompt:y.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!T(ye,e.values,e.deleteKey))return!1;const t=Ae(he),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(le=null,ie=null),o}}:null},unloadPrivateConfig(){if(we())try{ve(Oe)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=Y(),t=Q(e);if(!e||!t)return;D(z(t.id)),s(z(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(D(W()),s(W(),{force:!0})):Z(W(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=Y(),t=Q(e);if(!t||e?.appliedId!==t.id)return null;const o=X(z(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=Y(),o=Q(t);if(!o||t?.appliedId!==o.id)return;const n=X(z(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog),s=JSON.stringify(n.inferenceModels)!==JSON.stringify(r),i={...ge(n),inferenceModels:r},l=JSON.stringify(i)!==JSON.stringify(n);le=null;const a=we()?Ae(he):null;if(!a?.has("inferenceModels"))return void(l&&Z(z(o.id),i));const c=Oe.filter(e=>a.has(e)),d=!0!==e.settings?.force_registry&&Me();if(l&&Z(z(o.id),i),d||s)try{d?ve(Oe):Ee({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),le=d?{action:"remove",values:Object.fromEntries(c.map(e=>[e,null])),deleteKey:c.length===a.size}:{action:"write",values:{inferenceModels:r},deleteKey:!1},new $(y.t("tools.claude_desktop.refresh_needs_admin"))}},detectCurrentConfig(){try{if(we()){const e=Ae(he)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=Q(Y());if(!e)return{apiKey:null};const t=X(z(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=Y(),t=Q(e);return{meta:e,applied:t?X(z(t.id)):null,desktop:X(q()),...we()?{policy:Object.fromEntries(Ae(he)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;we()&&Ae(he)?.has("inferenceModels")&&(Ce(),De(["delete",he,"/v","inferenceModels","/f"]),e=!0);const t=Q(Y()),o=t?X(z(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;Z(z(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(ne&&ne.models.length>0){const{models:t,source:o,groups:n}=ne;e.push({kind:"summary",text:y.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:y.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!==re&&e.push({kind:"detail",text:y.t(re?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!v()||e.push({kind:"action",text:y.t("tools.claude_desktop.restart_hint")}),le?(e.push({kind:"action",text:y.t(`tools.claude_desktop.policy_stale_${le.action}`)}),e.push({kind:"detail",text:ie??""})):ie?(e.push({kind:"detail",text:y.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:ie})):we()&&se&&e.push({kind:"detail",text:y.t(`tools.claude_desktop.registry_${se}`,{key:he})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:y.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[W(),q()];try{const t=Q(Y());t&&e.push(z(t.id))}catch{}return e},backupPaths(){const e=[W(),q()];we()&&e.push(l(claudeDesktopUserDataDir(),_e));try{const t=Q(Y());t&&e.push(z(t.id))}catch{}return e}};
|