@vibeapi/cli 0.0.60 → 0.0.61
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/dist/lib/model-refresh.js +1 -1
- package/dist/lib/post-apply.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/elevated-reg.d.ts +19 -0
- package/dist/lib/tools/elevated-reg.js +1 -0
- package/dist/lib/tools/types.d.ts +12 -0
- package/dist/lib/tools/types.js +1 -1
- package/dist/locales/en_US.json +10 -2
- package/dist/locales/zh_CN.json +10 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,mkdirSync as o,readFileSync as t,writeFileSync as r}from"fs";import{dirname as n,join as s}from"path";import i from"chalk";import{configManager as l}from"./config.js";import{i18n as
|
|
1
|
+
import{existsSync as e,mkdirSync as o,readFileSync as t,writeFileSync as r}from"fs";import{dirname as n,join as s}from"path";import i from"chalk";import{configManager as l}from"./config.js";import{i18n as f}from"./i18n.js";import{resolveModelCatalog as d}from"./model-catalog.js";import{listAdapters as c}from"./tools/registry.js";import{UserActionNeeded as a}from"./tools/types.js";import{logger as u}from"../utils/logger.js";import{resolveUpdateCachePath as m}from"./auto-update.js";export const MODEL_REFRESH_INTERVAL_MS=36e5;const h=new Set(["setup","init","config","auth","enter","completion","update","lang","logs"]),p=["--json","--dry-run","--help","-h","--version","-v"],g=[];export function shouldSkipModelRefresh(e,o=process.env){if("1"===o.VIBECLI_DISABLE_MODEL_REFRESH)return!0;if(p.some(o=>e.includes(o)))return!0;const t=e.find(e=>!e.startsWith("-"));return void 0===t||h.has(t)}export async function refreshModelMenus(){const e=new Map,o=[];g.length=0;for(const t of c())if(t.refreshModelMenu&&t.listedModels)try{const r=l.getApiKeyForTool(t.name);if(!r||t.detectCurrentConfig().apiKey!==r)continue;const n=t.listedModels();if(null===n)continue;e.has(r)||e.set(r,await d(r));const s=e.get(r);if(!s)continue;t.refreshModelMenu({apiKey:r,baseUrl:l.getBaseUrl(),models:l.getModelsForTool(t.name),settings:l.getToolSettings(t.name),catalog:s});const i=t.listedModels()??[],f=i.filter(e=>!n.includes(e)),c=n.filter(e=>!i.includes(e));(f.length>0||c.length>0)&&o.push({tool:t.displayName,added:f,removed:c})}catch(e){u.logError(`modelRefresh(${t.name})`,e),e instanceof a&&g.push(e.message)}return o}export async function runModelRefresh(l,d={}){const c=d.env??process.env;if(shouldSkipModelRefresh(l,c))return[];const a=d.now??Date.now(),h=function(e){return s(n(m(e)),"model-refresh.json")}(c);if(a-function(e){try{const o=JSON.parse(t(e,"utf-8")).refreshed_at;return"number"==typeof o?o:0}catch{return 0}}(h)<36e5)return[];let p=[];try{p=await refreshModelMenus(),e(n(h))||o(n(h),{recursive:!0}),r(h,JSON.stringify({refreshed_at:a})+"\n")}catch(e){u.logError("runModelRefresh",e)}const M=d.output??(e=>console.log(i.gray(e)));for(const e of g)M(e);for(const e of p){const o=[e.added.length>0?f.t("model_refresh.added",{models:e.added.join(", ")}):"",e.removed.length>0?f.t("model_refresh.removed",{models:e.removed.join(", ")}):""].filter(Boolean);M(f.t("model_refresh.changed",{tool:e.tool,changes:o.join(";")}))}return p}
|
package/dist/lib/post-apply.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"chalk";import t from"inquirer";import{i18n as
|
|
1
|
+
import o from"chalk";import t from"inquirer";import{i18n as n}from"./i18n.js";import{isNonInteractive as e,shouldAutoConfirm as i}from"./runtime-options.js";import{toolManager as r}from"./tool-manager.js";import{getAdapter as s}from"./tools/registry.js";import{upgradeTool as a}from"./tool-upgrade.js";async function p(o){const{ok:n}=await t.prompt([{type:"confirm",name:"ok",message:o,default:!0}]);return n}export async function postApplyPrompts(t){const l=!e()&&process.stdin.isTTY;for(const e of t){const t=s(e)?.pendingElevation?.();if(!t)continue;if(!(i()||l&&await p(t.prompt)))continue;const r=s(e)?.displayName??e;console.log(o.gray(" "+n.t("setup.elevation_running"))),console.log(t.run()?o.green(" √ "+n.t("setup.elevation_done",{tool:r})):o.yellow(" ! "+n.t("setup.elevation_failed",{tool:r})))}if(!l)return;const f=t.filter(o=>s(o)?.installSpec&&r.outdatedVersion(o));if(f.length>0){const o=f.map(o=>s(o)?.displayName??o).join("、");if(await p(n.t("setup.offer_upgrade",{tools:o})))for(const o of f)await a(o)}for(const e of t){const t=s(e);if(!t?.runningApp?.isRunning())continue;if(!await p(n.t("setup.offer_restart",{tool:t.displayName})))continue;const i=t.runningApp.restart();console.log(i?o.green(" √ "+n.t("setup.restarted",{tool:t.displayName})):o.yellow(" ! "+n.t("setup.restart_failed",{tool:t.displayName})))}}
|
|
@@ -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 C}from"./desktop-process.js";import{baseModelId as A,isClaudeModel as _}from"../model-catalog.js";const w=f;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";const D=/^[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 C.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 E=()=>a(claudeDesktopUserDataDir(),"configLibrary"),S=()=>a(E(),"_meta.json"),v=e=>a(E(),`${e}.json`),x=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function O(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 P(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 I(){const e=O(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 L(e){return e?.entries.find(e=>e.name===w&&D.test(e.id))}const j={opus:0,fable:1,sonnet:2,haiku:3};function T(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=T(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function $(e){return T(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>A(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(_)){i=[...new Set(t.models.filter(_).map(A))];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=A(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>j[$(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=a(e)-a(t);if(0!==n)return n;const r=T(e),s=T(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=$(e);t&&i.includes(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=$(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 N=null,G=null,U=null;function R(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 F={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 K(e){return Object.fromEntries(Object.entries(F).filter(([t])=>!e(t)))}const H="HKCU\\SOFTWARE\\Policies\\Claude",B="HKLM\\SOFTWARE\\Policies\\Claude",J="vibecli-claude-policy.reg",V=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let W=V;export function setRegRunnerForTests(e){W=e??V}function z(){return"win32"===process.platform}function Z(e){let t;try{t=W(["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 X(){if(null===Z(H))return;const e=a(claudeDesktopUserDataDir(),J);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),m(e),W(["export",H,e,"/y"])}catch(e){p.logError("claude-desktop.snapshotPolicy",e)}}function q(e){X();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)];W(["add",H,"/v",t,"/t",e,"/d",n,"/f"])}}const Q=[...Object.keys(R({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(F)];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 Z(B)?B: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 Y=/\d+\.\d+\.\d+/;function ee(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 te="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",oe="darwin"===process.platform||"win32"===process.platform?"https://cnb.cool/vibeapi/claude-desktop/-/releases/latest":"https://claude.ai/download",ne="darwin"===process.platform?`open ${oe}`:"win32"===process.platform?`start ${oe}`:`xdg-open ${oe}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:te,installCommand:ne,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"),...C.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?Y.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 ee(t)}const o=C.map(e=>`'${e}'`).join(",");return ee(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=>Y.exec(e)?.[0]??[]))}return null},runningApp:y()?{isRunning:k,restart:b}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const t=I()??{appliedId:"",entries:[]};let o=L(t);o||(o={id:l(),name:w},t.entries.push(o));const n=R(e);G=!0===n.disableDeploymentModeChooser,N={models:n.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const r=O(v(o.id))??{};P(v(o.id),{...K(e=>e in r),...r,...n}),t.appliedId=o.id,P(S(),t);const s=O(x())??{};if("3p"!==s.deploymentMode&&P(x(),{...s,deploymentMode:"3p"}),U=null,z())try{const e=Z(H);q({...K(t=>e?.has(t)??!1),...n})}catch(e){p.logError("claude-desktop.writePolicy",e),U=e instanceof Error?e.message.trim():String(e)}},unloadPrivateConfig(){if(z())try{!function(e){const t=Z(H);if(!t)return;X();let o=t.size;for(const n of e)t.has(n)&&(W(["delete",H,"/v",n,"/f"]),o-=1);o<=0&&W(["delete",H,"/f"])}(Q)}catch(e){p.logError("claude-desktop.removePolicy",e)}const e=I(),t=L(e);if(!e||!t)return;m(v(t.id)),s(v(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(m(S()),s(S(),{force:!0})):P(S(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=I(),t=L(e);if(!t||e?.appliedId!==t.id)return null;const o=O(v(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=I(),o=L(t);if(!o||t?.appliedId!==o.id)return;const n=O(v(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)&&(P(v(o.id),{...n,inferenceModels:r}),z()&&Z(H)?.has("inferenceModels")))try{q({inferenceModels:r})}catch(e){p.logError("claude-desktop.refreshModelMenu registry",e)}},detectCurrentConfig(){try{if(z()){const e=Z(H)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=L(I());if(!e)return{apiKey:null};const t=O(v(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=I(),t=L(e);return{meta:e,applied:t?O(v(t.id)):null,desktop:O(x()),...z()?{policy:Object.fromEntries(Z(H)??[])}:{}}}catch(e){return p.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;z()&&Z(H)?.has("inferenceModels")&&(X(),W(["delete",H,"/v","inferenceModels","/f"]),e=!0);const t=L(I()),o=t?O(v(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;P(v(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(N&&N.models.length>0){const{models:t,source:o,groups:n}=N;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!==G&&e.push({kind:"detail",text:u.t(G?"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")}),U?(e.push({kind:"action",text:u.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:U})):z()&&e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_written",{key:H})});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=L(I());t&&e.push(v(t.id))}catch{}return e},backupPaths(){const e=[S(),x()];z()&&e.push(a(claudeDesktopUserDataDir(),J));try{const t=L(I());t&&e.push(v(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 A}from"./desktop-process.js";import{setUserRegistryElevated as C}from"./elevated-reg.js";import{UserActionNeeded as _}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";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 A.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"),P=()=>a(O(),"_meta.json"),S=e=>a(O(),`${e}.json`),x=()=>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 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 I(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=L(P());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 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 G(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(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;for(const e of n){const t=G(e);t&&i.includes(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=G(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,R=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 Q(){return"win32"===process.platform}function Y(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===Y(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=Y(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 Y(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: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"),...A.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=A.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);U=!0===r.disableDeploymentModeChooser,K={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=L(S(n.id))??{};I(S(n.id),{...V(e=>e in s),...s,...r}),o.appliedId=n.id,I(P(),o);const i=L(x())??{};if("3p"!==i.deploymentMode&&I(x(),{...i,deploymentMode:"3p"}),R=null,F=null,Q()){const e=Y(W),o=ne.filter(t=>e?.has(t)),n={...V(t=>e?.has(t)??!1),...r},s=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"))||A.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{s?oe(ne):te(n)}catch(t){p.logError("claude-desktop.policy",t),R=t instanceof Error?t.message.trim():String(t),o.length>0&&(F=s?{action:"remove",values:Object.fromEntries(o.map(e=>[e,null])),deleteKey:o.length===e.size}:{action:"write",values:n,deleteKey:!1})}}},pendingElevation(){const e=F;return e?{prompt:u.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!C(J,e.values,e.deleteKey))return!1;const t=Y(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,R=null),o}}:null},unloadPrivateConfig(){if(Q())try{oe(ne)}catch(e){p.logError("claude-desktop.removePolicy",e)}const e=j(),t=T(e);if(!e||!t)return;m(S(t.id)),s(S(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(m(P()),s(P(),{force:!0})):I(P(),{...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=L(S(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=L(S(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(Q()&&Y(W)?.has("inferenceModels"))try{te({inferenceModels:r})}catch(e){throw p.logError("claude-desktop.refreshModelMenu registry",e),new _(u.t("tools.claude_desktop.refresh_needs_admin"))}I(S(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(Q()){const e=Y(W)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=T(j());if(!e)return{apiKey:null};const t=L(S(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?L(S(t.id)):null,desktop:L(x()),...Q()?{policy:Object.fromEntries(Y(W)??[])}:{}}}catch(e){return p.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;Q()&&Y(W)?.has("inferenceModels")&&(ee(),q(["delete",W,"/v","inferenceModels","/f"]),e=!0);const t=T(j()),o=t?L(S(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;I(S(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")}),F?(e.push({kind:"action",text:u.t(`tools.claude_desktop.policy_stale_${F.action}`)}),e.push({kind:"detail",text:R??""})):R?(e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:R})):Q()&&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=[P(),x()];try{const t=T(j());t&&e.push(S(t.id))}catch{}return e},backupPaths(){const e=[P(),x()];Q()&&e.push(a(claudeDesktopUserDataDir(),Z));try{const t=T(j());t&&e.push(S(t.id))}catch{}return e}};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Change registry values that need an administrator (`HKCU\Software\Policies` is
|
|
3
|
+
* read-only for standard users) through one UAC prompt: a `.reg` file imported by
|
|
4
|
+
* an elevated `reg.exe` — what double-clicking the gateway's downloadable `.reg`
|
|
5
|
+
* does too. The key is addressed as `HKEY_USERS\<SID>` rather than HKCU, so it
|
|
6
|
+
* still lands in this user's hive when the prompt is answered with another
|
|
7
|
+
* (administrator) account.
|
|
8
|
+
*/
|
|
9
|
+
/** A value to write; `null` deletes the value. */
|
|
10
|
+
export type RegValue = string | number | boolean | object | null;
|
|
11
|
+
/**
|
|
12
|
+
* `.reg` text for one key under `HKEY_USERS\<sid>\<subKey>`. `deleteKey` removes
|
|
13
|
+
* the whole key instead (used when every value in it is ours).
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildRegFile(sid: string, subKey: string, values: Record<string, RegValue>, deleteKey?: boolean): string;
|
|
16
|
+
/** Tests replace the SID lookup and the elevated import. */
|
|
17
|
+
export declare function setElevationForTests(sid: () => string | null, runner: (regFile: string) => boolean): void;
|
|
18
|
+
/** Write / delete values under HKCU-equivalent `subKey` with one UAC prompt. */
|
|
19
|
+
export declare function setUserRegistryElevated(subKey: string, values: Record<string, RegValue>, deleteKey?: boolean): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{spawnSync as r}from"child_process";import{mkdtempSync as e,rmSync as t,writeFileSync as o}from"fs";import{tmpdir as n}from"os";import{join as i}from"path";import{logger as s}from"../../utils/logger.js";function u(r){return`"${r.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}export function buildRegFile(r,e,t,o=!1){const n=`HKEY_USERS\\${r}\\${e}`;return o?`Windows Registry Editor Version 5.00\r\n\r\n[-${n}]\r\n`:`Windows Registry Editor Version 5.00\r\n\r\n[${n}]\r\n${Object.entries(t).map(([r,e])=>`${u(r)}=${null===e?"-":function(r){return"boolean"==typeof r?"dword:"+(r?"00000001":"00000000"):"number"==typeof r?`dword:${(r>>>0).toString(16).padStart(8,"0")}`:u("string"==typeof r?r:JSON.stringify(r))}(e)}`).join("\r\n")}\r\n`}let f=()=>{const e=r("whoami",["/user","/fo","csv","/nh"],{encoding:"utf-8",windowsHide:!0});return/"(S-1-[\d-]+)"/.exec(`${e.stdout??""}`)?.[1]??null},l=e=>{const t=r("powershell.exe",["-NoProfile","-NonInteractive","-Command",`$p = Start-Process -FilePath 'reg.exe' -ArgumentList @('import', '"${e}"') -Verb RunAs -Wait -PassThru -WindowStyle Hidden; exit $p.ExitCode`],{encoding:"utf-8",windowsHide:!0,timeout:3e5});return 0!==t.status&&s.logError("elevatedImport",new Error(`${t.stderr??""}`.trim()||`exit ${t.status}`)),0===t.status};export function setElevationForTests(r,e){f=r,l=e}export function setUserRegistryElevated(r,s,u=!1){const d=f();if(!d)return!1;const c=e(i(n(),"vibecli-reg-")),a=i(c,"vibecli.reg");try{return o(a,Buffer.concat([Buffer.from([255,254]),Buffer.from(buildRegFile(d,r,s,u),"utf16le")])),l(a)}finally{t(c,{recursive:!0,force:!0})}}
|
|
@@ -66,6 +66,14 @@ export interface ToolAdapter {
|
|
|
66
66
|
refreshModelMenu?(ctx: ToolApplyContext & {
|
|
67
67
|
catalog: ModelCatalog;
|
|
68
68
|
}): void;
|
|
69
|
+
/**
|
|
70
|
+
* A change the last apply could not make without an administrator (one UAC
|
|
71
|
+
* prompt fixes it); setup and the wizard offer to run it. Null when none.
|
|
72
|
+
*/
|
|
73
|
+
pendingElevation?(): {
|
|
74
|
+
prompt: string;
|
|
75
|
+
run(): boolean;
|
|
76
|
+
} | null;
|
|
69
77
|
/**
|
|
70
78
|
* GUI apps that only read their config at start: setup and the wizard offer
|
|
71
79
|
* to restart a running app after writing it.
|
|
@@ -149,3 +157,7 @@ export declare function pickModel(models: VibecliModels, fallback: string): stri
|
|
|
149
157
|
* raw base URL instead. Adjust here if a gateway uses a different path.
|
|
150
158
|
*/
|
|
151
159
|
export declare function withV1(baseUrl: string): string;
|
|
160
|
+
/** Thrown by a background refresh that needs the user to do something; its message is shown as is. */
|
|
161
|
+
export declare class UserActionNeeded extends Error {
|
|
162
|
+
constructor(message: string);
|
|
163
|
+
}
|
package/dist/lib/tools/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{homedir as
|
|
1
|
+
import{homedir as r}from"os";import{getDefaultModels as e}from"../model-registry.js";export function toolHome(){const e=process.env.VIBECLI_TEST_HOME;return e&&e.trim()?e.trim():r()}export function primaryModel(r){return r.opus||r.sonnet||r.reasoning||r.haiku}export function pickModel(r,o){const t=primaryModel(r);return t&&t!==e().opus?t:o}export function withV1(r){const e=(r||"").replace(/\/+$/,"");return/\/v\d+$/.test(e)?e:`${e}/v1`}export class UserActionNeeded extends Error{constructor(r){super(r),this.name="UserActionNeeded"}}
|
package/dist/locales/en_US.json
CHANGED
|
@@ -354,7 +354,10 @@
|
|
|
354
354
|
"offer_upgrade": "{{tools}} is too old; upgrade now?",
|
|
355
355
|
"offer_restart": "{{tool}} is running; restart it so the new config takes effect? (closes its windows)",
|
|
356
356
|
"restarted": "{{tool}} restarted",
|
|
357
|
-
"restart_failed": "Could not restart {{tool}}; quit it completely and open it again"
|
|
357
|
+
"restart_failed": "Could not restart {{tool}}; quit it completely and open it again",
|
|
358
|
+
"elevation_running": "Click Yes in the Windows prompt…",
|
|
359
|
+
"elevation_done": "{{tool}} registry updated",
|
|
360
|
+
"elevation_failed": "Could not update {{tool}}'s registry (prompt declined, or this account is not an administrator): open PowerShell as administrator and run vibecli setup"
|
|
358
361
|
},
|
|
359
362
|
"tools": {
|
|
360
363
|
"version_outdated": "version {{current}} is too old (needs {{min}} or later); upgrade with {{upgrade}}",
|
|
@@ -372,7 +375,12 @@
|
|
|
372
375
|
"official_login_hidden": "The official Claude.ai sign-in entry is hidden; the desktop is gateway-only. Run vibecli setup --claude-official on to bring it back",
|
|
373
376
|
"official_login_shown": "The official Claude.ai sign-in entry stays visible, so users can switch between the gateway and their own account. Run vibecli setup --claude-official off to hide it",
|
|
374
377
|
"models_summary": "{{count}} Claude models, default {{default}}",
|
|
375
|
-
"registry_denied": "
|
|
378
|
+
"registry_denied": "No administrator rights, registry backstop skipped; there are no old registry settings, so the local config applies",
|
|
379
|
+
"policy_stale_remove": "Claude Desktop still uses old registry settings (most likely from the .reg file downloaded from the gateway page), which override the new config; removing them needs one administrator confirmation, after which updates need none",
|
|
380
|
+
"policy_stale_write": "Claude Desktop still uses old registry settings (most likely from the .reg file downloaded from the gateway page); writing the new config there needs one administrator confirmation",
|
|
381
|
+
"elevate_remove": "Remove the old registry settings? Windows asks for administrator confirmation once; later updates won't need it",
|
|
382
|
+
"elevate_write": "Write the new config to the registry? Windows asks for administrator confirmation once",
|
|
383
|
+
"refresh_needs_admin": "Claude Desktop's model list lives in the registry and needs administrator confirmation to change: run vibecli setup and confirm"
|
|
376
384
|
},
|
|
377
385
|
"claude_code": {
|
|
378
386
|
"gateway_models": "{{count}} more models added to /model ({{vendors}})",
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -354,7 +354,10 @@
|
|
|
354
354
|
"offer_upgrade": "{{tools}} 版本过旧,现在升级吗?",
|
|
355
355
|
"offer_restart": "{{tool}} 正在运行,要重启它让新配置生效吗?(会关掉当前窗口)",
|
|
356
356
|
"restarted": "{{tool}} 已重启",
|
|
357
|
-
"restart_failed": "{{tool}} 没能自动重启,请完全退出后手动打开"
|
|
357
|
+
"restart_failed": "{{tool}} 没能自动重启,请完全退出后手动打开",
|
|
358
|
+
"elevation_running": "请在弹出的系统窗口里点「是」…",
|
|
359
|
+
"elevation_done": "{{tool}} 的注册表已更新",
|
|
360
|
+
"elevation_failed": "没能更新 {{tool}} 的注册表(系统确认被取消,或这个账号不是管理员):用管理员身份打开 PowerShell 再运行 vibecli setup"
|
|
358
361
|
},
|
|
359
362
|
"tools": {
|
|
360
363
|
"version_outdated": "版本 {{current}} 过旧,需要 {{min}} 及以上,运行 {{upgrade}} 升级",
|
|
@@ -372,7 +375,12 @@
|
|
|
372
375
|
"official_login_hidden": "官方登录(Claude.ai 账号)入口已隐藏,桌面端只走网关;要恢复运行 vibecli setup --claude-official on",
|
|
373
376
|
"official_login_shown": "官方登录(Claude.ai 账号)入口保持可见,用户可在网关与官方账号间切换;要隐藏运行 vibecli setup --claude-official off",
|
|
374
377
|
"models_summary": "{{count}} 个 Claude 模型,默认 {{default}}",
|
|
375
|
-
"registry_denied": "
|
|
378
|
+
"registry_denied": "没有管理员权限,跳过了注册表兜底;注册表里没有旧配置,本地配置会生效",
|
|
379
|
+
"policy_stale_remove": "桌面端还在用注册表里的旧配置(多半是以前从网关页面下载 .reg 写入的),它会挡住刚写好的配置;删掉它需要管理员确认一次,之后更新不再需要管理员",
|
|
380
|
+
"policy_stale_write": "桌面端还在用注册表里的旧配置(多半是以前从网关页面下载 .reg 写入的);把新配置写进去需要管理员确认一次",
|
|
381
|
+
"elevate_remove": "删掉注册表里的旧配置吗?会弹出一次系统的管理员确认,之后更新桌面端不再需要管理员",
|
|
382
|
+
"elevate_write": "把新配置写进注册表吗?会弹出一次系统的管理员确认",
|
|
383
|
+
"refresh_needs_admin": "Claude 桌面端的模型列表在注册表里,更新它需要管理员确认:运行 vibecli setup 按提示确认即可"
|
|
376
384
|
},
|
|
377
385
|
"claude_code": {
|
|
378
386
|
"gateway_models": "/model 菜单加入 {{count}} 个其他模型({{vendors}})",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeapi/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.61",
|
|
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",
|