@vibeapi/cli 0.0.83 → 0.0.85
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 +9 -1
- package/dist/lib/tool-upgrade.d.ts +1 -1
- package/dist/lib/tool-upgrade.js +1 -1
- package/dist/lib/tools/claude-code.d.ts +0 -1
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/tools/grok.js +1 -1
- package/dist/lib/tools/tool-installs.d.ts +12 -3
- package/dist/lib/tools/tool-installs.js +1 -1
- package/dist/locales/en_US.json +4 -0
- package/dist/locales/zh_CN.json +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,6 +24,14 @@ npx --yes --registry https://npm.cnb.cool/vibeapi/npm/-/packages/ @vibeapi/cli@l
|
|
|
24
24
|
|
|
25
25
|
全局安装的 `vibecli` 每次启动都会进入自动更新预检(6 小时内复用缓存),固定按 **CNB → npmjs → npmmirror → Yarn registry** 查询和安装;检测到新版会自动升级并重新执行当前命令。网络或权限错误不会阻断原命令,每个安装源最长等待 45 秒,安装失败后 1 小时内不重复打扰。设置 `VIBECLI_DISABLE_AUTO_UPDATE=1` 可关闭启动更新。`npx @latest` 在 CLI 启动前由 npm 解析,因此首次下载失败时请使用上面的 CNB 命令。
|
|
26
26
|
|
|
27
|
+
还没装编码工具?国内一条命令装好(与官方安装器相同的安装方式,程序从国内镜像下载;再跑一次就是升级):
|
|
28
|
+
|
|
29
|
+
| 工具 | macOS / Linux | Windows PowerShell |
|
|
30
|
+
| --------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
31
|
+
| Claude Code | `curl -fsSL https://cnb.cool/vibeapi/install/-/git/raw/main/claude-code.sh \| sh` | `irm https://cnb.cool/vibeapi/install/-/git/raw/main/claude-code.ps1 \| iex` |
|
|
32
|
+
| Codex | `curl -fsSL https://cnb.cool/vibeapi/install/-/git/raw/main/codex.sh \| sh` | `irm https://cnb.cool/vibeapi/install/-/git/raw/main/codex.ps1 \| iex` |
|
|
33
|
+
| Antigravity CLI | `curl -fsSL https://cnb.cool/vibeapi/install/-/git/raw/main/agy.sh \| sh` | `irm https://cnb.cool/vibeapi/install/-/git/raw/main/agy.ps1 \| iex` |
|
|
34
|
+
|
|
27
35
|
## 快速开始
|
|
28
36
|
|
|
29
37
|
下面三种方式**三选一即可**,任选一种就已经配置完成 —— 不要按顺序依次执行。
|
|
@@ -95,7 +103,7 @@ vibecli config <tool> clear-model # 清掉钉死的模型设置,回到工
|
|
|
95
103
|
vibecli config tool-model set codex gpt-6-astra # 单独给某工具指定模型
|
|
96
104
|
vibecli config profile use work # 切换 profile
|
|
97
105
|
vibecli doctor # 健康巡检(--deep 实发一条请求)
|
|
98
|
-
vibecli upgrade # 升级 Claude Code / Codex,官方渠道连不上自动改走国内镜像
|
|
106
|
+
vibecli upgrade # 升级 Claude Code / Codex / agy,官方渠道连不上自动改走国内镜像
|
|
99
107
|
vibecli codex sessions # 换过登录方式后 Codex 旧会话不显示时,让它们重新出现(先退出 Codex)
|
|
100
108
|
vibecli setup --desktop-registry on # Windows:桌面端不认本地配置时,强制写注册表(会请求一次管理员确认)
|
|
101
109
|
vibecli base # 查看并测试所有接入地址
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Tests replace the process runner. */
|
|
2
|
-
export declare function setUpgradeRunnerForTests(fake: (command: string, args: string[]) => boolean): void;
|
|
2
|
+
export declare function setUpgradeRunnerForTests(fake: (command: string, args: string[], timeoutMs?: number) => boolean): void;
|
|
3
3
|
/**
|
|
4
4
|
* `vibecli upgrade <tool>`: upgrade the copy PATH runs the way it was installed
|
|
5
5
|
* (vendor updater / npm via npmmirror / Homebrew). When the vendor updater
|
package/dist/lib/tool-upgrade.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as
|
|
1
|
+
import{spawnSync as e}from"child_process";import{rmSync as r}from"fs";import{join as o}from"path";import t from"chalk";import n from"inquirer";import{i18n as i}from"./i18n.js";import{logger as s}from"../utils/logger.js";import{compareVersions as a,getToolMinVersion as l}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as c,forgetInstalls as u,installLabel as m,mirrorInstallCommand as d,npmMirrorInstallCommand as g,npmUninstallCommand as f}from"./tools/tool-installs.js";import{toolHome as w}from"./tools/types.js";import{isNonInteractive as h,shouldAutoConfirm as v}from"./runtime-options.js";let y=(r,o,n)=>{console.log(t.gray("$ ")+[r,...o].join(" "));const i="win32"!==process.platform||/\.exe$/i.test(r)?e(r,o,{stdio:"inherit",timeout:n}):e([r,...o].map(e=>/\s/.test(e)?`"${e}"`:e).join(" "),{stdio:"inherit",shell:!0,timeout:n});return i.error&&s.logError(`upgrade: ${r}`,i.error),0===i.status};export function setUpgradeRunnerForTests(e){y=e}function _(e){return e.mirrorScript?"win32"===process.platform?y("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${e.mirrorScript.ps1} | iex`]):y("sh",["-c",d(e)]):b(e)}function b(e){const[r,...o]=g(e).split(" "),n=y(r,o);return n||"win32"===process.platform||console.log(t.yellow(" ! "+i.t("upgrade.npm_permission",{command:g(e)}))),n}function k(e,t){switch(t.kind){case"npm":e.npmPackage&&y("npm",["uninstall","-g",e.npmPackage]);break;case"brew":e.brew&&y("brew",["uninstall",e.brew]);break;case"native":try{r(t.path,{force:!0});for(const t of e.native?.dataDirs??[])r(o(w(),...t),{recursive:!0,force:!0})}catch(e){s.logError("upgrade: remove native copy",e)}break;default:return!1}return u(),!c(e).some(e=>e.path===t.path)}function j(e,r){switch(r.kind){case"npm":return f(e);case"brew":return`brew uninstall ${e.brew}`;case"native":return i.t("upgrade.delete_paths",{paths:[r.path,...(e.native?.dataDirs??[]).map(e=>o(w(),...e))].join("、")});default:return i.t("upgrade.delete_paths",{paths:r.path})}}export async function upgradeTool(e){const r=p(e),o=r?.installSpec;if(!r||!o)throw new Error(i.t("upgrade.unsupported",{tool:e}));const d=r.displayName;u();const g=c(o);if(console.log(t.bold(`\n${d}`)),0===g.length)console.log(i.t("upgrade.not_installed_installing",{tool:d})),_(o);else{const e=g[0];console.log(t.gray(" "+i.t("upgrade.current",{copy:m(e)})));const r=function(e,r){switch(r.kind){case"native":return y(r.path,e.native?.updateArgs??["update"],e.native?.updateTimeoutMs);case"npm":return b(e);case"brew":return!!e.brew&&y("brew",["upgrade",e.brew]);default:return!1}}(o,e);r||"other"!==e.kind?r||"npm"===e.kind||"native"===e.kind&&await async function(e){const r=e.native?.mirrorUpdate;if(!r)return!1;console.log(t.yellow(" ! "+i.t("upgrade.native_mirror_trying")));try{const{version:e,manifestVerified:o}=await r();return console.log(t.green(" √ "+i.t(o?"upgrade.native_mirror_done_verified":"upgrade.native_mirror_done",{version:e}))),!0}catch(e){return s.logError("upgrade: native mirror",e),console.log(t.yellow(" ! "+i.t("upgrade.native_mirror_failed",{reason:e instanceof Error?e.message:String(e)}))),!1}}(o)||(console.log(t.yellow(" ! "+i.t("upgrade.fallback_mirror"))),_(o)):console.log(t.yellow(" ! "+i.t("upgrade.unknown_install",{path:e.path})))}u(),await async function(e,r){const o=c(e);if(o.length<2)return;const s=function(e){return e.reduce((e,r)=>r.version&&(!e.version||a(r.version,e.version)>0)?r:e)}(o),l=o.filter(e=>e!==s);console.log(t.yellow(" ! "+i.t("upgrade.duplicates",{tool:r,keep:m(s),others:l.map(m).join("、")})));let p=v();p||h()||!process.stdin.isTTY||(p=(await n.prompt([{type:"confirm",name:"remove",message:i.t("upgrade.confirm_remove"),default:!0}])).remove);for(const r of l)p&&k(e,r)?console.log(t.green(" √ "+i.t("upgrade.removed",{copy:m(r)}))):console.log(t.yellow(" ! "+i.t("upgrade.remove_by_hand",{how:j(e,r)})))}(o,d),u();const f=c(o)[0];if(!f)return console.log(t.red(" × "+i.t("upgrade.still_missing",{tool:d}))),!1;const w=l(e);if(w&&f.version&&a(f.version,w)<0){console.log(t.yellow(" ! "+i.t("upgrade.still_old",{copy:m(f),min:w})));for(const e of r.upgradeHints?.(w)??[])console.log(t.yellow(" ! "+e));return!1}return console.log(t.green(" √ "+i.t("upgrade.done",{copy:m(f)}))),!0}
|
|
@@ -9,5 +9,4 @@ export declare function setClaudeKeychainProbeForTests(fake: () => boolean): voi
|
|
|
9
9
|
* so this is only reported, never changed.
|
|
10
10
|
*/
|
|
11
11
|
export declare function claudeAccountLoginPresent(): boolean;
|
|
12
|
-
/** Thin adapter over the full-featured ClaudeCodeManager singleton. */
|
|
13
12
|
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
|
|
1
|
+
import{join as e}from"path";import{applyGatewayModels as t,claudeCodeManager as o}from"../claude-code-manager.js";import{backupBeforeWrite as n}from"./backup.js";import{i18n as a}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,mirrorInstallCommand as h,vibeapiInstallScripts as C}from"./tool-installs.js";import{updateNativeFromMirror as _}from"./claude-native-mirror.js";const k=e(d(),".claude","settings.json"),y=e(d(),".claude.json");let j,P=null,S=()=>0===c("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore"}).status;export function setClaudeKeychainProbeForTests(e){S=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 S()}catch{return!1}}function v(){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 x(e){if(!e)return;const t=new Set(e.models);return i("claude-code",e.clientModels).filter(e=>t.has(e.id))}const b={command:"claude",npmPackage:"@anthropic-ai/claude-code",native:{binDir:[".local","bin"],updateArgs:["update"],dataDirs:[[".local","share","claude"]],mirrorUpdate:()=>_(v())},mirrorScript:C("claude-code"),brew:"claude-code"};export const claudeCodeAdapter={name:"claude-code",displayName:"Claude Code",command:"claude",installCommand:h(b),upgradeCommand:"claude update",installSpec:b,upgradeHints:e=>"stable"===v()?[a.t("tools.claude_code.stable_channel",{min:e})]:[],configPath:k,wantsModelCatalog:!0,loadPrivateConfig(e){n(k),n(y),j=x(e.catalog),o.loadPrivateConfig(e.apiKey,e.models,e.catalog?.models,j);const t=f(claudeCodeAdapter.installSpec)[0];P=t?g(t.path):null},unloadPrivateConfig(){n(k),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=>(n(k),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 a=o.getSettings(),s=t(a,x(e.catalog));JSON.stringify(s)!==JSON.stringify(a)&&(n(k),o.saveSettings(s))},applyNotes(){const e=[];P?.installed.length&&(e.push({kind:"summary",text:a.t("tools.claude_code.plugins_installed",{count:String(P.installed.length)})}),e.push({kind:"detail",text:P.installed.join(", ")})),("marketplace"===P?.skipped||P?.failed.length)&&e.push({kind:"action",text:a.t("tools.claude_code.plugins_failed")}),j&&j.length>0&&(e.push({kind:"summary",text:a.t("tools.claude_code.gateway_models",{count:String(j.length),vendors:l(j.map(e=>e.id)).join(" / ")})}),e.push({kind:"detail",text:j.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:a.t("tools.claude_code.no_git_bash")}),claudeAccountLoginPresent()&&e.push({kind:"detail",text:a.t("tools.claude_code.account_login_overridden")});for(const t of m())e.push({kind:"action",text:a.t("tools.claude_code.managed_override",{source:t.source,keys:t.keys.join(", ")})});for(const t of o.getLastTierFallbacks())e.push({kind:"detail",text:a.t("tools.claude_code.tier_fallback",{tier:t.tier,from:t.from,to:t.to})});return e},backupPaths:()=>[k,y],forceResetPaths:()=>[k]};
|
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
|
|
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";import{mirrorInstallCommand as b,vibeapiInstallScripts as h}from"./tool-installs.js";const k=()=>o(d(),".codex"),w=()=>o(k(),"config.toml"),j=()=>o(k(),"auth.json"),C="OPENAI_API_KEY",v="custom",M=1e6,O=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function E(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function N(e,t){return E(e[t])||(e[t]={}),e[t]}function S(){if(!e(w()))return{};const o=t(w(),"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 A(){if(!e(j()))return{};try{const e=JSON.parse(t(j(),"utf-8"));return E(e)?e:{}}catch{return{}}}let P=null;function T(o,n,i){const s=!1!==n.settings?.one_million_context;!function(e){e.model_context_window===M&&delete e.model_context_window,e.model_auto_compact_token_limit===O&&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")),P="skipped",o.model_catalog_json===p()&&delete o.model_catalog_json,void(s&&(o.model_context_window=M,o.model_auto_compact_token_limit=O));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}:{}});P={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",b=p();e(b)&&t(b,"utf-8")===y||(l(b),a(b,y)),o.model_catalog_json=b}export function setCodexOneMillionContext(e,t){const o=S(),r=n.stringify(o),i="string"==typeof o.model?o.model:m("codex");T(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},i);const s=n.stringify(o);s!==r&&(l(w()),a(w(),s))}const I={command:"codex",npmPackage:"@openai/codex",native:{binDir:"win32"===process.platform?["AppData","Local","Programs","OpenAI","Codex","bin"]:[".local","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".codex","packages","standalone"]]},mirrorScript:h("codex"),brew:"codex"};export const codexAdapter={name:"codex",displayName:"Codex",command:"codex",installCommand:b(I),installSpec:I,configPath:w(),wantsModelCatalog:!0,listedModels(){if(S().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){S().model_catalog_json===p()&&setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog)},applyNotes(){if("skipped"===P)return[{kind:"action",text:i.t("tools.codex.catalog_skipped")}];if(!P)return[];const e=new Map;for(const t of P.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(P.listed.length),breakdown:t})},{kind:"detail",text:P.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=S();d.model=r,d.model_provider=v,d.model_reasoning_effort="high",T(d,e,r);const u=N(d,"model_providers"),p=E(u[v])?{...u[v]}:{};delete p.env_key;const{experimental_bearer_token:_,...g}=p;u[v]={...g,name:"custom",wire_api:"responses",requires_openai_auth:!0,base_url:i};const f=N(d,"profiles"),x=E(f[r])?{...f[r]}:{};f[r]={...x,model_provider:v,model:r},N(N(d,"tui"),"model_availability_nux")[r]=4;const y=N(d,"features");y.goals=!0,y.js_repl=!1,l(w()),a(w(),n.stringify(d)),function(e){const t=e.trim();if(!t)return;const o={...A(),auth_mode:"apikey",[C]:t};l(j()),a(j(),JSON.stringify(o,null,2)+"\n")}(e.apiKey)},unloadPrivateConfig(){if(!e(w()))return;let t;try{t=S()}catch(e){return void r.logError("codexAdapter.unloadPrivateConfig",e)}const o=t.model_providers;E(o)&&(delete o[v],0===Object.keys(o).length&&delete t.model_providers),t.model_provider===v&&delete t.model_provider,t.model_catalog_json===p()&&delete t.model_catalog_json,l(w()),a(w(),n.stringify(t))},detectCurrentConfig(){const e=A()[C];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return S()}catch(e){return r.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[w(),j(),p()]};export function codexAuthProblem(){try{const e=S(),t=e.model_providers?.[v];if(e.model_provider!==v||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=A();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
package/dist/lib/tools/grok.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as r from"@iarna/toml";import{logger as n}from"../../utils/logger.js";import{PROVIDER_KEY as i}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as
|
|
1
|
+
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as r from"@iarna/toml";import{logger as n}from"../../utils/logger.js";import{PROVIDER_KEY as i}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as a,toolHome as d,withV1 as m}from"./types.js";import{i18n as f}from"../i18n.js";import{getToolDefaultModel as c}from"../model-registry.js";import{gatewayModelSpecs as g,modelBlurb as u,modelFamily as p,prettyModelName as y}from"../gateway-models.js";const h=()=>o(o(d(),".grok"),"config.toml"),k=i,b=`${i}-`,w=["low","medium","high","xhigh"];let _=null;const j=e=>`${b}${e}`,x=e=>e===k||e.startsWith(b),C="win32"===process.platform?'powershell -c "irm https://x.ai/cli/install.ps1 | iex"':"curl -fsSL https://x.ai/cli/install.sh | bash";function v(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function M(e,t){return v(e[t])||(e[t]={}),e[t]}function E(){if(!e(h()))return{};const o=t(h(),"utf-8");if(!o.trim())return{};try{const e=r.parse(o);if(!v(e))throw new Error("config.toml root must be a TOML table");return e}catch(e){throw new Error(`Existing ~/.grok/config.toml cannot be parsed, back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function A(e){return v(e.model)?Object.entries(e.model).filter(e=>x(e[0])&&v(e[1])):[]}function O(e,t){let o=g("grok",e.catalog?.clientModels);if(e.catalog){const t=new Set(e.catalog.models);o=o.filter(e=>t.has(e.id))}return o.some(e=>e.id===t)?o:[{id:t},...o]}function S(e,t,o){M(e,"endpoints").models_base_url=m(t.baseUrl);const r=M(e,"model"),n=new Map(A(e));for(const e of n.keys())delete r[e];for(const e of o){const o=j(e.id),i={...n.get(o)??{},name:e.name??y(e.id),model:e.id,base_url:m(t.baseUrl),api_key:t.apiKey,context_window:e.contextWindow??5e5,api_backend:"responses",reasoning_summary:"concise"};"grok"===p(e.id)&&(i.supports_reasoning_effort=!0,i.reasoning_efforts=w);const s=u(e.description);s?i.description=s:delete i.description,r[o]=i}}export const grokAdapter={name:"grok",displayName:"Grok Build",command:"grok",installCommand:C,configPath:h(),wantsModelCatalog:!0,loadPrivateConfig(e){const t=E(),o=a(e.models,c("grok")),n=O(e,o);S(t,e,n);const i=e=>e.name??y(e.id);_={names:n.map(i),defaultName:i(n.find(e=>e.id===o))},M(t,"models").default=j(o),s(h()),l(h(),r.stringify(t))},unloadPrivateConfig(){if(!e(h()))return;let t;try{t=E()}catch(e){return void n.logError("grokAdapter.unloadPrivateConfig",e)}if(v(t.model)){for(const[e]of A(t))delete t.model[e];0===Object.keys(t.model).length&&delete t.model}v(t.models)&&"string"==typeof t.models.default&&x(t.models.default)&&(delete t.models.default,0===Object.keys(t.models).length&&delete t.models),v(t.endpoints)&&(delete t.endpoints.models_base_url,0===Object.keys(t.endpoints).length&&delete t.endpoints),s(h()),l(h(),r.stringify(t))},detectCurrentConfig(){try{const e=E(),t=A(e),o=v(e.models)?e.models.default:void 0,r=t.find(([e])=>e===o)?.[1]??t[0]?.[1],n=r?r.api_key:null;return{apiKey:"string"==typeof n&&n.trim()?n:null}}catch{return{apiKey:null}}},listedModels(){try{const e=A(E());return e.length>0?e.map(([,e])=>String(e.model)):null}catch{return null}},refreshModelMenu(e){const t=E(),o=M(t,"models"),n="string"==typeof o.default?o.default:void 0,i=n?A(t).find(([e])=>e===n)?.[1].model:void 0,d="string"==typeof i&&n!==k&&e.catalog.models.includes(i)?i:a(e.models,c("grok")),m=r.stringify(t);S(t,e,O(e,d)),(void 0===n||x(n))&&(o.default=j(d)),r.stringify(t)!==m&&(s(h()),l(h(),r.stringify(t)))},applyNotes:()=>_?[{kind:"summary",text:f.t("tools.grok.menu_written",{count:String(_.names.length),list:_.names.join(f.t("tools.grok.list_separator")),default:_.defaultName})}]:[],getConfig(){try{return E()}catch(e){return n.logError("grokAdapter.getConfig",e),null}}};
|
|
@@ -11,8 +11,9 @@ export interface ToolInstallSpec {
|
|
|
11
11
|
/** npm package of the global install (`@anthropic-ai/claude-code`); absent for tools not on npm. */
|
|
12
12
|
npmPackage?: string;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
* npm mirror's place
|
|
14
|
+
* Our China-reachable install scripts (CNB): they lay out the vendor's native install from a
|
|
15
|
+
* mirror and take the npm mirror's place for fresh installs and when the vendor updater
|
|
16
|
+
* fails. npm copies are still upgraded through npm.
|
|
16
17
|
*/
|
|
17
18
|
mirrorScript?: {
|
|
18
19
|
sh: string;
|
|
@@ -24,6 +25,8 @@ export interface ToolInstallSpec {
|
|
|
24
25
|
binDir: string[];
|
|
25
26
|
/** Arguments that make the launcher update itself (`update`). */
|
|
26
27
|
updateArgs: string[];
|
|
28
|
+
/** Give up on the vendor updater after this long (it can hang when its server is blocked). */
|
|
29
|
+
updateTimeoutMs?: number;
|
|
27
30
|
/** Directories under home that belong to it, removed together with the launcher. */
|
|
28
31
|
dataDirs: string[][];
|
|
29
32
|
/**
|
|
@@ -46,7 +49,13 @@ export interface ToolInstall {
|
|
|
46
49
|
}
|
|
47
50
|
/** npmmirror carries the same packages (including the per-platform native binaries) and is reachable from mainland China. */
|
|
48
51
|
export declare const NPM_MIRROR = "https://registry.npmmirror.com";
|
|
49
|
-
/**
|
|
52
|
+
/** VibeAPI's install scripts on CNB (cnb.cool/vibeapi/install): native installs laid out from npmmirror. */
|
|
53
|
+
export declare function vibeapiInstallScripts(tool: string): {
|
|
54
|
+
sh: string;
|
|
55
|
+
ps1: string;
|
|
56
|
+
};
|
|
57
|
+
export declare function npmMirrorInstallCommand(spec: ToolInstallSpec): string;
|
|
58
|
+
/** The China-reachable install command: our install script when there is one, otherwise npm from npmmirror. */
|
|
50
59
|
export declare function mirrorInstallCommand(spec: ToolInstallSpec): string;
|
|
51
60
|
export declare function npmUninstallCommand(spec: ToolInstallSpec): string;
|
|
52
61
|
/** `原生安装 2.1.295 (C:\\Users\\me\\.local\\bin\\claude.exe)` */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{existsSync as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{existsSync as n,realpathSync as r,statSync as o}from"fs";import{delimiter as e,dirname as i,isAbsolute as s,join as c}from"path";import{i18n as a}from"../i18n.js";import{toolHome as p}from"./types.js";export const NPM_MIRROR="https://registry.npmmirror.com";export function vibeapiInstallScripts(t){const n="https://cnb.cool/vibeapi/install/-/git/raw/main";return{sh:`${n}/${t}.sh`,ps1:`${n}/${t}.ps1`}}export function npmMirrorInstallCommand(t){return`npm install -g ${t.npmPackage}@latest --registry=${NPM_MIRROR}`}export function mirrorInstallCommand(t){return t.mirrorScript?"win32"===process.platform?`powershell -NoProfile -ExecutionPolicy Bypass -Command "irm ${t.mirrorScript.ps1} | iex"`:`curl -fsSL ${t.mirrorScript.sh} | sh`:npmMirrorInstallCommand(t)}export function npmUninstallCommand(t){return`npm uninstall -g ${t.npmPackage}`}export function installLabel(t){return`${a.t(`upgrade.kind.${t.kind}`)} ${t.version??"?"} (${t.path})`}let m=n=>{const r={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]};return`${(/\.cmd$/i.test(n)?t(`"${n}" --version`,{...r,shell:!0}):t(n,["--version"],r)).stdout??""}`};const l=new Map;export function setVersionRunnerForTests(t){m=t,l.clear()}export function forgetInstalls(){l.clear()}function u(t){try{return o(t).isFile()}catch{return!1}}function f(t,o){if(t.native&&(e=i(o),s=c(p(),...t.native.binDir),"win32"===process.platform?e.toLowerCase()===s.toLowerCase():e===s))return"native";var e,s;const a=t.npmPackage?c("node_modules",...t.npmPackage.split("/")):null;if(a&&n(c(i(o),a)))return"npm";let m=o;try{m=r(o)}catch{return"other"}return a&&m.includes(a)?"npm":/[\\/](Cellar|Caskroom)[\\/]/.test(m)?"brew":"other"}export function findInstalls(t){const n=l.get(t.command);if(n)return n;const o="win32"===process.platform?[`${t.command}.exe`,`${t.command}.cmd`]:[t.command],i=new Set,a=[];for(const n of(process.env.PATH??"").split(e))if(n&&s(n))for(const e of o){const o=c(n,e);if(!u(o))continue;let s=o;try{s=r(o)}catch{}const p="win32"===process.platform?s.toLowerCase():s;if(i.has(p))continue;i.add(p);const l=m(o).match(/(\d+)\.(\d+)\.(\d+)/);a.push({path:o,kind:f(t,o),version:l?l[0]:null})}return l.set(t.command,a),a}
|
package/dist/locales/en_US.json
CHANGED
|
@@ -381,6 +381,10 @@
|
|
|
381
381
|
"reopen_terminal": "Key and address were added to {{rc}}; open a new terminal before running agy",
|
|
382
382
|
"reopen_terminal_windows": "Key and address were saved as user environment variables; reopen the terminal before running agy"
|
|
383
383
|
},
|
|
384
|
+
"grok": {
|
|
385
|
+
"menu_written": "{{count}} models in the menu ({{list}}), default {{default}}",
|
|
386
|
+
"list_separator": ", "
|
|
387
|
+
},
|
|
384
388
|
"codex": {
|
|
385
389
|
"catalog_written": "{{count}} models in the menu ({{breakdown}}); reopen the Codex desktop app to see them",
|
|
386
390
|
"catalog_skipped": "Couldn't read Codex's built-in model list (not installed, or older than 0.122), so the menu has GPT models only; install or upgrade Codex and run this again"
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -381,6 +381,10 @@
|
|
|
381
381
|
"reopen_terminal": "Key 与地址已写入 {{rc}},新开一个终端再运行 agy",
|
|
382
382
|
"reopen_terminal_windows": "Key 与地址已写入用户环境变量,重新打开终端再运行 agy"
|
|
383
383
|
},
|
|
384
|
+
"grok": {
|
|
385
|
+
"menu_written": "模型菜单 {{count}} 个({{list}}),默认 {{default}}",
|
|
386
|
+
"list_separator": "、"
|
|
387
|
+
},
|
|
384
388
|
"codex": {
|
|
385
389
|
"catalog_written": "模型菜单 {{count}} 个({{breakdown}}),Codex 桌面版重开后生效",
|
|
386
390
|
"catalog_skipped": "没读到 Codex 自带的模型列表(未安装或版本低于 0.122),模型菜单只有 GPT;安装或升级 Codex 后再运行一次"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeapi/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.85",
|
|
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",
|