@vibeapi/api-helper 0.0.119 → 0.0.120
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.
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export interface DesktopCliPin {
|
|
2
2
|
version: string;
|
|
3
|
-
/** sha256 of the
|
|
3
|
+
/** sha256 of what the app would download (`claude.exe.zst`, or `claude.app.tar.zst` for a bundle), as `.verified` records it. */
|
|
4
4
|
checksum: string;
|
|
5
5
|
}
|
|
6
6
|
/** The CLI build an app.asar pins for `platformKey`; null when the layout isn't the one we know. */
|
|
7
|
-
export declare function readDesktopCliPin(asar: Buffer, platformKey: string): DesktopCliPin | null;
|
|
7
|
+
export declare function readDesktopCliPin(asar: Buffer, platformKey: string, bundle?: boolean): DesktopCliPin | null;
|
|
8
8
|
export type DesktopCliResult = {
|
|
9
9
|
status: 'present';
|
|
10
10
|
version: string;
|
|
@@ -21,14 +21,26 @@ export interface DesktopCliOptions {
|
|
|
21
21
|
userDataDir: string;
|
|
22
22
|
asar: Buffer;
|
|
23
23
|
platformKey: string;
|
|
24
|
-
/**
|
|
24
|
+
/** macOS: the app runs `claude.app` extracted from `claude.app.tar.zst`. */
|
|
25
|
+
bundle?: boolean;
|
|
26
|
+
/** Single-binary platforms: the CLI's native `versions/` dir; a file named after the pinned version there is copied instead of downloading. */
|
|
25
27
|
localVersionsDir?: string;
|
|
26
28
|
/** Called before a download (not for a local copy), e.g. to tell the user why setup pauses. */
|
|
27
29
|
onDownload?: (version: string) => void;
|
|
28
|
-
/** Writes the binary of `version` to the given path
|
|
30
|
+
/** Writes the binary of `version` (a bundle: its `.tar.zst`) to the given path. Default: npmmirror for binaries; required for bundles. */
|
|
29
31
|
download?: (version: string, outPath: string) => Promise<void>;
|
|
30
32
|
}
|
|
31
33
|
/** Puts the pinned CLI build where the app looks; does nothing when it is already there. */
|
|
32
34
|
export declare function installDesktopCli(options: DesktopCliOptions): Promise<DesktopCliResult>;
|
|
33
|
-
/**
|
|
34
|
-
export declare function
|
|
35
|
+
/** Tests replace the network. */
|
|
36
|
+
export declare function setDesktopCliFetchForTests(fake: typeof fetch): void;
|
|
37
|
+
export interface EnsureDesktopCliOptions {
|
|
38
|
+
userDataDir: string;
|
|
39
|
+
onDownload?: (version: string) => void;
|
|
40
|
+
/** macOS: the installed app's version, naming the mirror release that carries its bundle. */
|
|
41
|
+
desktopVersion?: string | null;
|
|
42
|
+
/** macOS: the CNB desktop mirror repository (`https://cnb.cool/<group>/claude-desktop`). */
|
|
43
|
+
mirrorRepo?: string | null;
|
|
44
|
+
}
|
|
45
|
+
/** Give the installed Claude Desktop the CLI build its Code tab needs, from China-reachable sources. */
|
|
46
|
+
export declare function ensureDesktopCli(options: EnsureDesktopCliOptions): Promise<DesktopCliResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{execFileSync as
|
|
1
|
+
import{execFileSync as e}from"child_process";import{createHash as t}from"crypto";import{createReadStream as r,createWriteStream as s,existsSync as i,readdirSync as n,readFileSync as o}from"fs";import{copyFile as a,mkdir as l,readFile as c,rename as u,rm as f,writeFile as p}from"fs/promises";import{isAbsolute as d,join as h,normalize as m,sep as w}from"path";import{Readable as g,Writable as b}from"stream";import{pipeline as y}from"stream/promises";import*as v from"zlib";import{logger as k}from"../../utils/logger.js";import{downloadNativeBinary as D,nativeLayout as $,nativePlatformKey as C}from"./claude-native-mirror.js";import{WINDOWS_PACKAGE_FAMILIES as N}from"./desktop-process.js";import{toolHome as x}from"./types.js";export function readDesktopCliPin(e,t,r=!1){const s=e.indexOf('claude-code-releases","sdkWrapperVersion"');if(s<0)return null;const i=e.lastIndexOf("JSON.parse('",s),n=e.indexOf("')",s);if(i<0||n<0)return null;try{const s=JSON.parse(e.subarray(i+12,n).toString("utf-8")),o="string"==typeof s.version?s.version:"",a=s.manifest?.platforms?.[t],l=r?a?.bundle?.checksum:a?.checksum;return/^\d+\.\d+\.\d+$/.test(o)&&"string"==typeof l&&/^[0-9a-f]{64}$/.test(l)?{version:o,checksum:l}:null}catch{return null}}class A extends b{dest;buffer=Buffer.alloc(0);remaining=0;padding=0;file=null;longName=null;collectingLongName=null;constructor(e){super(),this.dest=e}_write(e,t,r){this.buffer=this.buffer.length?Buffer.concat([this.buffer,e]):e,this.drain().then(()=>r()).catch(r)}_final(e){this.remaining>0?e(new Error("archive ends inside an entry")):e()}target(e){const t=m(e);if(!t||d(t)||".."===t||t.startsWith(`..${w}`))throw new Error(`unsafe path in archive: ${e}`);return h(this.dest,t)}async closeFile(){const e=this.file;this.file=null,e&&await new Promise((t,r)=>e.end(e=>e?r(e):t()))}async drain(){for(;;){if(this.remaining>0){if(0===this.buffer.length)return;const e=this.buffer.subarray(0,Math.min(this.remaining,this.buffer.length));this.buffer=this.buffer.subarray(e.length),this.remaining-=e.length,this.collectingLongName?this.collectingLongName.push(e):this.file&&!this.file.write(e)&&await new Promise(e=>this.file.once("drain",()=>e())),0===this.remaining&&(this.collectingLongName&&(this.longName=Buffer.concat(this.collectingLongName).toString("utf-8").replace(/\0.*$/s,""),this.collectingLongName=null),await this.closeFile());continue}if(this.padding>0){if(this.buffer.length<this.padding)return;this.buffer=this.buffer.subarray(this.padding),this.padding=0}if(this.buffer.length<512)return;const e=this.buffer.subarray(0,512);if(this.buffer=this.buffer.subarray(512),e.every(e=>0===e))continue;const t=(t,r)=>e.subarray(t,t+r).toString("utf-8").replace(/\0.*$/s,""),r=t(345,155);let i=r?`${r}/${t(0,100)}`:t(0,100);null!==this.longName&&(i=this.longName,this.longName=null);const n=parseInt(t(124,12).trim()||"0",8),o=511&parseInt(t(100,8).trim()||"644",8),a=t(156,1)||"0";if(this.remaining=n,this.padding=(512-n%512)%512,"L"===a)this.collectingLongName=[];else if("x"===a||"g"===a);else if("5"===a)await l(this.target(i),{recursive:!0});else{if("0"!==a)throw new Error(`unexpected entry type ${a} in archive: ${i}`);{const e=this.target(i);await l(h(e,".."),{recursive:!0}),this.file=s(e,{mode:o||420}),0===n&&await this.closeFile()}}}}}export async function installDesktopCli(e){const s=readDesktopCliPin(e.asar,e.platformKey,e.bundle);if(!s)return{status:"skipped",reason:"unknown app layout"};if(e.bundle&&!e.download)return{status:"skipped",reason:"no bundle mirror"};const n=e.platformKey.startsWith("win32")?"claude.exe":"claude",o=h(e.userDataDir,"claude-code",s.version),d=h(o,s.checksum.slice(0,12)),m=e.bundle?h(d,"claude.app","Contents","MacOS","claude"):h(d,n),w=h(d,".verified");try{if(i(m)&&(await c(w,"utf-8")).trim()===s.checksum)return{status:"present",version:s.version}}catch{}await l(o,{recursive:!0});const g=h(o,`.partial-${s.checksum.slice(0,12)}`),k=`${g}.download`;try{await f(w,{force:!0}),await f(g,{recursive:!0,force:!0});let n="mirror";if(e.bundle){if(e.onDownload?.(s.version),await e.download(s.version,k),await async function(e,s,i){const n=t("sha256");if(await y(r(e),new b({write(e,t,r){n.update(e),r()}})),n.digest("hex")!==s)throw new Error("downloaded bundle does not match the app's checksum");const o=v.createZstdDecompress;if(!o)throw new Error(`Node ${process.version} cannot decompress zstd (needs 22.15 or newer)`);await y(r(e),o(),new A(i))}(k,s.checksum,g),!i(h(g,"claude.app","Contents","MacOS","claude")))throw new Error("bundle has no claude.app");await f(d,{recursive:!0,force:!0}),await u(g,d)}else{const t=e.localVersionsDir?h(e.localVersionsDir,s.version):null;if(t&&i(t))await a(t,g),n="local";else{e.onDownload?.(s.version);const t=e.download??((t,r)=>D(e.platformKey,t,r));await t(s.version,g)}await l(d,{recursive:!0}),await u(g,m)}return await p(w,s.checksum),{status:"installed",version:s.version,source:n}}finally{await f(g,{recursive:!0,force:!0}),await f(k,{force:!0}),await f(`${g}.download`,{force:!0})}}let L=(...e)=>fetch(...e);export function setDesktopCliFetchForTests(e){L=e}export async function ensureDesktopCli(t){const r=C();if(!r)return{status:"skipped",reason:"unsupported architecture"};if("win32"===process.platform){const s=function(){const t=h(process.env.LOCALAPPDATA||"","AnthropicClaude");if(process.env.LOCALAPPDATA&&i(t)){const e=n(t).filter(e=>/^app-\d+\.\d+\.\d+$/.test(e)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(const r of e){const e=h(t,r,"resources","app.asar");if(i(e))return e}}try{const t=e("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${N.map(e=>`'${e}'`).join(",")}) -contains $_.PackageFamilyName } | ForEach-Object { $_.InstallLocation }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"]});for(const e of t.split(/\r?\n/).map(e=>e.trim()).filter(Boolean)){const t=h(e,"app","resources","app.asar");if(i(t))return t}}catch(e){k.logError("claude-desktop-cli.windowsAsarPath",e)}return null}();return s?installDesktopCli({userDataDir:t.userDataDir,asar:o(s),platformKey:r,localVersionsDir:$().versionsDir,onDownload:t.onDownload}):{status:"skipped",reason:"app.asar not found"}}if("darwin"===process.platform){const e=function(){for(const e of["/Applications/Claude.app",h(x(),"Applications","Claude.app")]){const t=h(e,"Contents","Resources","app.asar");if(i(t))return t}return null}();if(!e)return{status:"skipped",reason:"app.asar not found"};const{mirrorRepo:n,desktopVersion:a}=t;return installDesktopCli({userDataDir:t.userDataDir,asar:o(e),platformKey:r,bundle:!0,onDownload:t.onDownload,download:n&&a?(e,t)=>async function(e,t){const r=await L(e,{signal:AbortSignal.timeout(9e5)});if(!r.ok||!r.body)throw new Error(`${e}: HTTP ${r.status}`);await y(g.fromWeb(r.body),s(t))}(`${n}/-/releases/download/v${a}/claude-code-${e}-${r}.app.tar.zst`,t):void 0})}return{status:"skipped",reason:"unsupported platform"}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as a}from"path";import{randomUUID as l}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import p from"chalk";import{logger as u}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m}from"./claude-desktop-cli.js";import{i18n as g}from"../i18n.js";import{BRAND_NAME as y,brand as h,brandEnv as k,CLI_NAME as _}from"../brand.js";import{backupBeforeWrite as b,atomicWriteFile as A}from"./backup.js";import{toolHome as C}from"./types.js";import{canRestartDesktop as D,isDesktopRunning as w,restartDesktop as E,WINDOWS_PACKAGE_FAMILIES as M}from"./desktop-process.js";import{setUserRegistryElevated as v}from"./elevated-reg.js";import{UserActionNeeded as O}from"./types.js";import{baseModelId as S,isClaudeModel as x}from"../model-catalog.js";import{getDefaultModels as P}from"../model-registry.js";const j=y;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const L=/^[a-f0-9-]{36}$/;function I(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=C(),n=Boolean(k("TEST_HOME")?.trim());switch(process.platform){case"darwin":return a(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(o,"AppData","Local");return M.map(t=>a(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??a(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:a(o,".config");return a(e,"Claude-3p")}}}const T=()=>a(claudeDesktopUserDataDir(),"configLibrary"),$=()=>a(T(),"_meta.json"),G=e=>a(T(),`${e}.json`),N=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function R(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return I(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed, back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function U(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),b(n),A(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function K(){const e=R($());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>I(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function F(e){return e?.entries.find(e=>e.name===j&&L.test(e.id))}const H={opus:0,fable:1,sonnet:2,haiku:3};function B(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=B(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function J(e){return B(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>S(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(x)){i=[...new Set(t.models.filter(x).map(S))];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=S(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>H[J(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=a(e)-a(t);if(0!==n)return n;const r=B(e),s=B(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const l=new Set,c=new Map,d=new Set(Object.values(P()).map(e=>S(e||"")));for(const e of n){const t=J(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=J(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||l.has(t)||(o.isFamilyDefault=!0,l.add(t))}return o})}let W=null,V=null,z=null,Z=null;function X(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const q={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}};function Y(e){return Object.fromEntries(Object.entries(q).filter(([t])=>!e(t)))}const Q="SOFTWARE\\Policies\\Claude",ee=`HKCU\\${Q}`,te="HKLM\\SOFTWARE\\Policies\\Claude",oe=`${_}-claude-policy.reg`,ne=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let re=ne;export function setRegRunnerForTests(e){re=e??ne}function se(){return"win32"===process.platform}function ie(e){let t;try{t=re(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function ae(){if(null===ie(ee))return;const e=a(claudeDesktopUserDataDir(),oe);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),b(e),re(["export",ee,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function le(e){ae();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];re(["add",ee,"/v",t,"/t",e,"/d",n,"/f"])}}function ce(e){const t=ie(ee);if(!t)return;ae();let o=t.size;for(const n of e)t.has(n)&&(re(["delete",ee,"/v",n,"/f"]),o-=1);o<=0&&re(["delete",ee,"/f"])}const de=[...Object.keys(X({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(q)];export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return ie(te)?te:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return u.logError("claude-desktop.detectManagedConfig",e),null}}function pe(){const e=C();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",a(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||a(e,"AppData","Local");o=[a(t,"AnthropicClaude"),a(t,"Programs","Claude"),...M.map(e=>a(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",a(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),a(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const ue=/\d+\.\d+\.\d+/;function fe(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}const me="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",ge="darwin"!==process.platform&&"win32"!==process.platform||!h().installMirror?.claudeDesktop?"https://claude.ai/download":h().installMirror.claudeDesktop,ye="darwin"===process.platform?`open ${ge}`:"win32"===process.platform?`start ${ge}`:`xdg-open ${ge}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:me,installCommand:ye,configPath:$(),isInstalled:pe,installedVersion:function(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",a(C(),"Applications","Claude.app")]){const o=a(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?ue.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(C(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return fe(t)}const o=M.map(e=>`'${e}'`).join(",");return fe(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"]}).split(/\r?\n/).flatMap(e=>ue.exec(e)?.[0]??[]))}return null},prepareRuntime:async function(){if("win32"!==process.platform||!pe())return[];const e=Date.now();try{const t=await m(claudeDesktopUserDataDir(),e=>console.log(p.gray(" "+g.t("tools.claude_desktop.code_cli_downloading",{version:e}))));return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:g.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return u.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:g.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:D()?{isRunning:w,restart:E}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const o=K()??{appliedId:"",entries:[]};let n=F(o);n||(n={id:l(),name:j},o.entries.push(n));const r=X(e);V=!0===r.disableDeploymentModeChooser,W={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=R(G(n.id))??{};U(G(n.id),{...Y(e=>e in s),...s,...r}),o.appliedId=n.id,U($(),o);const i=R(N())??{};if("3p"!==i.deploymentMode&&U(N(),{...i,deploymentMode:"3p"}),z=null,Z=null,se()){const o=ie(ee),n=de.filter(e=>o?.has(e)),s={...Y(e=>o?.has(e)??!1),...r},i=!0===e.settings?.force_registry,l=!i&&function(){const e=!Boolean(k("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(C(),"AppData","Local");return!!t(a(e,"AnthropicClaude"))||M.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{l?ce(de):le(s)}catch(e){u.logError("claude-desktop.policy",e),z=e instanceof Error?e.message.trim():String(e),(n.length>0||i)&&(Z=l?{action:"remove",values:Object.fromEntries(n.map(e=>[e,null])),deleteKey:n.length===o.size}:{action:"write",values:s,deleteKey:!1})}}},pendingElevation(){const e=Z;return e?{prompt:g.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!v(Q,e.values,e.deleteKey))return!1;const t=ie(ee),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(Z=null,z=null),o}}:null},unloadPrivateConfig(){if(se())try{ce(de)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=K(),t=F(e);if(!e||!t)return;b(G(t.id)),s(G(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(b($()),s($(),{force:!0})):U($(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=K(),t=F(e);if(!t||e?.appliedId!==t.id)return null;const o=R(G(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=K(),o=F(t);if(!o||t?.appliedId!==o.id)return;const n=R(G(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(se()&&ie(ee)?.has("inferenceModels"))try{le({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),new O(g.t("tools.claude_desktop.refresh_needs_admin"))}U(G(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(se()){const e=ie(ee)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=F(K());if(!e)return{apiKey:null};const t=R(G(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return u.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=K(),t=F(e);return{meta:e,applied:t?R(G(t.id)):null,desktop:R(N()),...se()?{policy:Object.fromEntries(ie(ee)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;se()&&ie(ee)?.has("inferenceModels")&&(ae(),re(["delete",ee,"/v","inferenceModels","/f"]),e=!0);const t=F(K()),o=t?R(G(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;U(G(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(W&&W.models.length>0){const{models:t,source:o,groups:n}=W;e.push({kind:"summary",text:g.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:g.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==V&&e.push({kind:"detail",text:g.t(V?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),D()&&!w()||e.push({kind:"action",text:g.t("tools.claude_desktop.restart_hint")}),Z?(e.push({kind:"action",text:g.t(`tools.claude_desktop.policy_stale_${Z.action}`)}),e.push({kind:"detail",text:z??""})):z?(e.push({kind:"detail",text:g.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:z})):se()&&e.push({kind:"detail",text:g.t("tools.claude_desktop.registry_written",{key:ee})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:g.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[$(),N()];try{const t=F(K());t&&e.push(G(t.id))}catch{}return e},backupPaths(){const e=[$(),N()];se()&&e.push(a(claudeDesktopUserDataDir(),oe));try{const t=F(K());t&&e.push(G(t.id))}catch{}return e}};
|
|
1
|
+
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as a}from"path";import{randomUUID as l}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import p from"chalk";import{logger as u}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m}from"./claude-desktop-cli.js";import{i18n as g}from"../i18n.js";import{BRAND_NAME as y,brand as h,brandEnv as k,CLI_NAME as _}from"../brand.js";import{backupBeforeWrite as b,atomicWriteFile as D}from"./backup.js";import{toolHome as A}from"./types.js";import{canRestartDesktop as C,isDesktopRunning as w,restartDesktop as E,WINDOWS_PACKAGE_FAMILIES as M}from"./desktop-process.js";import{setUserRegistryElevated as v}from"./elevated-reg.js";import{UserActionNeeded as O}from"./types.js";import{baseModelId as S,isClaudeModel as x}from"../model-catalog.js";import{getDefaultModels as P}from"../model-registry.js";const j=y;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const L=/^[a-f0-9-]{36}$/;function I(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=A(),n=Boolean(k("TEST_HOME")?.trim());switch(process.platform){case"darwin":return a(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(o,"AppData","Local");return M.map(t=>a(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??a(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:a(o,".config");return a(e,"Claude-3p")}}}const T=()=>a(claudeDesktopUserDataDir(),"configLibrary"),$=()=>a(T(),"_meta.json"),R=e=>a(T(),`${e}.json`),G=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function N(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return I(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed, back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function U(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),b(n),D(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function K(){const e=N($());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>I(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function F(e){return e?.entries.find(e=>e.name===j&&L.test(e.id))}const H={opus:0,fable:1,sonnet:2,haiku:3};function B(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=B(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function J(e){return B(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>S(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(x)){i=[...new Set(t.models.filter(x).map(S))];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=S(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>H[J(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=a(e)-a(t);if(0!==n)return n;const r=B(e),s=B(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const l=new Set,c=new Map,d=new Set(Object.values(P()).map(e=>S(e||"")));for(const e of n){const t=J(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=J(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||l.has(t)||(o.isFamilyDefault=!0,l.add(t))}return o})}let V=null,W=null,z=null,Z=null;function X(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const q={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}};function Y(e){return Object.fromEntries(Object.entries(q).filter(([t])=>!e(t)))}const Q="SOFTWARE\\Policies\\Claude",ee=`HKCU\\${Q}`,te="HKLM\\SOFTWARE\\Policies\\Claude",oe=`${_}-claude-policy.reg`,ne=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let re=ne;export function setRegRunnerForTests(e){re=e??ne}function se(){return"win32"===process.platform}function ie(e){let t;try{t=re(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function ae(){if(null===ie(ee))return;const e=a(claudeDesktopUserDataDir(),oe);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),b(e),re(["export",ee,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function le(e){ae();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];re(["add",ee,"/v",t,"/t",e,"/d",n,"/f"])}}function ce(e){const t=ie(ee);if(!t)return;ae();let o=t.size;for(const n of e)t.has(n)&&(re(["delete",ee,"/v",n,"/f"]),o-=1);o<=0&&re(["delete",ee,"/f"])}const de=[...Object.keys(X({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(q)];export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return ie(te)?te:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return u.logError("claude-desktop.detectManagedConfig",e),null}}function pe(){const e=A();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",a(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||a(e,"AppData","Local");o=[a(t,"AnthropicClaude"),a(t,"Programs","Claude"),...M.map(e=>a(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",a(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),a(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const ue=/\d+\.\d+\.\d+/;function fe(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}function me(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",a(A(),"Applications","Claude.app")]){const o=a(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?ue.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(A(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return fe(t)}const o=M.map(e=>`'${e}'`).join(",");return fe(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"]}).split(/\r?\n/).flatMap(e=>ue.exec(e)?.[0]??[]))}return null}const ge="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",ye="darwin"!==process.platform&&"win32"!==process.platform||!h().installMirror?.claudeDesktop?"https://claude.ai/download":h().installMirror.claudeDesktop,he="darwin"===process.platform?`open ${ye}`:"win32"===process.platform?`start ${ye}`:`xdg-open ${ye}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:ge,installCommand:he,configPath:$(),isInstalled:pe,installedVersion:me,prepareRuntime:async function(){if("win32"!==process.platform&&"darwin"!==process.platform||!pe())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+g.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?me():null,mirrorRepo:h().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null});return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:g.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return u.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:g.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:w,restart:E}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const o=K()??{appliedId:"",entries:[]};let n=F(o);n||(n={id:l(),name:j},o.entries.push(n));const r=X(e);W=!0===r.disableDeploymentModeChooser,V={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=N(R(n.id))??{};U(R(n.id),{...Y(e=>e in s),...s,...r}),o.appliedId=n.id,U($(),o);const i=N(G())??{};if("3p"!==i.deploymentMode&&U(G(),{...i,deploymentMode:"3p"}),z=null,Z=null,se()){const o=ie(ee),n=de.filter(e=>o?.has(e)),s={...Y(e=>o?.has(e)??!1),...r},i=!0===e.settings?.force_registry,l=!i&&function(){const e=!Boolean(k("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(A(),"AppData","Local");return!!t(a(e,"AnthropicClaude"))||M.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{l?ce(de):le(s)}catch(e){u.logError("claude-desktop.policy",e),z=e instanceof Error?e.message.trim():String(e),(n.length>0||i)&&(Z=l?{action:"remove",values:Object.fromEntries(n.map(e=>[e,null])),deleteKey:n.length===o.size}:{action:"write",values:s,deleteKey:!1})}}},pendingElevation(){const e=Z;return e?{prompt:g.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!v(Q,e.values,e.deleteKey))return!1;const t=ie(ee),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(Z=null,z=null),o}}:null},unloadPrivateConfig(){if(se())try{ce(de)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=K(),t=F(e);if(!e||!t)return;b(R(t.id)),s(R(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(b($()),s($(),{force:!0})):U($(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=K(),t=F(e);if(!t||e?.appliedId!==t.id)return null;const o=N(R(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=K(),o=F(t);if(!o||t?.appliedId!==o.id)return;const n=N(R(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(se()&&ie(ee)?.has("inferenceModels"))try{le({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),new O(g.t("tools.claude_desktop.refresh_needs_admin"))}U(R(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(se()){const e=ie(ee)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=F(K());if(!e)return{apiKey:null};const t=N(R(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return u.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=K(),t=F(e);return{meta:e,applied:t?N(R(t.id)):null,desktop:N(G()),...se()?{policy:Object.fromEntries(ie(ee)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;se()&&ie(ee)?.has("inferenceModels")&&(ae(),re(["delete",ee,"/v","inferenceModels","/f"]),e=!0);const t=F(K()),o=t?N(R(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;U(R(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(V&&V.models.length>0){const{models:t,source:o,groups:n}=V;e.push({kind:"summary",text:g.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:g.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==W&&e.push({kind:"detail",text:g.t(W?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!w()||e.push({kind:"action",text:g.t("tools.claude_desktop.restart_hint")}),Z?(e.push({kind:"action",text:g.t(`tools.claude_desktop.policy_stale_${Z.action}`)}),e.push({kind:"detail",text:z??""})):z?(e.push({kind:"detail",text:g.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:z})):se()&&e.push({kind:"detail",text:g.t("tools.claude_desktop.registry_written",{key:ee})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:g.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[$(),G()];try{const t=F(K());t&&e.push(R(t.id))}catch{}return e},backupPaths(){const e=[$(),G()];se()&&e.push(a(claudeDesktopUserDataDir(),oe));try{const t=F(K());t&&e.push(R(t.id))}catch{}return e}};
|
package/dist/locales/en_US.json
CHANGED
|
@@ -402,7 +402,7 @@
|
|
|
402
402
|
"unload_other_key": "Codex is still signed in with another API key (not the {{brand}} key, left as is). To use your ChatGPT subscription, run codex logout, then codex login"
|
|
403
403
|
},
|
|
404
404
|
"claude_desktop": {
|
|
405
|
-
"code_cli_downloading": "Downloading Claude Code {{version}} for Claude Desktop's Code tab from the China mirror (about
|
|
405
|
+
"code_cli_downloading": "Downloading Claude Code {{version}} for Claude Desktop's Code tab from the China mirror (about 100 MB)",
|
|
406
406
|
"code_cli_installed": "Claude Desktop's Code tab has Claude Code {{version}} and no longer needs downloads.claude.ai",
|
|
407
407
|
"code_cli_failed": "Could not prepare Claude Code for Claude Desktop's Code tab ({{reason}}); the tab may say it cannot download it. Run setup again when the network is better",
|
|
408
408
|
"restart_hint": "Fully quit Claude Desktop and reopen it for the change to take effect",
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -402,7 +402,7 @@
|
|
|
402
402
|
"unload_other_key": "Codex 仍在用另一个 API Key 登录(不是 {{brand}} 的 Key,没有动它)。改用 ChatGPT 订阅:运行 codex logout,再运行 codex login"
|
|
403
403
|
},
|
|
404
404
|
"claude_desktop": {
|
|
405
|
-
"code_cli_downloading": "正在为 Claude 桌面端的 Code 标签页从国内镜像下载 Claude Code {{version}}(约
|
|
405
|
+
"code_cli_downloading": "正在为 Claude 桌面端的 Code 标签页从国内镜像下载 Claude Code {{version}}(约 100 MB)",
|
|
406
406
|
"code_cli_installed": "Claude 桌面端的 Code 标签页已备好 Claude Code {{version}},不用再从 downloads.claude.ai 下载",
|
|
407
407
|
"code_cli_failed": "没能给 Claude 桌面端的 Code 标签页备好 Claude Code({{reason}}),Code 标签页可能提示无法下载;网络好的时候重新运行 setup 即可",
|
|
408
408
|
"restart_hint": "完全退出 Claude 桌面端再重新打开才会生效",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeapi/api-helper",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.120",
|
|
4
4
|
"description": "CLI tool for managing AI coding assistants (Claude Code, Codex, OpenClaw, Hermes, AtomCode, Grok Build) with one unified config",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|