@vibeapi/api-helper 0.0.96 → 0.0.97
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/client-config.snapshot.json +123 -10
- package/dist/brand.json +76 -0
- package/dist/cli.js +1 -1
- package/dist/client-config.snapshot.json +123 -10
- package/dist/commands/base.js +1 -1
- package/dist/commands/completion.js +1 -1
- package/dist/commands/setup.d.ts +2 -0
- package/dist/commands/setup.js +1 -1
- package/dist/commands/update.d.ts +2 -1
- package/dist/commands/update.js +1 -1
- package/dist/lib/api-validator.js +1 -1
- package/dist/lib/auto-update.js +1 -1
- package/dist/lib/brand.d.ts +82 -8
- package/dist/lib/brand.js +1 -1
- package/dist/lib/cli-help.d.ts +1 -1
- package/dist/lib/cli-help.js +1 -1
- package/dist/lib/client-config-sync.js +1 -1
- package/dist/lib/client-config.d.ts +5 -4
- package/dist/lib/client-config.js +1 -1
- package/dist/lib/codex-sessions.js +1 -1
- package/dist/lib/command-docs.js +1 -1
- package/dist/lib/command.js +1 -1
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/errors.d.ts +10 -10
- package/dist/lib/errors.js +1 -1
- package/dist/lib/gateway-models.js +1 -1
- package/dist/lib/gateway-protocol.d.ts +13 -0
- package/dist/lib/gateway-protocol.js +1 -0
- package/dist/lib/i18n.js +1 -1
- package/dist/lib/model-refresh.js +1 -1
- package/dist/lib/model-registry.d.ts +2 -4
- package/dist/lib/model-registry.js +1 -1
- package/dist/lib/persistent-env.js +1 -1
- package/dist/lib/program.js +1 -1
- package/dist/lib/secret-store.js +1 -1
- package/dist/lib/tool-manager.d.ts +8 -0
- package/dist/lib/tool-manager.js +1 -1
- package/dist/lib/tools/antigravity.js +1 -1
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/claude-plugins.d.ts +8 -13
- package/dist/lib/tools/claude-plugins.js +1 -1
- package/dist/lib/tools/codex-catalog.d.ts +1 -1
- package/dist/lib/tools/codex-catalog.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/tools/elevated-reg.js +1 -1
- package/dist/lib/tools/grok.js +1 -1
- package/dist/lib/tools/openclaw.js +1 -1
- package/dist/lib/tools/tool-installs.d.ts +2 -2
- package/dist/lib/tools/tool-installs.js +1 -1
- package/dist/lib/tools/types.js +1 -1
- package/dist/lib/windows-env.js +1 -1
- package/dist/lib/wizard.js +1 -1
- package/dist/locales/en_US.json +105 -97
- package/dist/locales/zh_CN.json +105 -97
- package/dist/models.json +1 -27
- package/dist/utils/logger.js +1 -1
- package/models.json +1 -27
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,mkdirSync as o,readFileSync as r,writeFileSync as t}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
|
|
1
|
+
import{existsSync as e,mkdirSync as o,readFileSync as r,writeFileSync as t}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 m}from"../utils/logger.js";import{resolveUpdateCachePath as u}from"./auto-update.js";import{isHelpRequest as h}from"./cli-help.js";import{brandEnvName as p}from"./brand.js";export const MODEL_REFRESH_INTERVAL_MS=36e5;const g=new Set(["setup","init","config","auth","enter","completion","update","lang","logs","refresh"]),M=["--json","--dry-run","--help","-h","--version","-v"],y=[];export function shouldSkipModelRefresh(e,o=process.env){if("1"===o[p("DISABLE_MODEL_REFRESH")])return!0;if(M.some(o=>e.includes(o))||h(e))return!0;const r=e.find(e=>!e.startsWith("-"));return void 0!==r&&g.has(r)}export async function refreshModelMenus(){const e=new Map,o=[];y.length=0;for(const r of c())if(r.refreshModelMenu&&r.listedModels)try{const t=l.getApiKeyForTool(r.name);if(!t||r.detectCurrentConfig().apiKey!==t)continue;const n=r.listedModels();if(null===n)continue;e.has(t)||e.set(t,await d(t));const s=e.get(t);if(!s)continue;r.refreshModelMenu({apiKey:t,baseUrl:l.getBaseUrl(),models:l.getModelsForTool(r.name),settings:l.getToolSettings(r.name),catalog:s});const i=r.listedModels()??[],f=i.filter(e=>!n.includes(e)),c=n.filter(e=>!i.includes(e));(f.length>0||c.length>0)&&o.push({tool:r.displayName,added:f,removed:c})}catch(e){m.logError(`modelRefresh(${r.name})`,e),e instanceof a&&y.push(e.message)}return o}export async function runModelRefresh(l,d={}){const c=d.env??process.env,a=d.now??Date.now(),h=function(e){return s(n(u(e)),"model-refresh.json")}(c);if(!d.force){if(shouldSkipModelRefresh(l,c))return[];if(a-function(e){try{const o=JSON.parse(r(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}),t(h,JSON.stringify({refreshed_at:a})+"\n")}catch(e){m.logError("runModelRefresh",e)}const g=d.output??(e=>console.log(i.gray(e)));for(const e of y)g(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);g(f.t("model_refresh.changed",{tool:e.tool,changes:o.join(";")}))}return p}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ClientSection } from './client-config.js';
|
|
2
2
|
export interface Models {
|
|
3
3
|
haiku: string;
|
|
4
4
|
sonnet: string;
|
|
@@ -87,8 +87,6 @@ export interface ModelRegistryData {
|
|
|
87
87
|
agy?: Partial<AgyRules>;
|
|
88
88
|
/** Oldest tool release vibecli's written config works with (tool id → semver). */
|
|
89
89
|
toolMinVersions?: Record<string, string>;
|
|
90
|
-
/** Addresses the gateway answers on, in the operator's order; used until the gateway's own list is cached. */
|
|
91
|
-
gatewayAddresses?: GatewayAddress[];
|
|
92
90
|
}
|
|
93
91
|
/** One address the gateway answers on (another domain or route to the same site). */
|
|
94
92
|
export interface GatewayAddress {
|
|
@@ -100,7 +98,7 @@ export interface GatewayAddress {
|
|
|
100
98
|
* per-slot / per-tool values replace the built-in ones, the tombstone lists (retired defaults,
|
|
101
99
|
* retired models) are unions, the agy menu and the 1M fallback list are replaced when given.
|
|
102
100
|
*/
|
|
103
|
-
export declare function
|
|
101
|
+
export declare function overlayClientSection(base: ModelRegistryData, v: ClientSection | undefined): ModelRegistryData;
|
|
104
102
|
export declare function getDefaultModels(): Models;
|
|
105
103
|
/** Earlier default for this slot, saved into a profile by the wizard's prefilled inputs. */
|
|
106
104
|
export declare function isRetiredDefaultModel(slot: string, model: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dirname as e,join as o}from"path";import{fileURLToPath as t}from"url";import{existsSync as l,readFileSync as n}from"fs";import{currentClientConfig as r,
|
|
1
|
+
import{dirname as e,join as o}from"path";import{fileURLToPath as t}from"url";import{existsSync as l,readFileSync as n}from"fs";import{currentClientConfig as r,usableClientSection as s}from"./client-config.js";import{brand as a}from"./brand.js";const i=e(t(import.meta.url)),d=(e=[],o=[])=>[...new Set([...e,...o])];export function overlayClientSection(e,o){if(!o)return e;const t={...e.retiredDefaultModels??{}};for(const[e,l]of Object.entries(o.retiredDefaultModels??{}))t[e]=d(t[e],l);return{...e,defaultModels:{...e.defaultModels,...o.defaultModels??{}},retiredDefaultModels:t,toolDefaults:{...e.toolDefaults??{},...o.toolDefaults??{}},claudeCode:o.tierChains?{...e.claudeCode??{},tierChains:{...e.claudeCode?.tierChains??{},...o.tierChains}}:e.claudeCode,claudeDesktop:o.oneMillionFallback?{...e.claudeDesktop??{},oneMillionFallback:[...o.oneMillionFallback]}:e.claudeDesktop,gatewayModels:o.retiredModels?{...e.gatewayModels??{},retired:d(e.gatewayModels?.retired,o.retiredModels)}:e.gatewayModels,toolMinVersions:{...e.toolMinVersions??{},...o.toolMinVersions??{}},agy:o.agyModels?{...e.agy??{},gatewayModels:[...o.agyModels]}:e.agy}}let u=null;function c(){return u||(u=overlayClientSection(function(){const e=[o(i,"..","..","models.json"),o(i,"..","models.json"),o(i,"models.json")];for(const o of e)if(l(o))return JSON.parse(n(o,"utf-8"));throw new Error(`models.json not found, searched: ${e.join(", ")}`)}(),s(r()?.config))),u}export function getDefaultModels(){return{...c().defaultModels}}export function isRetiredDefaultModel(e,o){return c().retiredDefaultModels?.[e]?.includes(o)??!1}export function getDefaultToolModel(){return c().defaultToolModel?.trim()||"gpt-5.5"}export function getToolDefaultModel(e){const o=c().toolDefaults;return o&&Object.prototype.hasOwnProperty.call(o,e)?(o[e]??"").trim():getDefaultToolModel()}export function getPresets(){return[...c().presets]}export function resolvePreset(e){return e.models?{...e.models}:e.model?{haiku:e.model,sonnet:e.model,opus:e.model,reasoning:e.model}:getDefaultModels()}export function getClaudeCodeTierChains(){const e=c().claudeCode?.tierChains??{};return Object.fromEntries(Object.entries(e).map(([e,o])=>[e,[...o]]))}export function getClaudeDesktopRules(){const e=c().claudeDesktop??{};return{oneMillionFallback:[...e.oneMillionFallback??[]],oneMillionExclusions:(e.oneMillionExclusions??[]).map(e=>({...e,models:[...e.models]}))}}export function getGatewayModelRules(){const e=c().gatewayModels??{};return{autoCompactRatio:e.autoCompactRatio??.8,models:(e.models??[]).map(e=>({...e})),retired:[...e.retired??[]]}}export function getBuiltinGatewayAddresses(){return a().gatewayAddresses.map(e=>({...e}))}export function getCodexRules(){return{standardContextWindow:c().codex?.standardContextWindow??272e3}}export function getAgyRules(){return{gatewayModels:[...c().agy?.gatewayModels??[]]}}export function compareVersions(e,o){const t=e.split(".").map(e=>parseInt(e,10)||0),l=o.split(".").map(e=>parseInt(e,10)||0);for(let e=0;e<Math.max(t.length,l.length);e++){const o=(t[e]??0)-(l[e]??0);if(0!==o)return o}return 0}export function getToolMinVersion(e){return c().toolMinVersions?.[e]?.trim()||null}export function reloadRegistry(){u=null}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{chmodSync as t,existsSync as n,readFileSync as o,realpathSync as r,unlinkSync as e}from"fs";import{join as s}from"path";import{logger as i}from"../utils/logger.js";import{getShellRcFilePath as c}from"./env-cleanup.js";import{broadcastEnvChange as f,deleteWindowsEnv as u,readWindowsEnv as p,setUserEnv as l}from"./windows-env.js";import{atomicWriteFile as m,backupBeforeWrite as a}from"./tools/backup.js";import{toolHome as $}from"./tools/types.js";const
|
|
1
|
+
import{chmodSync as t,existsSync as n,readFileSync as o,realpathSync as r,unlinkSync as e}from"fs";import{join as s}from"path";import{logger as i}from"../utils/logger.js";import{getShellRcFilePath as c}from"./env-cleanup.js";import{broadcastEnvChange as f,deleteWindowsEnv as u,readWindowsEnv as p,setUserEnv as l}from"./windows-env.js";import{atomicWriteFile as m,backupBeforeWrite as a}from"./tools/backup.js";import{toolHome as $}from"./tools/types.js";import{CLI_NAME as d}from"./brand.js";const h=t=>`# ${d}:${t}`;function v(){const t=$(),o=new Set,r=c();r&&o.add(r);for(const r of[".zshrc",".bashrc"]){const e=s(t,r);n(e)&&o.add(e)}return[...o]}function j(t,n,o){const r=`"${function(t){const n=$();return t.startsWith(n+"/")?`$HOME/${t.slice(n.length+1)}`:t}(n)}"`;return t.endsWith(".fish")?`test -f ${r}; and source ${r} ${h(o)}`:`[ -f ${r} ] && . ${r} ${h(o)}`}function w(t,o){const e=n(t)?r(t):t;a(e),m(e,o)}function E(t,n){return t.split("\n").filter(t=>!t.trimEnd().endsWith(h(n))).join("\n")}function b(t,n){if(/['\r\n]/.test(n))throw new Error(`${t} contains a quote or newline and cannot be written to a shell env file`)}export function writePersistentEnv(r,e,s){for(const[t,n]of Object.entries(s))b(t,n);const i=Object.entries(s).map(([t,n])=>`export ${t}='${n}'`).join("\n");a(e),m(e,`# Written by ${d}. Loaded from your shell profile.\n${i}\n`,384),t(e,384);for(const[t,n]of Object.entries(s))process.env[t]=n;if("win32"===process.platform){for(const[t,n]of Object.entries(s))l(t,n);return f(),{rcFiles:[]}}const c=[];for(const t of v()){const s=n(t)?o(t,"utf-8"):"",i=j(t,e,r);if(s.split("\n").some(t=>t.trimEnd()===i)){c.push(t);continue}const f=E(s,r).replace(/\n*$/,"");w(t,`${f?f+"\n\n":""}${i}\n`),c.push(t)}return{rcFiles:c}}export function removePersistentEnv(t,r,s){const c=readPersistentEnvFile(r);if(n(r)&&(a(r),e(r)),"win32"===process.platform){let t=!1;for(const n of s)if(void 0!==c[n]&&p("user",n)===c[n])try{u("user",n),t=!0}catch(t){i.logError("persistentEnv.remove",t)}return void(t&&f())}for(const r of v()){if(!n(r))continue;const e=o(r,"utf-8"),s=E(e,t);s!==e&&w(r,s)}}export function readPersistentEnvFile(t){const r={};if(!n(t))return r;for(const n of o(t,"utf-8").split("\n")){const t=n.match(/^export ([A-Z_][A-Z0-9_]*)='([^']*)'$/);t&&(r[t[1]]=t[2])}return r}
|
package/dist/lib/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Command as e,Option as o}from"commander";import{readFileSync as t}from"fs";import{join as i,dirname as s}from"path";import{fileURLToPath as a}from"url";import{i18n as n}from"./i18n.js";import{wizard as c}from"./wizard.js";import{SUPPORTED_TOOLS as r}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as u}from"./cli-help.js";import{langCommand as m,authCommand as d,doctorCommand as b,configCommand as g,statusCommand as f,refreshCommand as v}from"../commands/index.js";import{logsCommand as x}from"../commands/logs.js";import{completionCommand as h}from"../commands/completion.js";import{benchCommand as y}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{codexSessionsCommand as w}from"../commands/codex-sessions.js";import{setupCommand as j,DEDICATED_KEYS as O}from"../commands/setup.js";import{baseCommand as S}from"../commands/base.js";import{usageError as z}from"./errors.js";function C(e,o){return n.t(`help.${e}`,o)}function G(e,o){return{command:e,note:C(o)}}function $(e){const o=C(e);return o===`help.${e}`?"":o}function R(e,o=[]){return{when:$(`${e}.when`),prerequisites:$(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>G(e,o))}}function E(e){return e.helpCommand("help [command]",C("help_command"))}export function buildProgram(){const $=new e;$.name("vibecli").summary(C("root.summary")).description(C("root.description")).configureHelp(u()).allowExcessArguments(!0).optionsGroup(C("group.global_options")).helpOption("-h, --help",C("global.help")).version(function(){try{const e=s(a(import.meta.url));return JSON.parse(t(i(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",C("global.version")).option("--base <url>",C("global.base")).option("--non-interactive",C("global.non_interactive")).option("--json",C("global.json")).option("-y, --yes",C("global.yes")).option("--dry-run",C("global.dry_run")).option("--no-color",C("global.no_color")),$.configureOutput({writeErr:()=>{},outputError:()=>{}}),$.showSuggestionAfterError(),$.exitOverride(e=>{throw e}),$.commandsGroup(C("group.configure"));const L=$.command("setup").summary(C("setup.summary")).description(C("setup.description")).option("--key <key>",C("setup.opt.key"));for(const e of O){const t=new o(`--${e.option} <key>`,C(`setup.opt.${e.option}`));e.hidden&&t.hideHelp(),L.addOption(t)}L.option("--1m",C("setup.opt.one_m")).option("--no-1m",C("setup.opt.no_one_m")).option("--claude-official <on|off>",C("setup.opt.claude_official")).option("--desktop-registry <on|off>",C("setup.opt.desktop_registry")).option("--force",C("setup.opt.force")).option("--all",C("setup.opt.all")).action(async e=>{const o=Boolean(e.key||O.some(o=>e[o.option])),t=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,i="zh_CN"===n.getLocale()?"<你的 Key>":"<your key>";if(!o&&!t)throw z(n.t("setup.usage"),`vibecli setup --key ${i}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw z(n.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),"vibecli setup --claude-official on|off","invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw z(n.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),"vibecli setup --desktop-registry on|off","invalid_value");await j({key:e.key,...Object.fromEntries(O.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force})}),p(L,{...R("setup",[["vibecli init","setup.alt.init"],["vibecli config <tool>","setup.alt.config"],["vibecli auth <key>","setup.alt.auth"]]),sections:[{title:C("setup.autodetect_title"),rows:[["Claude",C("setup.autodetect.claude")],["GPT",C("setup.autodetect.gpt")],["Grok",C("setup.autodetect.grok")],["Gemini",C("setup.autodetect.gemini")]]}],examples:[G("vibecli setup --key sk-xxx","setup.ex.key"),G("vibecli setup --claudekey sk-a --codexkey sk-b --agykey sk-g","setup.ex.split"),G("vibecli setup --desktopkey sk-d --claude-official off","setup.ex.desktop"),G("vibecli setup --key sk-xxx --force","setup.ex.force"),G("vibecli setup --key sk-xxx --base https://www.vibeapi.si","setup.ex.base")]});const N=$.command("init").summary(C("init.summary")).description(C("init.description")).action(async()=>{await c.runFirstTimeSetup()});p(N,{...R("init",[["vibecli setup --key <key>","init.alt.setup"],["vibecli","init.alt.menu"]]),examples:[G("vibecli init","init.ex.run"),G("vibecli init --base https://www.vibeapi.si","init.ex.base"),G("vibecli","init.ex.menu")]});const A=$.command("auth").summary(C("auth.summary")).description(C("auth.description")).argument("[token]",C("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});E(A);const K=A.command("revoke").description(C("auth.revoke")).action(async()=>{await d(["revoke"])});p(K,{examples:[G("vibecli auth revoke","auth.ex.revoke_ask"),G("vibecli auth revoke --yes","auth.ex.revoke")]});const B=A.command("reload <tool>").description(C("auth.reload")).action(async e=>{await d(["reload",e])});p(B,{examples:[G("vibecli auth reload claude-code","auth.ex.reload"),G("vibecli auth reload claude-code --json","auth.ex.reload_json")]}),p(A,{...R("auth",[["vibecli setup --key <key>","auth.alt.setup"]]),examples:[G("vibecli auth","auth.ex.prompt"),G("vibecli auth sk-xxx --non-interactive","auth.ex.save"),G("vibecli auth revoke --yes","auth.ex.revoke"),G("vibecli auth reload claude-code","auth.ex.reload")]});const H=$.command("config").summary(C("config.summary")).description(C("config.description")).argument("[args...]",C("config.arg.args")).option("-f, --force",C("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(H,{...R("config",[["vibecli setup --key <key> --force","config.alt.setup"],["vibecli status","config.alt.status"]]),sections:[{title:C("config.subcommands_title"),rows:[["<tool>",C("config.sub.tool")],["<tool> --force",C("config.sub.tool_force")],["<tool> --non-interactive",C("config.sub.tool_non_interactive")],["<tool> restore",C("config.sub.tool_restore")],["<tool> backups",C("config.sub.tool_backups")],["<tool> clear-model",C("config.sub.tool_clear_model")],["tool-model list",C("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",C("config.sub.tool_model_set")],["tool-model clear <tool>",C("config.sub.tool_model_clear")],["profile list",C("config.sub.profile_list")],["profile create <name>",C("config.sub.profile_create")],["profile use <name>",C("config.sub.profile_use")],["profile delete <name>",C("config.sub.profile_delete")],["preset list",C("config.sub.preset_list")],["preset save <name>",C("config.sub.preset_save")],["preset use <name>",C("config.sub.preset_use")],["preset delete <name>",C("config.sub.preset_delete")],["backup list",C("config.sub.backup_list")],["backup create [label]",C("config.sub.backup_create")],["backup restore <name>",C("config.sub.backup_restore")]]},{title:C("config.tools_title"),rows:Object.values(r).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[G("vibecli config codex","config.ex.menu"),G("vibecli config claude-code --force","config.ex.force"),G("vibecli config tool-model set codex gpt-6-astra","config.ex.tool_model"),G("vibecli config profile create work","config.ex.profile"),G("vibecli config backup create before-upgrade","config.ex.backup")]});const M=$.command("base").summary(C("base.summary")).description(C("base.description")).argument("[target]",C("base.arg.target")).action(async e=>{await S(e)});p(M,{...R("base",[["vibecli doctor","base.alt.doctor"],["vibecli bench","base.alt.bench"]]),sections:[{title:C("base.targets_title"),rows:[[C("base.target.none_term"),C("base.target.none")],[C("base.target.index_term"),C("base.target.index")],[C("base.target.url_term"),C("base.target.url")],["auto",C("base.target.auto")],["default",C("base.target.default",{url:l})]]}],examples:[G("vibecli base","base.ex.list"),G("vibecli base auto","base.ex.auto"),G("vibecli base 2","base.ex.index"),G("vibecli base https://www.vibeapi.si","base.ex.url"),G("vibecli base default","base.ex.default")]}),$.commandsGroup(C("group.diagnose"));const P=$.command("status").summary(C("status.summary")).description(C("status.description")).action(async()=>{await f()});p(P,{...R("status",[["vibecli doctor","status.alt.doctor"]]),examples:[G("vibecli status","status.ex.show"),G("vibecli status --json","status.ex.json")]});const T=$.command("doctor").summary(C("doctor.summary")).description(C("doctor.description")).option("--deep",C("doctor.opt.deep")).action(async e=>{await b({deep:e.deep})});p(T,{...R("doctor",[["vibecli base auto","doctor.alt.base"],["vibecli logs tail","doctor.alt.logs"]]),examples:[G("vibecli doctor","doctor.ex.run"),G("vibecli doctor --deep","doctor.ex.deep")]});const U=$.command("bench").summary(C("bench.summary")).description(C("bench.description")).option("--samples <n>",C("bench.opt.samples"),"5").action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),await y(o)});p(U,{...R("bench",[["vibecli base","bench.alt.base"]]),examples:[G("vibecli bench","bench.ex.run"),G("vibecli bench --samples 3","bench.ex.samples"),G("vibecli bench --json","bench.ex.json")]});const q=$.command("logs").summary(C("logs.summary")).description(C("logs.description")).argument("[action]",C("logs.arg.action")).argument("[file]",C("logs.arg.file")).action(async(e,o)=>{const t=[];e&&t.push(e),o&&t.push(o),await x(t)});p(q,{...R("logs",[["vibecli doctor","logs.alt.doctor"]]),sections:[{title:C("logs.actions_title"),rows:[["list",C("logs.action.list")],["tail [file]",C("logs.action.tail")],["path",C("logs.action.path")]]}],examples:[G("vibecli logs","logs.ex.list"),G("vibecli logs tail","logs.ex.tail"),G("vibecli logs path","logs.ex.path")]}),$.commandsGroup(C("group.maintain"));const F=$.command("upgrade").summary(C("upgrade.summary")).description(C("upgrade.description")).argument("[tools...]",C("upgrade.arg.tools")).action(async(e=[])=>{await _(e)});p(F,{...R("upgrade",[["vibecli update","upgrade.alt.update"]]),examples:[G("vibecli upgrade","upgrade.ex.all"),G("vibecli upgrade claude-code","upgrade.ex.one"),G("vibecli upgrade codex agy","upgrade.ex.many")]});const J=$.command("refresh").summary(C("refresh.summary")).description(C("refresh.description")).action(async()=>{await v()});p(J,{...R("refresh",[["vibecli setup --key <你的 Key>","refresh.alt.setup"]]),examples:[G("vibecli refresh","refresh.ex.run"),G("vibecli refresh --base https://hk.vibeapi.cn","refresh.ex.base")]});const D=$.command("update").summary(C("update.summary")).description(C("update.description")).action(async()=>{await k()});p(D,{...R("update",[["vibecli upgrade","update.alt.upgrade"]]),examples:[G("vibecli update","update.ex.check"),G("vibecli update --json","update.ex.json")]});const I=$.command("codex").summary(C("codex.summary")).description(C("codex.description"));E(I);const Q=I.command("sessions").summary(C("codex_sessions.summary")).description(C("codex_sessions.description")).option("--to <provider>",C("codex_sessions.opt.to")).option("--undo <dir>",C("codex_sessions.opt.undo")).action(async e=>{await w(e)});p(I,{...R("codex"),examples:[G("vibecli codex sessions","codex_sessions.ex.move"),G("vibecli codex sessions --undo <dir>","codex_sessions.ex.undo")]}),p(Q,{...R("codex_sessions",[["vibecli codex sessions --undo <dir>","codex_sessions.alt.undo"]]),examples:[G("vibecli codex sessions","codex_sessions.ex.move"),G("vibecli codex sessions --to custom","codex_sessions.ex.to"),G("vibecli codex sessions --undo <dir>","codex_sessions.ex.undo")]});const V=$.command("lang").summary(C("lang.summary")).description(C("lang.description"));E(V);const W=V.command("show").description(C("lang.show")).action(async()=>{await m(["show"])}),X=V.command("set <locale>").description(C("lang.set")).action(async e=>{await m(["set",e])}),Y=[G("vibecli lang show","lang.ex.show"),G("vibecli lang set en_US","lang.ex.set_en"),G("vibecli lang set zh_CN","lang.ex.set_zh")];p(V,{...R("lang",[["vibecli enter lang","lang.alt.enter"]]),examples:Y}),p(W,{examples:[Y[0],G("vibecli lang show --json","lang.ex.show_json")]}),p(X,{examples:Y.slice(1)});const Z=$.command("completion").summary(C("completion.summary")).description(C("completion.description")).argument("<shell>",C("completion.arg.shell")).action(async e=>{await h([e])});p(Z,{...R("completion"),examples:[G("vibecli completion bash > ~/.vibecli-completion.bash","completion.ex.bash"),G("vibecli completion zsh > ~/.vibecli-completion.zsh","completion.ex.zsh"),G("vibecli completion fish > ~/.config/fish/completions/vibecli.fish","completion.ex.fish")]});const ee=$.command("enter").summary(C("enter.summary")).description(C("enter.description")).argument("[option]",C("enter.arg.option")).action(async e=>{if(e)switch(e){case"lang":case"language":await c.configLanguage();break;case"apikey":case"api-key":await c.configApiKey();break;case"models":await c.configModels();break;default:await g([e])}else await c.run()});p(ee,{...R("enter",[["vibecli","enter.alt.menu"],["vibecli config <tool>","enter.alt.config"]]),sections:[{title:C("enter.options_title"),rows:[[C("enter.option.none_term"),C("enter.option.none")],["lang",C("enter.option.lang")],["apikey",C("enter.option.apikey")],["models",C("enter.option.models")],["<tool>",C("enter.option.tool")]]}],examples:[G("vibecli enter","enter.ex.menu"),G("vibecli enter models","enter.ex.models"),G("vibecli enter codex","enter.ex.tool")]}),E($),$.action(async()=>{await c.run()}),p($,{examples:[G("vibecli","root.ex.menu"),G("vibecli setup --key sk-xxx","root.ex.setup"),G("vibecli doctor","root.ex.doctor"),G("vibecli base auto","root.ex.base"),G("vibecli config codex","root.ex.config")]});const oe=e=>{for(const o of e.commands)o.helpOption("-h, --help",C("global.help")),oe(o)};return oe($),$}
|
|
1
|
+
import{Command as e,Option as o}from"commander";import{readFileSync as t}from"fs";import{join as s,dirname as a}from"path";import{fileURLToPath as n}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as u}from"./cli-help.js";import{langCommand as m,authCommand as d,doctorCommand as g,configCommand as f,statusCommand as x,refreshCommand as y}from"../commands/index.js";import{logsCommand as b}from"../commands/logs.js";import{completionCommand as h}from"../commands/completion.js";import{benchCommand as $}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{codexSessionsCommand as w}from"../commands/codex-sessions.js";import{setupCommand as v,DEDICATED_KEYS as j}from"../commands/setup.js";import{baseCommand as O}from"../commands/base.js";import{usageError as S}from"./errors.js";import{brand as z,CLI_NAME as A}from"./brand.js";const C=(z().gatewayAddresses[1]??z().gatewayAddresses[0]).url,G=(z().gatewayAddresses[2]??z().gatewayAddresses[0]).url;function R(e,o){return i.t(`help.${e}`,o)}function E(e,o){return{command:e,note:R(o)}}function L(e){const o=R(e);return o===`help.${e}`?"":o}function N(e,o=[]){return{when:L(`${e}.when`),prerequisites:L(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>E(e,o))}}function K(e){return e.helpCommand("help [command]",R("help_command"))}export function buildProgram(){const z=new e;z.name(`${A}`).summary(R("root.summary")).description(R("root.description")).configureHelp(u()).allowExcessArguments(!0).optionsGroup(R("group.global_options")).helpOption("-h, --help",R("global.help")).version(function(){try{const e=a(n(import.meta.url));return JSON.parse(t(s(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",R("global.version")).option("--base <url>",R("global.base")).option("--non-interactive",R("global.non_interactive")).option("--json",R("global.json")).option("-y, --yes",R("global.yes")).option("--dry-run",R("global.dry_run")).option("--no-color",R("global.no_color")),z.configureOutput({writeErr:()=>{},outputError:()=>{}}),z.showSuggestionAfterError(),z.exitOverride(e=>{throw e}),z.commandsGroup(R("group.configure"));const L=z.command("setup").summary(R("setup.summary")).description(R("setup.description")).option("--key <key>",R("setup.opt.key"));for(const e of j){const t=new o(`--${e.option} <key>`,R(`setup.opt.${e.option}`));e.hidden&&t.hideHelp(),L.addOption(t)}L.option("--1m",R("setup.opt.one_m")).option("--no-1m",R("setup.opt.no_one_m")).option("--claude-official <on|off>",R("setup.opt.claude_official")).option("--desktop-registry <on|off>",R("setup.opt.desktop_registry")).option("--force",R("setup.opt.force")).option("--install",R("setup.opt.install")).option("--no-install",R("setup.opt.no_install")).option("--all",R("setup.opt.all")).action(async e=>{const o=Boolean(e.key||j.some(o=>e[o.option])),t=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,s="zh_CN"===i.getLocale()?"<你的 Key>":"<your key>";if(!o&&!t)throw S(i.t("setup.usage"),`${A} setup --key ${s}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw S(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${A} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw S(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${A} setup --desktop-registry on|off`,"invalid_value");await v({key:e.key,...Object.fromEntries(j.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install})}),p(L,{...N("setup",[[`${A} init`,"setup.alt.init"],[`${A} config <tool>`,"setup.alt.config"],[`${A} auth <key>`,"setup.alt.auth"]]),sections:[{title:R("setup.autodetect_title"),rows:[["Claude",R("setup.autodetect.claude")],["GPT",R("setup.autodetect.gpt")],["Grok",R("setup.autodetect.grok")],["Gemini",R("setup.autodetect.gemini")]]}],examples:[E(`${A} setup --key sk-xxx`,"setup.ex.key"),E(`${A} setup --key sk-xxx --install`,"setup.ex.install"),E(`${A} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),E(`${A} setup --key sk-xxx --force`,"setup.ex.force"),E(`${A} setup --key sk-xxx --base ${C}`,"setup.ex.base")]});const B=z.command("init").summary(R("init.summary")).description(R("init.description")).action(async()=>{await r.runFirstTimeSetup()});p(B,{...N("init",[[`${A} setup --key <key>`,"init.alt.setup"],[`${A}`,"init.alt.menu"]]),examples:[E(`${A} init`,"init.ex.run"),E(`${A} init --base ${C}`,"init.ex.base"),E(`${A}`,"init.ex.menu")]});const H=z.command("auth").summary(R("auth.summary")).description(R("auth.description")).argument("[token]",R("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});K(H);const M=H.command("revoke").description(R("auth.revoke")).action(async()=>{await d(["revoke"])});p(M,{examples:[E(`${A} auth revoke`,"auth.ex.revoke_ask"),E(`${A} auth revoke --yes`,"auth.ex.revoke")]});const P=H.command("reload <tool>").description(R("auth.reload")).action(async e=>{await d(["reload",e])});p(P,{examples:[E(`${A} auth reload claude-code`,"auth.ex.reload"),E(`${A} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(H,{...N("auth",[[`${A} setup --key <key>`,"auth.alt.setup"]]),examples:[E(`${A} auth`,"auth.ex.prompt"),E(`${A} auth sk-xxx --non-interactive`,"auth.ex.save"),E(`${A} auth revoke --yes`,"auth.ex.revoke"),E(`${A} auth reload claude-code`,"auth.ex.reload")]});const T=z.command("config").summary(R("config.summary")).description(R("config.description")).argument("[args...]",R("config.arg.args")).option("-f, --force",R("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await f(o.force?[...e,"--force"]:e)});p(T,{...N("config",[[`${A} setup --key <key> --force`,"config.alt.setup"],[`${A} status`,"config.alt.status"]]),sections:[{title:R("config.subcommands_title"),rows:[["<tool>",R("config.sub.tool")],["<tool> --force",R("config.sub.tool_force")],["<tool> --non-interactive",R("config.sub.tool_non_interactive")],["<tool> restore",R("config.sub.tool_restore")],["<tool> backups",R("config.sub.tool_backups")],["<tool> clear-model",R("config.sub.tool_clear_model")],["tool-model list",R("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",R("config.sub.tool_model_set")],["tool-model clear <tool>",R("config.sub.tool_model_clear")],["profile list",R("config.sub.profile_list")],["profile create <name>",R("config.sub.profile_create")],["profile use <name>",R("config.sub.profile_use")],["profile delete <name>",R("config.sub.profile_delete")],["preset list",R("config.sub.preset_list")],["preset save <name>",R("config.sub.preset_save")],["preset use <name>",R("config.sub.preset_use")],["preset delete <name>",R("config.sub.preset_delete")],["backup list",R("config.sub.backup_list")],["backup create [label]",R("config.sub.backup_create")],["backup restore <name>",R("config.sub.backup_restore")]]},{title:R("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[E(`${A} config codex`,"config.ex.menu"),E(`${A} config claude-code --force`,"config.ex.force"),E(`${A} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),E(`${A} config profile create work`,"config.ex.profile"),E(`${A} config backup create before-upgrade`,"config.ex.backup")]});const U=z.command("base").summary(R("base.summary")).description(R("base.description")).argument("[target]",R("base.arg.target")).action(async e=>{await O(e)});p(U,{...N("base",[[`${A} doctor`,"base.alt.doctor"],[`${A} bench`,"base.alt.bench"]]),sections:[{title:R("base.targets_title"),rows:[[R("base.target.none_term"),R("base.target.none")],[R("base.target.index_term"),R("base.target.index")],[R("base.target.url_term"),R("base.target.url")],["auto",R("base.target.auto")],["default",R("base.target.default",{url:l})]]}],examples:[E(`${A} base`,"base.ex.list"),E(`${A} base auto`,"base.ex.auto"),E(`${A} base 2`,"base.ex.index"),E(`${A} base ${C}`,"base.ex.url"),E(`${A} base default`,"base.ex.default")]}),z.commandsGroup(R("group.diagnose"));const q=z.command("status").summary(R("status.summary")).description(R("status.description")).action(async()=>{await x()});p(q,{...N("status",[[`${A} doctor`,"status.alt.doctor"]]),examples:[E(`${A} status`,"status.ex.show"),E(`${A} status --json`,"status.ex.json")]});const F=z.command("doctor").summary(R("doctor.summary")).description(R("doctor.description")).option("--deep",R("doctor.opt.deep")).action(async e=>{await g({deep:e.deep})});p(F,{...N("doctor",[[`${A} base auto`,"doctor.alt.base"],[`${A} logs tail`,"doctor.alt.logs"]]),examples:[E(`${A} doctor`,"doctor.ex.run"),E(`${A} doctor --deep`,"doctor.ex.deep")]});const J=z.command("bench").summary(R("bench.summary")).description(R("bench.description")).option("--samples <n>",R("bench.opt.samples"),"5").action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),await $(o)});p(J,{...N("bench",[[`${A} base`,"bench.alt.base"]]),examples:[E(`${A} bench`,"bench.ex.run"),E(`${A} bench --samples 3`,"bench.ex.samples"),E(`${A} bench --json`,"bench.ex.json")]});const D=z.command("logs").summary(R("logs.summary")).description(R("logs.description")).argument("[action]",R("logs.arg.action")).argument("[file]",R("logs.arg.file")).action(async(e,o)=>{const t=[];e&&t.push(e),o&&t.push(o),await b(t)});p(D,{...N("logs",[[`${A} doctor`,"logs.alt.doctor"]]),sections:[{title:R("logs.actions_title"),rows:[["list",R("logs.action.list")],["tail [file]",R("logs.action.tail")],["path",R("logs.action.path")]]}],examples:[E(`${A} logs`,"logs.ex.list"),E(`${A} logs tail`,"logs.ex.tail"),E(`${A} logs path`,"logs.ex.path")]}),z.commandsGroup(R("group.maintain"));const I=z.command("upgrade").summary(R("upgrade.summary")).description(R("upgrade.description")).argument("[tools...]",R("upgrade.arg.tools")).action(async(e=[])=>{await _(e)});p(I,{...N("upgrade",[[`${A} update`,"upgrade.alt.update"]]),examples:[E(`${A} upgrade`,"upgrade.ex.all"),E(`${A} upgrade claude-code`,"upgrade.ex.one"),E(`${A} upgrade codex agy`,"upgrade.ex.many")]});const Q=z.command("refresh").summary(R("refresh.summary")).description(R("refresh.description")).action(async()=>{await y()});p(Q,{...N("refresh",[[`${A} setup --key <你的 Key>`,"refresh.alt.setup"]]),examples:[E(`${A} refresh`,"refresh.ex.run"),E(`${A} refresh --base ${G}`,"refresh.ex.base")]});const V=z.command("update").summary(R("update.summary")).description(R("update.description")).action(async()=>{await k()});p(V,{...N("update",[[`${A} upgrade`,"update.alt.upgrade"]]),examples:[E(`${A} update`,"update.ex.check"),E(`${A} update --json`,"update.ex.json")]});const W=z.command("codex").summary(R("codex.summary")).description(R("codex.description"));K(W);const X=W.command("sessions").summary(R("codex_sessions.summary")).description(R("codex_sessions.description")).option("--to <provider>",R("codex_sessions.opt.to")).option("--undo <dir>",R("codex_sessions.opt.undo")).action(async e=>{await w(e)});p(W,{...N("codex"),examples:[E(`${A} codex sessions`,"codex_sessions.ex.move"),E(`${A} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(X,{...N("codex_sessions",[[`${A} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[E(`${A} codex sessions`,"codex_sessions.ex.move"),E(`${A} codex sessions --to custom`,"codex_sessions.ex.to"),E(`${A} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const Y=z.command("lang").summary(R("lang.summary")).description(R("lang.description"));K(Y);const Z=Y.command("show").description(R("lang.show")).action(async()=>{await m(["show"])}),ee=Y.command("set <locale>").description(R("lang.set")).action(async e=>{await m(["set",e])}),oe=[E(`${A} lang show`,"lang.ex.show"),E(`${A} lang set en_US`,"lang.ex.set_en"),E(`${A} lang set zh_CN`,"lang.ex.set_zh")];p(Y,{...N("lang",[[`${A} enter lang`,"lang.alt.enter"]]),examples:oe}),p(Z,{examples:[oe[0],E(`${A} lang show --json`,"lang.ex.show_json")]}),p(ee,{examples:oe.slice(1)});const te=z.command("completion").summary(R("completion.summary")).description(R("completion.description")).argument("<shell>",R("completion.arg.shell")).action(async e=>{await h([e])});p(te,{...N("completion"),examples:[E(`${A} completion bash > ~/.${A}-completion.bash`,"completion.ex.bash"),E(`${A} completion zsh > ~/.${A}-completion.zsh`,"completion.ex.zsh"),E(`${A} completion fish > ~/.config/fish/completions/${A}.fish`,"completion.ex.fish")]});const se=z.command("enter").summary(R("enter.summary")).description(R("enter.description")).argument("[option]",R("enter.arg.option")).action(async e=>{if(e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await f([e])}else await r.run()});p(se,{...N("enter",[[`${A}`,"enter.alt.menu"],[`${A} config <tool>`,"enter.alt.config"]]),sections:[{title:R("enter.options_title"),rows:[[R("enter.option.none_term"),R("enter.option.none")],["lang",R("enter.option.lang")],["apikey",R("enter.option.apikey")],["models",R("enter.option.models")],["<tool>",R("enter.option.tool")]]}],examples:[E(`${A} enter`,"enter.ex.menu"),E(`${A} enter models`,"enter.ex.models"),E(`${A} enter codex`,"enter.ex.tool")]}),K(z),z.action(async()=>{await r.run()}),p(z,{examples:[E(`${A}`,"root.ex.menu"),E(`${A} setup --key sk-xxx`,"root.ex.setup"),E(`${A} doctor`,"root.ex.doctor"),E(`${A} base auto`,"root.ex.base"),E(`${A} config codex`,"root.ex.config")]});const ae=e=>{for(const o of e.commands)o.helpOption("-h, --help",R("global.help")),ae(o)};return ae(z),z}
|
package/dist/lib/secret-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t}from"fs";import{hostname as r,userInfo as o}from"os";import{createDecipheriv as s,scryptSync as
|
|
1
|
+
import{existsSync as e,readFileSync as t}from"fs";import{hostname as r,userInfo as o}from"os";import{createDecipheriv as s,scryptSync as n}from"crypto";import{CLI_NAME as c}from"./brand.js";export class SecretStoreDecryptError extends Error{cause;constructor(e,t){super(e),this.cause=t,this.name="SecretStoreDecryptError"}}function i(e){return!e||"object"!=typeof e||Array.isArray(e)?{}:Object.fromEntries(Object.entries(e).filter(e=>"string"==typeof e[1]&&Boolean(e[1].trim())).map(([e,t])=>[e,t.trim()]))}export function readLegacySecretsFile(a){if(!e(a))return{};let f;try{const e=JSON.parse(t(a,"utf-8"));if(!function(e){if(!e||"object"!=typeof e)return!1;const t=e;return(2===t.version||1===t.version)&&"string"==typeof t.iv&&"string"==typeof t.salt&&"string"==typeof t.auth_tag&&"string"==typeof t.cipher_text}(e))throw new Error("invalid secret envelope");f=e}catch(e){throw new SecretStoreDecryptError(`Failed to read legacy secret envelope: ${a}`,e)}try{const e=Buffer.from(f.salt,"base64"),t=Buffer.from(f.iv,"base64"),a=Buffer.from(f.auth_tag,"base64"),p=Buffer.from(f.cipher_text,"base64"),y=1===f.version?16384:32768,u=s("aes-256-gcm",function(e,t){const s=`${o().username}:${r()}:${c}-secret-store`;return n(s,e,32,{N:t,maxmem:67108864})}(e,y),t);u.setAuthTag(a);const m=Buffer.concat([u.update(p),u.final()]);return function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{};const t=e,r=i(t.api_keys),o=t.tool_api_keys&&"object"==typeof t.tool_api_keys?t.tool_api_keys:{},s=Object.fromEntries(Object.entries(o).map(([e,t])=>[e,i(t)]).filter(([,e])=>Object.keys(e).length>0));return{...Object.keys(r).length>0?{api_keys:r}:{},...Object.keys(s).length>0?{tool_api_keys:s}:{}}}(JSON.parse(m.toString("utf-8")))}catch(e){throw new SecretStoreDecryptError(`Failed to decrypt legacy secret envelope: ${a} (host or user identity may have changed)`,e)}}
|
|
@@ -30,6 +30,14 @@ export declare class ToolManager {
|
|
|
30
30
|
private constructor();
|
|
31
31
|
static getInstance(): ToolManager;
|
|
32
32
|
isToolInstalled(toolName: string): boolean;
|
|
33
|
+
/** Whether the tool's command resolves in this process's PATH (what the user's terminal runs). */
|
|
34
|
+
isOnPath(toolName: string): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The vendor-layout launcher (`~/.local/bin/claude`, `~/.grok/bin/grok`) when it exists. A tool
|
|
37
|
+
* just installed there is installed even though the terminal that started us can't see it yet:
|
|
38
|
+
* `curl | sh` installers can only add the directory to PATH for new terminals.
|
|
39
|
+
*/
|
|
40
|
+
nativeLauncher(toolName: string): string | null;
|
|
33
41
|
installTool(toolName: string): Promise<void>;
|
|
34
42
|
getToolConfig(toolName: string): any;
|
|
35
43
|
updateToolConfig(toolName: string, config: any): void;
|
package/dist/lib/tool-manager.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{logger as i}from"../utils/logger.js";import{configManager as
|
|
1
|
+
import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{logger as i}from"../utils/logger.js";import{configManager as s}from"./config.js";import{getAdapter as l,listAdapters as a,TOOL_ADAPTERS as c}from"./tools/registry.js";import{backupBeforeWrite as d,listBackups as p,restoreBackup as u}from"./tools/backup.js";import{existsSync as m,rmSync as f}from"fs";import{join as g}from"path";import{toolHome as h}from"./tools/types.js";import{stringWidth as w}from"../utils/string-width.js";import{resolveModelCatalog as P}from"./model-catalog.js";import{compareVersions as y,getToolMinVersion as T}from"./model-registry.js";import{findInstalls as C,forgetInstalls as $,installLabel as k,mirrorInstallCommand as E}from"./tools/tool-installs.js";import{CLI_NAME as v}from"./brand.js";export{y as compareVersions};function O(o){const t=c[o];return{name:t.name,command:t.command,installCommand:t.installCommand,configPath:t.configPath,displayName:t.displayName,...t.hidden?{hidden:!0}:{}}}export const SUPPORTED_TOOLS=Object.fromEntries(Object.keys(c).map(o=>[o,O(o)]));export class ToolManager{static instance;constructor(){}static getInstance(){return ToolManager.instance||(ToolManager.instance=new ToolManager),ToolManager.instance}isToolInstalled(o){if(!SUPPORTED_TOOLS[o])return!1;const t=l(o);if(t?.isInstalled)try{return t.isInstalled()}catch{return!1}return this.isOnPath(o)||null!==this.nativeLauncher(o)}isOnPath(t){const n=SUPPORTED_TOOLS[t];if(!n)return!1;try{const t="win32"===process.platform?`where ${n.command}`:`which ${n.command}`;return o(t,{stdio:"pipe"}),!0}catch{return!1}}nativeLauncher(o){const t=l(o),n=t?.installSpec?.native?.binDir;if(!t||!n)return null;const e="win32"===process.platform?`${t.command}.exe`:t.command,r=g(h(),...n,e);return m(r)?r:null}async installTool(t){const i=SUPPORTED_TOOLS[t];if(!i)throw new Error(`Unknown tool: ${t}`);const s=l(t)?.installSpec,a=s?E(s):i.installCommand;console.log(r.gray("$ ")+r.white(a));try{return o(a,{stdio:"inherit"}),$(),void console.log(r.green("√ "+n.t("wizard.tool_installed")))}catch(o){if(console.log(r.red("× "+n.t("wizard.install_failed"))),!/EACCES|EPERM|permission denied/i.test(`${o?.message??""}${o?.stderr??""}`)&&243!==o?.status&&!a.startsWith("npm "))throw new Error(`Failed to install ${i.displayName}: ${o}`);console.log(r.yellow(" ! "+("win32"===process.platform?n.t("install.permission_windows",{command:a}):n.t("install.permission_unix",{command:a}))))}const{action:c}=await e.prompt([{type:"list",name:"action",message:n.t("install.what_next"),choices:[{name:n.t("install.installed_continue"),value:"continue"},{name:n.t("install.cancel_install"),value:"cancel"}]}]);if("cancel"===c)throw new Error(n.t("install.user_cancelled"));if($(),!this.isToolInstalled(t))throw console.log(r.red("× "+n.t("install.still_not_installed",{tool:i.displayName}))),new Error(`${i.displayName} is not installed`);console.log(r.green("√ "+n.t("install.verified_success",{tool:i.displayName})))}getToolConfig(o){const t=l(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{return t.getConfig()}catch(t){return i.warn(`Failed to read config for ${o}:`,t),i.logError(`ToolManager.getToolConfig(${o})`,t),null}}updateToolConfig(o,t){const n=l(o);if(!n)throw new Error(`Unknown tool: ${o}`);if(!n.updateConfig)throw new Error(`Tool ${o} does not support raw config updates`);n.updateConfig(t)}forceResetConfig(o){const t=l(o);if(!t)throw new Error(`Unknown tool: ${o}`);const n=t.forceResetPaths?t.forceResetPaths():this.backupPathsFor(t),e=[];for(const o of n)m(o)&&(d(o),f(o,{force:!0}),e.push(o));return e}loadPrivateConfig(o,t,n,e,r={}){const i=l(o);if(!i)throw new Error(`Unknown tool: ${o}`);r.force&&this.forceResetConfig(o),i.loadPrivateConfig({apiKey:t,baseUrl:s.getBaseUrl(),models:n,settings:s.getToolSettings(o),...e?{catalog:e}:{}})}async applyPrivateConfig(o,t,n,e={}){const r=l(o);if(!r)throw new Error(`Unknown tool: ${o}`);const i=r.wantsModelCatalog?await P(t):null;e.force?this.loadPrivateConfig(o,t,n,i??void 0,{force:!0}):i?this.loadPrivateConfig(o,t,n,i):this.loadPrivateConfig(o,t,n)}applyNotes(o){const t=l(o);if(!t)return[];const e=[];try{t.applyNotes&&e.push(...t.applyNotes())}catch(t){i.logError(`ToolManager.applyNotes(${o})`,t)}const r=this.outdatedVersion(o);if(r){e.push({kind:"action",text:n.t("tools.version_outdated",{current:r.current,min:r.min,upgrade:t.installSpec?`${v} upgrade ${o}`:t.upgradeCommand||t.installCommand})});for(const o of t.upgradeHints?.(r.min)??[])e.push({kind:"action",text:o})}const s=t.installSpec?C(t.installSpec):[];return s.length>1&&e.push({kind:"action",text:n.t("upgrade.duplicates_note",{count:String(s.length),active:k(s[0]),others:s.slice(1).map(k).join("、"),tool:o})}),e}printApplied(o,t=16){const n=SUPPORTED_TOOLS[o]?.displayName??o,e=this.applyNotes(o);for(const o of e.filter(o=>"detail"===o.kind))i.record(`${n}: ${o.text}`);const s=e.filter(o=>"summary"===o.kind).map(o=>o.text).join(";"),l=" ".repeat(Math.max(1,t-w(n)));console.log(r.green("√ "+n)+(s?l+s:""));for(const o of e.filter(o=>"action"===o.kind))console.log(r.yellow(" ! "+o.text))}installedVersion(o){const n=l(o);if(!n)return null;if(n.installSpec)return C(n.installSpec)[0]?.version??null;if(n.installedVersion)try{return n.installedVersion()}catch(t){return i.logError(`ToolManager.installedVersion(${o})`,t),null}if(n.isInstalled)return null;try{const o={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},e=`${("win32"===process.platform?t(`${n.command} --version`,{...o,shell:!0}):t(n.command,["--version"],o)).stdout??""}`.match(/(\d+)\.(\d+)\.(\d+)/);return e?e[0]:null}catch{return null}}outdatedVersion(o){const t=T(o);if(!t)return null;const n=this.installedVersion(o);return n&&y(n,t)<0?{current:n,min:t}:null}unloadPrivateConfig(o){const t=l(o);if(!t)throw new Error(`Unknown tool: ${o}`);t.unloadPrivateConfig()}async clearPinnedModels(o){const t=l(o);if(!t)throw new Error(`Unknown tool: ${o}`);if(s.setToolModel(o,null),!t.clearPinnedModels)return[];const n=s.getApiKeyForTool(o),e=t.wantsModelCatalog&&n?await P(n):null;return t.clearPinnedModels(e??void 0)}supportsClearPinnedModels(o){return Boolean(l(o)?.clearPinnedModels)}detectCurrentConfig(o){const t=l(o);if(!t)throw new Error(`Unknown tool: ${o}`);return t.detectCurrentConfig()}backupPathsFor(o){return o.backupPaths?o.backupPaths():[o.configPath]}listToolBackups(o){const t=l(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,backups:p(o)}))}restorePrivateConfig(o){const t=l(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,result:u(o)}))}getInstalledTools(){return Object.keys(SUPPORTED_TOOLS).filter(o=>this.isToolInstalled(o))}getSupportedTools(){return a().filter(o=>!o.hidden).map(o=>O(o.name))}isGitInstalled(){try{const t="win32"===process.platform?"where git":"which git";return o(t,{stdio:"pipe"}),!0}catch{return!1}}}export const toolManager=ToolManager.getInstance();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{chmodSync as t,existsSync as
|
|
1
|
+
import{chmodSync as t,existsSync as r,readFileSync as e}from"fs";import{join as n}from"path";import{i18n as o}from"../i18n.js";import{prettyModelName as i}from"../gateway-models.js";import{getAgyRules as a}from"../model-registry.js";import{logger as l}from"../../utils/logger.js";import{readPersistentEnvFile as s,removePersistentEnv as c,writePersistentEnv as u}from"../persistent-env.js";import{backupBeforeWrite as p,atomicWriteFile as g}from"./backup.js";import{findInstalls as d,mirrorInstallCommand as m}from"./tool-installs.js";import{toolHome as y}from"./types.js";import{brand as f,PROVIDER_KEY as v}from"../brand.js";const A="agy",_="AGY_LLM_GATEWAY_MODELS",h=["GEMINI_API_KEY","GOOGLE_GEMINI_BASE_URL","AGY_LLM_GATEWAY_URL","AGY_LLM_GATEWAY_API_KEY"],E="gemini",j=()=>n(y(),".gemini","antigravity-cli"),b=()=>n(j(),"settings.json"),w=()=>n(j(),`${v}.env`),I=()=>n(y(),".antigravity","settings.json"),K=f().installMirror?.agy,P={command:"agy",native:{binDir:"win32"===process.platform?["AppData","Local","agy","bin"]:[".local","bin"],updateArgs:["update"],dataDirs:[]},...K?{mirrorScript:{sh:`${K}/install.sh`,ps1:`${K}/install.ps1`}}:{}};function M(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}function G(t,n){if(!r(t))return{};const o=e(t,"utf-8");if(!o.trim())return{};try{const t=JSON.parse(o);if(!M(t))throw new Error(`${n} root must be an object`);return t}catch(t){throw new Error(`Existing ${n} cannot be parsed, back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}const L=()=>G(b(),"~/.gemini/antigravity-cli/settings.json"),C=()=>G(I(),"~/.antigravity/settings.json");function N(r,e,n){p(r),g(r,JSON.stringify(e,null,2)+"\n",n),void 0!==n&&t(r,n)}function S(t){return(t||"").replace(/\/+$/,"").replace(/\/v1(beta)?$/,"")}function Y(t){const r=a().gatewayModels,e=t?r.filter(r=>t.models.includes(r)):[];return e.length>0?e:r}const $=t=>i(t.replace(/-preview$/,""));function k(t){const r=t.gateway;return M(r)&&!0===r.enabled&&"string"==typeof r.apiKey&&r.apiKey.trim()&&"string"==typeof r.url?{url:r.url,apiKey:r.apiKey}:null}function O(t){const r=t.models;return M(r)&&Array.isArray(r.list)?r.list.map(t=>M(t)&&"string"==typeof t.modelId?t.modelId:"").filter(Boolean):[]}function x(){try{if(L().modelProvider!==E)return null}catch{return null}const t=s(w()),r=t.GEMINI_API_KEY;return r&&r.trim()?{apiKey:r,url:t.GOOGLE_GEMINI_BASE_URL??""}:null}function U(t,r,e){const n=L(),o=C();o.gateway={...M(o.gateway)?o.gateway:{},enabled:!0,url:r,apiKey:t,wireProtocol:"genai"},o.models={...M(o.models)?o.models:{},defaultModelId:e[0],list:e.map(t=>({modelId:t,displayName:$(t),supportsThinking:!0}))},N(I(),o,384),h.some(t=>void 0!==s(w())[t])&&c(A,w(),h);const i=u(A,w(),{[_]:e.join(",")}).rcFiles;for(const t of h)delete process.env[t];return n.modelProvider===E&&(delete n.modelProvider,N(b(),n)),i}let D=null,R=null;export const antigravityAdapter={name:"agy",displayName:"Antigravity CLI",command:"agy",installCommand:m(P),installSpec:P,configPath:I(),wantsModelCatalog:!0,loadPrivateConfig(t){L(),C();const r=Y(t.catalog);D=U(t.apiKey,S(t.baseUrl),r),R=r},unloadPrivateConfig(){try{const t=C();k(t)&&(delete t.gateway,delete t.models,N(I(),t,384))}catch(t){l.logError("antigravityAdapter.unloadPrivateConfig",t)}try{const t=L();t.modelProvider===E&&(delete t.modelProvider,N(b(),t))}catch(t){l.logError("antigravityAdapter.unloadPrivateConfig",t)}c(A,w(),[_,...h])},detectCurrentConfig(){try{const t=k(C());if(t)return{apiKey:t.apiKey}}catch{return{apiKey:null}}return{apiKey:x()?.apiKey??null}},listedModels(){try{const t=C();if(k(t))return O(t)}catch{return null}return x()?[]:null},refreshModelMenu(t){const r=C(),e=k(r)??x();if(!e)return;const n=Y(t.catalog),o=e.url||S(t.baseUrl);null!==k(r)&&O(r).join(",")===n.join(",")&&s(w())[_]===n.join(",")&&null===x()||U(e.apiKey,o,n)},getConfig(){try{return C()}catch(t){return l.logError("antigravityAdapter.getConfig",t),null}},applyNotes(){const t=[];if(R&&R.length>0){const r=R.map($);t.push({kind:"summary",text:o.t("tools.agy.menu_written",{count:String(r.length),list:r.join(o.t("tools.grok.list_separator")),default:r[0]})})}return null===D||0===d(P).length||t.push({kind:"action",text:o.t("tools.agy.effort_after_reopen")}),t},backupPaths:()=>[I(),b(),w()],forceResetPaths:()=>[w()]};
|
|
@@ -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 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 d}from"../gateway-models.js";import{toolHome as l}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,brandInstallScripts as C}from"./tool-installs.js";import{updateNativeFromMirror as _}from"./claude-native-mirror.js";import{brandEnv as j}from"../brand.js";const k=e(l(),".claude","settings.json"),y=e(l(),".claude.json");let P,S=null,v=()=>0===c("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore"}).status;export function setClaudeKeychainProbeForTests(e){v=e}export function claudeAccountLoginPresent(){const t=process.env.CLAUDE_CONFIG_DIR?.trim()||e(l(),".claude");if(u(e(t,".credentials.json")))return!0;if("darwin"!==process.platform||j("TEST_HOME"))return!1;try{return v()}catch{return!1}}function b(){try{const t=JSON.parse(p(e(l(),".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 w={command:"claude",npmPackage:"@anthropic-ai/claude-code",native:{binDir:[".local","bin"],updateArgs:["update"],dataDirs:[[".local","share","claude"]],mirrorUpdate:()=>_(b())},mirrorScript:C("claude-code"),brew:"claude-code"};export const claudeCodeAdapter={name:"claude-code",displayName:"Claude Code",command:"claude",installCommand:h(w),upgradeCommand:"claude update",installSpec:w,upgradeHints:e=>"stable"===b()?[n.t("tools.claude_code.stable_channel",{min:e})]:[],configPath:k,wantsModelCatalog:!0,loadPrivateConfig(e){a(k),a(y),P=x(e.catalog),o.loadPrivateConfig(e.apiKey,e.models,e.catalog?.models,P);const t=f(claudeCodeAdapter.installSpec)[0];S=t?g(t.path):null},unloadPrivateConfig(){a(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=>(a(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 n=o.getSettings(),s=t(n,x(e.catalog));JSON.stringify(s)!==JSON.stringify(n)&&(a(k),o.saveSettings(s))},applyNotes(){const e=[];S?.installed.length&&(e.push({kind:"summary",text:n.t("tools.claude_code.plugins_installed",{count:String(S.installed.length)})}),e.push({kind:"detail",text:S.installed.join(", ")})),("marketplace"===S?.skipped||S?.failed.length)&&e.push({kind:"action",text:n.t("tools.claude_code.plugins_failed")}),P&&P.length>0&&(e.push({kind:"summary",text:n.t("tools.claude_code.gateway_models",{count:String(P.length),vendors:d(P.map(e=>e.id)).join(" / ")})}),e.push({kind:"detail",text:P.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:()=>[k,y],forceResetPaths:()=>[k]};
|
|
@@ -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";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
|
+
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,brand as m,brandEnv as g,CLI_NAME as h}from"../brand.js";import{backupBeforeWrite as y,atomicWriteFile as k}from"./backup.js";import{toolHome as b}from"./types.js";import{canRestartDesktop as _,isDesktopRunning as A,restartDesktop as C,WINDOWS_PACKAGE_FAMILIES as D}from"./desktop-process.js";import{setUserRegistryElevated as E}from"./elevated-reg.js";import{UserActionNeeded as w}from"./types.js";import{baseModelId as M,isClaudeModel as v}from"../model-catalog.js";import{getDefaultModels as O}from"../model-registry.js";const S=f;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const P=/^[a-f0-9-]{36}$/;function x(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=b(),n=Boolean(g("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 D.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 L=()=>a(claudeDesktopUserDataDir(),"configLibrary"),j=()=>a(L(),"_meta.json"),I=e=>a(L(),`${e}.json`),T=()=>a(claudeDesktopUserDataDir(),"claude_desktop_config.json");function $(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return x(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 G(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),y(n),k(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){p.logError("claude-desktop.writeJson.chmod",e)}}function N(){const e=$(j());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>x(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function R(e){return e?.entries.find(e=>e.name===S&&P.test(e.id))}const K={opus:0,fable:1,sonnet:2,haiku:3};function U(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=U(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function F(e){return U(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>M(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(v)){i=[...new Set(t.models.filter(v).map(M))];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=M(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const a=e=>K[F(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=U(e),s=U(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(O()).map(e=>M(e||"")));for(const e of n){const t=F(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=F(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 H=null,B=null,J=null,W=null;function V(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 z={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 Z(e){return Object.fromEntries(Object.entries(z).filter(([t])=>!e(t)))}const X="SOFTWARE\\Policies\\Claude",q=`HKCU\\${X}`,Y="HKLM\\SOFTWARE\\Policies\\Claude",Q=`${h}-claude-policy.reg`,ee=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let te=ee;export function setRegRunnerForTests(e){te=e??ee}function oe(){return"win32"===process.platform}function ne(e){let t;try{t=te(["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 re(){if(null===ne(q))return;const e=a(claudeDesktopUserDataDir(),Q);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),y(e),te(["export",q,e,"/y"])}catch(e){p.logError("claude-desktop.snapshotPolicy",e)}}function se(e){re();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)];te(["add",q,"/v",t,"/t",e,"/d",n,"/f"])}}function ie(e){const t=ne(q);if(!t)return;re();let o=t.size;for(const n of e)t.has(n)&&(te(["delete",q,"/v",n,"/f"]),o-=1);o<=0&&te(["delete",q,"/f"])}const ae=[...Object.keys(V({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(z)];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 ne(Y)?Y: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 le=/\d+\.\d+\.\d+/;function ce(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 de="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",pe="darwin"!==process.platform&&"win32"!==process.platform||!m().installMirror?.claudeDesktop?"https://claude.ai/download":m().installMirror.claudeDesktop,ue="darwin"===process.platform?`open ${pe}`:"win32"===process.platform?`start ${pe}`:`xdg-open ${pe}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:de,installCommand:ue,configPath:j(),isInstalled:function(){const e=b();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"),...D.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(b(),"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?le.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(b(),"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 ce(t)}const o=D.map(e=>`'${e}'`).join(",");return ce(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=>le.exec(e)?.[0]??[]))}return null},runningApp:_()?{isRunning:A,restart:C}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const o=N()??{appliedId:"",entries:[]};let n=R(o);n||(n={id:l(),name:S},o.entries.push(n));const r=V(e);B=!0===r.disableDeploymentModeChooser,H={models:r.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const s=$(I(n.id))??{};G(I(n.id),{...Z(e=>e in s),...s,...r}),o.appliedId=n.id,G(j(),o);const i=$(T())??{};if("3p"!==i.deploymentMode&&G(T(),{...i,deploymentMode:"3p"}),J=null,W=null,oe()){const o=ne(q),n=ae.filter(e=>o?.has(e)),s={...Z(e=>o?.has(e)??!1),...r},i=!0===e.settings?.force_registry,l=!i&&function(){const e=!Boolean(g("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:a(b(),"AppData","Local");return!!t(a(e,"AnthropicClaude"))||D.some(o=>t(a(e,"Packages",o,"LocalCache","Local","Claude-3p")))}();try{l?ie(ae):se(s)}catch(e){p.logError("claude-desktop.policy",e),J=e instanceof Error?e.message.trim():String(e),(n.length>0||i)&&(W=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=W;return e?{prompt:u.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!E(X,e.values,e.deleteKey))return!1;const t=ne(q),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(W=null,J=null),o}}:null},unloadPrivateConfig(){if(oe())try{ie(ae)}catch(e){p.logError("claude-desktop.removePolicy",e)}const e=N(),t=R(e);if(!e||!t)return;y(I(t.id)),s(I(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(y(j()),s(j(),{force:!0})):G(j(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=N(),t=R(e);if(!t||e?.appliedId!==t.id)return null;const o=$(I(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=N(),o=R(t);if(!o||t?.appliedId!==o.id)return;const n=$(I(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog);if(JSON.stringify(n.inferenceModels)!==JSON.stringify(r)){if(oe()&&ne(q)?.has("inferenceModels"))try{se({inferenceModels:r})}catch(e){throw p.logError("claude-desktop.refreshModelMenu registry",e),new w(u.t("tools.claude_desktop.refresh_needs_admin"))}G(I(o.id),{...n,inferenceModels:r})}},detectCurrentConfig(){try{if(oe()){const e=ne(q)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=R(N());if(!e)return{apiKey:null};const t=$(I(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=N(),t=R(e);return{meta:e,applied:t?$(I(t.id)):null,desktop:$(T()),...oe()?{policy:Object.fromEntries(ne(q)??[])}:{}}}catch(e){return p.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;oe()&&ne(q)?.has("inferenceModels")&&(re(),te(["delete",q,"/v","inferenceModels","/f"]),e=!0);const t=R(N()),o=t?$(I(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;G(I(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(H&&H.models.length>0){const{models:t,source:o,groups:n}=H;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!==B&&e.push({kind:"detail",text:u.t(B?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),_()&&!A()||e.push({kind:"action",text:u.t("tools.claude_desktop.restart_hint")}),W?(e.push({kind:"action",text:u.t(`tools.claude_desktop.policy_stale_${W.action}`)}),e.push({kind:"detail",text:J??""})):J?(e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:J})):oe()&&e.push({kind:"detail",text:u.t("tools.claude_desktop.registry_written",{key:q})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:u.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[j(),T()];try{const t=R(N());t&&e.push(I(t.id))}catch{}return e},backupPaths(){const e=[j(),T()];oe()&&e.push(a(claudeDesktopUserDataDir(),Q));try{const t=R(N());t&&e.push(I(t.id))}catch{}return e}};
|
|
@@ -8,20 +8,15 @@
|
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
10
|
* Where the plugins come from, probed in this order before anything is added: the
|
|
11
|
-
* daily CNB
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* `claude-plugins-official` for github.com/anthropics/; plugin names are the same.
|
|
11
|
+
* brand's daily CNB copies (`pluginMarketplaces` in the brand file; reachable in and outside
|
|
12
|
+
* mainland China), else Anthropic's GitHub repo. A copy needs its own marketplace name because
|
|
13
|
+
* Claude Code reserves `claude-plugins-official` for github.com/anthropics/; plugin names are the same.
|
|
15
14
|
*/
|
|
16
|
-
export declare const PLUGIN_SOURCES:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
readonly name: "claude-plugins-official";
|
|
22
|
-
readonly add: "anthropics/claude-plugins-official";
|
|
23
|
-
readonly probe: "https://github.com/anthropics/claude-plugins-official.git";
|
|
24
|
-
}];
|
|
15
|
+
export declare const PLUGIN_SOURCES: ReadonlyArray<{
|
|
16
|
+
name: string;
|
|
17
|
+
add: string;
|
|
18
|
+
probe: string;
|
|
19
|
+
}>;
|
|
25
20
|
export declare const OFFICIAL_PLUGINS: string[];
|
|
26
21
|
export interface PluginInstallResult {
|
|
27
22
|
installed: string[];
|
|
@@ -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=[
|
|
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";import{brandEnv as r,brand as l}from"../brand.js";export const PLUGIN_SOURCES=[...l().pluginMarketplaces,{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 a="official_plugins_offered";let d=(t,s)=>{const l=e(t,s,{env:r("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},c=t=>0===e("git",["ls-remote","--heads",t],{timeout:8e3,windowsHide:!0,stdio:"ignore"}).status;export function setClaudePluginRunnerForTests(e){d=e}export function setPluginSourceProbeForTests(e){c=e}export function installOfficialPlugins(e){if("1"===r("SKIP_CLAUDE_PLUGINS"))return{installed:[],failed:[],skipped:"disabled"};const o=s.getToolSetting("claude-code",a),l=new Set("string"==typeof o?o.split(",").filter(Boolean):[]),p=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}}(),u=e=>p.has(e),f=OFFICIAL_PLUGINS.filter(e=>!l.has(e)&&!u(e));if(0===f.length)return{installed:[],failed:[],skipped:null};const m=PLUGIN_SOURCES.find(e=>c(e.probe));if(!m)return{installed:[],failed:[],skipped:"marketplace"};d(e,["plugin","marketplace","add",m.add]);const g={installed:[],failed:[],skipped:null,source:m.name};for(const t of f)d(e,["plugin","install",`${t}@${m.name}`])?(g.installed.push(t),l.add(t)):g.failed.push(t);for(const e of OFFICIAL_PLUGINS)u(e)&&l.add(e);return s.setToolSetting("claude-code",a,[...l].join(",")),g}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type GatewayModelSpec } from '../model-registry.js';
|
|
2
2
|
type Dict = Record<string, unknown>;
|
|
3
|
-
export declare const CODEX_CATALOG_FILE
|
|
3
|
+
export declare const CODEX_CATALOG_FILE: string;
|
|
4
4
|
export declare const codexCatalogPath: () => string;
|
|
5
5
|
/** The catalog built into the installed Codex binary; null when no binary answers. */
|
|
6
6
|
export declare function loadBundledCodexModels(): Dict[] | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{existsSync as e,readFileSync as o}from"fs";import{dirname as n,join as i}from"path";import{fileURLToPath as s}from"url";import{logger as r}from"../../utils/logger.js";import{getCodexRules as l,compareVersions as u}from"../model-registry.js";import{autoCompactTokens as a,modelBlurb as d,prettyModelName as c}from"../gateway-models.js";import{toolHome as p}from"./types.js";const
|
|
1
|
+
import{spawnSync as t}from"child_process";import{existsSync as e,readFileSync as o}from"fs";import{dirname as n,join as i}from"path";import{fileURLToPath as s}from"url";import{logger as r}from"../../utils/logger.js";import{getCodexRules as l,compareVersions as u}from"../model-registry.js";import{autoCompactTokens as a,modelBlurb as d,prettyModelName as c}from"../gateway-models.js";import{toolHome as p}from"./types.js";import{brandEnv as _,PROVIDER_KEY as m}from"../brand.js";const f=n(s(import.meta.url));export const CODEX_CATALOG_FILE=`${m}-model-catalog.json`;export const codexCatalogPath=()=>i(p(),".codex",CODEX_CATALOG_FILE);function x(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}function w(t){try{const e=JSON.parse(t),o=x(e)&&Array.isArray(e.models)?e.models.filter(x):[];return o.length>0?o:null}catch{return null}}export function loadBundledCodexModels(){for(const o of function(){const t=_("CODEX_BIN");if(void 0!==t)return t.trim()?[t.trim()]:[];const e=["codex"];if("darwin"===process.platform)for(const t of["/Applications",i(p(),"Applications")])e.push(i(t,"ChatGPT.app/Contents/Resources/codex-cli/bin/codex")),e.push(i(t,"Codex.app/Contents/Resources/codex"));return e}()){if("codex"!==o&&!e(o))continue;const n={encoding:"utf-8",timeout:2e4,maxBuffer:67108864,windowsHide:!0,stdio:["ignore","pipe","pipe"]},i="win32"===process.platform&&"codex"===o?t("codex debug models --bundled",{...n,shell:!0}):t(o,["debug","models","--bundled"],n);if(0===i.status&&i.stdout){const t=w(i.stdout);if(t)return t}(i.error||0!==i.status)&&r.logError("loadBundledCodexModels",i.error??new Error(`${o} exited ${i.status}`))}return null}export function loadPreviousCodexModels(){const t=g()?.filter(t=>!h(t));return t&&t.length>0?t:null}export function previousGatewayModelIds(){return(g()??[]).filter(h).map(t=>String(t.slug))}function g(){return e(codexCatalogPath())?w(o(codexCatalogPath(),"utf-8")):null}function h(t){return"number"==typeof t.priority&&t.priority>=1e3}let y=null;function b(){if(null!==y)return y;const t=[i(f,"..","..","..","codex-base-instructions.md"),i(f,"..","..","codex-base-instructions.md"),i(f,"codex-base-instructions.md")],n=t.find(t=>e(t));if(!n)throw new Error(`codex-base-instructions.md not found, searched: ${t.join(", ")}`);return y=o(n,"utf-8"),y}function C(t){return"number"==typeof t&&Number.isFinite(t)&&t>0?t:void 0}function v(t,e,o,n){const i=o?t:Math.min(t,e);return{window:i,compact:a(i,n)}}function M(t,e,o,n){const{standardContextWindow:i}=l();let s=C(t.contextWindow)??i;n&&t.id.startsWith("claude-")&&(s=n.has(t.id)?Math.max(s,1e6):Math.min(s,2e5));const{window:r,compact:u}=v(s,i,o,C(t.autoCompactTokens));return{slug:t.id,display_name:t.name||c(t.id),description:d(t.description,{millionContext:r>=1e6})??null,supported_reasoning_levels:[],shell_type:"unified_exec",visibility:"list",supported_in_api:!0,priority:e,additional_speed_tiers:[],service_tiers:[],availability_nux:null,upgrade:null,model_messages:{instructions_template:b()},base_instructions:b(),supports_reasoning_summaries:!0,supports_parallel_tool_calls:!1,prefer_websockets:!1,include_skills_usage_instructions:!1,include_plugin_usage_instructions:!1,include_apps_usage_instructions:!1,default_reasoning_summary:"auto",support_verbosity:!1,default_verbosity:null,apply_patch_tool_type:null,web_search_tool_type:"text",truncation_policy:{mode:"bytes",limit:1e4},supports_image_detail_original:!1,context_window:r,max_context_window:r,auto_compact_token_limit:u,effective_context_window_percent:95,experimental_supported_tools:[],input_modalities:["text","image"],supports_search_tool:!1,supports_experimental_context:!1,use_responses_lite:!1,supports_reasoning_effort_updates:!1,node_repl_auto_review_required:!1,node_repl_disabled:!1}}function A(t,e,o){if("list"!==t.visibility)return t;const n=C(t.context_window);if(!n)return t;const i=C(t.max_context_window)??n,s=o?Math.min(C(e?.contextWindow)??i,i):n,{window:r,compact:l}=v(s,n,!0,C(e?.autoCompactTokens));return{...t,context_window:r,auto_compact_token_limit:l}}export function buildCodexCatalog(t){const{bundled:e,specs:o,oneMillion:n,selectedModel:i}=t,s=t.claudeOneMillion?new Set(t.claudeOneMillion):void 0,r=t.keyModels?new Set(t.keyModels):null,l=new Set(t.gatewayAvailable),a=t=>!r||r.has(t)||t===i,d=t=>l.has(t)||t===i,c=new Map(o.map(t=>[t.id,t])),p=[],_=new Set;for(const t of e){const e="string"==typeof t.slug?t.slug:"";e&&!_.has(e)&&("list"!==t.visibility||a(e))&&(_.add(e),p.push(A(t,c.get(e),n)))}const m=[...o];i&&!c.has(i)&&m.push({id:i});const f=function(t){const e=new Map;for(const o of t){const t=/^claude-([a-z]+)-(.+)$/.exec(o);if(!t)continue;const n=t[2].split("-").filter(t=>/^\d{1,2}$/.test(t)).join("."),i=e.get(t[1]);(!i||u(n,i.version)>0)&&e.set(t[1],{id:o,version:n})}return new Set([...e.values()].map(t=>t.id))}(m.map(t=>t.id).filter(d));for(const t of m)!_.has(t.id)&&d(t.id)&&(t.id.startsWith("claude-")&&!f.has(t.id)&&t.id!==i||(_.add(t.id),p.push(M(t,1e3+p.length,n,s))));return{models:p}}
|
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 f,previousGatewayModelIds as g}from"./codex-catalog.js";import{gatewayModelSpecs as x,modelFamily as y}from"../gateway-models.js";import{mirrorInstallCommand as b,
|
|
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 f,previousGatewayModelIds as g}from"./codex-catalog.js";import{gatewayModelSpecs as x,modelFamily as y}from"../gateway-models.js";import{mirrorInstallCommand as b,brandInstallScripts as h}from"./tool-installs.js";const k=()=>o(d(),".codex"),j=()=>o(k(),"config.toml"),w=()=>o(k(),"auth.json"),O="OPENAI_API_KEY",C="custom",v=1e6,M=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(j()))return{};const o=t(j(),"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(w()))return{};try{const e=JSON.parse(t(w(),"utf-8"));return E(e)?e:{}}catch{return{}}}function P(e){const t=e.profiles;if(E(t)){for(const[e,o]of Object.entries(t))E(o)&&2===Object.keys(o).length&&o.model_provider===C&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let T=null;function I(o,n,i){const s=!1!==n.settings?.one_million_context;!function(e){e.model_context_window===v&&delete e.model_context_window,e.model_auto_compact_token_limit===M&&delete e.model_auto_compact_token_limit}(o);const d=_()??f();if(!d)return r.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),T="skipped",o.model_catalog_json===p()&&delete o.model_catalog_json,void(s&&(o.model_context_window=v,o.model_auto_compact_token_limit=M));const c=n.catalog,m=u({bundled:d,specs:x("codex",c?.clientModels),...c?{keyModels:c.models}:{},gatewayAvailable:c?.models??g(),oneMillion:s,selectedModel:i,..."gateway"===c?.oneMillionSource?{claudeOneMillion:c.oneMillion}:{}});T={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");I(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},i);const s=n.stringify(o);s!==r&&(l(j()),a(j(),s))}const L={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(L),installSpec:L,configPath:j(),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"===T)return[{kind:"action",text:i.t("tools.codex.catalog_skipped")}];if(!T)return[];const e=new Map;for(const t of T.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(T.listed.length),breakdown:t})},{kind:"detail",text:T.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=C,d.model_reasoning_effort="high",I(d,e,r);const u=N(d,"model_providers"),p=E(u[C])?{...u[C]}:{};delete p.env_key;const{experimental_bearer_token:_,...f}=p;u[C]={...f,name:"custom",wire_api:"responses",requires_openai_auth:!0,base_url:i},P(d),N(N(d,"tui"),"model_availability_nux")[r]=4;const g=N(d,"features");g.goals=!0,g.js_repl=!1,l(j()),a(j(),n.stringify(d)),function(e){const t=e.trim();if(!t)return;const o={...A(),auth_mode:"apikey",[O]:t};l(w()),a(w(),JSON.stringify(o,null,2)+"\n")}(e.apiKey)},unloadPrivateConfig(){if(!e(j()))return;let t;try{t=S()}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,P(t),l(j()),a(j(),n.stringify(t))},detectCurrentConfig(){const e=A()[O];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return S()}catch(e){return r.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[j(),w(),p()]};export function codexAuthProblem(){try{const e=S(),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=A();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
|
@@ -1 +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
|
|
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";import{CLI_NAME as u}from"../brand.js";function f(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])=>`${f(r)}=${null===e?"-":function(r){return"boolean"==typeof r?"dword:"+(r?"00000001":"00000000"):"number"==typeof r?`dword:${(r>>>0).toString(16).padStart(8,"0")}`:f("string"==typeof r?r:JSON.stringify(r))}(e)}`).join("\r\n")}\r\n`}let d=()=>{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){d=r,l=e}export function setUserRegistryElevated(r,s,f=!1){const c=d();if(!c)return!1;const m=e(i(n(),`${u}-reg-`)),a=i(m,`${u}.reg`);try{return o(a,Buffer.concat([Buffer.from([255,254]),Buffer.from(buildRegFile(c,r,s,f),"utf16le")])),l(a)}finally{t(m,{recursive:!0,force:!0})}}
|
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 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
|
|
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";import{brandInstallScripts as k,mirrorInstallCommand as h}from"./tool-installs.js";const b=()=>o(o(d(),".grok"),"config.toml"),_=i,j=`${i}-`,w=["low","medium","high","xhigh"];let v=null;const C=e=>`${j}${e}`,x=e=>e===_||e.startsWith(j),M={command:"grok",npmPackage:"@xai-official/grok",mirrorScript:k("grok"),native:{binDir:[".grok","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".grok","downloads"]]}};function A(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function E(e,t){return A(e[t])||(e[t]={}),e[t]}function S(){if(!e(b()))return{};const o=t(b(),"utf-8");if(!o.trim())return{};try{const e=r.parse(o);if(!A(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 O(e){return A(e.model)?Object.entries(e.model).filter(e=>x(e[0])&&A(e[1])):[]}function P(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 N(e,t,o){E(e,"endpoints").models_base_url=m(t.baseUrl);const r=E(e,"model"),n=new Map(O(e));for(const e of n.keys())delete r[e];for(const e of o){const o=C(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:h(M),installSpec:M,configPath:b(),wantsModelCatalog:!0,loadPrivateConfig(e){const t=S(),o=a(e.models,c("grok")),n=P(e,o);N(t,e,n);const i=e=>e.name??y(e.id);v={names:n.map(i),defaultName:i(n.find(e=>e.id===o))},E(t,"models").default=C(o),s(b()),l(b(),r.stringify(t))},unloadPrivateConfig(){if(!e(b()))return;let t;try{t=S()}catch(e){return void n.logError("grokAdapter.unloadPrivateConfig",e)}if(A(t.model)){for(const[e]of O(t))delete t.model[e];0===Object.keys(t.model).length&&delete t.model}A(t.models)&&"string"==typeof t.models.default&&x(t.models.default)&&(delete t.models.default,0===Object.keys(t.models).length&&delete t.models),A(t.endpoints)&&(delete t.endpoints.models_base_url,0===Object.keys(t.endpoints).length&&delete t.endpoints),s(b()),l(b(),r.stringify(t))},detectCurrentConfig(){try{const e=S(),t=O(e),o=A(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=O(S());return e.length>0?e.map(([,e])=>String(e.model)):null}catch{return null}},refreshModelMenu(e){const t=S(),o=E(t,"models"),n="string"==typeof o.default?o.default:void 0,i=n?O(t).find(([e])=>e===n)?.[1].model:void 0,d="string"==typeof i&&n!==_&&e.catalog.models.includes(i)?i:a(e.models,c("grok")),m=r.stringify(t);N(t,e,P(e,d)),(void 0===n||x(n))&&(o.default=C(d)),r.stringify(t)!==m&&(s(b()),l(b(),r.stringify(t)))},applyNotes:()=>v?[{kind:"summary",text:f.t("tools.grok.menu_written",{count:String(v.names.length),list:v.names.join(f.t("tools.grok.list_separator")),default:v.defaultName})}]:[],getConfig(){try{return S()}catch(e){return n.logError("grokAdapter.getConfig",e),null}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as r}from"fs";import{join as o}from"path";import{logger as t}from"../../utils/logger.js";import{PROVIDER_KEY as n}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as a,toolHome as i,withV1 as d}from"./types.js";import{getToolDefaultModel as m}from"../model-registry.js";const p=()=>o(o(i(),".openclaw"),"openclaw.json");function c(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function f(){if(!e(p()))return{};const o=r(p(),"utf-8");if(!o.trim())return{};const t=JSON.parse(o);if(!c(t))throw new Error("openclaw.json root must be a JSON object");return t}export const openclawAdapter={name:"openclaw",displayName:"OpenClaw",command:"openclaw",installCommand:"npm install -g openclaw",hidden:!0,configPath:p(),loadPrivateConfig(e){let r;try{r=f()}catch(e){throw new Error(`Existing ~/.openclaw/openclaw.json cannot be parsed, back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}const o=c(r.models)?r.models:r.models={};o.mode||(o.mode="merge");const t=c(o.providers)?o.providers:o.providers={},i=c(t[n])?{...t[n]}:{},u=a(e.models,m("openclaw"))||function(e){const r=c(e.agents)?e.agents:{},o=c(r.defaults)?r.defaults:{},t=c(o.model)?o.model:{},s=`${n}/`;if("string"==typeof t.primary&&t.primary.startsWith(s))return t.primary.slice(s.length);const l=c(e.models)?e.models:{},a=c(l.providers)?l.providers:{},i=c(a
|
|
1
|
+
import{existsSync as e,readFileSync as r}from"fs";import{join as o}from"path";import{logger as t}from"../../utils/logger.js";import{PROVIDER_KEY as n}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as a,toolHome as i,withV1 as d}from"./types.js";import{getToolDefaultModel as m}from"../model-registry.js";const p=()=>o(o(i(),".openclaw"),"openclaw.json");function c(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function f(){if(!e(p()))return{};const o=r(p(),"utf-8");if(!o.trim())return{};const t=JSON.parse(o);if(!c(t))throw new Error("openclaw.json root must be a JSON object");return t}export const openclawAdapter={name:"openclaw",displayName:"OpenClaw",command:"openclaw",installCommand:"npm install -g openclaw",hidden:!0,configPath:p(),loadPrivateConfig(e){let r;try{r=f()}catch(e){throw new Error(`Existing ~/.openclaw/openclaw.json cannot be parsed, back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}const o=c(r.models)?r.models:r.models={};o.mode||(o.mode="merge");const t=c(o.providers)?o.providers:o.providers={},i=c(t[n])?{...t[n]}:{},u=a(e.models,m("openclaw"))||function(e){const r=c(e.agents)?e.agents:{},o=c(r.defaults)?r.defaults:{},t=c(o.model)?o.model:{},s=`${n}/`;if("string"==typeof t.primary&&t.primary.startsWith(s))return t.primary.slice(s.length);const l=c(e.models)?e.models:{},a=(c(l.providers)?l.providers:{})[n],i=c(a)?a:null;return i&&Array.isArray(i.models)&&c(i.models[0])&&"string"==typeof i.models[0].id?i.models[0].id:""}(r);t[n]={...i,baseUrl:d(e.baseUrl),api:"openai-completions",apiKey:e.apiKey,models:[{id:u,name:u}]};const y=c(r.agents)?r.agents:r.agents={},g=c(y.defaults)?y.defaults:y.defaults={},w=c(g.model)?g.model:g.model={},h=`${n}/${u}`;w.primary=h;const v=c(g.models)?g.models:g.models={};Object.prototype.hasOwnProperty.call(v,h)||(v[h]={}),s(p()),l(p(),JSON.stringify(r,null,2))},unloadPrivateConfig(){if(!e(p()))return;let r;try{r=f()}catch(e){return void t.logError("openclawAdapter.unloadPrivateConfig",e)}const o=c(r.models)?r.models:null;o&&c(o.providers)&&delete o.providers[n];const a=c(r.agents)?r.agents:null,i=a&&c(a.defaults)?a.defaults:null,d=i&&c(i.model)?i.model:null,m=`${n}/`;if(d&&"string"==typeof d.primary&&d.primary.startsWith(m)&&delete d.primary,i&&c(i.models))for(const e of Object.keys(i.models))e.startsWith(m)&&delete i.models[e];s(p()),l(p(),JSON.stringify(r,null,2))},detectCurrentConfig(){try{const e=f(),r=c(e.models)?e.models:{},o=(c(r.providers)?r.providers:{})[n],t=c(o)?o:null,s=t&&"string"==typeof t.apiKey?t.apiKey:null;return{apiKey:s&&s.trim()?s:null}}catch{return{apiKey:null}}},getConfig(){try{return f()}catch(e){return t.logError("openclawAdapter.getConfig",e),null}}};
|
|
@@ -50,10 +50,10 @@ export interface ToolInstall {
|
|
|
50
50
|
/** npmmirror carries the same packages (including the per-platform native binaries) and is reachable from mainland China. */
|
|
51
51
|
export declare const NPM_MIRROR = "https://registry.npmmirror.com";
|
|
52
52
|
/** VibeAPI's install scripts on CNB (cnb.cool/vibeapi/install): native installs laid out from npmmirror. */
|
|
53
|
-
export declare function
|
|
53
|
+
export declare function brandInstallScripts(tool: string): {
|
|
54
54
|
sh: string;
|
|
55
55
|
ps1: string;
|
|
56
|
-
};
|
|
56
|
+
} | undefined;
|
|
57
57
|
export declare function npmMirrorInstallCommand(spec: ToolInstallSpec): string;
|
|
58
58
|
/** The China-reachable install command: our install script when there is one, otherwise npm from npmmirror. */
|
|
59
59
|
export declare function mirrorInstallCommand(spec: ToolInstallSpec): string;
|