@vibeapi/cli 0.0.66 → 0.0.68
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 +3 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/lib/gateway-models.d.ts +4 -4
- package/dist/lib/gateway-models.js +1 -1
- package/dist/lib/tools/claude-code.d.ts +10 -0
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/claude-plugins.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/locales/en_US.json +5 -2
- package/dist/locales/zh_CN.json +5 -2
- package/dist/models.json +2 -4
- package/models.json +2 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ vibecli config claude-code clear-model # 模型选择被钉住时,交还给
|
|
|
79
79
|
- **多工具一键配置**:把当前 API Key / 模型注入 Claude Code、Claude Desktop(桌面端第三方推理模式,写应用本地配置库,无需管理员 / 描述文件)、Codex、OpenClaw、Hermes、AtomCode、Grok Build(OpenCode 暂时下架,`vibecli config opencode` 仍可用)。
|
|
80
80
|
- **按工具选模型**:使用默认 / 实时从 API 拉取 / 内置预设 / 手动输入;每个工具可用不同模型。
|
|
81
81
|
- Claude Code 用默认模型时不写 `ANTHROPIC_*_MODEL` 环境变量,顶层 `model` 由 `settings-template.json` 提供(当前为 `opus[1m]`);显式选择其它模型时会覆盖该模板值。Codex 默认 `gpt-6-astra`,Grok Build 默认 `grok-4.6`,其余工具默认 `gpt-5.5`。
|
|
82
|
-
- Codex(CLI 与桌面版)的模型菜单除自带的 GPT 模型外,还列出网关的 Claude 与国产模型(只列 Key 能用的);Claude Code 的 `/model` 菜单也会在内置档位后列出 Key 能用的国产模型;每个模型按自己的上下文窗口设置,窗口用到 80% 时自动压缩。默认启用 1M 上下文,交互配置 Codex 时可取消(取消后窗口不超过 272K)。需要 Codex 0.122 及以上;Codex、Claude Code 版本过旧时,配置完成会提示升级命令。
|
|
82
|
+
- Codex(CLI 与桌面版)的模型菜单除自带的 GPT 模型外,还列出网关的 Claude、Gemini 与国产模型(只列 Key 能用的);Claude Code 的 `/model` 菜单也会在内置档位后列出 Key 能用的国产模型;每个模型按自己的上下文窗口设置,窗口用到 80% 时自动压缩。默认启用 1M 上下文,交互配置 Codex 时可取消(取消后窗口不超过 272K)。需要 Codex 0.122 及以上;Codex、Claude Code 版本过旧时,配置完成会提示升级命令。
|
|
83
83
|
- **不动你的其它配置**:只改本工具的 provider 字段,你的 hooks、MCP、插件、权限设置原样保留。
|
|
84
84
|
- **配置改坏了一键重置**:`vibecli config <tool> --force`(或 `setup … --force`)先快照再整份重写为推荐配置,坏掉的 JSON/TOML 也能救回;不加 `--force` 时只幂等合并、不碰坏文件。
|
|
85
85
|
- **改前自动备份 + 一键还原**:覆盖配置前先快照(每文件留 10 份),`vibecli config <tool> restore` 随时回退;还原本身也可再撤销。
|
|
@@ -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
|
## 支持
|
package/dist/commands/doctor.js
CHANGED
|
@@ -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
|
|
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)}
|
|
@@ -12,8 +12,8 @@ export declare function autoCompactTokens(window: number, explicit?: number): nu
|
|
|
12
12
|
* The models to add for `tool`. When the gateway publishes its client config
|
|
13
13
|
* (`/api/platform/vibecode/config`) its lists win — fields it leaves out keep the
|
|
14
14
|
* built-in values, and Claude models only come from it when `models.json` lists
|
|
15
|
-
* them too (so a model removed there, like Haiku for Codex, stays out)
|
|
16
|
-
* the built-in list from `models.json` → `gatewayModels`.
|
|
15
|
+
* them too (so a model removed there, like Haiku for Codex, stays out); Codex also
|
|
16
|
+
* gets the `gemini` list. Otherwise the built-in list from `models.json` → `gatewayModels`.
|
|
17
17
|
*/
|
|
18
18
|
export declare function gatewayModelSpecs(tool: GatewayModelTool, clientModels?: Record<string, GatewayClientModel[]>): GatewayModelSpec[];
|
|
19
19
|
/**
|
|
@@ -32,6 +32,6 @@ export declare function modelBlurb(description: string | undefined, options?: {
|
|
|
32
32
|
export declare function prettyModelName(id: string): string;
|
|
33
33
|
/** Vendor names in first-seen order: `glm-5.3`, `glm-5.2`, `kimi-k3` → `GLM`, `Kimi`. */
|
|
34
34
|
export declare function vendorNames(ids: string[]): string[];
|
|
35
|
-
export type ModelFamily = 'gpt' | 'claude' | 'grok' | 'other';
|
|
36
|
-
/** Coarse family for a summary line; everything that isn't GPT, Claude or Grok counts as other (domestic). */
|
|
35
|
+
export type ModelFamily = 'gpt' | 'claude' | 'gemini' | 'grok' | 'other';
|
|
36
|
+
/** Coarse family for a summary line; everything that isn't GPT, Claude, Gemini or Grok counts as other (domestic). */
|
|
37
37
|
export declare function modelFamily(id: string): ModelFamily;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getGatewayModelRules as t}from"./model-registry.js";export function autoCompactTokens(e,o){return o&&o>0?Math.min(o,e):Math.floor(e*t().autoCompactRatio)}export function gatewayModelSpecs(e,o){const
|
|
1
|
+
import{getGatewayModelRules as t}from"./model-registry.js";export function autoCompactTokens(e,o){return o&&o>0?Math.min(o,e):Math.floor(e*t().autoCompactRatio)}export function gatewayModelSpecs(e,o){const i=t().models,n=i.filter(t=>function(t,e){return"codex"===t?!1!==e.codex:!e.id.startsWith("claude-")&&!1!==e.claudeCode}(e,t));if(!o)return n;const r=new Map(("claude-code"===e?i:n).map(t=>[t.id,t])),s=(o.gemini??[]).filter(t=>!1!==i.find(e=>e.id===t.id)?.codex),d="codex"===e?[...o.codex??[],...s,...(o.claude??[]).filter(t=>t.id.startsWith("claude-")&&r.has(t.id))]:function(t,e){return[...(t.codex??[]).filter(t=>"gpt"===modelFamily(t.id)),...t.gemini??[],...t.grok??[],...(t.claude??[]).filter(t=>!t.id.startsWith("claude-"))].filter(t=>e.get(t.id)?.claudeCode??!0)}(o,r);if(0===d.length)return n;const c=new Set,l=[];for(const t of d)c.has(t.id)||(c.add(t.id),l.push({...r.get(t.id),...t}));return l}const e={gpt:"GPT",gemini:"Gemini",glm:"GLM",deepseek:"DeepSeek",minimax:"MiniMax",qwen:"Qwen"};export function modelBlurb(t,e={}){const o=[];for(const i of(t??"").split("|")){const t=i.trim();t&&(/\d\s*万?\s*输出|output\D*\d|\d\D*output/i.test(t)||(/[\d百千]\s*万?\s*上下文|context\D*\d|\d\D*context/i.test(t)?e.millionContext&&!o.includes("百万上下文")&&o.unshift("百万上下文"):o.push(t)))}return e.millionContext&&!o.includes("百万上下文")&&o.unshift("百万上下文"),o.length>0?o.join(" | "):void 0}export function prettyModelName(t){const o=t.replace(/^([a-z]+)(\d)/i,"$1 $2").split(/[-_\s]+/).filter(Boolean),i=[];for(const t of o){const o=i[i.length-1];if(/^\d+$/.test(t)&&o&&/^\d+$/.test(o)&&t.length<=2&&!/^\d{8}$/.test(t)){i[i.length-1]=`${o}.${t}`;continue}const n=t.toLowerCase();i.push(e[n]??(/^[a-z]\d/i.test(t)?t.toUpperCase():t[0].toUpperCase()+t.slice(1)))}return i.join(" ")}export function vendorNames(t){return[...new Set(t.map(t=>prettyModelName(t).split(" ")[0]))]}export function modelFamily(t){const e=t.toLowerCase();return e.startsWith("claude-")?"claude":e.startsWith("gemini")?"gemini":e.startsWith("grok")?"grok":/^(gpt|o\d|codex)/.test(e)?"gpt":"other"}
|
|
@@ -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
|
|
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}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as e}from"child_process";import{readFileSync as t}from"fs";import{join as i}from"path";import{logger as o}from"../../utils/logger.js";import{configManager as s}from"../config.js";import{toolHome as n}from"./types.js";export const PLUGIN_SOURCES=[{name:"vibeapi-plugins",add:"https://cnb.cool/sla/claude-plugins-official.git",probe:"https://cnb.cool/sla/claude-plugins-official.git"},{name:"claude-plugins-official",add:"anthropics/claude-plugins-official",probe:"https://github.com/anthropics/claude-plugins-official.git"}];export const OFFICIAL_PLUGINS=["code-review","feature-dev","frontend-design","pr-review-toolkit","commit-commands","security-guidance","code-simplifier","skill-creator","claude-md-management","claude-code-setup"];const l="official_plugins_offered";let r=(t,
|
|
1
|
+
import{spawnSync as e}from"child_process";import{readFileSync as t}from"fs";import{join as i}from"path";import{logger as o}from"../../utils/logger.js";import{configManager as s}from"../config.js";import{toolHome as n}from"./types.js";export const PLUGIN_SOURCES=[{name:"vibeapi-plugins",add:"https://cnb.cool/sla/claude-plugins-official.git",probe:"https://cnb.cool/sla/claude-plugins-official.git"},{name:"claude-plugins-official",add:"anthropics/claude-plugins-official",probe:"https://github.com/anthropics/claude-plugins-official.git"}];export const OFFICIAL_PLUGINS=["code-review","feature-dev","frontend-design","pr-review-toolkit","commit-commands","security-guidance","code-simplifier","skill-creator","claude-md-management","claude-code-setup"];const l="official_plugins_offered";let r=(t,s)=>{const l=e(t,s,{env:process.env.VIBECLI_TEST_HOME?{...process.env,CLAUDE_CONFIG_DIR:i(n(),".claude")}:process.env,encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"],shell:"win32"===process.platform&&/\.cmd$/i.test(t)});return 0!==l.status&&o.logError(`claude ${s.join(" ")}`,new Error(`${l.stderr??""}${l.stdout??""}`.trim())),0===l.status},a=t=>0===e("git",["ls-remote","--heads",t],{timeout:8e3,windowsHide:!0,stdio:"ignore"}).status;export function setClaudePluginRunnerForTests(e){r=e}export function setPluginSourceProbeForTests(e){a=e}export function installOfficialPlugins(e){if("1"===process.env.VIBECLI_SKIP_CLAUDE_PLUGINS)return{installed:[],failed:[],skipped:"disabled"};const o=s.getToolSetting("claude-code",l),c=new Set("string"==typeof o?o.split(",").filter(Boolean):[]),d=function(){try{const e=JSON.parse(t(i(n(),".claude","plugins","installed_plugins.json"),"utf-8"));return new Set(Object.keys(e.plugins??{}).map(e=>e.replace(/@[^@]*$/,"")))}catch{return new Set}}(),p=e=>d.has(e),u=OFFICIAL_PLUGINS.filter(e=>!c.has(e)&&!p(e));if(0===u.length)return{installed:[],failed:[],skipped:null};const f=PLUGIN_SOURCES.find(e=>a(e.probe));if(!f)return{installed:[],failed:[],skipped:"marketplace"};r(e,["plugin","marketplace","add",f.add]);const g={installed:[],failed:[],skipped:null,source:f.name};for(const t of u)r(e,["plugin","install",`${t}@${f.name}`])?(g.installed.push(t),c.add(t)):g.failed.push(t);for(const e of OFFICIAL_PLUGINS)p(e)&&c.add(e);return s.setToolSetting("claude-code",l,[...c].join(",")),g}
|
package/dist/lib/tools/codex.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as n from"@iarna/toml";import{logger as r}from"../../utils/logger.js";import{i18n as i}from"../i18n.js";import{backupBeforeWrite as l,atomicWriteFile as a}from"./backup.js";import{pickModel as s,toolHome as d,withV1 as c}from"./types.js";import{getToolDefaultModel as m}from"../model-registry.js";import{buildCodexCatalog as u,codexCatalogPath as p,loadBundledCodexModels as _,loadPreviousCodexModels as g,previousGatewayModelIds as f}from"./codex-catalog.js";import{gatewayModelSpecs as x,modelFamily as y}from"../gateway-models.js";const h=()=>o(d(),".codex"),b=()=>o(h(),"config.toml"),k=()=>o(h(),"auth.json"),w="OPENAI_API_KEY",C="custom",j=1e6,v=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function E(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function M(e,t){return E(e[t])||(e[t]={}),e[t]}function O(){if(!e(b()))return{};const o=t(b(),"utf-8");if(!o.trim())return{};try{const e=n.parse(o);if(!E(e))throw new Error("config.toml root must be a TOML table");return e}catch(e){throw new Error(`Existing ~/.codex/config.toml cannot be parsed, back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function N(){if(!e(k()))return{};try{const e=JSON.parse(t(k(),"utf-8"));return E(e)?e:{}}catch{return{}}}let S=null;function A(o,n,i){const s=!1!==n.settings?.one_million_context;!function(e){e.model_context_window===j&&delete e.model_context_window,e.model_auto_compact_token_limit===v&&delete e.model_auto_compact_token_limit}(o);const d=_()??g();if(!d)return r.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),S="skipped",o.model_catalog_json===p()&&delete o.model_catalog_json,void(s&&(o.model_context_window=j,o.model_auto_compact_token_limit=v));const c=n.catalog,m=u({bundled:d,specs:x("codex",c?.clientModels),...c?{keyModels:c.models}:{},gatewayAvailable:c?.models??f(),oneMillion:s,selectedModel:i,..."gateway"===c?.oneMillionSource?{claudeOneMillion:c.oneMillion}:{}});S={listed:m.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))};const y=JSON.stringify(m,null,2)+"\n",h=p();e(h)&&t(h,"utf-8")===y||(l(h),a(h,y)),o.model_catalog_json=h}export function setCodexOneMillionContext(e,t){const o=O(),r=n.stringify(o),i="string"==typeof o.model?o.model:m("codex");A(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},i);const s=n.stringify(o);s!==r&&(l(b()),a(b(),s))}export const codexAdapter={name:"codex",displayName:"Codex",command:"codex",installCommand:"npm install -g @openai/codex",upgradeCommand:"npm install -g @openai/codex@latest",installSpec:{command:"codex",npmPackage:"@openai/codex",brew:"codex"},configPath:b(),wantsModelCatalog:!0,listedModels(){if(O().model_catalog_json!==p())return null;try{return(JSON.parse(t(p(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){O().model_catalog_json===p()&&setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog)},applyNotes(){if("skipped"===S)return[{kind:"action",text:i.t("tools.codex.catalog_skipped")}];if(!S)return[];const e=new Map;for(const t of S.listed)e.set(y(t.id),(e.get(y(t.id))??0)+1);const t=["gpt","claude","other","grok"].filter(t=>e.has(t)).map(t=>`${i.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:i.t("tools.codex.catalog_written",{count:String(S.listed.length),breakdown:t})},{kind:"detail",text:S.listed.map(e=>e.name).join(", ")}]},loadPrivateConfig(e){const t=m("codex"),o=s(e.models,t),r=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,i=c(e.baseUrl),d=O();d.model=r,d.model_provider=C,d.model_reasoning_effort="high",A(d,e,r);const u=M(d,"model_providers"),p=E(u[C])?{...u[C]}:{};delete p.env_key;const{experimental_bearer_token:_,...g}=p;u[C]={...g,name:"custom",wire_api:"responses",requires_openai_auth:!0,base_url:i};const f=M(d,"profiles"),x=E(f[r])?{...f[r]}:{};f[r]={...x,model_provider:C,model:r},M(M(d,"tui"),"model_availability_nux")[r]=4;const y=M(d,"features");y.goals=!0,y.js_repl=!1,l(b()),a(b(),n.stringify(d)),function(e){const t=e.trim();if(!t)return;const o={...N(),auth_mode:"apikey",[w]:t};l(k()),a(k(),JSON.stringify(o,null,2)+"\n")}(e.apiKey)},unloadPrivateConfig(){if(!e(b()))return;let t;try{t=O()}catch(e){return void r.logError("codexAdapter.unloadPrivateConfig",e)}const o=t.model_providers;E(o)&&(delete o[C],0===Object.keys(o).length&&delete t.model_providers),t.model_provider===C&&delete t.model_provider,t.model_catalog_json===p()&&delete t.model_catalog_json,l(b()),a(b(),n.stringify(t))},detectCurrentConfig(){const e=N()[w];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return O()}catch(e){return r.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[b(),k(),p()]};export function codexAuthProblem(){try{const e=O(),t=e.model_providers?.[C];if(e.model_provider!==C||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=N();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
|
1
|
+
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as n from"@iarna/toml";import{logger as r}from"../../utils/logger.js";import{i18n as i}from"../i18n.js";import{backupBeforeWrite as l,atomicWriteFile as a}from"./backup.js";import{pickModel as s,toolHome as d,withV1 as c}from"./types.js";import{getToolDefaultModel as m}from"../model-registry.js";import{buildCodexCatalog as u,codexCatalogPath as p,loadBundledCodexModels as _,loadPreviousCodexModels as g,previousGatewayModelIds as f}from"./codex-catalog.js";import{gatewayModelSpecs as x,modelFamily as y}from"../gateway-models.js";const h=()=>o(d(),".codex"),b=()=>o(h(),"config.toml"),k=()=>o(h(),"auth.json"),w="OPENAI_API_KEY",C="custom",j=1e6,v=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function E(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function M(e,t){return E(e[t])||(e[t]={}),e[t]}function O(){if(!e(b()))return{};const o=t(b(),"utf-8");if(!o.trim())return{};try{const e=n.parse(o);if(!E(e))throw new Error("config.toml root must be a TOML table");return e}catch(e){throw new Error(`Existing ~/.codex/config.toml cannot be parsed, back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function N(){if(!e(k()))return{};try{const e=JSON.parse(t(k(),"utf-8"));return E(e)?e:{}}catch{return{}}}let S=null;function A(o,n,i){const s=!1!==n.settings?.one_million_context;!function(e){e.model_context_window===j&&delete e.model_context_window,e.model_auto_compact_token_limit===v&&delete e.model_auto_compact_token_limit}(o);const d=_()??g();if(!d)return r.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),S="skipped",o.model_catalog_json===p()&&delete o.model_catalog_json,void(s&&(o.model_context_window=j,o.model_auto_compact_token_limit=v));const c=n.catalog,m=u({bundled:d,specs:x("codex",c?.clientModels),...c?{keyModels:c.models}:{},gatewayAvailable:c?.models??f(),oneMillion:s,selectedModel:i,..."gateway"===c?.oneMillionSource?{claudeOneMillion:c.oneMillion}:{}});S={listed:m.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))};const y=JSON.stringify(m,null,2)+"\n",h=p();e(h)&&t(h,"utf-8")===y||(l(h),a(h,y)),o.model_catalog_json=h}export function setCodexOneMillionContext(e,t){const o=O(),r=n.stringify(o),i="string"==typeof o.model?o.model:m("codex");A(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},i);const s=n.stringify(o);s!==r&&(l(b()),a(b(),s))}export const codexAdapter={name:"codex",displayName:"Codex",command:"codex",installCommand:"npm install -g @openai/codex",upgradeCommand:"npm install -g @openai/codex@latest",installSpec:{command:"codex",npmPackage:"@openai/codex",brew:"codex"},configPath:b(),wantsModelCatalog:!0,listedModels(){if(O().model_catalog_json!==p())return null;try{return(JSON.parse(t(p(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){O().model_catalog_json===p()&&setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog)},applyNotes(){if("skipped"===S)return[{kind:"action",text:i.t("tools.codex.catalog_skipped")}];if(!S)return[];const e=new Map;for(const t of S.listed)e.set(y(t.id),(e.get(y(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${i.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:i.t("tools.codex.catalog_written",{count:String(S.listed.length),breakdown:t})},{kind:"detail",text:S.listed.map(e=>e.name).join(", ")}]},loadPrivateConfig(e){const t=m("codex"),o=s(e.models,t),r=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,i=c(e.baseUrl),d=O();d.model=r,d.model_provider=C,d.model_reasoning_effort="high",A(d,e,r);const u=M(d,"model_providers"),p=E(u[C])?{...u[C]}:{};delete p.env_key;const{experimental_bearer_token:_,...g}=p;u[C]={...g,name:"custom",wire_api:"responses",requires_openai_auth:!0,base_url:i};const f=M(d,"profiles"),x=E(f[r])?{...f[r]}:{};f[r]={...x,model_provider:C,model:r},M(M(d,"tui"),"model_availability_nux")[r]=4;const y=M(d,"features");y.goals=!0,y.js_repl=!1,l(b()),a(b(),n.stringify(d)),function(e){const t=e.trim();if(!t)return;const o={...N(),auth_mode:"apikey",[w]:t};l(k()),a(k(),JSON.stringify(o,null,2)+"\n")}(e.apiKey)},unloadPrivateConfig(){if(!e(b()))return;let t;try{t=O()}catch(e){return void r.logError("codexAdapter.unloadPrivateConfig",e)}const o=t.model_providers;E(o)&&(delete o[C],0===Object.keys(o).length&&delete t.model_providers),t.model_provider===C&&delete t.model_provider,t.model_catalog_json===p()&&delete t.model_catalog_json,l(b()),a(b(),n.stringify(t))},detectCurrentConfig(){const e=N()[w];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return O()}catch(e){return r.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[b(),k(),p()]};export function codexAuthProblem(){try{const e=O(),t=e.model_providers?.[C];if(e.model_provider!==C||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=N();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
package/dist/locales/en_US.json
CHANGED
|
@@ -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,11 +396,13 @@
|
|
|
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",
|
|
402
404
|
"claude": "Claude",
|
|
405
|
+
"gemini": "Gemini",
|
|
403
406
|
"other": "Chinese",
|
|
404
407
|
"grok": "Grok"
|
|
405
408
|
}
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -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,11 +396,13 @@
|
|
|
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",
|
|
402
404
|
"claude": "Claude",
|
|
405
|
+
"gemini": "Gemini",
|
|
403
406
|
"other": "国产",
|
|
404
407
|
"grok": "Grok"
|
|
405
408
|
}
|
package/dist/models.json
CHANGED
|
@@ -194,15 +194,13 @@
|
|
|
194
194
|
"id": "gemini-3.8-flash",
|
|
195
195
|
"name": "Gemini 3.8 Flash",
|
|
196
196
|
"description": "105 万上下文 | 推理与编码",
|
|
197
|
-
"contextWindow": 1048576
|
|
198
|
-
"codex": false
|
|
197
|
+
"contextWindow": 1048576
|
|
199
198
|
},
|
|
200
199
|
{
|
|
201
200
|
"id": "gemini-3.1-pro",
|
|
202
201
|
"name": "Gemini 3.1 Pro",
|
|
203
202
|
"description": "100 万上下文 | 深度推理 | 长文档",
|
|
204
|
-
"contextWindow": 1000000
|
|
205
|
-
"codex": false
|
|
203
|
+
"contextWindow": 1000000
|
|
206
204
|
},
|
|
207
205
|
{
|
|
208
206
|
"id": "gemini-3.7-flash",
|
package/models.json
CHANGED
|
@@ -194,15 +194,13 @@
|
|
|
194
194
|
"id": "gemini-3.8-flash",
|
|
195
195
|
"name": "Gemini 3.8 Flash",
|
|
196
196
|
"description": "105 万上下文 | 推理与编码",
|
|
197
|
-
"contextWindow": 1048576
|
|
198
|
-
"codex": false
|
|
197
|
+
"contextWindow": 1048576
|
|
199
198
|
},
|
|
200
199
|
{
|
|
201
200
|
"id": "gemini-3.1-pro",
|
|
202
201
|
"name": "Gemini 3.1 Pro",
|
|
203
202
|
"description": "100 万上下文 | 深度推理 | 长文档",
|
|
204
|
-
"contextWindow": 1000000
|
|
205
|
-
"codex": false
|
|
203
|
+
"contextWindow": 1000000
|
|
206
204
|
},
|
|
207
205
|
{
|
|
208
206
|
"id": "gemini-3.7-flash",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeapi/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.68",
|
|
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",
|