@vibeapi/cli 0.0.66 → 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -96,6 +96,8 @@ vibecli config tool-model set codex gpt-6-astra # 单独给某工具指定模
96
96
  vibecli config profile use work # 切换 profile
97
97
  vibecli doctor # 健康巡检(--deep 实发一条请求)
98
98
  vibecli upgrade # 升级 Claude Code / Codex,官方渠道连不上自动改走国内镜像
99
+ vibecli codex sessions # 换过登录方式后 Codex 旧会话不显示时,让它们重新出现(先退出 Codex)
100
+ vibecli setup --desktop-registry on # Windows:桌面端不认本地配置时,强制写注册表(会请求一次管理员确认)
99
101
  ```
100
102
 
101
103
  ## 支持
@@ -1 +1 @@
1
- import t from"chalk";import o from"ora";import{spawnSync as s}from"child_process";import{readFileSync as e}from"fs";import{connect as a}from"net";import{join as n}from"path";import{configManager as r}from"../lib/config.js";import{toolManager as c}from"../lib/tool-manager.js";import{i18n as i}from"../lib/i18n.js";import{validateApiKey as l}from"../lib/api-validator.js";import{getAdapter as d}from"../lib/tools/registry.js";import{findInstalls as p,installLabel as u}from"../lib/tools/tool-installs.js";import{detectManagedOverrides as m}from"../lib/tools/claude-managed.js";import{codexAuthProblem as _}from"../lib/tools/codex.js";import{toolHome as g}from"../lib/tools/types.js";const f=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function h(t,o,s=3e3){return new Promise(e=>{const n=a({host:t,port:o}),r=t=>{n.destroy(),e(t)};n.setTimeout(s,()=>r(!1)),n.once("connect",()=>r(!0)),n.once("error",()=>r(!1))})}export async function doctorCommand(a={}){const y=o(i.t("doctor.checking")).start(),w=[],$=Number(process.versions.node.split(".")[0]);w.push({name:"Node.js",status:$>=20?"pass":"fail",message:`v${process.versions.node}`}),y.text=i.t("doctor.check_proxy"),w.push(await async function(){const t=i.t("doctor.proxy"),o=new Map;for(const t of f){const s=process.env[t]?.trim();s&&!o.has(s)&&o.set(s,t)}if(0===o.size)return{name:t,status:"pass",message:i.t("doctor.proxy_none")};const s=[];for(const[t,e]of o){let o;try{o=new URL(t.includes("://")?t:`http://${t}`)}catch{s.push(`${e}=${t}`);continue}const a=Number(o.port)||("https:"===o.protocol?443:o.protocol.startsWith("socks")?1080:80);await h(o.hostname,a)||s.push(`${e}=${t}`)}return 0===s.length?{name:t,status:"pass",message:[...o.keys()].join(", ")}:{name:t,status:"fail",message:i.t("doctor.proxy_dead",{proxies:s.join(", ")})}}()),y.text=i.t("doctor.check_api_key_network");const x=r.getApiKey(),j=i.t("doctor.api_key_network");if(x){const t=await l(x);t.valid?w.push({name:j,status:"pass"}):"invalid_api_key"===t.error?w.push({name:j,status:"fail",message:i.t("doctor.api_key_invalid")}):w.push({name:j,status:"fail",message:`${i.t("doctor.network_error")}: ${t.message??t.error}`})}else w.push({name:j,status:"fail",message:i.t("doctor.api_key_missing")});y.text=i.t("doctor.check_tools");const T=c.getInstalledTools();w.push({name:i.t("doctor.installed_tools"),status:T.length>0?"pass":"warn",message:T.length>0?T.map(t=>d(t)?.displayName??t).join(", "):i.t("doctor.no_tools_installed")}),w.push(...function(){const t=[];for(const o of c.getInstalledTools()){const s=d(o);if(!s?.installSpec)continue;const e=p(s.installSpec);if(0===e.length)continue;const a=[],n=c.outdatedVersion(o);n&&a.push(i.t("doctor.tool_outdated",{min:n.min})),e.length>1&&a.push(i.t("doctor.tool_duplicates",{others:e.slice(1).map(u).join("、")})),t.push({name:s.displayName,status:a.length>0?"warn":"pass",message:[u(e[0]),...a,...a.length>0?[i.t("doctor.run_upgrade",{tool:o})]:[]].join("\n ")})}return t}());const k=function(){if(!c.isToolInstalled("claude-code"))return null;const t=i.t("doctor.claude_config"),o=m();if(o.length>0){const s=o.map(t=>`${t.source}: ${t.keys.join(", ")}`).join("; ");return{name:t,status:"fail",message:i.t("doctor.claude_managed",{detail:s})}}let s={};try{s=JSON.parse(e(n(g(),".claude","settings.json"),"utf-8")).env??{}}catch{}const a=r.getApiKeyForTool("claude-code");return s.ANTHROPIC_AUTH_TOKEN&&s.ANTHROPIC_BASE_URL?s.ANTHROPIC_BASE_URL!==r.getBaseUrl()||a&&s.ANTHROPIC_AUTH_TOKEN!==a?{name:t,status:"warn",message:i.t("doctor.claude_config_changed")}:{name:t,status:"pass"}:{name:t,status:"warn",message:i.t("doctor.claude_not_configured")}}();k&&w.push(k);const b=T.includes("codex")?_():null;T.includes("codex")&&w.push({name:i.t("doctor.codex_auth"),status:b?"fail":"pass",message:b?i.t(`doctor.codex_${b}`):void 0}),"win32"===process.platform&&T.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&w.push({name:"Git for Windows",status:c.isGitInstalled()?"pass":"warn",message:c.isGitInstalled()?void 0:i.t("tools.claude_code.no_git_bash")}),a.deep&&T.includes("claude-code")&&(y.text=i.t("doctor.check_claude_request"),w.push(function(){const t=i.t("doctor.claude_request"),o=p(d("claude-code").installSpec)[0];if(!o)return{name:t,status:"warn",message:i.t("doctor.claude_request_skipped")};const e={encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},a=["-p","Reply with the single word OK."],n=/\.cmd$/i.test(o.path)?s(`"${o.path}" ${a.map(t=>`"${t}"`).join(" ")}`,{...e,shell:!0}):s(o.path,a,e),r=`${n.stdout??""}`.trim();if(0===n.status&&r)return{name:t,status:"pass",message:r.slice(0,80)};const c=(`${n.stderr??""}`.trim()||r||n.error?.message||`exit ${n.status}`).slice(0,300);return{name:t,status:"fail",message:i.t("doctor.claude_request_failed",{reason:c})}}())),y.stop(),console.log("\n"+t.bold(i.t("doctor.results_title"))+"\n");const A={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of w)console.log(`${A[o.status]} ${o.name}`),o.message&&console.log(t.gray(` ${o.message}`));w.every(t=>"pass"===t.status)&&console.log("\n"+t.green.bold(i.t("doctor.all_good"))),!a.deep&&T.includes("claude-code")&&console.log(t.gray("\n"+i.t("doctor.deep_hint"))),w.some(t=>"fail"===t.status)&&(process.exitCode=1)}
1
+ import t from"chalk";import o from"ora";import{spawnSync as s}from"child_process";import{readFileSync as e}from"fs";import{connect as a}from"net";import{join as n}from"path";import{configManager as r}from"../lib/config.js";import{toolManager as c}from"../lib/tool-manager.js";import{i18n as i}from"../lib/i18n.js";import{validateApiKey as l}from"../lib/api-validator.js";import{getAdapter as d}from"../lib/tools/registry.js";import{findInstalls as u,installLabel as p}from"../lib/tools/tool-installs.js";import{detectManagedOverrides as m}from"../lib/tools/claude-managed.js";import{codexAuthProblem as _}from"../lib/tools/codex.js";import{claudeAccountLoginPresent as g}from"../lib/tools/claude-code.js";import{toolHome as f}from"../lib/tools/types.js";const h=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function y(t,o,s=3e3){return new Promise(e=>{const n=a({host:t,port:o}),r=t=>{n.destroy(),e(t)};n.setTimeout(s,()=>r(!1)),n.once("connect",()=>r(!0)),n.once("error",()=>r(!1))})}export async function doctorCommand(a={}){const w=o(i.t("doctor.checking")).start(),$=[],j=Number(process.versions.node.split(".")[0]);$.push({name:"Node.js",status:j>=20?"pass":"fail",message:`v${process.versions.node}`}),w.text=i.t("doctor.check_proxy"),$.push(await async function(){const t=i.t("doctor.proxy"),o=new Map;for(const t of h){const s=process.env[t]?.trim();s&&!o.has(s)&&o.set(s,t)}if(0===o.size)return{name:t,status:"pass",message:i.t("doctor.proxy_none")};const s=[];for(const[t,e]of o){let o;try{o=new URL(t.includes("://")?t:`http://${t}`)}catch{s.push(`${e}=${t}`);continue}const a=Number(o.port)||("https:"===o.protocol?443:o.protocol.startsWith("socks")?1080:80);await y(o.hostname,a)||s.push(`${e}=${t}`)}return 0===s.length?{name:t,status:"pass",message:[...o.keys()].join(", ")}:{name:t,status:"fail",message:i.t("doctor.proxy_dead",{proxies:s.join(", ")})}}()),w.text=i.t("doctor.check_api_key_network");const x=r.getApiKey(),T=i.t("doctor.api_key_network");if(x){const t=await l(x);t.valid?$.push({name:T,status:"pass"}):"invalid_api_key"===t.error?$.push({name:T,status:"fail",message:i.t("doctor.api_key_invalid")}):$.push({name:T,status:"fail",message:`${i.t("doctor.network_error")}: ${t.message??t.error}`})}else $.push({name:T,status:"fail",message:i.t("doctor.api_key_missing")});w.text=i.t("doctor.check_tools");const k=c.getInstalledTools();$.push({name:i.t("doctor.installed_tools"),status:k.length>0?"pass":"warn",message:k.length>0?k.map(t=>d(t)?.displayName??t).join(", "):i.t("doctor.no_tools_installed")}),$.push(...function(){const t=[];for(const o of c.getInstalledTools()){const s=d(o);if(!s?.installSpec)continue;const e=u(s.installSpec);if(0===e.length)continue;const a=[],n=c.outdatedVersion(o);n&&a.push(i.t("doctor.tool_outdated",{min:n.min})),e.length>1&&a.push(i.t("doctor.tool_duplicates",{others:e.slice(1).map(p).join("、")})),t.push({name:s.displayName,status:a.length>0?"warn":"pass",message:[p(e[0]),...a,...a.length>0?[i.t("doctor.run_upgrade",{tool:o})]:[]].join("\n ")})}return t}());const b=function(){if(!c.isToolInstalled("claude-code"))return null;const t=i.t("doctor.claude_config"),o=m();if(o.length>0){const s=o.map(t=>`${t.source}: ${t.keys.join(", ")}`).join("; ");return{name:t,status:"fail",message:i.t("doctor.claude_managed",{detail:s})}}let s={};try{s=JSON.parse(e(n(f(),".claude","settings.json"),"utf-8")).env??{}}catch{}const a=r.getApiKeyForTool("claude-code");return s.ANTHROPIC_AUTH_TOKEN&&s.ANTHROPIC_BASE_URL?s.ANTHROPIC_BASE_URL!==r.getBaseUrl()||a&&s.ANTHROPIC_AUTH_TOKEN!==a?{name:t,status:"warn",message:i.t("doctor.claude_config_changed")}:{name:t,status:"pass"}:{name:t,status:"warn",message:i.t("doctor.claude_not_configured")}}();b&&$.push(b),k.includes("claude-code")&&g()&&$.push({name:i.t("doctor.claude_login"),status:"pass",message:i.t("tools.claude_code.account_login_overridden")});const v=k.includes("codex")?_():null;k.includes("codex")&&$.push({name:i.t("doctor.codex_auth"),status:v?"fail":"pass",message:v?i.t(`doctor.codex_${v}`):void 0}),"win32"===process.platform&&k.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&$.push({name:"Git for Windows",status:c.isGitInstalled()?"pass":"warn",message:c.isGitInstalled()?void 0:i.t("tools.claude_code.no_git_bash")}),a.deep&&k.includes("claude-code")&&(w.text=i.t("doctor.check_claude_request"),$.push(function(){const t=i.t("doctor.claude_request"),o=u(d("claude-code").installSpec)[0];if(!o)return{name:t,status:"warn",message:i.t("doctor.claude_request_skipped")};const e={encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},a=["-p","Reply with the single word OK."],n=/\.cmd$/i.test(o.path)?s(`"${o.path}" ${a.map(t=>`"${t}"`).join(" ")}`,{...e,shell:!0}):s(o.path,a,e),r=`${n.stdout??""}`.trim();if(0===n.status&&r)return{name:t,status:"pass",message:r.slice(0,80)};const c=(`${n.stderr??""}`.trim()||r||n.error?.message||`exit ${n.status}`).slice(0,300);return{name:t,status:"fail",message:i.t("doctor.claude_request_failed",{reason:c})}}())),w.stop(),console.log("\n"+t.bold(i.t("doctor.results_title"))+"\n");const A={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of $)console.log(`${A[o.status]} ${o.name}`),o.message&&console.log(t.gray(` ${o.message}`));$.every(t=>"pass"===t.status)&&console.log("\n"+t.green.bold(i.t("doctor.all_good"))),!a.deep&&k.includes("claude-code")&&console.log(t.gray("\n"+i.t("doctor.deep_hint"))),$.some(t=>"fail"===t.status)&&(process.exitCode=1)}
@@ -1,3 +1,13 @@
1
1
  import { type ToolAdapter } from './types.js';
2
+ /** Tests replace the macOS keychain probe. */
3
+ export declare function setClaudeKeychainProbeForTests(fake: () => boolean): void;
4
+ /**
5
+ * Whether Claude Code holds an official claude.ai / Console login: `.credentials.json`
6
+ * in its config dir (Linux, Windows), or the "Claude Code-credentials" keychain item
7
+ * (macOS; existence only, the secret is never read). The token vibecli writes to
8
+ * settings.json `env` takes precedence over that login (known Claude Code behavior),
9
+ * so this is only reported, never changed.
10
+ */
11
+ export declare function claudeAccountLoginPresent(): boolean;
2
12
  /** Thin adapter over the full-featured ClaudeCodeManager singleton. */
3
13
  export declare const claudeCodeAdapter: ToolAdapter;
@@ -1 +1 @@
1
- import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite as a}from"./backup.js";import{i18n as n}from"../i18n.js";import{baseModelId as s}from"../model-catalog.js";import{gatewayModelSpecs as i,prettyModelName as l,vendorNames as d}from"../gateway-models.js";import{toolHome as r}from"./types.js";import{spawnSync as c}from"child_process";import{readFileSync as u}from"fs";import{detectManagedOverrides as m}from"./claude-managed.js";import{installOfficialPlugins as p}from"./claude-plugins.js";import{findInstalls as g}from"./tool-installs.js";import{updateNativeFromMirror as f}from"./claude-native-mirror.js";const h=e(r(),".claude","settings.json"),C=e(r(),".claude.json");let _,k=null;function j(){try{const t=JSON.parse(u(e(r(),".claude","settings.json"),"utf-8"));return"string"==typeof t.autoUpdatesChannel?t.autoUpdatesChannel:"latest"}catch{return"latest"}}function y(e){if(!e)return;const t=new Set(e.models);return i("claude-code",e.clientModels).filter(e=>t.has(e.id))}export const claudeCodeAdapter={name:"claude-code",displayName:"Claude Code",command:"claude",installCommand:"npm install -g @anthropic-ai/claude-code",upgradeCommand:"claude update",installSpec:{command:"claude",npmPackage:"@anthropic-ai/claude-code",native:{binDir:[".local","bin"],updateArgs:["update"],dataDirs:[[".local","share","claude"]],mirrorUpdate:()=>f(j())},brew:"claude-code"},upgradeHints:e=>"stable"===j()?[n.t("tools.claude_code.stable_channel",{min:e})]:[],configPath:h,wantsModelCatalog:!0,loadPrivateConfig(e){a(h),a(C),_=y(e.catalog),o.loadPrivateConfig(e.apiKey,e.models,e.catalog?.models,_);const t=g(claudeCodeAdapter.installSpec)[0];k=t?p(t.path):null},unloadPrivateConfig(){a(h),o.unloadPrivateConfig()},detectCurrentConfig:()=>o.detectCurrentConfig(),getConfig:()=>({settings:o.getSettings(),mcp:o.getMCPConfig()}),updateConfig(e){const t=e||{};t.settings&&o.saveSettings(t.settings),t.mcp&&o.saveMCPConfig(t.mcp)},clearPinnedModels:e=>(a(h),o.clearPinnedModels(e?.models)),listedModels(){const e=o.getSettings().modelPicker;return Array.isArray(e?.options)?e.options.map(e=>s(String(e.model))):null},refreshModelMenu(e){const n=o.getSettings(),s=t(n,y(e.catalog));JSON.stringify(s)!==JSON.stringify(n)&&(a(h),o.saveSettings(s))},applyNotes(){const e=[];k?.installed.length&&(e.push({kind:"summary",text:n.t("tools.claude_code.plugins_installed",{count:String(k.installed.length)})}),e.push({kind:"detail",text:k.installed.join(", ")})),("marketplace"===k?.skipped||k?.failed.length)&&e.push({kind:"action",text:n.t("tools.claude_code.plugins_failed")}),_&&_.length>0&&(e.push({kind:"summary",text:n.t("tools.claude_code.gateway_models",{count:String(_.length),vendors:d(_.map(e=>e.id)).join(" / ")})}),e.push({kind:"detail",text:_.map(e=>e.name||l(e.id)).join(", ")})),"win32"!==process.platform||process.env.CLAUDE_CODE_GIT_BASH_PATH||0===c("where",["git"],{windowsHide:!0,stdio:"ignore"}).status||e.push({kind:"action",text:n.t("tools.claude_code.no_git_bash")});for(const t of m())e.push({kind:"action",text:n.t("tools.claude_code.managed_override",{source:t.source,keys:t.keys.join(", ")})});for(const t of o.getLastTierFallbacks())e.push({kind:"detail",text:n.t("tools.claude_code.tier_fallback",{tier:t.tier,from:t.from,to:t.to})});return e},backupPaths:()=>[h,C],forceResetPaths:()=>[h]};
1
+ import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite as a}from"./backup.js";import{i18n as n}from"../i18n.js";import{baseModelId as s}from"../model-catalog.js";import{gatewayModelSpecs as i,prettyModelName as r,vendorNames as l}from"../gateway-models.js";import{toolHome as d}from"./types.js";import{spawnSync as c}from"child_process";import{existsSync as u,readFileSync as p}from"fs";import{detectManagedOverrides as m}from"./claude-managed.js";import{installOfficialPlugins as g}from"./claude-plugins.js";import{findInstalls as f}from"./tool-installs.js";import{updateNativeFromMirror as h}from"./claude-native-mirror.js";const C=e(d(),".claude","settings.json"),_=e(d(),".claude.json");let k,y=null,j=()=>0===c("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore"}).status;export function setClaudeKeychainProbeForTests(e){j=e}export function claudeAccountLoginPresent(){const t=process.env.CLAUDE_CONFIG_DIR?.trim()||e(d(),".claude");if(u(e(t,".credentials.json")))return!0;if("darwin"!==process.platform||process.env.VIBECLI_TEST_HOME)return!1;try{return j()}catch{return!1}}function P(){try{const t=JSON.parse(p(e(d(),".claude","settings.json"),"utf-8"));return"string"==typeof t.autoUpdatesChannel?t.autoUpdatesChannel:"latest"}catch{return"latest"}}function S(e){if(!e)return;const t=new Set(e.models);return i("claude-code",e.clientModels).filter(e=>t.has(e.id))}export const claudeCodeAdapter={name:"claude-code",displayName:"Claude Code",command:"claude",installCommand:"npm install -g @anthropic-ai/claude-code",upgradeCommand:"claude update",installSpec:{command:"claude",npmPackage:"@anthropic-ai/claude-code",native:{binDir:[".local","bin"],updateArgs:["update"],dataDirs:[[".local","share","claude"]],mirrorUpdate:()=>h(P())},brew:"claude-code"},upgradeHints:e=>"stable"===P()?[n.t("tools.claude_code.stable_channel",{min:e})]:[],configPath:C,wantsModelCatalog:!0,loadPrivateConfig(e){a(C),a(_),k=S(e.catalog),o.loadPrivateConfig(e.apiKey,e.models,e.catalog?.models,k);const t=f(claudeCodeAdapter.installSpec)[0];y=t?g(t.path):null},unloadPrivateConfig(){a(C),o.unloadPrivateConfig()},detectCurrentConfig:()=>o.detectCurrentConfig(),getConfig:()=>({settings:o.getSettings(),mcp:o.getMCPConfig()}),updateConfig(e){const t=e||{};t.settings&&o.saveSettings(t.settings),t.mcp&&o.saveMCPConfig(t.mcp)},clearPinnedModels:e=>(a(C),o.clearPinnedModels(e?.models)),listedModels(){const e=o.getSettings().modelPicker;return Array.isArray(e?.options)?e.options.map(e=>s(String(e.model))):null},refreshModelMenu(e){const n=o.getSettings(),s=t(n,S(e.catalog));JSON.stringify(s)!==JSON.stringify(n)&&(a(C),o.saveSettings(s))},applyNotes(){const e=[];y?.installed.length&&(e.push({kind:"summary",text:n.t("tools.claude_code.plugins_installed",{count:String(y.installed.length)})}),e.push({kind:"detail",text:y.installed.join(", ")})),("marketplace"===y?.skipped||y?.failed.length)&&e.push({kind:"action",text:n.t("tools.claude_code.plugins_failed")}),k&&k.length>0&&(e.push({kind:"summary",text:n.t("tools.claude_code.gateway_models",{count:String(k.length),vendors:l(k.map(e=>e.id)).join(" / ")})}),e.push({kind:"detail",text:k.map(e=>e.name||r(e.id)).join(", ")})),"win32"!==process.platform||process.env.CLAUDE_CODE_GIT_BASH_PATH||0===c("where",["git"],{windowsHide:!0,stdio:"ignore"}).status||e.push({kind:"action",text:n.t("tools.claude_code.no_git_bash")}),claudeAccountLoginPresent()&&e.push({kind:"detail",text:n.t("tools.claude_code.account_login_overridden")});for(const t of m())e.push({kind:"action",text:n.t("tools.claude_code.managed_override",{source:t.source,keys:t.keys.join(", ")})});for(const t of o.getLastTierFallbacks())e.push({kind:"detail",text:n.t("tools.claude_code.tier_fallback",{tier:t.tier,from:t.from,to:t.to})});return e},backupPaths:()=>[C,_],forceResetPaths:()=>[C]};
@@ -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{logger as p}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{BRAND_NAME as f}from"../brand.js";import{backupBeforeWrite as m,atomicWriteFile as g}from"./backup.js";import{toolHome as h}from"./types.js";import{canRestartDesktop as y,isDesktopRunning as k,restartDesktop as b,WINDOWS_PACKAGE_FAMILIES as _}from"./desktop-process.js";import{setUserRegistryElevated as A}from"./elevated-reg.js";import{UserActionNeeded as C}from"./types.js";import{baseModelId as E,isClaudeModel as D}from"../model-catalog.js";const v=f;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const w=/^[a-f0-9-]{36}$/;function M(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=h(),n=Boolean(process.env.VIBECLI_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 _.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 O=()=>a(claudeDesktopUserDataDir(),"configLibrary"),S=()=>a(O(),"_meta.json"),P=e=>a(O(),`${e}.json`),x=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function I(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return M(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 L(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),m(n),g(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){p.logError("claude-desktop.writeJson.chmod",e)}}function j(){const e=I(S());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>M(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function T(e){return e?.entries.find(e=>e.name===v&&w.test(e.id))}const $={opus:0,fable:1,sonnet:2,haiku:3};function G(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=G(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function N(e){return G(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>E(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(D)){i=[...new Set(t.models.filter(D).map(E))];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=E(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>$[N(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=G(e),s=G(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;for(const e of n){const t=N(e);t&&i.includes(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=N(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 R=null,K=null,U=null,F=null;function H(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 B={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};function V(e){return Object.fromEntries(Object.entries(B).filter(([t])=>!e(t)))}const J="SOFTWARE\\Policies\\Claude",W=`HKCU\\${J}`,z="HKLM\\SOFTWARE\\Policies\\Claude",Z="vibecli-claude-policy.reg",X=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let q=X;export function setRegRunnerForTests(e){q=e??X}function Y(){return"win32"===process.platform}function Q(e){let t;try{t=q(["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 ee(){if(null===Q(W))return;const e=a(claudeDesktopUserDataDir(),Z);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),m(e),q(["export",W,e,"/y"])}catch(e){p.logError("claude-desktop.snapshotPolicy",e)}}function te(e){ee();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)];q(["add",W,"/v",t,"/t",e,"/d",n,"/f"])}}function oe(e){const t=Q(W);if(!t)return;ee();let o=t.size;for(const n of e)t.has(n)&&(q(["delete",W,"/v",n,"/f"]),o-=1);o<=0&&q(["delete",W,"/f"])}const ne=[...Object.keys(H({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(B),"banner"];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 Q(z)?z:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return p.logError("claude-desktop.detectManagedConfig",e),null}}const re=/\d+\.\d+\.\d+/;function se(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 ie="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",ae="darwin"===process.platform||"win32"===process.platform?"https://cnb.cool/vibeapi/claude-desktop/-/releases/latest":"https://claude.ai/download",le="darwin"===process.platform?`open ${ae}`:"win32"===process.platform?`start ${ae}`:`xdg-open ${ae}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:ie,installCommand:le,configPath:S(),isInstalled:function(){const e=h();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"),..._.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))},installedVersion:function(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",a(h(),"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?re.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(h(),"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 se(t)}const o=_.map(e=>`'${e}'`).join(",");return se(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=>re.exec(e)?.[0]??[]))}return null},runningApp:y()?{isRunning:k,restart:b}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const o=j()??{appliedId:"",entries:[]};let n=T(o);n||(n={id:l(),name:v},o.entries.push(n));const r=H(e);K=!0===r.disableDeploymentModeChooser,R={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=I(P(n.id))??{};L(P(n.id),{...V(e=>e in s),...s,...r}),o.appliedId=n.id,L(S(),o);const i=I(x())??{};if("3p"!==i.deploymentMode&&L(x(),{...i,deploymentMode:"3p"}),U=null,F=null,Y()){const o=Q(W),n=ne.filter(e=>o?.has(e)),s={...V(e=>o?.has(e)??!1),...r},i=!0===e.settings?.force_registry,l=!i&&function(){const e=!Boolean(process.env.VIBECLI_TEST_HOME?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(h(),"AppData","Local");return!!t(a(e,"AnthropicClaude"))||_.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{l?oe(ne):te(s)}catch(e){p.logError("claude-desktop.policy",e),U=e instanceof Error?e.message.trim():String(e),(n.length>0||i)&&(F=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=F;return e?{prompt:u.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!A(J,e.values,e.deleteKey))return!1;const t=Q(W),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(F=null,U=null),o}}:null},unloadPrivateConfig(){if(Y())try{oe(ne)}catch(e){p.logError("claude-desktop.removePolicy",e)}const e=j(),t=T(e);if(!e||!t)return;m(P(t.id)),s(P(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(m(S()),s(S(),{force:!0})):L(S(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=j(),t=T(e);if(!t||e?.appliedId!==t.id)return null;const o=I(P(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=j(),o=T(t);if(!o||t?.appliedId!==o.id)return;const n=I(P(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(Y()&&Q(W)?.has("inferenceModels"))try{te({inferenceModels:r})}catch(e){throw p.logError("claude-desktop.refreshModelMenu registry",e),new C(u.t("tools.claude_desktop.refresh_needs_admin"))}L(P(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(Y()){const e=Q(W)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=T(j());if(!e)return{apiKey:null};const t=I(P(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return p.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=j(),t=T(e);return{meta:e,applied:t?I(P(t.id)):null,desktop:I(x()),...Y()?{policy:Object.fromEntries(Q(W)??[])}:{}}}catch(e){return p.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;Y()&&Q(W)?.has("inferenceModels")&&(ee(),q(["delete",W,"/v","inferenceModels","/f"]),e=!0);const t=T(j()),o=t?I(P(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;L(P(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(R&&R.models.length>0){const{models:t,source:o,groups:n}=R;e.push({kind:"summary",text:u.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:u.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!==K&&e.push({kind:"detail",text:u.t(K?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),y()&&!k()||e.push({kind:"action",text:u.t("tools.claude_desktop.restart_hint")}),F?(e.push({kind:"action",text:u.t(`tools.claude_desktop.policy_stale_${F.action}`)}),e.push({kind:"detail",text:U??""})):U?(e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:U})):Y()&&e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_written",{key:W})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:u.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[S(),x()];try{const t=T(j());t&&e.push(P(t.id))}catch{}return e},backupPaths(){const e=[S(),x()];Y()&&e.push(a(claudeDesktopUserDataDir(),Z));try{const t=T(j());t&&e.push(P(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{logger as p}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{BRAND_NAME as f}from"../brand.js";import{backupBeforeWrite as m,atomicWriteFile as g}from"./backup.js";import{toolHome as h}from"./types.js";import{canRestartDesktop as y,isDesktopRunning as k,restartDesktop as b,WINDOWS_PACKAGE_FAMILIES as _}from"./desktop-process.js";import{setUserRegistryElevated as A}from"./elevated-reg.js";import{UserActionNeeded as C}from"./types.js";import{baseModelId as E,isClaudeModel as D}from"../model-catalog.js";import{getDefaultModels as v}from"../model-registry.js";const w=f;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const M=/^[a-f0-9-]{36}$/;function O(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=h(),n=Boolean(process.env.VIBECLI_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 _.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 S=()=>a(claudeDesktopUserDataDir(),"configLibrary"),P=()=>a(S(),"_meta.json"),x=e=>a(S(),`${e}.json`),I=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function L(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return O(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 j(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),m(n),g(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){p.logError("claude-desktop.writeJson.chmod",e)}}function T(){const e=L(P());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>O(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function $(e){return e?.entries.find(e=>e.name===w&&M.test(e.id))}const G={opus:0,fable:1,sonnet:2,haiku:3};function N(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=N(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function R(e){return N(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>E(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(D)){i=[...new Set(t.models.filter(D).map(E))];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=E(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>G[R(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=N(e),s=N(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(v()).map(e=>E(e||"")));for(const e of n){const t=R(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=R(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 K=null,U=null,F=null,H=null;function B(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 V={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 J(e){return Object.fromEntries(Object.entries(V).filter(([t])=>!e(t)))}const W="SOFTWARE\\Policies\\Claude",z=`HKCU\\${W}`,Z="HKLM\\SOFTWARE\\Policies\\Claude",X="vibecli-claude-policy.reg",q=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let Y=q;export function setRegRunnerForTests(e){Y=e??q}function Q(){return"win32"===process.platform}function ee(e){let t;try{t=Y(["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 te(){if(null===ee(z))return;const e=a(claudeDesktopUserDataDir(),X);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),m(e),Y(["export",z,e,"/y"])}catch(e){p.logError("claude-desktop.snapshotPolicy",e)}}function oe(e){te();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)];Y(["add",z,"/v",t,"/t",e,"/d",n,"/f"])}}function ne(e){const t=ee(z);if(!t)return;te();let o=t.size;for(const n of e)t.has(n)&&(Y(["delete",z,"/v",n,"/f"]),o-=1);o<=0&&Y(["delete",z,"/f"])}const re=[...Object.keys(B({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(V)];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 ee(Z)?Z:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return p.logError("claude-desktop.detectManagedConfig",e),null}}const se=/\d+\.\d+\.\d+/;function ie(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 ae="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",le="darwin"===process.platform||"win32"===process.platform?"https://cnb.cool/vibeapi/claude-desktop/-/releases/latest":"https://claude.ai/download",ce="darwin"===process.platform?`open ${le}`:"win32"===process.platform?`start ${le}`:`xdg-open ${le}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:ae,installCommand:ce,configPath:P(),isInstalled:function(){const e=h();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"),..._.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))},installedVersion:function(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",a(h(),"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?se.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(h(),"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 ie(t)}const o=_.map(e=>`'${e}'`).join(",");return ie(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=>se.exec(e)?.[0]??[]))}return null},runningApp:y()?{isRunning:k,restart:b}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const o=T()??{appliedId:"",entries:[]};let n=$(o);n||(n={id:l(),name:w},o.entries.push(n));const r=B(e);U=!0===r.disableDeploymentModeChooser,K={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=L(x(n.id))??{};j(x(n.id),{...J(e=>e in s),...s,...r}),o.appliedId=n.id,j(P(),o);const i=L(I())??{};if("3p"!==i.deploymentMode&&j(I(),{...i,deploymentMode:"3p"}),F=null,H=null,Q()){const o=ee(z),n=re.filter(e=>o?.has(e)),s={...J(e=>o?.has(e)??!1),...r},i=!0===e.settings?.force_registry,l=!i&&function(){const e=!Boolean(process.env.VIBECLI_TEST_HOME?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(h(),"AppData","Local");return!!t(a(e,"AnthropicClaude"))||_.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{l?ne(re):oe(s)}catch(e){p.logError("claude-desktop.policy",e),F=e instanceof Error?e.message.trim():String(e),(n.length>0||i)&&(H=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=H;return e?{prompt:u.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!A(W,e.values,e.deleteKey))return!1;const t=ee(z),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(H=null,F=null),o}}:null},unloadPrivateConfig(){if(Q())try{ne(re)}catch(e){p.logError("claude-desktop.removePolicy",e)}const e=T(),t=$(e);if(!e||!t)return;m(x(t.id)),s(x(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(m(P()),s(P(),{force:!0})):j(P(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=T(),t=$(e);if(!t||e?.appliedId!==t.id)return null;const o=L(x(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=T(),o=$(t);if(!o||t?.appliedId!==o.id)return;const n=L(x(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(Q()&&ee(z)?.has("inferenceModels"))try{oe({inferenceModels:r})}catch(e){throw p.logError("claude-desktop.refreshModelMenu registry",e),new C(u.t("tools.claude_desktop.refresh_needs_admin"))}j(x(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(Q()){const e=ee(z)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=$(T());if(!e)return{apiKey:null};const t=L(x(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return p.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=T(),t=$(e);return{meta:e,applied:t?L(x(t.id)):null,desktop:L(I()),...Q()?{policy:Object.fromEntries(ee(z)??[])}:{}}}catch(e){return p.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;Q()&&ee(z)?.has("inferenceModels")&&(te(),Y(["delete",z,"/v","inferenceModels","/f"]),e=!0);const t=$(T()),o=t?L(x(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;j(x(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(K&&K.models.length>0){const{models:t,source:o,groups:n}=K;e.push({kind:"summary",text:u.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:u.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!==U&&e.push({kind:"detail",text:u.t(U?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),y()&&!k()||e.push({kind:"action",text:u.t("tools.claude_desktop.restart_hint")}),H?(e.push({kind:"action",text:u.t(`tools.claude_desktop.policy_stale_${H.action}`)}),e.push({kind:"detail",text:F??""})):F?(e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:F})):Q()&&e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_written",{key:z})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:u.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[P(),I()];try{const t=$(T());t&&e.push(x(t.id))}catch{}return e},backupPaths(){const e=[P(),I()];Q()&&e.push(a(claudeDesktopUserDataDir(),X));try{const t=$(T());t&&e.push(x(t.id))}catch{}return e}};
@@ -213,7 +213,8 @@
213
213
  "deep_hint": "Add --deep to send one real request through Claude Code (uses a little credit) and confirm the whole chain works",
214
214
  "codex_auth": "Codex token",
215
215
  "codex_stale_bearer": "~/.codex/config.toml has experimental_bearer_token under [model_providers.custom] (usually PROXY_MANAGED left by cc-switch's proxy mode); Codex sends it as the token and gets 401 Invalid token. vibecli setup removes it",
216
- "codex_chatgpt_login": "Codex is signed in with a ChatGPT account and sends that credential to VibeAPI (401 Invalid token); run vibecli setup to switch back to the key"
216
+ "codex_chatgpt_login": "Codex is signed in with a ChatGPT account and sends that credential to VibeAPI (401 Invalid token); run vibecli setup to switch back to the key",
217
+ "claude_login": "Claude account login"
217
218
  },
218
219
  "preset": {
219
220
  "claude_mix": "Claude Mix",
@@ -395,7 +396,8 @@
395
396
  "managed_override": "Claude Code managed settings found ({{source}}); {{keys}} there override what vibecli writes, so this config won't take effect. Managed settings usually come from your company's IT; ask your administrator",
396
397
  "no_git_bash": "Git for Windows not found: Claude Code falls back to PowerShell for commands, which works, but bash commands and scripts won't; install Git (winget install Git.Git, or download from https://registry.npmmirror.com/binary.html?path=git-for-windows/)",
397
398
  "plugins_installed": "{{count}} official plugins installed (code review, feature dev, frontend design, …); type / to see them",
398
- "plugins_failed": "Official plugins could not be installed (GitHub unreachable, most likely); everything else works. Run vibecli setup again later"
399
+ "plugins_failed": "Official plugins could not be installed (GitHub unreachable, most likely); everything else works. Run vibecli setup again later",
400
+ "account_login_overridden": "Claude Code on this computer is signed in to a Claude account; the VibeAPI token vibecli writes takes precedence, so Claude Code uses VibeAPI. To go back to the account, remove the VibeAPI config with vibecli config claude-code"
399
401
  },
400
402
  "model_family": {
401
403
  "gpt": "GPT",
@@ -213,7 +213,8 @@
213
213
  "deep_hint": "加上 --deep 会用 Claude Code 实际发一条请求(消耗少量额度),确认整条链路能用",
214
214
  "codex_auth": "Codex 令牌",
215
215
  "codex_stale_bearer": "~/.codex/config.toml 的 [model_providers.custom] 里有 experimental_bearer_token(多半是 cc-switch 等工具代理模式留下的 PROXY_MANAGED),Codex 会把它当令牌发出去,导致 401 Invalid token;运行 vibecli setup 会删掉它",
216
- "codex_chatgpt_login": "Codex 当前是 ChatGPT 账号登录状态,会把 ChatGPT 的凭据发给 VibeAPI,导致 401 Invalid token;运行 vibecli setup 改回令牌登录"
216
+ "codex_chatgpt_login": "Codex 当前是 ChatGPT 账号登录状态,会把 ChatGPT 的凭据发给 VibeAPI,导致 401 Invalid token;运行 vibecli setup 改回令牌登录",
217
+ "claude_login": "Claude 官方登录"
217
218
  },
218
219
  "preset": {
219
220
  "claude_mix": "Claude 混合",
@@ -395,7 +396,8 @@
395
396
  "managed_override": "检测到 Claude Code 的托管配置({{source}}),其中 {{keys}} 优先于 vibecli 写入的设置,会让这里的配置不生效;托管配置一般是公司电脑统一下发的,请联系管理员",
396
397
  "no_git_bash": "没找到 Git for Windows:Claude Code 会改用 PowerShell 执行命令,可以用,但 bash 写法的命令和脚本跑不了;建议安装 Git(winget install Git.Git,或从国内镜像 https://registry.npmmirror.com/binary.html?path=git-for-windows/ 下载)",
397
398
  "plugins_installed": "装好 {{count}} 个官方插件(代码审查、功能开发、前端设计等),输入 / 可以看到",
398
- "plugins_failed": "官方插件没装上(多半是连不上 GitHub),不影响使用;网络好时再运行一次 vibecli setup 即可"
399
+ "plugins_failed": "官方插件没装上(多半是连不上 GitHub),不影响使用;网络好时再运行一次 vibecli setup 即可",
400
+ "account_login_overridden": "这台电脑的 Claude Code 登录过 Claude 官方账号;vibecli 写入的 VibeAPI 令牌会优先生效,Claude Code 走 VibeAPI。要改回官方账号,用 vibecli config claude-code 移除 VibeAPI 配置"
399
401
  },
400
402
  "model_family": {
401
403
  "gpt": "GPT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeapi/cli",
3
- "version": "0.0.66",
3
+ "version": "0.0.67",
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",