@vibeapi/cli 0.0.166 → 0.0.168

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/brand.json CHANGED
@@ -9,6 +9,15 @@
9
9
  "apiKeyEnv": "VIBEAPI_API_KEY",
10
10
  "desktopEntryName": "VibeAPI",
11
11
  "packageName": "@vibeapi/api-helper",
12
+ "gatewayProtocol": {
13
+ "clientConfigPath": "/api/platform/vibecode/config",
14
+ "keyInfoPath": "/api/platform/vibecode/key",
15
+ "telemetryPath": "/api/platform/vibecode/telemetry",
16
+ "reportPath": "/api/platform/vibecode/report",
17
+ "clientSection": "vibecli",
18
+ "minClientVersion": "min_vibecli_version",
19
+ "installIdHeader": "X-VibeCLI-Install-Id"
20
+ },
12
21
  "gatewayAddresses": [
13
22
  {
14
23
  "url": "https://www.vibeapi.cn",
@@ -1 +1 @@
1
- import{refreshClientConfig as o}from"../lib/client-config-sync.js";import t from"chalk";import e from"ora";import{spawnSync as s}from"child_process";import{existsSync as r,readdirSync as n,readFileSync as a}from"fs";import{connect as c}from"net";import{join as i}from"path";import{configManager as l}from"../lib/config.js";import{savedApiKey as d}from"./base.js";import{toolManager as p}from"../lib/tool-manager.js";import{i18n as u}from"../lib/i18n.js";import{validateApiKey as m}from"../lib/api-validator.js";import{getAdapter as f}from"../lib/tools/registry.js";import{findInstalls as _,installLabel as g}from"../lib/tools/tool-installs.js";import{detectManagedOverrides as h}from"../lib/tools/claude-managed.js";import{codexAuthProblem as y,codexCatalogRejection as k,codexConfigPath as w,codexWorkModeOn as b}from"../lib/tools/codex.js";import{claudeAccountLoginPresent as v}from"../lib/tools/claude-code.js";import{toolHome as j}from"../lib/tools/types.js";import{gatewayAddresses as x,probeGatewayAddress as $}from"../lib/gateway-addresses.js";import{listAdapters as T}from"../lib/tools/registry.js";import{logger as A}from"../utils/logger.js";import{maskHome as P,maskSecrets as R,uploadReport as N}from"../lib/telemetry.js";import{CLI_NAME as O}from"../lib/brand.js";import{appStatus as I,appStatusText as C,appTools as H,appUpgradeCommand as L,getApp as S}from"../lib/app-update.js";import{balanceLookupEnabled as U,balanceNeedsAttention as E,balanceText as K,fetchKeyBalances as B}from"../lib/key-balance.js";const G=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function D(o,t,e=3e3){return new Promise(s=>{const r=c({host:o,port:t}),n=o=>{r.destroy(),s(o)};r.setTimeout(e,()=>n(!1)),r.once("connect",()=>n(!0)),r.once("error",()=>n(!1))})}function q(){const o=A.getLogDir();if(!r(o))return"";const t=n(o).filter(o=>/^\d{4}-\d{2}-\d{2}\.log$/.test(o)).sort().slice(-2).map(t=>`== ${t}\n`+a(i(o,t),"utf-8")).join("\n");return R(t.slice(-15e4))}function F(){const o={};for(const t of G){const e=process.env[t]?.trim();if(e)try{const s=new URL(e.includes("://")?e:`http://${e}`);o[t]=`${s.protocol}//${s.host}`}catch{o[t]="(unparsable)"}}return o}export async function doctorCommand(r={}){const n=e(u.t("doctor.checking")).start(),c=[],A=Number(process.versions.node.split(".")[0]);c.push({name:"Node.js",status:A>=20?"pass":"fail",message:`v${process.versions.node}`}),n.text=u.t("doctor.check_proxy"),c.push(await async function(){const o=u.t("doctor.proxy"),t=new Map;for(const o of G){const e=process.env[o]?.trim();e&&!t.has(e)&&t.set(e,o)}if(0===t.size)return{name:o,status:"pass",message:u.t("doctor.proxy_none")};const e=[];for(const[o,s]of t){let t;try{t=new URL(o.includes("://")?o:`http://${o}`)}catch{e.push(`${s}=${o}`);continue}const r=Number(t.port)||("https:"===t.protocol?443:t.protocol.startsWith("socks")?1080:80);await D(t.hostname,r)||e.push(`${s}=${o}`)}return 0===e.length?{name:o,status:"pass",message:[...t.keys()].join(", ")}:{name:o,status:"fail",message:u.t("doctor.proxy_dead",{proxies:e.join(", ")})}}()),n.text=u.t("doctor.check_api_key_network");const R=d(),M=u.t("doctor.api_key_network");if(R){const o=await m(R);o.valid?(c.push({name:M,status:"pass"}),n.text=u.t("doctor.check_balance"),c.push(...await async function(o){if(!U())return[];const t=l.listToolApiKeys().map(o=>({tool:o,key:l.getApiKeyForTool(o)})).filter(t=>Boolean(t.key)&&t.key!==o),e=await B([o,...t.map(o=>o.key)]),s=[{name:u.t("doctor.balance"),key:o},...t.map(o=>({name:u.t("doctor.balance_tool",{tool:f(o.tool)?.displayName??o.tool}),key:o.key}))],r=[];for(const o of s){const t=e.get(o.key);t&&r.push({name:o.name,status:E(t)?"warn":"pass",message:K(t)})}return r}(R))):"invalid_api_key"===o.error?c.push({name:M,status:"fail",message:u.t("doctor.api_key_invalid")}):(c.push({name:M,status:"fail",message:`${u.t("doctor.network_error")}: ${o.message??o.error}`}),n.text=u.t("doctor.check_other_addresses"),c.push(await async function(){const o=u.t("doctor.other_addresses"),t=l.getBaseUrl(),e=x().filter(o=>o.url!==t),s=d(),r=await Promise.all(e.map(o=>$(o.url,{apiKey:s}))),n=e.filter((o,t)=>r[t].ok).map(o=>o.url);return 0===n.length?{name:o,status:"fail",message:u.t("doctor.other_addresses_none")}:{name:o,status:"warn",message:u.t("doctor.other_addresses_found",{urls:n.join(", ")})}}()))}else c.push({name:M,status:"fail",message:u.t("doctor.api_key_missing")});n.text=u.t("doctor.check_client_config");const X=await o();c.push({name:u.t("doctor.client_config"),status:"cloud"===X.source||"cache"===X.source&&!X.problem?"pass":"warn",message:[X.source?u.t(`refresh.source.${X.source}`):u.t("refresh.source.none"),X.revision?u.t("doctor.client_config_revision",{revision:X.revision}):"",X.problem??""].filter(Boolean).join(" · ")}),n.text=u.t("doctor.check_tools");const Y=p.getInstalledTools();c.push({name:u.t("doctor.installed_tools"),status:Y.length>0?"pass":"warn",message:Y.length>0?Y.map(o=>f(o)?.displayName??o).join(u.t("setup.list_separator")):u.t("doctor.no_tools_installed")}),c.push(...function(){const o=[];for(const t of p.getInstalledTools()){const e=f(t);if(!e?.installSpec)continue;const s=_(e.installSpec);if(0===s.length)continue;const r=[],n=p.outdatedVersion(t);n&&r.push(u.t("doctor.tool_outdated",{min:n.min})),s.length>1&&r.push(u.t("doctor.tool_duplicates",{others:s.slice(1).map(g).join("、")})),o.push({name:e.displayName,status:r.length>0?"warn":"pass",message:[g(s[0]),...r,...r.length>0?[u.t("doctor.run_upgrade",{tool:t})]:[]].join("\n ")})}return o}()),c.push(...await async function(){const o=[];for(const t of H()){const e=await I(t,{refresh:!0});if(!e.installed||!e.current)continue;const s=u.t("doctor.app_version",{tool:e.name});if(e.outdated){const r=e.blocker?u.t(`app_update.blocked_${e.blocker}`,{tool:e.name,url:S(t)?.appInstaller.downloadPage??"",command:L(t)}):u.t("doctor.run_app_upgrade",{command:L(t)});o.push({name:s,status:"warn",message:`${C(e)}\n ${r}`})}else o.push({name:s,status:"pass",message:C(e)})}return o}());const V=function(){if(!p.isToolInstalled("claude-code"))return null;const o=u.t("doctor.claude_config"),t=h();if(t.length>0){const e=t.map(o=>`${o.source}: ${o.keys.join(", ")}`).join("; ");return{name:o,status:"fail",message:u.t("doctor.claude_managed",{detail:e})}}let e={};try{e=JSON.parse(a(i(process.env.CLAUDE_CONFIG_DIR?.trim()||i(j(),".claude"),"settings.json"),"utf-8")).env??{}}catch{}const s=l.getApiKeyForTool("claude-code");return e.ANTHROPIC_AUTH_TOKEN&&e.ANTHROPIC_BASE_URL?e.ANTHROPIC_BASE_URL!==l.getBaseUrl()||s&&e.ANTHROPIC_AUTH_TOKEN!==s?{name:o,status:"warn",message:u.t("doctor.claude_config_changed")}:{name:o,status:"pass"}:{name:o,status:"warn",message:u.t("doctor.claude_not_configured")}}();V&&c.push(V),Y.includes("claude-code")&&v()&&c.push({name:u.t("doctor.claude_login"),status:"pass",message:u.t("tools.claude_code.account_login_overridden")});const W=Y.includes("codex")?y():null;if(Y.includes("codex")&&c.push({name:u.t("doctor.codex_auth"),status:W?"fail":"pass",message:W?u.t(`doctor.codex_${W}`,{path:P(w())}):void 0}),Y.includes("codex")){const o=k();c.push({name:u.t("doctor.codex_catalog"),status:o?"fail":"pass",message:o?u.t("doctor.codex_catalog_rejected",{path:o.bin,version:o.version??"?",error:o.error}):void 0})}Y.includes("codex")&&b()&&c.push({name:u.t("doctor.codex_work_mode"),status:"warn",message:u.t("tools.codex.work_mode_on")}),"win32"===process.platform&&Y.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&c.push({name:"Git for Windows",status:p.isGitInstalled()?"pass":"warn",message:p.isGitInstalled()?void 0:u.t("tools.claude_code.no_git_bash")}),r.deep&&Y.includes("claude-code")&&(n.text=u.t("doctor.check_claude_request"),c.push(function(){const o=u.t("doctor.claude_request"),t=_(f("claude-code").installSpec)[0];if(!t)return{name:o,status:"warn",message:u.t("doctor.claude_request_skipped")};const e={encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},r=["-p","Reply with the single word OK."],n=/\.cmd$/i.test(t.path)?s(`"${t.path}" ${r.map(o=>`"${o}"`).join(" ")}`,{...e,shell:!0}):s(t.path,r,e),a=`${n.stdout??""}`.trim();if(0===n.status&&a)return{name:o,status:"pass",message:a.slice(0,80)};const c=(`${n.stderr??""}`.trim()||a||n.error?.message||`exit ${n.status}`).slice(0,300);return{name:o,status:"fail",message:u.t("doctor.claude_request_failed",{reason:c})}}())),n.stop(),console.log("\n"+t.bold(u.t("doctor.results_title"))+"\n");const z={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of c)console.log(`${z[o.status]} ${o.name}`),o.message&&console.log(t.gray(` ${o.message}`));if(c.every(o=>"pass"===o.status)&&console.log("\n"+t.green.bold(u.t("doctor.all_good"))),!r.deep&&Y.includes("claude-code")&&console.log(t.gray("\n"+u.t("doctor.deep_hint"))),r.report){const o=e(u.t("doctor.report_uploading")).start(),t=await N(function(o,t){const e={};for(const o of T()){if(o.hidden)continue;let t=null;try{t=p.detectCurrentConfig(o.name).apiKey?"has_key":"no_key"}catch{t="unreadable"}e[o.name]={installed:p.isToolInstalled(o.name),version:p.installedVersion(o.name),copies:o.installSpec?_(o.installSpec).map(o=>({kind:o.kind,version:o.version,path:o.path})):void 0,config:t}}const s=l.getProfile();return{checks:o,tools:e,settings:{base_url:l.getBaseUrl(),profile:l.getActiveProfileName(),profiles:l.listProfiles().length,key_fingerprint:l.getApiKeyFingerprint()||null,tool_keys:Object.keys(s.tool_api_keys??{}),models:s.models,tool_models:s.tool_models??{},tool_settings:s.tool_settings??{},lang:l.getLang()},client_config:t,env:{shell:process.env.SHELL??process.env.ComSpec??null,term:process.env.TERM_PROGRAM??null,proxies:F()},log:q()}}(c,{source:X.source??void 0,revision:X.revision,problem:X.problem}));t?o.succeed(u.t("doctor.report_done",{code:t})):o.fail(u.t("doctor.report_failed",{cli:O}))}else c.some(o=>"fail"===o.status)&&console.log(t.gray("\n"+u.t("doctor.report_hint",{cli:O})));c.some(o=>"fail"===o.status)&&(process.exitCode=1)}
1
+ import{refreshClientConfig as o}from"../lib/client-config-sync.js";import e from"chalk";import t from"ora";import{spawnSync as s}from"child_process";import{existsSync as n,readdirSync as r,readFileSync as a}from"fs";import{connect as c}from"net";import{join as i}from"path";import{configManager as l}from"../lib/config.js";import{savedApiKey as d}from"./base.js";import{toolManager as p}from"../lib/tool-manager.js";import{i18n as u}from"../lib/i18n.js";import{validateApiKey as m}from"../lib/api-validator.js";import{getAdapter as f}from"../lib/tools/registry.js";import{findInstalls as g,installLabel as _}from"../lib/tools/tool-installs.js";import{detectManagedOverrides as h}from"../lib/tools/claude-managed.js";import{codexAuthProblem as y,codexCatalogRejection as k,codexConfigPath as w,codexWorkModeOn as b}from"../lib/tools/codex.js";import{claudeAccountLoginPresent as v}from"../lib/tools/claude-code.js";import{toolHome as j}from"../lib/tools/types.js";import{gatewayAddresses as $,probeGatewayAddress as x}from"../lib/gateway-addresses.js";import{listAdapters as T}from"../lib/tools/registry.js";import{logger as A}from"../utils/logger.js";import{maskHome as P,maskSecrets as R,noteFailureReason as N,uploadReport as O}from"../lib/telemetry.js";import{CLI_NAME as I}from"../lib/brand.js";import{appStatus as C,appStatusText as H,appTools as L,appUpgradeCommand as S,getApp as U}from"../lib/app-update.js";import{balanceLookupEnabled as E,balanceNeedsAttention as K,balanceText as B,fetchKeyBalances as G}from"../lib/key-balance.js";const D=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function q(o,e,t=3e3){return new Promise(s=>{const n=c({host:o,port:e}),r=o=>{n.destroy(),s(o)};n.setTimeout(t,()=>r(!1)),n.once("connect",()=>r(!0)),n.once("error",()=>r(!1))})}function F(){const o=A.getLogDir();if(!n(o))return"";const e=r(o).filter(o=>/^\d{4}-\d{2}-\d{2}\.log$/.test(o)).sort().slice(-2).map(e=>`== ${e}\n`+a(i(o,e),"utf-8")).join("\n");return R(e.slice(-15e4))}function M(){const o={};for(const e of D){const t=process.env[e]?.trim();if(t)try{const s=new URL(t.includes("://")?t:`http://${t}`);o[e]=`${s.protocol}//${s.host}`}catch{o[e]="(unparsable)"}}return o}export async function doctorCommand(n={}){const r=t(u.t("doctor.checking")).start(),c=[],A=Number(process.versions.node.split(".")[0]);c.push({name:"Node.js",status:A>=20?"pass":"fail",message:`v${process.versions.node}`}),r.text=u.t("doctor.check_proxy"),c.push(await async function(){const o=u.t("doctor.proxy"),e=new Map;for(const o of D){const t=process.env[o]?.trim();t&&!e.has(t)&&e.set(t,o)}if(0===e.size)return{name:o,status:"pass",message:u.t("doctor.proxy_none")};const t=[];for(const[o,s]of e){let e;try{e=new URL(o.includes("://")?o:`http://${o}`)}catch{t.push(`${s}=${o}`);continue}const n=Number(e.port)||("https:"===e.protocol?443:e.protocol.startsWith("socks")?1080:80);await q(e.hostname,n)||t.push(`${s}=${o}`)}return 0===t.length?{name:o,status:"pass",message:[...e.keys()].join(", ")}:{name:o,status:"fail",message:u.t("doctor.proxy_dead",{proxies:t.join(", ")})}}()),r.text=u.t("doctor.check_api_key_network");const R=d(),X=u.t("doctor.api_key_network");if(R){const o=await m(R);o.valid?(c.push({name:X,status:"pass"}),r.text=u.t("doctor.check_balance"),c.push(...await async function(o){if(!E())return[];const e=l.listToolApiKeys().map(o=>({tool:o,key:l.getApiKeyForTool(o)})).filter(e=>Boolean(e.key)&&e.key!==o),t=await G([o,...e.map(o=>o.key)]),s=[{name:u.t("doctor.balance"),key:o},...e.map(o=>({name:u.t("doctor.balance_tool",{tool:f(o.tool)?.displayName??o.tool}),key:o.key}))],n=[];for(const o of s){const e=t.get(o.key);e&&n.push({name:o.name,status:K(e)?"warn":"pass",message:B(e)})}return n}(R))):"invalid_api_key"===o.error?c.push({name:X,status:"fail",message:u.t("doctor.api_key_invalid")}):(c.push({name:X,status:"fail",message:`${u.t("doctor.network_error")}: ${o.message??o.error}`}),r.text=u.t("doctor.check_other_addresses"),c.push(await async function(){const o=u.t("doctor.other_addresses"),e=l.getBaseUrl(),t=$().filter(o=>o.url!==e),s=d(),n=await Promise.all(t.map(o=>x(o.url,{apiKey:s}))),r=t.filter((o,e)=>n[e].ok).map(o=>o.url);return 0===r.length?{name:o,status:"fail",message:u.t("doctor.other_addresses_none")}:{name:o,status:"warn",message:u.t("doctor.other_addresses_found",{urls:r.join(", ")})}}()))}else c.push({name:X,status:"fail",message:u.t("doctor.api_key_missing")});r.text=u.t("doctor.check_client_config");const Y=await o();c.push({name:u.t("doctor.client_config"),status:"cloud"===Y.source||"cache"===Y.source&&!Y.problem?"pass":"warn",message:[Y.source?u.t(`refresh.source.${Y.source}`):u.t("refresh.source.none"),Y.revision?u.t("doctor.client_config_revision",{revision:Y.revision}):"",Y.problem??""].filter(Boolean).join(" · ")}),r.text=u.t("doctor.check_tools");const V=p.getInstalledTools();c.push({name:u.t("doctor.installed_tools"),status:V.length>0?"pass":"warn",message:V.length>0?V.map(o=>f(o)?.displayName??o).join(u.t("setup.list_separator")):u.t("doctor.no_tools_installed")}),c.push(...function(){const o=[];for(const e of p.getInstalledTools()){const t=f(e);if(!t?.installSpec)continue;const s=g(t.installSpec);if(0===s.length)continue;const n=[],r=p.outdatedVersion(e);r&&n.push(u.t("doctor.tool_outdated",{min:r.min})),s.length>1&&n.push(u.t("doctor.tool_duplicates",{others:s.slice(1).map(_).join("、")})),o.push({name:t.displayName,status:n.length>0?"warn":"pass",message:[_(s[0]),...n,...n.length>0?[u.t("doctor.run_upgrade",{tool:e})]:[]].join("\n ")})}return o}()),c.push(...await async function(){const o=[];for(const e of L()){const t=await C(e,{refresh:!0});if(!t.installed||!t.current)continue;const s=u.t("doctor.app_version",{tool:t.name});if(t.outdated){const n=t.blocker?u.t(`app_update.blocked_${t.blocker}`,{tool:t.name,url:U(e)?.appInstaller.downloadPage??"",command:S(e)}):u.t("doctor.run_app_upgrade",{command:S(e)});o.push({name:s,status:"warn",message:`${H(t)}\n ${n}`})}else o.push({name:s,status:"pass",message:H(t)})}return o}());const W=function(){if(!p.isToolInstalled("claude-code"))return null;const o=u.t("doctor.claude_config"),e=h();if(e.length>0){const t=e.map(o=>`${o.source}: ${o.keys.join(", ")}`).join("; ");return{name:o,status:"fail",message:u.t("doctor.claude_managed",{detail:t})}}let t={};try{t=JSON.parse(a(i(process.env.CLAUDE_CONFIG_DIR?.trim()||i(j(),".claude"),"settings.json"),"utf-8")).env??{}}catch{}const s=l.getApiKeyForTool("claude-code");return t.ANTHROPIC_AUTH_TOKEN&&t.ANTHROPIC_BASE_URL?t.ANTHROPIC_BASE_URL!==l.getBaseUrl()||s&&t.ANTHROPIC_AUTH_TOKEN!==s?{name:o,status:"warn",message:u.t("doctor.claude_config_changed")}:{name:o,status:"pass"}:{name:o,status:"warn",message:u.t("doctor.claude_not_configured")}}();W&&c.push(W),V.includes("claude-code")&&v()&&c.push({name:u.t("doctor.claude_login"),status:"pass",message:u.t("tools.claude_code.account_login_overridden")});const z=V.includes("codex")?y():null;if(V.includes("codex")&&c.push({name:u.t("doctor.codex_auth"),status:z?"fail":"pass",message:z?u.t(`doctor.codex_${z}`,{path:P(w())}):void 0}),V.includes("codex")){const o=k();c.push({name:u.t("doctor.codex_catalog"),status:o?"fail":"pass",message:o?u.t("doctor.codex_catalog_rejected",{path:o.bin,version:o.version??"?",error:o.error}):void 0})}V.includes("codex")&&b()&&c.push({name:u.t("doctor.codex_work_mode"),status:"warn",message:u.t("tools.codex.work_mode_on")}),"win32"===process.platform&&V.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&c.push({name:"Git for Windows",status:p.isGitInstalled()?"pass":"warn",message:p.isGitInstalled()?void 0:u.t("tools.claude_code.no_git_bash")}),n.deep&&V.includes("claude-code")&&(r.text=u.t("doctor.check_claude_request"),c.push(function(){const o=u.t("doctor.claude_request"),e=g(f("claude-code").installSpec)[0];if(!e)return{name:o,status:"warn",message:u.t("doctor.claude_request_skipped")};const t={encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},n=["-p","Reply with the single word OK."],r=/\.cmd$/i.test(e.path)?s(`"${e.path}" ${n.map(o=>`"${o}"`).join(" ")}`,{...t,shell:!0}):s(e.path,n,t),a=`${r.stdout??""}`.trim();if(0===r.status&&a)return{name:o,status:"pass",message:a.slice(0,80)};const c=(`${r.stderr??""}`.trim()||a||r.error?.message||`exit ${r.status}`).slice(0,300);return{name:o,status:"fail",message:u.t("doctor.claude_request_failed",{reason:c})}}())),r.stop(),console.log("\n"+e.bold(u.t("doctor.results_title"))+"\n");const J={pass:e.green("√"),warn:e.yellow("!"),fail:e.red("×")};for(const o of c)console.log(`${J[o.status]} ${o.name}`),o.message&&console.log(e.gray(` ${o.message}`));if(c.every(o=>"pass"===o.status)&&console.log("\n"+e.green.bold(u.t("doctor.all_good"))),!n.deep&&V.includes("claude-code")&&console.log(e.gray("\n"+u.t("doctor.deep_hint"))),n.report){const o=t(u.t("doctor.report_uploading")).start(),e=await O(function(o,e){const t={};for(const o of T()){if(o.hidden)continue;let e=null;try{e=p.detectCurrentConfig(o.name).apiKey?"has_key":"no_key"}catch{e="unreadable"}t[o.name]={installed:p.isToolInstalled(o.name),version:p.installedVersion(o.name),copies:o.installSpec?g(o.installSpec).map(o=>({kind:o.kind,version:o.version,path:o.path})):void 0,config:e}}const s=l.getProfile();return{checks:o,tools:t,settings:{base_url:l.getBaseUrl(),profile:l.getActiveProfileName(),profiles:l.listProfiles().length,key_fingerprint:l.getApiKeyFingerprint()||null,tool_keys:Object.keys(s.tool_api_keys??{}),models:s.models,tool_models:s.tool_models??{},tool_settings:s.tool_settings??{},lang:l.getLang()},client_config:e,env:{shell:process.env.SHELL??process.env.ComSpec??null,term:process.env.TERM_PROGRAM??null,proxies:M()},log:F()}}(c,{source:Y.source??void 0,revision:Y.revision,problem:Y.problem}));e?o.succeed(u.t("doctor.report_done",{code:e})):o.fail(u.t("doctor.report_failed",{cli:I}))}else c.some(o=>"fail"===o.status)&&console.log(e.gray("\n"+u.t("doctor.report_hint",{cli:I})));const Q=c.filter(o=>"fail"===o.status);Q.length>0&&(N(Q.map(o=>o.message?`${o.name}: ${o.message}`:o.name).join("; ")),process.exitCode=1)}
@@ -12,6 +12,16 @@ export interface BrandPluginMarketplace {
12
12
  add: string;
13
13
  probe: string;
14
14
  }
15
+ /** Names on the gateway's API; see src/lib/gateway-protocol.ts. */
16
+ export interface GatewayProtocol {
17
+ clientConfigPath: string;
18
+ keyInfoPath: string;
19
+ telemetryPath: string;
20
+ reportPath: string;
21
+ clientSection: string;
22
+ minClientVersion: string;
23
+ installIdHeader: string;
24
+ }
15
25
  export interface Brand {
16
26
  id: string;
17
27
  /** Provider name shown to users and written into tool configs, e.g. `name = "VibeAPI"` in Codex. */
@@ -34,6 +44,8 @@ export interface Brand {
34
44
  desktopEntryName: string;
35
45
  /** npm package name used by the update check when package.json is unreadable. */
36
46
  packageName: string;
47
+ /** Only the default brand sets this: the names its gateway serves. Everyone else uses the neutral set. */
48
+ gatewayProtocol?: Partial<GatewayProtocol>;
37
49
  /** Built-in gateway addresses; the order is the priority (first = main site). */
38
50
  gatewayAddresses: BrandGatewayAddress[];
39
51
  links: {
@@ -1 +1 @@
1
- import{i18n as n,detectSystemLang as o}from"./i18n.js";import{configManager as r}from"./config.js";import{runModelRefresh as t}from"./model-refresh.js";import{refreshClientConfig as e}from"./client-config-sync.js";import{normalizeBaseUrl as i}from"./gateway-addresses.js";import s from"chalk";import{setRuntimeOptions as m,detectColorPreferenceFromEnv as a,isDryRun as c}from"./runtime-options.js";import{runStartupUpdate as d}from"./auto-update.js";import{buildProgram as l}from"./program.js";import{firstCommandWord as u,isHelpRequest as p,renderHelpTopic as g}from"./cli-help.js";import{reportCliError as f,usageError as h,CliError as _}from"./errors.js";import{CLI_NAME as y}from"./brand.js";import{dryRunUnsupportedCommand as w}from"./dry-run.js";import{flushTelemetry as j,installClientHeaders as k,maskSecrets as v,setTelemetryCommand as C,track as x}from"./telemetry.js";export{buildProgram}from"./program.js";const A=new Set(["setup","init","auth","enter","config"]);export class Command{program;configuring=!1;constructor(){const t=r.isLangChosen()?r.getLang():o();n.loadFromConfig(t),this.program=l()}preflightArgs(n){const o=o=>n.includes(o),t=!o("--no-color")&&a();if(m({nonInteractive:o("--non-interactive"),json:o("--json"),yes:o("--yes")||o("-y"),dryRun:o("--dry-run"),color:t}),t||(s.level=0),this.configuring=!1,p(n))return;let e;for(let o=0;o<n.length;o+=1){const r=n[o];"--base"===r&&n[o+1]?(e=n[o+1],o+=1):r.startsWith("--base=")&&(e=r.slice(7))}const c=u(n),d=void 0===c&&!["--version","-v"].some(o);this.configuring=d||void 0!==c&&A.has(c),e&&r.setBaseUrl(i(e)??e,this.configuring&&!o("--dry-run"))}async execute(n){const o=Date.now();let r=!1;try{if(this.preflightArgs(n),k(),p(n)||["--version","-v"].some(o=>n.includes(o))||(C(u(n)??"wizard"),x("command","start",{detail:{args:n.filter(n=>n.startsWith("-")&&!/key/i.test(n))}}),r=!0),"help"===n[0]&&n[1]){const o=g(n[1]);if(o)return void process.stdout.write(o)}if(this.rejectUnknownCommand(n),!p(n)){if(c()&&this.rejectUnsupportedDryRun(n),(await d(n)).handled)return;this.configuring&&await e({timeoutMs:5e3}),await t(n)}if(await this.program.parseAsync(n,{from:"user"}),r){const n=Boolean(process.exitCode)&&0!==process.exitCode;x("command",n?"fail":"ok",{duration_ms:Date.now()-o,...n?{detail:{exit_code:process.exitCode}}:{}})}}catch(t){if("commander.helpDisplayed"===t?.code||"commander.version"===t?.code)return;const e=this.normalizeCommanderError(t,n),i=f(e);if(r){const n=e instanceof _?`${e.type}${e.subtype?"/"+e.subtype:""}`:void 0;x("command",130===i?"cancel":"fail",{duration_ms:Date.now()-o,error:e,detail:{exit_code:i,...n?{type:n}:{}}})}}finally{r&&await j()}}rejectUnsupportedDryRun(o){const r=w(o);if(null!==r)throw h(n.t("runtime.dry_run_unsupported",{command:r,cli:y}),n.t("runtime.dry_run_unsupported_hint",{cli:y}),"dry_run_unsupported")}rejectUnknownCommand(o){const r=u(o);if(!r||"help"===r)return;if(this.program.commands.some(n=>n.name()===r))return;const t=this.suggestCommand(r),e=t?n.t("cli.unknown_hint_suggestion",{command:t}):n.t("cli.unknown_hint");throw h(n.t("cli.error_unknown",{command:r}),e,"unknown_command")}suggestCommand(n){const o=(n,o)=>{const r=Array.from({length:o.length+1},(n,o)=>o);for(let t=1;t<=n.length;t+=1){let e=r[0];r[0]=t;for(let i=1;i<=o.length;i+=1){const s=r[i];r[i]=Math.min(r[i]+1,r[i-1]+1,e+(n[t-1]===o[i-1]?0:1)),e=s}}return r[o.length]};return this.program.commands.map(n=>n.name()).map(r=>({name:r,score:o(n,r)})).filter(({score:o})=>o<=Math.max(2,Math.floor(n.length/2))).sort((n,o)=>n.score-o.score)[0]?.name}normalizeCommanderError(o,r){if(o instanceof _)return o;const t=o?.code,e=o instanceof Error?o.message:String(o);if("commander.unknownOption"===t||"commander.missingArgument"===t||"commander.missingMandatoryOption"===t||"commander.invalidArgument"===t){const o=u(r),i=/'([^']+)'/.exec(e)?.[1]??"",s="commander.unknownOption"===t?"cli.err_unknown_option":"commander.missingArgument"===t?"cli.err_missing_argument":"commander.missingMandatoryOption"===t?"cli.err_missing_option":null,m="commander.unknownOption"===t?this.gluedOption(i):void 0,a=v(i),c=m?n.t("cli.err_glued_option",{name:a,option:m}):s&&i?n.t(s,{name:a}):v(e.replace(/^error:\s*/,""));return h(c,o?n.t("cli.unknown_option_hint",{command:o}):n.t("cli.unknown_option_hint_root"),t)}return o}gluedOption(n){const o=new Set,r=n=>{for(const r of n.options)r.long&&o.add(r.long);for(const o of n.commands)r(o)};return r(this.program),[...o].filter(o=>n.length>o.length&&n.startsWith(o)).sort((n,o)=>o.length-n.length)[0]}getProgram(){return this.program}}
1
+ import{i18n as n,detectSystemLang as o}from"./i18n.js";import{configManager as r}from"./config.js";import{runModelRefresh as t}from"./model-refresh.js";import{refreshClientConfig as e}from"./client-config-sync.js";import{normalizeBaseUrl as i}from"./gateway-addresses.js";import s from"chalk";import{setRuntimeOptions as m,detectColorPreferenceFromEnv as a,isDryRun as c}from"./runtime-options.js";import{runStartupUpdate as d}from"./auto-update.js";import{buildProgram as l}from"./program.js";import{firstCommandWord as u,isHelpRequest as p,renderHelpTopic as g}from"./cli-help.js";import{reportCliError as f,usageError as h,CliError as _}from"./errors.js";import{CLI_NAME as y}from"./brand.js";import{dryRunUnsupportedCommand as w}from"./dry-run.js";import{flushTelemetry as j,installClientHeaders as k,lastFailureReason as v,maskSecrets as C,setTelemetryCommand as x,track as A,watchConsoleErrors as O}from"./telemetry.js";export{buildProgram}from"./program.js";const b=new Set(["setup","init","auth","enter","config"]);export class Command{program;configuring=!1;constructor(){const t=r.isLangChosen()?r.getLang():o();n.loadFromConfig(t),this.program=l()}preflightArgs(n){const o=o=>n.includes(o),t=!o("--no-color")&&a();if(m({nonInteractive:o("--non-interactive"),json:o("--json"),yes:o("--yes")||o("-y"),dryRun:o("--dry-run"),color:t}),t||(s.level=0),this.configuring=!1,p(n))return;let e;for(let o=0;o<n.length;o+=1){const r=n[o];"--base"===r&&n[o+1]?(e=n[o+1],o+=1):r.startsWith("--base=")&&(e=r.slice(7))}const c=u(n),d=void 0===c&&!["--version","-v"].some(o);this.configuring=d||void 0!==c&&b.has(c),e&&r.setBaseUrl(i(e)??e,this.configuring&&!o("--dry-run"))}async execute(n){const o=Date.now();let r=!1;try{if(this.preflightArgs(n),k(),p(n)||["--version","-v"].some(o=>n.includes(o))||(x(u(n)??"wizard"),A("command","start",{detail:{args:n.filter(n=>n.startsWith("-")&&!/key/i.test(n))}}),r=!0,O()),"help"===n[0]&&n[1]){const o=g(n[1]);if(o)return void process.stdout.write(o)}if(this.rejectUnknownCommand(n),!p(n)){if(c()&&this.rejectUnsupportedDryRun(n),(await d(n)).handled)return;this.configuring&&await e({timeoutMs:5e3}),await t(n)}if(await this.program.parseAsync(n,{from:"user"}),r){const n=Boolean(process.exitCode)&&0!==process.exitCode;A("command",n?"fail":"ok",{duration_ms:Date.now()-o,...n?{error:v(),detail:{exit_code:process.exitCode}}:{}})}}catch(t){if("commander.helpDisplayed"===t?.code||"commander.version"===t?.code)return;const e=this.normalizeCommanderError(t,n),i=f(e);if(r){const n=e instanceof _?`${e.type}${e.subtype?"/"+e.subtype:""}`:void 0;A("command",130===i?"cancel":"fail",{duration_ms:Date.now()-o,error:e,detail:{exit_code:i,...n?{type:n}:{}}})}}finally{r&&await j()}}rejectUnsupportedDryRun(o){const r=w(o);if(null!==r)throw h(n.t("runtime.dry_run_unsupported",{command:r,cli:y}),n.t("runtime.dry_run_unsupported_hint",{cli:y}),"dry_run_unsupported")}rejectUnknownCommand(o){const r=u(o);if(!r||"help"===r)return;if(this.program.commands.some(n=>n.name()===r))return;const t=this.suggestCommand(r),e=t?n.t("cli.unknown_hint_suggestion",{command:t}):n.t("cli.unknown_hint");throw h(n.t("cli.error_unknown",{command:r}),e,"unknown_command")}suggestCommand(n){const o=(n,o)=>{const r=Array.from({length:o.length+1},(n,o)=>o);for(let t=1;t<=n.length;t+=1){let e=r[0];r[0]=t;for(let i=1;i<=o.length;i+=1){const s=r[i];r[i]=Math.min(r[i]+1,r[i-1]+1,e+(n[t-1]===o[i-1]?0:1)),e=s}}return r[o.length]};return this.program.commands.map(n=>n.name()).map(r=>({name:r,score:o(n,r)})).filter(({score:o})=>o<=Math.max(2,Math.floor(n.length/2))).sort((n,o)=>n.score-o.score)[0]?.name}normalizeCommanderError(o,r){if(o instanceof _)return o;const t=o?.code,e=o instanceof Error?o.message:String(o);if("commander.unknownOption"===t||"commander.missingArgument"===t||"commander.missingMandatoryOption"===t||"commander.invalidArgument"===t){const o=u(r),i=/'([^']+)'/.exec(e)?.[1]??"",s="commander.unknownOption"===t?"cli.err_unknown_option":"commander.missingArgument"===t?"cli.err_missing_argument":"commander.missingMandatoryOption"===t?"cli.err_missing_option":null,m="commander.unknownOption"===t?this.gluedOption(i):void 0,a=C(i),c=m?n.t("cli.err_glued_option",{name:a,option:m}):s&&i?n.t(s,{name:a}):C(e.replace(/^error:\s*/,""));return h(c,o?n.t("cli.unknown_option_hint",{command:o}):n.t("cli.unknown_option_hint_root"),t)}return o}gluedOption(n){const o=new Set,r=n=>{for(const r of n.options)r.long&&o.add(r.long);for(const o of n.commands)r(o)};return r(this.program),[...o].filter(o=>n.length>o.length&&n.startsWith(o)).sort((n,o)=>o.length-n.length)[0]}getProgram(){return this.program}}
@@ -1,15 +1,21 @@
1
+ import { type GatewayProtocol } from './brand.js';
1
2
  /**
2
- * Names fixed by the gateway's API (New API `controller/vibecode_*.go`). They are part of the wire
3
- * format every site serves, not branding, so a white-label build keeps them; the package leak check
4
- * (`scripts/brands.mjs`) allows them in this module only — keep every such name here.
3
+ * Names on the gateway's API. They come from the brand: a white-label build uses the neutral set below
4
+ * (same values as `NEUTRAL_GATEWAY_PROTOCOL` in scripts/brands.mjs) and the default brand's file keeps the
5
+ * names its old gateway serves. No brand's names may be written in `src/`; the package leak check has no exemptions.
5
6
  */
7
+ export declare const NEUTRAL_GATEWAY_PROTOCOL: GatewayProtocol;
6
8
  /** Client configuration for the coding tools (models, defaults, rollout). */
7
- export declare const CLIENT_CONFIG_PATH = "/api/platform/vibecode/config";
9
+ export declare const CLIENT_CONFIG_PATH: string;
8
10
  /** Per-key group and group-model table. */
9
- export declare const KEY_INFO_PATH = "/api/platform/vibecode/key";
11
+ export declare const KEY_INFO_PATH: string;
12
+ /** Step events. */
13
+ export declare const TELEMETRY_PATH: string;
14
+ /** Diagnostic reports. */
15
+ export declare const REPORT_PATH: string;
10
16
  /** Section of the client configuration that belongs to this CLI. */
11
- export declare const CLIENT_SECTION = "vibecli";
17
+ export declare const CLIENT_SECTION: string;
12
18
  /** Model-row field: lowest CLI version that may see the row. */
13
- export declare const MIN_CLIENT_VERSION = "min_vibecli_version";
19
+ export declare const MIN_CLIENT_VERSION: string;
14
20
  /** Request header carrying the install id, so support can match a machine's events and reports. */
15
- export declare const INSTALL_ID_HEADER = "X-VibeCLI-Install-Id";
21
+ export declare const INSTALL_ID_HEADER: string;
@@ -1 +1 @@
1
- export const CLIENT_CONFIG_PATH="/api/platform/vibecode/config";export const KEY_INFO_PATH="/api/platform/vibecode/key";export const CLIENT_SECTION="vibecli";export const MIN_CLIENT_VERSION="min_vibecli_version";export const INSTALL_ID_HEADER="X-VibeCLI-Install-Id";
1
+ import{brand as t}from"./brand.js";export const NEUTRAL_GATEWAY_PROTOCOL={clientConfigPath:"/api/platform/cli/config",keyInfoPath:"/api/platform/cli/key",telemetryPath:"/api/platform/cli/telemetry",reportPath:"/api/platform/cli/report",clientSection:"cli_client",minClientVersion:"min_cli_version",installIdHeader:"X-CLI-Install-Id"};const e={...NEUTRAL_GATEWAY_PROTOCOL,...t().gatewayProtocol};export const CLIENT_CONFIG_PATH=e.clientConfigPath;export const KEY_INFO_PATH=e.keyInfoPath;export const TELEMETRY_PATH=e.telemetryPath;export const REPORT_PATH=e.reportPath;export const CLIENT_SECTION=e.clientSection;export const MIN_CLIENT_VERSION=e.minClientVersion;export const INSTALL_ID_HEADER=e.installIdHeader;
@@ -39,6 +39,14 @@ export declare function telemetryPending(): boolean;
39
39
  export declare function maskHome(text: string): string;
40
40
  /** API keys anywhere in a text (error messages, logs) become `sk-…abcd`; the home directory becomes `~`. */
41
41
  export declare function maskSecrets(text: string): string;
42
+ /** What a command that ends with a failing exit code told the user; goes with its `command fail` event. */
43
+ export declare function noteFailureReason(reason: string): void;
44
+ export declare function lastFailureReason(): string | undefined;
45
+ /**
46
+ * Commands report most failures with console.error and a plain exit code, without throwing: remember the last one,
47
+ * or support sees `exit_code: 1` and no reason. Spinners write to stderr directly, so their frames don't count.
48
+ */
49
+ export declare function watchConsoleErrors(): void;
42
50
  /** The command this process runs (`setup`, `config`, … or `wizard`), recorded with every event. */
43
51
  export declare function setTelemetryCommand(name: string): void;
44
52
  export declare function track(step: string, status: StepStatus, extra?: {
@@ -1 +1 @@
1
- import{randomUUID as e}from"crypto";import{arch as t,homedir as r,release as o}from"os";import{brand as n,brandEnv as s,CLI_NAME as a}from"./brand.js";import{clientVersion as i,installId as c}from"./client-config.js";import{configManager as l}from"./config.js";import{gatewayAddresses as u}from"./gateway-addresses.js";import{INSTALL_ID_HEADER as p}from"./gateway-protocol.js";const d=e();let f="wizard",m=[];const g=new Set;let h=null,y=S;export function telemetryEnabled(){if(process.env.VITEST&&!w)return!1;const e=s("TELEMETRY")?.trim().toLowerCase();return!("0"===e||"false"===e||"off"===e)}let w=!1;export function setTelemetrySenderForTests(e){y=e??S,w=null!==e,m=[]}export function clientHeaders(){const e=`${a}/${i()} (${process.platform} ${o()}; ${t()}) node/${process.versions.node}`;return telemetryEnabled()?{"User-Agent":e,[p]:c()}:{"User-Agent":e}}export function installClientHeaders(){const e=globalThis.fetch;if(!e||e.gatewayHeaders)return;const t=(t,r)=>{try{const o=new URL("string"==typeof t||t instanceof URL?t.toString():t.url);if(new Set([l.getBaseUrl(),...u().map(e=>e.url)].map(e=>new URL(e).host)).has(o.host)){const o=new Headers(r?.headers??(t instanceof Request?t.headers:void 0));for(const[e,t]of Object.entries(clientHeaders()))o.has(e)||o.set(e,t);return e(t,{...r,headers:o})}}catch{}return e(t,r)};t.gatewayHeaders=!0,globalThis.fetch=t}export function telemetryPending(){return g.size>0}function T(){return{install_id:c(),cli_version:i(),brand:n().id,os:process.platform,os_release:o(),arch:t(),node_version:process.versions.node}}export function maskHome(e){const t=r();if(!t||t.length<2)return e;const o=new Set([t,t.replace(/\\/g,"/")]);let n=e;for(const e of o)n=n.split(e).join("~");return n}export function maskSecrets(e){return maskHome(e).replace(/(sk-[A-Za-z0-9_-]{2})[A-Za-z0-9_-]{8,}([A-Za-z0-9_-]{4})\b/g,"$1…$2").replace(/(Bearer\s+)[A-Za-z0-9._~+/=-]{8,}/gi,"$1…").replace(/(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+(?::[^\s/@]*)?@/gi,"$1…@").replace(/\b((?:api[_-]?key|token|password|passwd|secret|auth)\s*[=:]\s*)("?)[^\s"&;,]{6,}\2/gi,"$1$2…$2")}export function setTelemetryCommand(e){f=e}export function track(e,t,r={}){if(!telemetryEnabled())return;const o=void 0===r.error?void 0:maskSecrets(r.error instanceof Error?r.error.message:String(r.error)).slice(0,2e3);m.push({ts:Date.now(),session:d,command:f,step:e,status:t,...void 0!==r.duration_ms?{duration_ms:Math.round(r.duration_ms)}:{},...o?{error:o}:{},...r.detail?{detail:r.detail}:{}}),"start"===t?b():h||(h=setTimeout(b,500),h.unref())}export async function trackStep(e,t,r){const o=Date.now();track(e,"start",r?{detail:r}:{});try{const r=await t();return track(e,"ok",{duration_ms:Date.now()-o}),r}catch(t){throw track(e,"fail",{duration_ms:Date.now()-o,error:t}),t}}function b(){if(h&&(clearTimeout(h),h=null),0===m.length)return;const e=m.splice(0,50),t=y("/api/platform/vibecode/telemetry",{...T(),events:e},3e3).then(()=>{},()=>{}).finally(()=>g.delete(t));g.add(t),m.length>0&&b()}export async function flushTelemetry(e=1500){b(),0!==g.size&&await Promise.race([Promise.allSettled([...g]),new Promise(t=>setTimeout(t,e).unref())])}export async function uploadReport(e){try{const t=await y("/api/platform/vibecode/report",{...T(),report:e},2e4),r=t?.data?.code;return"string"==typeof r&&r?r:null}catch{return null}}async function S(e,t,r){const o=l.getApiKey()?.trim(),n=await fetch(new URL(e,l.getBaseUrl()).toString(),{method:"POST",headers:{"Content-Type":"application/json",...clientHeaders(),...o?{Authorization:`Bearer ${o}`}:{}},body:JSON.stringify(t),signal:AbortSignal.timeout(r)});if(!n.ok)throw new Error(`HTTP ${n.status}`);return n.json().catch(()=>null)}
1
+ import{randomUUID as e}from"crypto";import{arch as t,homedir as r,release as o}from"os";import{format as n,stripVTControlCharacters as s}from"util";import{brand as a,brandEnv as i,CLI_NAME as c}from"./brand.js";import{clientVersion as l,installId as u}from"./client-config.js";import{configManager as p}from"./config.js";import{gatewayAddresses as f}from"./gateway-addresses.js";import{INSTALL_ID_HEADER as m,REPORT_PATH as d,TELEMETRY_PATH as g}from"./gateway-protocol.js";const h=e();let w="wizard",y=[];const T=new Set;let x=null,S=z;export function telemetryEnabled(){if(process.env.VITEST&&!k)return!1;const e=i("TELEMETRY")?.trim().toLowerCase();return!("0"===e||"false"===e||"off"===e)}let $,k=!1;export function setTelemetrySenderForTests(e){S=e??z,k=null!==e,y=[]}export function clientHeaders(){const e=`${c}/${l()} (${process.platform} ${o()}; ${t()}) node/${process.versions.node}`;return telemetryEnabled()?{"User-Agent":e,[m]:u()}:{"User-Agent":e}}export function installClientHeaders(){const e=globalThis.fetch;if(!e||e.gatewayHeaders)return;const t=(t,r)=>{try{const o=new URL("string"==typeof t||t instanceof URL?t.toString():t.url);if(new Set([p.getBaseUrl(),...f().map(e=>e.url)].map(e=>new URL(e).host)).has(o.host)){const o=new Headers(r?.headers??(t instanceof Request?t.headers:void 0));for(const[e,t]of Object.entries(clientHeaders()))o.has(e)||o.set(e,t);return e(t,{...r,headers:o})}}catch{}return e(t,r)};t.gatewayHeaders=!0,globalThis.fetch=t}export function telemetryPending(){return T.size>0}function _(){return{install_id:u(),cli_version:l(),brand:a().id,os:process.platform,os_release:o(),arch:t(),node_version:process.versions.node}}export function maskHome(e){const t=r();if(!t||t.length<2)return e;const o=new Set([t,t.replace(/\\/g,"/")]);let n=e;for(const e of o)n=n.split(e).join("~");return n}export function maskSecrets(e){return maskHome(e).replace(/(sk-[A-Za-z0-9_-]{2})[A-Za-z0-9_-]{8,}([A-Za-z0-9_-]{4})\b/g,"$1…$2").replace(/(Bearer\s+)[A-Za-z0-9._~+/=-]{8,}/gi,"$1…").replace(/(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+(?::[^\s/@]*)?@/gi,"$1…@").replace(/\b((?:api[_-]?key|token|password|passwd|secret|auth)\s*[=:]\s*)("?)[^\s"&;,]{6,}\2/gi,"$1$2…$2")}let b=!1;export function noteFailureReason(e){const t=s(e).split("\n").map(e=>e.trim()).filter(Boolean).pop();t&&($=t)}export function lastFailureReason(){return $}export function watchConsoleErrors(){if(b)return;b=!0;const e=console.error;console.error=(...t)=>{noteFailureReason(n(...t)),e.apply(console,t)}}export function setTelemetryCommand(e){w=e}export function track(e,t,r={}){if(!telemetryEnabled())return;const o=void 0===r.error?void 0:maskSecrets(r.error instanceof Error?r.error.message:String(r.error)).slice(0,2e3);y.push({ts:Date.now(),session:h,command:w,step:e,status:t,...void 0!==r.duration_ms?{duration_ms:Math.round(r.duration_ms)}:{},...o?{error:o}:{},...r.detail?{detail:r.detail}:{}}),"start"===t?v():x||(x=setTimeout(v,500),x.unref())}export async function trackStep(e,t,r){const o=Date.now();track(e,"start",r?{detail:r}:{});try{const r=await t();return track(e,"ok",{duration_ms:Date.now()-o}),r}catch(t){throw track(e,"fail",{duration_ms:Date.now()-o,error:t}),t}}function v(){if(x&&(clearTimeout(x),x=null),0===y.length)return;const e=y.splice(0,50),t=S(g,{..._(),events:e},3e3).then(()=>{},()=>{}).finally(()=>T.delete(t));T.add(t),y.length>0&&v()}export async function flushTelemetry(e=1500){v(),0!==T.size&&await Promise.race([Promise.allSettled([...T]),new Promise(t=>setTimeout(t,e).unref())])}export async function uploadReport(e){try{const t=await S(d,{..._(),report:e},2e4),r=t?.data?.code;return"string"==typeof r&&r?r:null}catch{return null}}async function z(e,t,r){const o=p.getApiKey()?.trim(),n=await fetch(new URL(e,p.getBaseUrl()).toString(),{method:"POST",headers:{"Content-Type":"application/json",...clientHeaders(),...o?{Authorization:`Bearer ${o}`}:{}},body:JSON.stringify(t),signal:AbortSignal.timeout(r)});if(!n.ok)throw new Error(`HTTP ${n.status}`);return n.json().catch(()=>null)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeapi/cli",
3
- "version": "0.0.166",
3
+ "version": "0.0.168",
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",