@vibeapi/cli 0.0.157 → 0.0.159
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/client-config.snapshot.json +1330 -57
- package/components.json +14 -0
- package/dist/client-config.snapshot.json +1330 -57
- package/dist/commands/setup.d.ts +8 -0
- package/dist/commands/setup.js +1 -1
- package/dist/components.json +14 -0
- package/dist/lib/api-validator.d.ts +5 -1
- package/dist/lib/api-validator.js +1 -1
- package/dist/lib/client-config-sync.d.ts +1 -0
- package/dist/lib/client-config-sync.js +1 -1
- package/dist/lib/client-config.d.ts +29 -0
- package/dist/lib/client-config.js +1 -1
- package/dist/lib/gateway-models.d.ts +5 -3
- package/dist/lib/gateway-models.js +1 -1
- package/dist/lib/model-catalog.d.ts +2 -0
- package/dist/lib/model-catalog.js +1 -1
- package/dist/lib/model-registry.d.ts +9 -1
- package/dist/lib/program.js +1 -1
- package/dist/lib/tools/claude-code.js +1 -1
- package/dist/lib/tools/codebuddy-models.d.ts +62 -0
- package/dist/lib/tools/codebuddy-models.js +1 -0
- package/dist/lib/tools/codebuddy.d.ts +2 -0
- package/dist/lib/tools/codebuddy.js +1 -0
- package/dist/lib/tools/codex-catalog.d.ts +5 -0
- package/dist/lib/tools/codex-catalog.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/tools/grok.js +1 -1
- package/dist/lib/tools/registry.js +1 -1
- package/dist/lib/tools/workbuddy.d.ts +2 -0
- package/dist/lib/tools/workbuddy.js +1 -0
- package/dist/locales/en_US.json +16 -2
- package/dist/locales/zh_CN.json +16 -2
- package/dist/models.json +3 -1
- package/models.json +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as e,readFileSync as t}from"fs";import{BRAND_NAME as r}from"../brand.js";import{gatewayModelSpecs as n,modelFamily as o,prettyModelName as i,vendorNames as s}from"../gateway-models.js";import{backupBeforeWrite as a,atomicWriteFile as p}from"./backup.js";import{withV1 as d}from"./types.js";export const CUSTOM_MODEL_PREFIX="custom-local:";const u="openai",l="openai-response",c=e=>!!e&&"object"==typeof e&&!Array.isArray(e);export const isOurEntry=e=>c(e)&&e.vendor===r;export function readModelsFile(r){if(!e(r))return{entries:[],wrap:e=>({models:e})};const n=t(r,"utf-8");if(!n.trim())return{entries:[],wrap:e=>({models:e})};let o;try{o=JSON.parse(n)}catch(e){throw new Error(`Existing ${r} cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}if(Array.isArray(o))return{entries:o,wrap:e=>e};if(c(o))return{entries:Array.isArray(o.models)?o.models:[],wrap:e=>({...o,models:e})};throw new Error(`Existing ${r} must hold a JSON object or array`)}export function writeModelsFile(r,n,o){const i=`${JSON.stringify(n.wrap(o),null,2)}\n`;e(r)&&t(r,"utf-8")===i||(a(r),p(r,i,384))}export const bareModelId=e=>e.replace(/\[[^\]]*\]$/,"");export function usesResponses(e){const t=e.capabilities?.toolCallEndpoints;if(t&&t.length>0)return t.includes(l)&&!t.includes(u);const r=e.endpointTypes;if(r&&r.length>0){if(r.includes(u))return!1;if(r.includes(l))return!0}return"gpt"===o(e.id)}function f(e){const t=e.endpointTypes;return!t||0===t.length||t.includes(u)||t.includes(l)}export function modelEntry(e,t,n,s=!1){const a=e.capabilities??{},p=usesResponses(e),u=o(e.id),l={id:e.id,name:s?e.id:e.name??i(e.id),vendor:r,url:p?d(t):`${d(t)}/chat/completions`,apiKey:n};p&&(l.api="openai-responses");const c=a.contextWindow??e.contextWindow;c&&(l.maxInputTokens=c);const f=a.maxOutput??e.maxOutputTokens;return f&&(l.maxOutputTokens=f),l.supportsToolCall=a.toolCall??!0,l.supportsImages=a.vision??"other"!==u,void 0!==a.reasoning&&(l.supportsReasoning=a.reasoning),a.reasoning&&a.reasoningEfforts&&(l.reasoning={...a.defaultReasoningEffort?{defaultEffort:a.defaultReasoningEffort}:{},supportedEfforts:a.reasoningEfforts}),l}export function menuSpecs(e,t){let r=n("codebuddy",e?.clientModels,e?.clientPersonal).filter(f);if(e){const n=new Set(e.models);r=r.filter(e=>n.has(e.id)),!r.some(e=>e.id===t)&&n.has(t)&&(r=[{id:t},...r])}else r.some(e=>e.id===t)||(r=[{id:t},...r]);const o=(e?.clientPersonal??[]).length>0,i=new Set,a=r.filter(e=>{if(o)return!0;const r=s([e.id])[0],n=!i.has(r);return i.add(r),e.id===t||!0===e.recommended||n}),p=a.findIndex(e=>e.id===t);return p>0?[a[p],...a.slice(0,p),...a.slice(p+1)]:a}export function mergeEntries(e,t,r,n,o=!1){const i=new Set(t.map(e=>e.id)),s=[],a=e.filter(e=>{if(isOurEntry(e))return!1;const t=c(e)&&"string"==typeof e.id?e.id:void 0;return!t||!i.has(t)||(s.push(t),!1)});return{entries:[...t.map(e=>modelEntry(e,r,n,o)),...a],replaced:s}}export function foreignIdsReplaced(e,t){const r=new Set(t.map(e=>e.id));return e.filter(e=>!isOurEntry(e)).filter(e=>c(e)&&"string"==typeof e.id&&r.has(e.id)).map(e=>String(e.id))}export function ourEntries(e){return e.filter(isOurEntry)}export function ourApiKey(e){const t=ourEntries(e)[0]?.apiKey;return"string"==typeof t&&t.trim()?t:null}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import{logger as r}from"../../utils/logger.js";import{i18n as d}from"../i18n.js";import{getToolDefaultModel as n}from"../model-registry.js";import{prettyModelName as i,vendorNames as s}from"../gateway-models.js";import{backupBeforeWrite as a,atomicWriteFile as l}from"./backup.js";import{CUSTOM_MODEL_PREFIX as c,bareModelId as u,foreignIdsReplaced as m,isOurEntry as p,menuSpecs as g,mergeEntries as f,ourApiKey as y,ourEntries as b,readModelsFile as h,writeModelsFile as j}from"./codebuddy-models.js";import{pickModel as C,toolHome as v}from"./types.js";const S=()=>process.env.CODEBUDDY_CONFIG_DIR?.trim()||o(v(),".codebuddy"),w=()=>o(S(),"models.json"),E=()=>o(S(),"settings.json"),N={command:"codebuddy",npmPackage:"@tencent-ai/codebuddy-code",brew:"codebuddy-code"};function P(){if(!e(E()))return{};const o=t(E(),"utf-8");if(!o.trim())return{};let r;try{r=JSON.parse(o)}catch(e){throw new Error(`Existing ${E()} cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}if(!(d=r)||"object"!=typeof d||Array.isArray(d))throw new Error(`Existing ${E()} must hold a JSON object`);var d;return r}function $(e){a(E()),l(E(),`${JSON.stringify(e,null,2)}\n`,384)}function _(e,t){return"string"==typeof e&&e.startsWith(c)&&t.has(e.slice(c.length))}const k=e=>u(C(e.models,n("codebuddy")));function x(e,t){return e.find(e=>e.id===t)??e[0]}let A=null;function O(e,t){const o=h(w()),{entries:r,replaced:d}=f(o.entries,t,e.baseUrl,e.apiKey);return j(w(),o,r),d}export const codebuddyAdapter={name:"codebuddy",displayName:"CodeBuddy Code",command:"codebuddy",installCommand:`npm install -g ${N.npmPackage}`,installSpec:N,get configPath(){return w()},wantsModelCatalog:!0,loadPrivateConfig(e){const t=k(e),o=g(e.catalog,t),r=P(),d=O(e,o),n=x(o,t);n&&(r.model=`${c}${n.id}`,$(r));const a=e=>e.name??i(e.id);A={names:o.map(a),vendors:s(o.map(e=>e.id)),defaultName:n?a(n):"",replaced:d}},unloadPrivateConfig(){let e;try{e=h(w())}catch(e){return void r.logError("codebuddyAdapter.unloadPrivateConfig",e)}const t=new Set(b(e.entries).map(e=>String(e.id)));t.size>0&&j(w(),e,e.entries.filter(e=>!p(e)));try{const e=P();_(e.model,t)&&(delete e.model,$(e))}catch(e){r.logError("codebuddyAdapter.unloadPrivateConfig",e)}},detectCurrentConfig(){try{return{apiKey:y(h(w()).entries)}}catch{return{apiKey:null}}},listedModels(){try{const e=b(h(w()).entries);return e.length>0?e.map(e=>String(e.id)):null}catch{return null}},refreshModelMenu(e){const t=h(w()),o=new Set(b(t.entries).map(e=>String(e.id))),r=P(),d=_(r.model,o)?String(r.model).slice(c.length):void 0,n=d&&e.catalog.models.includes(d)?d:k(e),i=g(e.catalog,n);O(e,i);const s=x(i,n);if(s&&(void 0===r.model||_(r.model,o))){const e=`${c}${s.id}`;r.model!==e&&(r.model=e,$(r))}},planNotes(){try{const e=h(w()),t=m(e.entries,g(void 0,n("codebuddy")));return t.length>0?[d.t("tools.codebuddy.replaces_models",{path:w(),list:t.join(d.t("tools.codebuddy.list_separator"))})]:[]}catch{return[]}},applyNotes(){if(!A)return[];const e=[{kind:"summary",text:d.t("tools.codebuddy.menu_written",{count:String(A.names.length),list:A.vendors.join(d.t("tools.codebuddy.list_separator")),default:A.defaultName})}];return A.replaced.length>0&&e.push({kind:"detail",text:d.t("tools.codebuddy.replaced_models",{tool:"codebuddy",list:A.replaced.join(d.t("tools.codebuddy.list_separator"))})}),e},backupPaths:()=>[w(),E()],forceResetPaths:()=>[w()],getConfig(){try{return{models:h(w()).entries,settings:P()}}catch(e){return r.logError("codebuddyAdapter.getConfig",e),null}}};
|
|
@@ -48,6 +48,11 @@ export interface BuildCodexCatalogOptions {
|
|
|
48
48
|
* table). When set, other Claude models get 200K whatever `models.json` says.
|
|
49
49
|
*/
|
|
50
50
|
claudeOneMillion?: string[];
|
|
51
|
+
/**
|
|
52
|
+
* The key's owner chose the `codex` list in the console: Codex's own GPT entries outside it
|
|
53
|
+
* stay out of the menu too (the selected model always stays).
|
|
54
|
+
*/
|
|
55
|
+
chosenGpt?: string[];
|
|
51
56
|
}
|
|
52
57
|
/**
|
|
53
58
|
* Catalog entries with every field an older Codex's own entries carry and they
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{existsSync as o,mkdtempSync as e,readFileSync as n,realpathSync as i,rmSync as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{existsSync as o,mkdtempSync as e,readFileSync as n,realpathSync as i,rmSync as s,statSync as r,writeFileSync as c}from"fs";import{tmpdir as l}from"os";import{delimiter as u,dirname as a,isAbsolute as d,join as p}from"path";import*as f from"@iarna/toml";import{fileURLToPath as m}from"url";import{logger as _}from"../../utils/logger.js";import{getCodexRules as x,compareVersions as g}from"../model-registry.js";import{autoCompactTokens as h,modelBlurb as w,prettyModelName as y}from"../gateway-models.js";import{codexHome as b,toolHome as v}from"./types.js";import{brandEnv as C,CLI_NAME as M,PROVIDER_KEY as j}from"../brand.js";const A=a(m(import.meta.url));export const CODEX_CATALOG_FILE=`${j}-model-catalog.json`;export const codexCatalogPath=()=>p(b(),CODEX_CATALOG_FILE);function O(){const t=C("CODEX_BIN");if(void 0!==t)return t.trim()?[t.trim()]:[];const o=["codex"];if("win32"===process.platform){const t=process.env.LOCALAPPDATA||p(v(),"AppData","Local");o.push(p(t,"Programs","OpenAI","Codex","bin","codex.exe"))}else o.push(p(v(),".local","bin","codex"));if("darwin"===process.platform)for(const t of["/Applications",p(v(),"Applications")])o.push(p(t,"ChatGPT.app/Contents/Resources/codex-cli/bin/codex")),o.push(p(t,"Codex.app/Contents/Resources/codex"));return o}function E(t){return!!t&&"object"==typeof t&&!Array.isArray(t)}function $(t){try{const o=JSON.parse(t),e=E(o)&&Array.isArray(o.models)?o.models.filter(E):[];return e.length>0?e:null}catch{return null}}function k(o,e,n){const i={encoding:"utf-8",timeout:2e4,maxBuffer:67108864,windowsHide:!0,stdio:["ignore","pipe","pipe"],...n?{env:n}:{}};return"win32"!==process.platform||"codex"!==o&&!/\.cmd$/i.test(o)?t(o,e,i):t(["codex"===o?"codex":`"${o}"`,...e].join(" "),{...i,shell:!0})}function P(t){const o=k(t,["debug","models","--bundled"]);if(0===o.status&&o.stdout){const t=$(o.stdout);if(t)return t}return(o.error||0!==o.status)&&_.logError("loadBundledCodexModels",o.error??new Error(`${t} exited ${o.status}`)),null}export function loadBundledCodexModels(t){if(t)return P(t);for(const t of O()){if("codex"!==t&&!o(t))continue;const e=P(t);if(e)return e}return null}function S(t){try{return r(t).isFile()}catch{return!1}}export function installedCodexBinaries(){const t=[],o=O();if(o.includes("codex")){const o="win32"===process.platform?["codex.exe","codex.cmd"]:["codex"];for(const e of(process.env.PATH??"").split(u))if(e&&d(e))for(const n of o)t.push(p(e,n))}t.push(...o.filter(t=>"codex"!==t));const e=new Set,n=[];for(const o of t){if(!S(o))continue;let t=o;try{t=i(o)}catch{}const s="win32"===process.platform?t.toLowerCase():t;e.has(s)||(e.add(s),n.push(o))}return n}export function codexBinaryVersion(t){const o=`${k(t,["--version"]).stdout??""}`.match(/(\d+)\.(\d+)\.(\d+)/);return o?o[0]:null}export function catalogRejections(t,o=installedCodexBinaries()){if(0===o.length)return[];const n=e(p(l(),`${M}-codex-`)),i=[];try{c(p(n,"config.toml"),f.stringify({model_catalog_json:t}));for(const t of o){const o=k(t,["debug","models"],{...process.env,CODEX_HOME:n});if(0===o.status)continue;const e=`${o.stderr??""}\n${o.stdout??""}`,s=e.split(/\r?\n/).find(t=>t.includes("model_catalog_json"));s?i.push({bin:t,version:codexBinaryVersion(t),error:s.trim()}):_.logError("catalogRejections",o.error??new Error(`${t} exited ${o.status}: ${e.trim().slice(0,500)}`))}}finally{s(n,{recursive:!0,force:!0})}return i}export function loadPreviousCodexModels(){const t=B()?.filter(t=>!L(t));return t&&t.length>0?t:null}export function previousGatewayModelIds(){return(B()??[]).filter(L).map(t=>String(t.slug))}function B(){return o(codexCatalogPath())?$(n(codexCatalogPath(),"utf-8")):null}function L(t){return"number"==typeof t.priority&&t.priority>=1e3}let W=null;function T(){if(null!==W)return W;const t=[p(A,"..","..","..","codex-base-instructions.md"),p(A,"..","..","codex-base-instructions.md"),p(A,"codex-base-instructions.md")],e=t.find(t=>o(t));if(!e)throw new Error(`codex-base-instructions.md not found, searched: ${t.join(", ")}`);return W=n(e,"utf-8"),W}function D(t){return"number"==typeof t&&Number.isFinite(t)&&t>0?t:void 0}function G(t,o,e,n){const i=e?t:Math.min(t,o);return{window:i,compact:h(i,n)}}function F(t,o,e,n){const{standardContextWindow:i}=x();let s=D(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:c}=G(s,i,e,D(t.autoCompactTokens));return{slug:t.id,display_name:t.name||y(t.id),description:w(t.description,{millionContext:r>=1e6})??null,supported_reasoning_levels:[],shell_type:"unified_exec",visibility:"list",supported_in_api:!0,priority:o,additional_speed_tiers:[],service_tiers:[],availability_nux:null,upgrade:null,model_messages:{instructions_template:T()},base_instructions:T(),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:c,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}}const I={supports_parallel_tool_calls:!0,supports_reasoning_summaries:!0};export function fillFromOlderEntries(t,o){const e=new Map(o.map(t=>[t.slug,t])),n=new Map;for(const t of o)for(const[o,e]of Object.entries(t))n.has(o)||n.set(o,e);return t.map(t=>{const o=e.get(t.slug),i={...t};for(const[t,e]of n)t in i||(i[t]=o&&t in o?o[t]:e);return i})}function R(t,o,e){if("list"!==(t=function(t){const o=Object.keys(I).filter(o=>!(o in t));return 0===o.length?t:{...t,...Object.fromEntries(o.map(t=>[t,I[t]]))}}(t)).visibility)return t;const n=D(t.context_window);if(!n)return t;const i=D(t.max_context_window)??n,s=e?Math.min(D(o?.contextWindow)??i,i):n,{window:r,compact:c}=G(s,n,!0,D(o?.autoCompactTokens));return{...t,context_window:r,auto_compact_token_limit:c}}function X(t,o){if(!t.startsWith("gpt-"))return;let e,n=4;for(const i of o){const o="string"==typeof i.slug?i.slug:"";if(!o.startsWith("gpt-")||"list"!==i.visibility)continue;let s=0;for(;s<o.length&&o[s]===t[s];)s++;s>n&&(e=i,n=s)}return e}function H(t,o,e,n){return R({...t,...Object.fromEntries(["slug","display_name","description","priority"].map(t=>[t,o[t]])),upgrade:null,availability_nux:null},e,n)}export function buildCodexCatalog(t){const{bundled:o,specs:e,oneMillion:n,selectedModel:i}=t,s=t.claudeOneMillion?new Set(t.claudeOneMillion):void 0,r=t.keyModels?new Set(t.keyModels):null,c=new Set(t.gatewayAvailable),l=t=>!r||r.has(t)||t===i,u=t=>c.has(t)||t===i,a=new Map(e.map(t=>[t.id,t])),d=t.chosenGpt?new Set(t.chosenGpt):null,p=t=>!!d&&t.startsWith("gpt-")&&!d.has(t)&&t!==i,f=[],m=new Set;for(const t of o){const o="string"==typeof t.slug?t.slug:"";o&&!m.has(o)&&("list"!==t.visibility||l(o)&&!p(o))&&(m.add(o),f.push(R(t,a.get(o),n)))}const _=[...e];i&&!a.has(i)&&_.push({id:i});const x=function(t){const o=new Map;for(const e of t){const t=/^claude-([a-z]+)-(.+)$/.exec(e);if(!t)continue;const n=t[2].split("-").filter(t=>/^\d{1,2}$/.test(t)).join("."),i=o.get(t[1]);(!i||g(n,i.version)>0)&&o.set(t[1],{id:e,version:n})}return new Set([...o.values()].map(t=>t.id))}(_.map(t=>t.id).filter(u));for(const t of _){if(m.has(t.id)||!u(t.id))continue;if(t.id.startsWith("claude-")&&!x.has(t.id)&&t.id!==i)continue;m.add(t.id);const e=F(t,1e3+f.length,n,s),r=X(t.id,o);f.push(r?H(r,e,t,n):e)}return{models:f}}
|
package/dist/lib/tools/codex.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,readdirSync as r,readFileSync as n,rmSync as s,statSync as i,writeFileSync as l}from"fs";import{join as a}from"path";import*as d from"@iarna/toml";import{logger as c}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{backupBeforeWrite as p,atomicWriteFile as m}from"./backup.js";import{codexHome as f,pickModel as _,toolHome as g,withV1 as x}from"./types.js";import{moveSessionsToProvider as h,NO_STATE_DB as y,runningCodexPids as k}from"../codex-sessions.js";import{codexFormat as b,codexRolloutFiles as v}from"../sessions/formats.js";import{getGatewayModelRules as w,getToolDefaultModel as j}from"../model-registry.js";import{ownsValue as S,takeField as C}from"../written-values.js";import{configManager as O}from"../config.js";import{maskHome as M,track as A}from"../telemetry.js";import{buildCodexCatalog as E,catalogRejections as N,codexCatalogPath as P,fillFromOlderEntries as T,installedCodexBinaries as D,loadBundledCodexModels as $,loadPreviousCodexModels as I,previousGatewayModelIds as L}from"./codex-catalog.js";import{gatewayModelSpecs as J,modelFamily as G}from"../gateway-models.js";import{isOurGatewayUrl as R,noteWrittenGatewayUrl as K}from"../gateway-addresses.js";import{findInstalls as X,mirrorInstallCommand as B,brandInstallScripts as U}from"./tool-installs.js";import{chatgptDesktopApp as W}from"./chatgpt-desktop.js";const q=()=>f(),z=()=>a(q(),"config.toml"),Y="sessions_move_declined",F=["browser_use","browser_use_external","computer_use"],H="desktop_features_restored";function Q(e){if(!0===O.getToolSetting("codex",H))return!1;const t=e.features,o=de(t)&&F.every(e=>!1===t[e]);if(O.setToolSetting("codex",H,!0),!o)return!1;for(const e of F)delete t[e];return!0}export function codexWorkModeOn(){try{const e=ue();return e.model_provider===te&&de(e.desktop)&&"STEPS_PROSE"===e.desktop.conversationDetailMode}catch{return!1}}function V(){try{if(de(ue().desktop))return!0}catch{}if("darwin"===process.platform)return["/Applications",a(g(),"Applications")].some(e=>["ChatGPT.app","Codex.app"].some(o=>t(a(e,o))));if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(g(),"AppData","Local"),"Packages");try{return r(e).some(e=>/^OpenAI\.(Codex|ChatGPT)/i.test(e))}catch{return!1}}return t("/usr/lib/chatgpt/ChatGPT")}export function codexConfigPath(){return z()}const Z=()=>a(q(),"auth.json"),ee="OPENAI_API_KEY",te="custom",oe="high",re=["gpt-5.5","gpt-5.6-sol","gpt-6-astra"],ne=["high","xhigh"],se={goals:!0,js_repl:!1};let ie=[];const le=1e6,ae=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function de(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function ce(e,t){return de(e[t])||(e[t]={}),e[t]}function ue(){if(!t(z()))return{};const e=n(z(),"utf-8");if(!e.trim())return{};try{const t=d.parse(e);if(!de(t))throw new Error("config.toml root must be a TOML table");return t}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 pe(){if(!t(Z()))return{};try{const e=JSON.parse(n(Z(),"utf-8"));return de(e)?e:{}}catch{return{}}}let me=null;function fe(e){const t=e.profiles;if(de(t)){for(const[e,o]of Object.entries(t))de(o)&&2===Object.keys(o).length&&o.model_provider===te&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let _e=null;const ge=()=>a(O.getConfigDir(),"codex-catalog-check.json");function xe(e){const o=P();t(o)&&n(o,"utf-8")===e||(p(o),m(o,e))}function he(t,r){if(0===r.length)return[];const s=function(t,o){const r=e("sha256").update(t);for(const e of o)try{const t=i(e);r.update(`\0${e}\0${t.size}\0${t.mtimeMs}`)}catch{r.update(`\0${e}`)}return r.digest("hex")}(t,r);if(function(e){try{return JSON.parse(n(ge(),"utf-8")).signature===e}catch{return!1}}(s))return[];const a=N(P(),r);return 0===a.length&&function(e){try{o(O.getConfigDir(),{recursive:!0}),l(ge(),JSON.stringify({signature:e})+"\n")}catch(e){c.logError("codexAdapter.rememberAccepted",e)}}(s),a}function ye(e,t,o){const r=!1!==t.settings?.one_million_context;!function(e){e.model_context_window===le&&delete e.model_context_window,e.model_auto_compact_token_limit===ae&&delete e.model_auto_compact_token_limit}(e);const n=()=>{e.model_catalog_json===P()&&delete e.model_catalog_json,r&&(e.model_context_window=le,e.model_auto_compact_token_limit=ae)},i=$()??I();if(!i)return c.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),_e="skipped",void n();const l=t.catalog,a=e=>E({bundled:e,specs:J("codex",l?.clientModels),...l?{keyModels:l.models}:{},gatewayAvailable:l?.models??L(),oneMillion:r,selectedModel:o,..."gateway"===l?.oneMillionSource?{claudeOneMillion:l.oneMillion}:{}}),d=e=>JSON.stringify(e,null,2)+"\n";let u=a(i);xe(d(u));const p=D(),m=he(d(u),p);if(m.length>0){const e=Date.now();let t=!1;for(const e of m){const o=$(e.bin);if(o){for(const e of[{models:T(u.models,o)},{models:T(a(o).models,o)}])if(xe(d(e)),0===he(d(e),p).length){u=e,t=!0;break}if(t)break}}if(A("codex-catalog",t?"fallback":"fail",{duration_ms:Date.now()-e,error:m[0].error,detail:{rejected_by:m.map(e=>({version:e.version,path:M(e.bin)}))}}),!t)return _e={rejectedBy:m[0]},s(P(),{force:!0}),void n()}_e={listed:u.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))},e.model_catalog_json=P()}export function codexCatalogRejection(){let e;try{e=ue()}catch{return null}return e.model_catalog_json===P()&&t(P())?N(P())[0]??null:null}export function setCodexOneMillionContext(e,t){const o=ue(),r=d.stringify(o),n="string"==typeof o.model?o.model:j("codex");ye(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},n);const s=d.stringify(o);s!==r&&(p(z()),m(z(),s))}const ke={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:U("codex"),brew:"codex"};function be(e){const t=de(e.model_providers)?e.model_providers[te]:void 0;if(!de(t))return null;const o="string"==typeof t.base_url?t.base_url.trim():"";return o&&!R(o)?o:null}let ve=null;function we(){if("skipped"===_e)return 0===X(ke).length?[]:[{kind:"action",text:u.t("tools.codex.catalog_skipped")}];if(!_e)return[];if("rejectedBy"in _e){const{bin:e,version:t}=_e.rejectedBy;return[{kind:"action",text:u.t("tools.codex.catalog_rejected",{path:e,version:t??"?"})}]}const e=new Map;for(const t of _e.listed)e.set(G(t.id),(e.get(G(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${u.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:u.t("tools.codex.catalog_written",{count:String(_e.listed.length),breakdown:t})},{kind:"detail",text:_e.listed.map(e=>e.name).join(", ")},...codexWorkModeOn()||V()?[{kind:"action",text:u.t(codexWorkModeOn()?"tools.codex.work_mode_on":"tools.codex.work_mode_hint")}]:[]]}export const codexAdapter={name:"codex",companionApps:[W],displayName:"Codex",command:"codex",installCommand:B(ke),installSpec:ke,configPath:z(),sessions:{format:b,files:()=>[...v(a(f(),"sessions")),...v(a(f(),"archived_sessions"))],resumeCommand:e=>({command:"codex",args:["resume",e]})},wantsModelCatalog:!0,listedModels(){if(ue().model_catalog_json!==P())return null;try{return(JSON.parse(n(P(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){if(ue().model_catalog_json!==P())return;setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog);const t=ue(),o=function(e,t){const o=de(e.model_providers)?e.model_providers[te]:void 0;return!(!de(o)||o.base_url!==t||!0===o.supports_standalone_web_search||(o.supports_standalone_web_search=!0,0))}(t,x(e.baseUrl));(Q(t)||o)&&(p(z()),m(z(),d.stringify(t)))},async followUp(){if(ue().model_provider!==te)return null;const e=await h(te,{dryRun:!0}),t=Math.max(e.moved.length,e.dbRows);if(0===t)return null;const o=O.getToolSettings("codex")[Y];if("number"==typeof o&&t<=o)return null;const r={count:String(t)};return k().length>0?{hint:u.t("tools.codex.sessions_hidden_running",r)}:{prompt:u.t("tools.codex.sessions_offer",r),hint:u.t("tools.codex.sessions_hidden",r),async run(){const e=await h(te),t=[...new Set(e.moved.map(e=>e.from))].join("、")||"-",o=String(Math.max(e.moved.length,e.dbRows)),r=[{kind:"summary",text:u.t("codex_sessions.moved",{count:o,from:t,target:te})},{kind:"summary",text:u.t("codex_sessions.backup",{dir:e.backupDir??""})}];return e.dbSkipped&&e.dbSkipped!==y&&r.push({kind:"action",text:u.t("codex_sessions.db_skipped",{reason:e.dbSkipped})}),r},decline(){O.setToolSetting("codex",Y,t)}}},applyNotes(){const e=[];return ve&&e.push({kind:"summary",text:u.t("tools.codex.provider_replaced",{url:ve})}),ie.length>0&&e.push({kind:"summary",text:u.t("tools.codex.replaced_user_settings",{values:ie.join(", ")})}),[...e,...we()]},planNotes(){let e;try{e=ue()}catch{return[]}const t=[],o=be(e);return o?t.push(u.t("tools.codex.plan_replace_provider",{url:o})):"string"==typeof e.model_provider&&e.model_provider!==te&&t.push(u.t("tools.codex.plan_switch_provider",{provider:e.model_provider})),t},loadPrivateConfig(e){const t=j("codex"),o=_(e.models,t),r=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,n=x(e.baseUrl),s=ue();ie=[];const i=w().retired,l=(e,t,o,r,n)=>{void 0===t||t===o||"string"==typeof t&&i.includes(t)||S(e,t,r)||ie.push(`${n} = ${String(t)}`),C(e,o)};l("codex.model",s.model,r,re,"model"),s.model=r,s.model_provider=te,l("codex.model_reasoning_effort",s.model_reasoning_effort,oe,ne,"model_reasoning_effort"),s.model_reasoning_effort=oe;const a="string"==typeof s.model?s.model:r;ye(s,e,a);const c=ce(s,"model_providers");ve=be(s),K(n);const u=de(c[te])?{...c[te]}:{};delete u.env_key;const{experimental_bearer_token:f,...g}=u;c[te]={...g,name:"custom",wire_api:"responses",requires_openai_auth:!0,supports_standalone_web_search:!0,base_url:n},fe(s),ce(ce(s,"tui"),"model_availability_nux")[a]=4;const h=ce(s,"features");for(const[e,t]of Object.entries(se))l(`codex.features.${e}`,void 0===h[e]?void 0:String(h[e]),String(t),[String(t)],`features.${e}`),h[e]=t;Q(s),p(z()),m(z(),d.stringify(s)),function(e){const t=e.trim();if(!t)return;const o={...pe(),auth_mode:"apikey",[ee]:t};p(Z()),m(Z(),JSON.stringify(o,null,2)+"\n",384)}(e.apiKey)},holdsOurConfig(e){const t=pe()[ee];return"string"==typeof t&&e.includes(t.trim())},unloadPrivateConfig(e){if(me=function(e){const t=pe(),o="string"==typeof t[ee]?t[ee].trim():"";if(!o)return de(t.tokens)?"chatgpt":null;if(!e.includes(o))return"other_key";const{[ee]:r,auth_mode:n,...i}=t;return p(Z()),de(i.tokens)?(m(Z(),JSON.stringify({...i,auth_mode:"chatgpt"},null,2)+"\n",384),"chatgpt"):(s(Z(),{force:!0}),"signed_out")}(e?.savedKeys??[]),!t(z()))return;let o;try{o=ue()}catch(e){return void c.logError("codexAdapter.unloadPrivateConfig",e)}const r=o.model_providers;de(r)&&de(r[te])&&R(r[te].base_url)&&de(r)&&(delete r[te],0===Object.keys(r).length&&delete o.model_providers,o.model_provider===te&&delete o.model_provider),o.model_catalog_json===P()&&delete o.model_catalog_json,Q(o),fe(o),p(z()),m(z(),d.stringify(o))},unloadNotes(){switch(me){case"chatgpt":return[{kind:"action",text:u.t("tools.codex.unload_chatgpt_restored")}];case"other_key":return[{kind:"action",text:u.t("tools.codex.unload_other_key")}];default:return[{kind:"action",text:u.t("tools.codex.unload_sign_in")}]}},detectCurrentConfig(){const e=pe()[ee];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return ue()}catch(e){return c.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[z(),Z(),P()]};export function codexAuthProblem(){try{const e=ue(),t=e.model_providers?.[te];if(e.model_provider!==te||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=pe();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
|
1
|
+
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as i,statSync as s,writeFileSync as l}from"fs";import{join as d}from"path";import*as a from"@iarna/toml";import{logger as c}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{backupBeforeWrite as p,atomicWriteFile as m}from"./backup.js";import{codexHome as f,pickModel as _,toolHome as g,withV1 as x}from"./types.js";import{moveSessionsToProvider as h,NO_STATE_DB as y,runningCodexPids as k}from"../codex-sessions.js";import{codexFormat as b,codexRolloutFiles as v}from"../sessions/formats.js";import{getGatewayModelRules as w,getToolDefaultModel as j}from"../model-registry.js";import{ownsValue as S,takeField as C}from"../written-values.js";import{configManager as O}from"../config.js";import{maskHome as M,track as A}from"../telemetry.js";import{buildCodexCatalog as E,catalogRejections as P,codexCatalogPath as N,fillFromOlderEntries as T,installedCodexBinaries as D,loadBundledCodexModels as $,loadPreviousCodexModels as I,previousGatewayModelIds as L}from"./codex-catalog.js";import{gatewayModelSpecs as J,modelFamily as G}from"../gateway-models.js";import{isOurGatewayUrl as R,noteWrittenGatewayUrl as K}from"../gateway-addresses.js";import{findInstalls as X,mirrorInstallCommand as B,brandInstallScripts as U}from"./tool-installs.js";import{chatgptDesktopApp as W}from"./chatgpt-desktop.js";const q=()=>f(),z=()=>d(q(),"config.toml"),Y="sessions_move_declined",F=["browser_use","browser_use_external","computer_use"],H="desktop_features_restored";function Q(e){if(!0===O.getToolSetting("codex",H))return!1;const t=e.features,o=ae(t)&&F.every(e=>!1===t[e]);if(O.setToolSetting("codex",H,!0),!o)return!1;for(const e of F)delete t[e];return!0}export function codexWorkModeOn(){try{const e=ue();return e.model_provider===te&&ae(e.desktop)&&"STEPS_PROSE"===e.desktop.conversationDetailMode}catch{return!1}}function V(){try{if(ae(ue().desktop))return!0}catch{}if("darwin"===process.platform)return["/Applications",d(g(),"Applications")].some(e=>["ChatGPT.app","Codex.app"].some(o=>t(d(e,o))));if("win32"===process.platform){const e=d(process.env.LOCALAPPDATA||d(g(),"AppData","Local"),"Packages");try{return n(e).some(e=>/^OpenAI\.(Codex|ChatGPT)/i.test(e))}catch{return!1}}return t("/usr/lib/chatgpt/ChatGPT")}export function codexConfigPath(){return z()}const Z=()=>d(q(),"auth.json"),ee="OPENAI_API_KEY",te="custom",oe="high",ne=["gpt-5.5","gpt-5.6-sol","gpt-6-astra"],re=["high","xhigh"],ie={goals:!0,js_repl:!1};let se=[];const le=1e6,de=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function ae(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function ce(e,t){return ae(e[t])||(e[t]={}),e[t]}function ue(){if(!t(z()))return{};const e=r(z(),"utf-8");if(!e.trim())return{};try{const t=a.parse(e);if(!ae(t))throw new Error("config.toml root must be a TOML table");return t}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 pe(){if(!t(Z()))return{};try{const e=JSON.parse(r(Z(),"utf-8"));return ae(e)?e:{}}catch{return{}}}let me=null;function fe(e){const t=e.profiles;if(ae(t)){for(const[e,o]of Object.entries(t))ae(o)&&2===Object.keys(o).length&&o.model_provider===te&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let _e=null;const ge=()=>d(O.getConfigDir(),"codex-catalog-check.json");function xe(e){const o=N();t(o)&&r(o,"utf-8")===e||(p(o),m(o,e))}function he(t,n){if(0===n.length)return[];const i=function(t,o){const n=e("sha256").update(t);for(const e of o)try{const t=s(e);n.update(`\0${e}\0${t.size}\0${t.mtimeMs}`)}catch{n.update(`\0${e}`)}return n.digest("hex")}(t,n);if(function(e){try{return JSON.parse(r(ge(),"utf-8")).signature===e}catch{return!1}}(i))return[];const d=P(N(),n);return 0===d.length&&function(e){try{o(O.getConfigDir(),{recursive:!0}),l(ge(),JSON.stringify({signature:e})+"\n")}catch(e){c.logError("codexAdapter.rememberAccepted",e)}}(i),d}function ye(e,t,o){const n=!1!==t.settings?.one_million_context;!function(e){e.model_context_window===le&&delete e.model_context_window,e.model_auto_compact_token_limit===de&&delete e.model_auto_compact_token_limit}(e);const r=()=>{e.model_catalog_json===N()&&delete e.model_catalog_json,n&&(e.model_context_window=le,e.model_auto_compact_token_limit=de)},s=$()??I();if(!s)return c.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),_e="skipped",void r();const l=t.catalog,d=e=>E({bundled:e,specs:J("codex",l?.clientModels,l?.clientPersonal),...l?.clientPersonal?.includes("codex")?{chosenGpt:(l.clientModels?.codex??[]).filter(e=>!e.hidden).map(e=>e.id)}:{},...l?{keyModels:l.models}:{},gatewayAvailable:l?.models??L(),oneMillion:n,selectedModel:o,..."gateway"===l?.oneMillionSource?{claudeOneMillion:l.oneMillion}:{}}),a=e=>JSON.stringify(e,null,2)+"\n";let u=d(s);xe(a(u));const p=D(),m=he(a(u),p);if(m.length>0){const e=Date.now();let t=!1;for(const e of m){const o=$(e.bin);if(o){for(const e of[{models:T(u.models,o)},{models:T(d(o).models,o)}])if(xe(a(e)),0===he(a(e),p).length){u=e,t=!0;break}if(t)break}}if(A("codex-catalog",t?"fallback":"fail",{duration_ms:Date.now()-e,error:m[0].error,detail:{rejected_by:m.map(e=>({version:e.version,path:M(e.bin)}))}}),!t)return _e={rejectedBy:m[0]},i(N(),{force:!0}),void r()}_e={listed:u.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))},e.model_catalog_json=N()}export function codexCatalogRejection(){let e;try{e=ue()}catch{return null}return e.model_catalog_json===N()&&t(N())?P(N())[0]??null:null}export function setCodexOneMillionContext(e,t){const o=ue(),n=a.stringify(o),r="string"==typeof o.model?o.model:j("codex");ye(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},r);const i=a.stringify(o);i!==n&&(p(z()),m(z(),i))}const ke={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:U("codex"),brew:"codex"};function be(e){const t=ae(e.model_providers)?e.model_providers[te]:void 0;if(!ae(t))return null;const o="string"==typeof t.base_url?t.base_url.trim():"";return o&&!R(o)?o:null}let ve=null;function we(){if("skipped"===_e)return 0===X(ke).length?[]:[{kind:"action",text:u.t("tools.codex.catalog_skipped")}];if(!_e)return[];if("rejectedBy"in _e){const{bin:e,version:t}=_e.rejectedBy;return[{kind:"action",text:u.t("tools.codex.catalog_rejected",{path:e,version:t??"?"})}]}const e=new Map;for(const t of _e.listed)e.set(G(t.id),(e.get(G(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${u.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:u.t("tools.codex.catalog_written",{count:String(_e.listed.length),breakdown:t})},{kind:"detail",text:_e.listed.map(e=>e.name).join(", ")},...codexWorkModeOn()||V()?[{kind:"action",text:u.t(codexWorkModeOn()?"tools.codex.work_mode_on":"tools.codex.work_mode_hint")}]:[]]}export const codexAdapter={name:"codex",companionApps:[W],displayName:"Codex",command:"codex",installCommand:B(ke),installSpec:ke,configPath:z(),sessions:{format:b,files:()=>[...v(d(f(),"sessions")),...v(d(f(),"archived_sessions"))],resumeCommand:e=>({command:"codex",args:["resume",e]})},wantsModelCatalog:!0,listedModels(){if(ue().model_catalog_json!==N())return null;try{return(JSON.parse(r(N(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){if(ue().model_catalog_json!==N())return;setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog);const t=ue(),o=function(e,t){const o=ae(e.model_providers)?e.model_providers[te]:void 0;return!(!ae(o)||o.base_url!==t||!0===o.supports_standalone_web_search||(o.supports_standalone_web_search=!0,0))}(t,x(e.baseUrl));(Q(t)||o)&&(p(z()),m(z(),a.stringify(t)))},async followUp(){if(ue().model_provider!==te)return null;const e=await h(te,{dryRun:!0}),t=Math.max(e.moved.length,e.dbRows);if(0===t)return null;const o=O.getToolSettings("codex")[Y];if("number"==typeof o&&t<=o)return null;const n={count:String(t)};return k().length>0?{hint:u.t("tools.codex.sessions_hidden_running",n)}:{prompt:u.t("tools.codex.sessions_offer",n),hint:u.t("tools.codex.sessions_hidden",n),async run(){const e=await h(te),t=[...new Set(e.moved.map(e=>e.from))].join("、")||"-",o=String(Math.max(e.moved.length,e.dbRows)),n=[{kind:"summary",text:u.t("codex_sessions.moved",{count:o,from:t,target:te})},{kind:"summary",text:u.t("codex_sessions.backup",{dir:e.backupDir??""})}];return e.dbSkipped&&e.dbSkipped!==y&&n.push({kind:"action",text:u.t("codex_sessions.db_skipped",{reason:e.dbSkipped})}),n},decline(){O.setToolSetting("codex",Y,t)}}},applyNotes(){const e=[];return ve&&e.push({kind:"summary",text:u.t("tools.codex.provider_replaced",{url:ve})}),se.length>0&&e.push({kind:"summary",text:u.t("tools.codex.replaced_user_settings",{values:se.join(", ")})}),[...e,...we()]},planNotes(){let e;try{e=ue()}catch{return[]}const t=[],o=be(e);return o?t.push(u.t("tools.codex.plan_replace_provider",{url:o})):"string"==typeof e.model_provider&&e.model_provider!==te&&t.push(u.t("tools.codex.plan_switch_provider",{provider:e.model_provider})),t},loadPrivateConfig(e){const t=j("codex"),o=_(e.models,t),n=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,r=x(e.baseUrl),i=ue();se=[];const s=w().retired,l=(e,t,o,n,r)=>{void 0===t||t===o||"string"==typeof t&&s.includes(t)||S(e,t,n)||se.push(`${r} = ${String(t)}`),C(e,o)};l("codex.model",i.model,n,ne,"model"),i.model=n,i.model_provider=te,l("codex.model_reasoning_effort",i.model_reasoning_effort,oe,re,"model_reasoning_effort"),i.model_reasoning_effort=oe;const d="string"==typeof i.model?i.model:n;ye(i,e,d);const c=ce(i,"model_providers");ve=be(i),K(r);const u=ae(c[te])?{...c[te]}:{};delete u.env_key;const{experimental_bearer_token:f,...g}=u;c[te]={...g,name:"custom",wire_api:"responses",requires_openai_auth:!0,supports_standalone_web_search:!0,base_url:r},fe(i),ce(ce(i,"tui"),"model_availability_nux")[d]=4;const h=ce(i,"features");for(const[e,t]of Object.entries(ie))l(`codex.features.${e}`,void 0===h[e]?void 0:String(h[e]),String(t),[String(t)],`features.${e}`),h[e]=t;Q(i),p(z()),m(z(),a.stringify(i)),function(e){const t=e.trim();if(!t)return;const o={...pe(),auth_mode:"apikey",[ee]:t};p(Z()),m(Z(),JSON.stringify(o,null,2)+"\n",384)}(e.apiKey)},holdsOurConfig(e){const t=pe()[ee];return"string"==typeof t&&e.includes(t.trim())},unloadPrivateConfig(e){if(me=function(e){const t=pe(),o="string"==typeof t[ee]?t[ee].trim():"";if(!o)return ae(t.tokens)?"chatgpt":null;if(!e.includes(o))return"other_key";const{[ee]:n,auth_mode:r,...s}=t;return p(Z()),ae(s.tokens)?(m(Z(),JSON.stringify({...s,auth_mode:"chatgpt"},null,2)+"\n",384),"chatgpt"):(i(Z(),{force:!0}),"signed_out")}(e?.savedKeys??[]),!t(z()))return;let o;try{o=ue()}catch(e){return void c.logError("codexAdapter.unloadPrivateConfig",e)}const n=o.model_providers;ae(n)&&ae(n[te])&&R(n[te].base_url)&&ae(n)&&(delete n[te],0===Object.keys(n).length&&delete o.model_providers,o.model_provider===te&&delete o.model_provider),o.model_catalog_json===N()&&delete o.model_catalog_json,Q(o),fe(o),p(z()),m(z(),a.stringify(o))},unloadNotes(){switch(me){case"chatgpt":return[{kind:"action",text:u.t("tools.codex.unload_chatgpt_restored")}];case"other_key":return[{kind:"action",text:u.t("tools.codex.unload_other_key")}];default:return[{kind:"action",text:u.t("tools.codex.unload_sign_in")}]}},detectCurrentConfig(){const e=pe()[ee];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return ue()}catch(e){return c.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[z(),Z(),N()]};export function codexAuthProblem(){try{const e=ue(),t=e.model_providers?.[te];if(e.model_provider!==te||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=pe();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
package/dist/lib/tools/grok.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as r from"@iarna/toml";import{logger as n}from"../../utils/logger.js";import{PROVIDER_KEY as i}from"../brand.js";import{backupBeforeWrite as
|
|
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 l,atomicWriteFile as s}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 g}from"../model-registry.js";import{gatewayModelSpecs as c,modelBlurb as u,modelFamily as p,prettyModelName as y}from"../gateway-models.js";import{brandInstallScripts as k,mirrorInstallCommand as b}from"./tool-installs.js";import{OFFICIAL_PLUGINS as h}from"./claude-plugins.js";const j=()=>o(o(d(),".grok"),"config.toml"),_=i,w=`${i}-`,A=["low","medium","high","xhigh"];let v=null;const C=e=>`${w}${e}`,M=e=>e===_||e.startsWith(w),x={command:"grok",npmPackage:"@xai-official/grok",npmMirrorTagStale:!0,mirrorScript:k("grok"),native:{binDir:[".grok","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".grok","downloads"]]}};function S(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function E(e,t){return S(e[t])||(e[t]={}),e[t]}function O(){if(!e(j()))return{};const o=t(j(),"utf-8");if(!o.trim())return{};try{const e=r.parse(o);if(!S(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 P(e){return S(e.model)?Object.entries(e.model).filter(e=>M(e[0])&&S(e[1])):[]}function N(e,t){let o=c("grok",e.catalog?.clientModels,e.catalog?.clientPersonal);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 $(e,t,o){E(e,"endpoints").models_base_url=m(t.baseUrl);const r=E(e,"model"),n=new Map(P(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=A);const l=u(e.description);l?i.description=l:delete i.description,r[o]=i}}export const grokAdapter={name:"grok",displayName:"Grok Build",command:"grok",installCommand:b(x),installSpec:x,configPath:j(),wantsModelCatalog:!0,loadPrivateConfig(e){const t=O(),o=a(e.models,g("grok")),n=N(e,o);$(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),function(e){const t=E(e,"plugins"),o=e=>Array.isArray(e)?e.map(String):[],r=o(t.enabled),n=o(t.disabled),i=h.filter(e=>!r.includes(e)&&!n.includes(e));i.length>0&&(t.disabled=[...n,...i])}(t),l(j()),s(j(),r.stringify(t))},unloadPrivateConfig(){if(!e(j()))return;let t;try{t=O()}catch(e){return void n.logError("grokAdapter.unloadPrivateConfig",e)}if(S(t.model)){for(const[e]of P(t))delete t.model[e];0===Object.keys(t.model).length&&delete t.model}S(t.models)&&"string"==typeof t.models.default&&M(t.models.default)&&(delete t.models.default,0===Object.keys(t.models).length&&delete t.models),S(t.endpoints)&&(delete t.endpoints.models_base_url,0===Object.keys(t.endpoints).length&&delete t.endpoints),function(e){if(!S(e.plugins)||!Array.isArray(e.plugins.disabled))return;const t=e.plugins.disabled.filter(e=>!h.includes(e));t.length>0?e.plugins.disabled=t:delete e.plugins.disabled,0===Object.keys(e.plugins).length&&delete e.plugins}(t),l(j()),s(j(),r.stringify(t))},detectCurrentConfig(){try{const e=O(),t=P(e),o=S(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=P(O());return e.length>0?e.map(([,e])=>String(e.model)):null}catch{return null}},refreshModelMenu(e){const t=O(),o=E(t,"models"),n="string"==typeof o.default?o.default:void 0,i=n?P(t).find(([e])=>e===n)?.[1].model:void 0,d="string"==typeof i&&n!==_&&e.catalog.models.includes(i)?i:a(e.models,g("grok")),m=r.stringify(t);$(t,e,N(e,d)),(void 0===n||M(n))&&(o.default=C(d)),r.stringify(t)!==m&&(l(j()),s(j(),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 O()}catch(e){return n.logError("grokAdapter.getConfig",e),null}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{claudeCodeAdapter as o}from"./claude-code.js";import{opencodeAdapter as r}from"./opencode.js";import{codexAdapter as t}from"./codex.js";import{openclawAdapter as m}from"./openclaw.js";import{hermesAdapter as e}from"./hermes.js";import{atomcodeAdapter as p}from"./atomcode.js";import{grokAdapter as s}from"./grok.js";import{claudeDesktopAdapter as i}from"./claude-desktop.js";import{antigravityAdapter as
|
|
1
|
+
import{claudeCodeAdapter as o}from"./claude-code.js";import{opencodeAdapter as r}from"./opencode.js";import{codexAdapter as t}from"./codex.js";import{openclawAdapter as m}from"./openclaw.js";import{hermesAdapter as e}from"./hermes.js";import{atomcodeAdapter as p}from"./atomcode.js";import{grokAdapter as s}from"./grok.js";import{claudeDesktopAdapter as i}from"./claude-desktop.js";import{antigravityAdapter as d}from"./antigravity.js";import{codebuddyAdapter as f}from"./codebuddy.js";import{workbuddyAdapter as c}from"./workbuddy.js";const n=[o,r,t,m,e,p,s,i,d,f,c];export const TOOL_ADAPTERS=Object.fromEntries(n.map(o=>[o.name,o]));export function getAdapter(o){return TOOL_ADAPTERS[o]}export function listAdapters(){return[...n]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as t}from"fs";import{join as r}from"path";import{logger as o}from"../../utils/logger.js";import{i18n as e}from"../i18n.js";import{getToolDefaultModel as n}from"../model-registry.js";import{prettyModelName as d,vendorNames as s}from"../gateway-models.js";import{bareModelId as i,foreignIdsReplaced as a,isOurEntry as l,menuSpecs as p,mergeEntries as u,ourApiKey as c,ourEntries as m,readModelsFile as y,writeModelsFile as g}from"./codebuddy-models.js";import{pickModel as f,toolHome as b}from"./types.js";const k=()=>process.env.WORKBUDDY_CONFIG_DIR?.trim()||process.env.CODEBUDDY_CONFIG_DIR?.trim()||r(b(),".workbuddy"),w=()=>r(k(),"models.json"),h="https://www.codebuddy.cn/work/";let C=null;function _(t,r){const o=y(w()),{entries:e,replaced:n}=u(o.entries,r,t.baseUrl,t.apiKey,!0);return g(w(),o,e),n}const j=t=>i(f(t.models,n("workbuddy")));export const workbuddyAdapter={name:"workbuddy",displayName:"WorkBuddy",command:"workbuddy",installCommand:"darwin"===process.platform?`open ${h}`:h,get configPath(){return w()},wantsModelCatalog:!0,isInstalled:function(){return!!t(k())||"darwin"===process.platform&&["/Applications/WorkBuddy.app",r(b(),"Applications","WorkBuddy.app")].some(r=>t(r))},loadPrivateConfig(t){const r=p(t.catalog,j(t)),o=_(t,r);C={names:r.map(t=>t.name??d(t.id)),vendors:s(r.map(t=>t.id)),replaced:o}},unloadPrivateConfig(){try{const t=y(w());if(0===m(t.entries).length)return;g(w(),t,t.entries.filter(t=>!l(t)))}catch(t){o.logError("workbuddyAdapter.unloadPrivateConfig",t)}},detectCurrentConfig(){try{return{apiKey:c(y(w()).entries)}}catch{return{apiKey:null}}},listedModels(){try{const t=m(y(w()).entries);return t.length>0?t.map(t=>String(t.id)):null}catch{return null}},refreshModelMenu(t){_(t,p(t.catalog,j(t)))},planNotes(){try{const t=y(w()),r=a(t.entries,p(void 0,n("workbuddy")));return r.length>0?[e.t("tools.codebuddy.replaces_models",{path:w(),list:r.join(e.t("tools.codebuddy.list_separator"))})]:[]}catch{return[]}},applyNotes(){if(!C)return[];const t=[{kind:"summary",text:e.t("tools.workbuddy.menu_written",{count:String(C.names.length),list:C.vendors.join(e.t("tools.codebuddy.list_separator"))})},{kind:"action",text:e.t("tools.workbuddy.pick_in_app")}];return C.replaced.length>0&&t.push({kind:"detail",text:e.t("tools.codebuddy.replaced_models",{tool:"workbuddy",list:C.replaced.join(e.t("tools.codebuddy.list_separator"))})}),t},backupPaths:()=>[w()],getConfig(){try{return y(w()).entries}catch(t){return o.logError("workbuddyAdapter.getConfig",t),null}}};
|
package/dist/locales/en_US.json
CHANGED
|
@@ -450,6 +450,16 @@
|
|
|
450
450
|
"gemini": "Gemini",
|
|
451
451
|
"other": "Chinese",
|
|
452
452
|
"grok": "Grok"
|
|
453
|
+
},
|
|
454
|
+
"codebuddy": {
|
|
455
|
+
"menu_written": "Wrote {{count}} models ({{list}}), default {{default}}",
|
|
456
|
+
"list_separator": ", ",
|
|
457
|
+
"replaces_models": "Models with the same id in {{path}} will be replaced: {{list}}",
|
|
458
|
+
"replaced_models": "Replaced models with the same id in models.json: {{list}} (undo with `{{cli}} config {{tool}} restore`)"
|
|
459
|
+
},
|
|
460
|
+
"workbuddy": {
|
|
461
|
+
"menu_written": "Wrote {{count}} models ({{list}})",
|
|
462
|
+
"pick_in_app": "Sign in to WorkBuddy, then pick a model from the Custom group of the chat model menu; an enterprise admin may have turned custom models off"
|
|
453
463
|
}
|
|
454
464
|
},
|
|
455
465
|
"upgrade": {
|
|
@@ -735,14 +745,18 @@
|
|
|
735
745
|
"force": "Back up, then rewrite each config with the recommended one (fixes broken configs)",
|
|
736
746
|
"all": "Configure every tool the API key can serve (the default)",
|
|
737
747
|
"install": "Install missing tools from the China mirrors without asking",
|
|
738
|
-
"no_install": "Only print install commands for missing tools"
|
|
748
|
+
"no_install": "Only print install commands for missing tools",
|
|
749
|
+
"codebuddykey": "API key just for CodeBuddy Code",
|
|
750
|
+
"workbuddykey": "API key just for WorkBuddy"
|
|
739
751
|
},
|
|
740
752
|
"autodetect_title": "Models the --key can use and the tools configured:",
|
|
741
753
|
"autodetect": {
|
|
742
754
|
"claude": "Claude Code, Claude Desktop (macOS / Windows: written ahead even when not installed; Linux: when installed)",
|
|
743
755
|
"gpt": "Codex",
|
|
744
756
|
"grok": "Grok Build",
|
|
745
|
-
"gemini": "Antigravity CLI"
|
|
757
|
+
"gemini": "Antigravity CLI",
|
|
758
|
+
"any_label": "Any",
|
|
759
|
+
"any": "CodeBuddy Code, WorkBuddy (only when installed)"
|
|
746
760
|
},
|
|
747
761
|
"ex": {
|
|
748
762
|
"key": "Configure every tool one API key can serve",
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -450,6 +450,16 @@
|
|
|
450
450
|
"gemini": "Gemini",
|
|
451
451
|
"other": "国产",
|
|
452
452
|
"grok": "Grok"
|
|
453
|
+
},
|
|
454
|
+
"codebuddy": {
|
|
455
|
+
"menu_written": "已写入 {{count}} 个模型({{list}}),默认 {{default}}",
|
|
456
|
+
"list_separator": "、",
|
|
457
|
+
"replaces_models": "{{path}} 里同名的模型会换成本站的:{{list}}",
|
|
458
|
+
"replaced_models": "已替换 models.json 里同名的模型:{{list}}(恢复运行 `{{cli}} config {{tool}} restore`)"
|
|
459
|
+
},
|
|
460
|
+
"workbuddy": {
|
|
461
|
+
"menu_written": "已写入 {{count}} 个模型({{list}})",
|
|
462
|
+
"pick_in_app": "在 WorkBuddy 登录后,到对话框的模型菜单「自定义模型」分组里选择;企业账号的管理员可能关闭了自定义模型"
|
|
453
463
|
}
|
|
454
464
|
},
|
|
455
465
|
"upgrade": {
|
|
@@ -735,14 +745,18 @@
|
|
|
735
745
|
"force": "先备份,再用推荐配置整份重写(用于修复改坏的配置)",
|
|
736
746
|
"all": "配置令牌能用的全部工具(默认行为)",
|
|
737
747
|
"install": "未安装的工具直接从国内镜像安装,不再询问",
|
|
738
|
-
"no_install": "未安装的工具只给出安装命令,不安装"
|
|
748
|
+
"no_install": "未安装的工具只给出安装命令,不安装",
|
|
749
|
+
"codebuddykey": "CodeBuddy Code 专属令牌",
|
|
750
|
+
"workbuddykey": "WorkBuddy 专属令牌"
|
|
739
751
|
},
|
|
740
752
|
"autodetect_title": "--key 能用的模型和自动配置的工具:",
|
|
741
753
|
"autodetect": {
|
|
742
754
|
"claude": "Claude Code、Claude Desktop(macOS、Windows 上未安装也会提前写好;Linux 上已安装才配置)",
|
|
743
755
|
"gpt": "Codex",
|
|
744
756
|
"grok": "Grok Build",
|
|
745
|
-
"gemini": "Antigravity CLI"
|
|
757
|
+
"gemini": "Antigravity CLI",
|
|
758
|
+
"any_label": "任意",
|
|
759
|
+
"any": "CodeBuddy Code、WorkBuddy(已安装才配置)"
|
|
746
760
|
},
|
|
747
761
|
"ex": {
|
|
748
762
|
"key": "用一个令牌配置它能用的全部工具",
|
package/dist/models.json
CHANGED
package/models.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeapi/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.159",
|
|
4
4
|
"description": "CLI tool for managing AI coding assistants (Claude Code, Codex, OpenClaw, Hermes, AtomCode, Grok Build) with one unified config",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|