@vibeapi/cli 0.0.167 → 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/commands/doctor.js
CHANGED
|
@@ -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)}
|
package/dist/lib/command.js
CHANGED
|
@@ -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,
|
|
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}}
|
package/dist/lib/telemetry.d.ts
CHANGED
|
@@ -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?: {
|
package/dist/lib/telemetry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID as e}from"crypto";import{arch as t,homedir as r,release as
|
|
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.
|
|
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",
|