tako-cli 0.1.15 → 0.1.17

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/index.js CHANGED
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env bun
2
- // @bun
3
1
  var wr=Object.create;var{getPrototypeOf:nr,defineProperty:y$,getOwnPropertyNames:pr}=Object;var Sr=Object.prototype.hasOwnProperty;var q=(r,m,a)=>{a=r!=null?wr(nr(r)):{};let e=m||!r||!r.__esModule?y$(a,"default",{value:r,enumerable:!0}):a;for(let t of pr(r))if(!Sr.call(e,t))y$(e,t,{get:()=>r[t],enumerable:!0});return e};var w$=(r,m)=>()=>(m||r((m={exports:{}}).exports,m),m.exports);var T=import.meta.require;var r$=w$((s1,Q$)=>{var $$={to(r,m){if(!m)return`\x1B[${r+1}G`;return`\x1B[${m+1};${r+1}H`},move(r,m){let a="";if(r<0)a+=`\x1B[${-r}D`;else if(r>0)a+=`\x1B[${r}C`;if(m<0)a+=`\x1B[${-m}A`;else if(m>0)a+=`\x1B[${m}B`;return a},up:(r=1)=>`\x1B[${r}A`,down:(r=1)=>`\x1B[${r}B`,forward:(r=1)=>`\x1B[${r}C`,backward:(r=1)=>`\x1B[${r}D`,nextLine:(r=1)=>"\x1B[E".repeat(r),prevLine:(r=1)=>"\x1B[F".repeat(r),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},Yr={up:(r=1)=>"\x1B[S".repeat(r),down:(r=1)=>"\x1B[T".repeat(r)},Hr={screen:"\x1B[2J",up:(r=1)=>"\x1B[1J".repeat(r),down:(r=1)=>"\x1B[J".repeat(r),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(r){let m="";for(let a=0;a<r;a++)m+=this.line+(a<r-1?$$.up():"");if(r)m+=$$.left;return m}};Q$.exports={cursor:$$,scroll:Yr,erase:Hr,beep:"\x07"}});var a$=w$((b1,m$)=>{var O=process||{},j$=O.argv||[],K=O.env||{},Lr=!(!!K.NO_COLOR||j$.includes("--no-color"))&&(!!K.FORCE_COLOR||j$.includes("--color")||O.platform==="win32"||(O.stdout||{}).isTTY&&K.TERM!=="dumb"||!!K.CI),Vr=(r,m,a=r)=>(e)=>{let t=""+e,h=t.indexOf(m,r.length);return~h?r+Xr(t,m,a,h)+m:r+t+m},Xr=(r,m,a,e)=>{let t="",h=0;do t+=r.substring(h,e)+a,h=e+m.length,e=r.indexOf(m,h);while(~e);return t+r.substring(h)},Y$=(r=Lr)=>{let m=r?Vr:()=>String;return{isColorSupported:r,reset:m("\x1B[0m","\x1B[0m"),bold:m("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:m("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:m("\x1B[3m","\x1B[23m"),underline:m("\x1B[4m","\x1B[24m"),inverse:m("\x1B[7m","\x1B[27m"),hidden:m("\x1B[8m","\x1B[28m"),strikethrough:m("\x1B[9m","\x1B[29m"),black:m("\x1B[30m","\x1B[39m"),red:m("\x1B[31m","\x1B[39m"),green:m("\x1B[32m","\x1B[39m"),yellow:m("\x1B[33m","\x1B[39m"),blue:m("\x1B[34m","\x1B[39m"),magenta:m("\x1B[35m","\x1B[39m"),cyan:m("\x1B[36m","\x1B[39m"),white:m("\x1B[37m","\x1B[39m"),gray:m("\x1B[90m","\x1B[39m"),bgBlack:m("\x1B[40m","\x1B[49m"),bgRed:m("\x1B[41m","\x1B[49m"),bgGreen:m("\x1B[42m","\x1B[49m"),bgYellow:m("\x1B[43m","\x1B[49m"),bgBlue:m("\x1B[44m","\x1B[49m"),bgMagenta:m("\x1B[45m","\x1B[49m"),bgCyan:m("\x1B[46m","\x1B[49m"),bgWhite:m("\x1B[47m","\x1B[49m"),blackBright:m("\x1B[90m","\x1B[39m"),redBright:m("\x1B[91m","\x1B[39m"),greenBright:m("\x1B[92m","\x1B[39m"),yellowBright:m("\x1B[93m","\x1B[39m"),blueBright:m("\x1B[94m","\x1B[39m"),magentaBright:m("\x1B[95m","\x1B[39m"),cyanBright:m("\x1B[96m","\x1B[39m"),whiteBright:m("\x1B[97m","\x1B[39m"),bgBlackBright:m("\x1B[100m","\x1B[49m"),bgRedBright:m("\x1B[101m","\x1B[49m"),bgGreenBright:m("\x1B[102m","\x1B[49m"),bgYellowBright:m("\x1B[103m","\x1B[49m"),bgBlueBright:m("\x1B[104m","\x1B[49m"),bgMagentaBright:m("\x1B[105m","\x1B[49m"),bgCyanBright:m("\x1B[106m","\x1B[49m"),bgWhiteBright:m("\x1B[107m","\x1B[49m")}};m$.exports=Y$();m$.exports.createColors=Y$});import{join as f$}from"path";import{homedir as Mr}from"os";import{join as L}from"path";var Q=L(Mr(),".tako"),p$=L(Q,"config.json"),u=L(Q,"tools"),Z=L(Q,"bun"),p=L(Z,"bin",process.platform==="win32"?"bun.exe":"bun");var M="https://claude-proxy.shiroha.tech",n$={apiKey:"",apiId:"",installedClients:{}};async function S$(){let r=await import("fs/promises");try{await r.mkdir(Q,{recursive:!0}),await r.mkdir(u,{recursive:!0})}catch{}}async function z(){await S$();try{let r=Bun.file(p$);if(await r.exists()){let m=await r.json();return{...n$,...m}}}catch{}return{...n$}}async function qr(r){await S$(),await Bun.write(p$,JSON.stringify(r,null,2))}async function P(r){let a={...await z(),...r};return await qr(a),a}async function M$(){return!!(await z()).apiKey}async function q$(){return(await z()).apiKey}async function W$(){return(await z()).apiId}function G$(r,m){if(!r.startsWith(Q))throw Error(`\u5B89\u5168\u68C0\u67E5\u5931\u8D25: ${m} \u8DEF\u5F84 "${r}" \u4E0D\u5728 Tako \u76EE\u5F55\u4E0B`)}function I(r){let m=f$(u,r);return G$(m,"\u5BA2\u6237\u7AEF\u5B89\u88C5\u76EE\u5F55"),m}function Z$(r){let m=I(r.id),a=f$(m,"node_modules",".bin",r.command);return G$(a,"\u5BA2\u6237\u7AEF\u53EF\u6267\u884C\u6587\u4EF6"),a}var z$=new Map;function U(r){z$.set(r.id,r)}function J$(){return Array.from(z$.values())}var Wr={id:"claude-code",name:"Claude Code",package:"@anthropic-ai/claude-code",command:"claude",runtime:"bun",getEnvVars(r){return{ANTHROPIC_BASE_URL:`${M}/api`,ANTHROPIC_AUTH_TOKEN:r}}};U(Wr);import{homedir as fr}from"os";import{join as F}from"path";var D=F(fr(),".codex"),Gr=F(D,"config.toml"),Zr=F(D,"auth.json"),zr=`model_provider = "crs"
4
2
  model = "gpt-5-codex"
5
3
  model_reasoning_effort = "high"
@@ -50,6 +48,6 @@ ${s.default.gray(C)} ${r}
50
48
  `)}
51
49
  `)},info:(r)=>{g.message(r,{symbol:s.default.blue(xm)})},success:(r)=>{g.message(r,{symbol:s.default.green(gm)})},step:(r)=>{g.message(r,{symbol:s.default.green(i$)})},warn:(r)=>{g.message(r,{symbol:s.default.yellow(lm)})},warning:(r)=>{g.warn(r)},error:(r)=>{g.message(r,{symbol:s.default.red(dm)})}},f=()=>{let r=o$?["\u25D2","\u25D0","\u25D3","\u25D1"]:["\u2022","o","O","0"],m=o$?80:120,a,e,t=!1,h="",$=(v="")=>{t=!0,a=u$(),h=v.replace(/\.+$/,""),process.stdout.write(`${s.default.gray(y)}
52
50
  `);let o=0,d=0;e=setInterval(()=>{let G=s.default.magenta(r[o]),B=".".repeat(Math.floor(d)).slice(0,3);process.stdout.write(j.cursor.move(-999,0)),process.stdout.write(j.erase.down(1)),process.stdout.write(`${G} ${h}${B}`),o=o+1<r.length?o+1:0,d=d<r.length?d+0.125:0},m)},b=(v="",o=0)=>{h=v??h,t=!1,clearInterval(e);let d=o===0?s.default.green(i$):o===1?s.default.red(F$):s.default.red(D$);process.stdout.write(j.cursor.move(-999,0)),process.stdout.write(j.erase.down(1)),process.stdout.write(`${d} ${h}
53
- `),a()},i=(v="")=>{h=v??h},c=(v)=>{let o=v>1?"Something went wrong":"Canceled";t&&b(o,v)};return process.on("uncaughtExceptionMonitor",()=>c(2)),process.on("unhandledRejection",()=>c(2)),process.on("SIGINT",()=>c(1)),process.on("SIGTERM",()=>c(1)),process.on("exit",c),{start:$,stop:b,message:i}};function wm(r){return r.startsWith("cr_")&&r.length>10}async function nm(r){try{let a=await(await fetch(`${M}/apiStats/api/get-key-id`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r})})).json();if(a.success&&a.data?.id)return{valid:!0,apiId:a.data.id};return{valid:!1,error:a.error||"Key \u9A8C\u8BC1\u5931\u8D25"}}catch(m){return{valid:!1,error:m instanceof Error?m.message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"}}}async function ar(r){if(!wm(r))return{success:!1,error:"Key \u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u5FC5\u987B\u4EE5 cr_ \u5F00\u5934"};let m=await nm(r);if(!m.valid)return{success:!1,error:m.error};return await P({apiKey:r,apiId:m.apiId}),{success:!0}}import{join as sr}from"path";var _=null,x$={cn:{npm:"https://registry.npmmirror.com",bun:"https://bun.sh/install",bunMirror:"https://registry.npmmirror.com/-/binary/bun"},global:{npm:"https://registry.npmjs.org",bun:"https://bun.sh/install",bunMirror:null}};async function k(){if(_)return _;let r=[pm,Sm,Mm];for(let m of r)try{let a=await Promise.race([m(),new Promise((e,t)=>setTimeout(()=>t(Error("timeout")),3000))]);if(a)return _=a,a}catch{}return _="cn","cn"}async function pm(){try{let r=await fetch("http://ip-api.com/json/?fields=countryCode",{signal:AbortSignal.timeout(2000)});if(!r.ok)return null;return(await r.json()).countryCode==="CN"?"cn":"global"}catch{return null}}async function Sm(){try{let r=await fetch("https://ipinfo.io/json",{signal:AbortSignal.timeout(2000)});if(!r.ok)return null;return(await r.json()).country==="CN"?"cn":"global"}catch{return null}}async function Mm(){try{let r=await fetch("https://api.ip.sb/geoip",{signal:AbortSignal.timeout(2000)});if(!r.ok)return null;return(await r.json()).country_code==="CN"?"cn":"global"}catch{return null}}async function qm(){let r=await k();return x$[r]}async function Y(){return(await qm()).npm}async function er(){if(await k()==="cn")return`curl -fsSL https://bun.sh/install | BUN_INSTALL_MIRROR="${x$.cn.bunMirror}" bash`;return"curl -fsSL https://bun.sh/install | bash"}async function tr(){let r=await k(),m=x$[r];if(r==="cn")g.info("\u68C0\u6D4B\u5230\u4E2D\u56FD\u5927\u9646\u7F51\u7EDC\uFF0C\u4F7F\u7528\u56FD\u5185\u955C\u50CF\u6E90"),g.message(` npm: ${m.npm}`);else g.info("\u4F7F\u7528\u56FD\u9645\u6E90")}var J=null;function Wm(r){return r.startsWith(Z)}async function br(){try{if(!await Bun.file(p).exists())return!1;let m=Bun.spawn([p,"--version"],{stdout:"pipe",stderr:"pipe"});return await m.exited,m.exitCode===0}catch{return!1}}async function fm(){if(process.platform==="win32")return!0;try{let m=Bun.spawn(["which","unzip"],{stdout:"pipe",stderr:"pipe"});if(await m.exited,m.exitCode===0)return!0}catch{}g.warn("\u6B63\u5728\u5B89\u88C5\u7CFB\u7EDF\u4F9D\u8D56 (unzip)...");let r=["apt-get update -qq && apt-get install -y -qq unzip","yum install -y -q unzip","dnf install -y -q unzip","pacman -S --noconfirm unzip","apk add --quiet unzip"];for(let m of r)try{let a=Bun.spawn(["bash","-c",`sudo ${m} 2>/dev/null || ${m}`],{stdout:"pipe",stderr:"pipe"});if(await a.exited,a.exitCode===0)return!0}catch{}return!1}async function Gm(){let r=f();if(!await fm())return g.error("\u8BF7\u5148\u624B\u52A8\u5B89\u88C5 unzip: apt install unzip / yum install unzip"),!1;await tr(),r.start("\u6B63\u5728\u5B89\u88C5 Tako \u4E13\u5C5E Bun \u8FD0\u884C\u65F6...");try{await(await import("fs/promises")).mkdir(Z,{recursive:!0});let a;if(process.platform==="win32"){let t=await k()==="cn"?'$env:BUN_INSTALL_MIRROR="https://registry.npmmirror.com/-/binary/bun"; ':"",h=`$env:BUN_INSTALL="${Z}"; ${t}irm bun.sh/install.ps1 | iex`;a=await Bun.spawn(["powershell","-Command",h],{stdout:"inherit",stderr:"inherit"}).exited}else{let e=await er(),t=`BUN_INSTALL="${Z}" ${e}`;a=await Bun.spawn(["bash","-c",t],{stdout:"inherit",stderr:"inherit"}).exited}if(a!==0)return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1;return J=p,r.stop("Tako \u4E13\u5C5E Bun \u5B89\u88C5\u5B8C\u6210"),g.info(`\u5B89\u88C5\u4F4D\u7F6E: ${Z}`),!0}catch(m){return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1}}async function Zm(){if(await br())return J=p,!0;return g.warn("\u672A\u68C0\u6D4B\u5230 Tako \u4E13\u5C5E Bun\uFF0C\u6B63\u5728\u81EA\u52A8\u5B89\u88C5..."),g.info("\uFF08\u4E0D\u4F1A\u5F71\u54CD\u60A8\u7CFB\u7EDF\u4E2D\u5DF2\u5B89\u88C5\u7684 Node.js \u6216 Bun\uFF09"),await Gm()}async function g$(){if(J){if(!Wm(J))J=p;return J}if(await br())return J=p,p;return p}async function cr(r){try{let m=await Y(),a=await fetch(`${m}/${r}/latest`);if(!a.ok)return null;return(await a.json()).version}catch{return null}}async function zm(r){return(await z()).installedClients[r.id]?.version||null}async function or(r){let m=I(r.id),a=sr(m,"package.json");try{return await Bun.file(a).exists()}catch{return!1}}async function ir(r){let m=await zm(r);if(!m)return!0;let a=await cr(r.package);if(!a)return!1;return m!==a}async function hr(r,m=!1){let a=f(),e=I(r.id);try{if(!await Zm())return{success:!1,error:"Tako \u4E13\u5C5E Bun \u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u6216\u624B\u52A8\u5220\u9664 ~/.tako/bun \u76EE\u5F55\u540E\u91CD\u8BD5"};let t=await or(r),h=m||await ir(r);if(t&&!h)return{success:!0};let $=t?"\u66F4\u65B0":"\u5B89\u88C5";a.start(`\u6B63\u5728${$} ${r.name}...`),await(await import("fs/promises")).mkdir(e,{recursive:!0});let i=sr(e,"package.json");if(!await Bun.file(i).exists())await Bun.write(i,JSON.stringify({name:`tako-${r.id}`,private:!0,dependencies:{}},null,2));let v=await g$(),o=await Y(),d=Bun.spawn([v,"add",r.package,"--registry",o],{cwd:e,stdout:"pipe",stderr:"pipe"});if(await d.exited!==0){let E=await new Response(d.stderr).text();return a.stop(`${$} ${r.name} \u5931\u8D25`),{success:!1,error:E}}let B=await cr(r.package);if(B){let E=await z();E.installedClients[r.id]={version:B,installedAt:new Date().toISOString()},await P(E)}return a.stop(`${r.name} ${$}\u5B8C\u6210`),{success:!0}}catch(t){return a.stop("\u64CD\u4F5C\u5931\u8D25"),{success:!1,error:t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}}}async function vr(r){if(!await or(r))return await hr(r);if(await ir(r))return await hr(r,!0);return{success:!0}}async function xr(r){try{let m=await vr(r);if(!m.success)return m;let a=await q$();if(!a)return{success:!1,error:"\u672A\u914D\u7F6E API Key"};if(r.setupConfigFiles)await r.setupConfigFiles(a);let e=Z$(r);if(!await Bun.file(e).exists())return{success:!1,error:`\u627E\u4E0D\u5230\u53EF\u6267\u884C\u6587\u4EF6: ${e}`};let h=r.getEnvVars(a),$={...process.env,...h};g.info(`\u542F\u52A8 ${r.name}...`);let b;if(r.runtime==="native")b=[e];else b=[await g$(),e];return await Bun.spawn(b,{env:$,stdio:["inherit","inherit","inherit"],cwd:process.cwd()}).exited,{success:!0}}catch(m){return{success:!1,error:m instanceof Error?m.message:"\u542F\u52A8\u5931\u8D25"}}}async function l$(){try{let r=await W$();if(!r)return{success:!1,error:"\u672A\u627E\u5230 API ID\uFF0C\u8BF7\u91CD\u65B0\u914D\u7F6E Key"};let a=await(await fetch(`${M}/apiStats/api/user-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r})})).json(),t=await(await fetch(`${M}/apiStats/api/user-model-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r,period:"daily"})})).json();if(!a.success)return{success:!1,error:a.error||a.message||"\u83B7\u53D6\u7EDF\u8BA1\u5931\u8D25"};let h=(t.data||[]).map(($)=>({model:$.model,requests:$.requests,cost:$.formatted?.total||"$0.00"}));return{success:!0,data:{totalRequests:a.data?.usage?.total?.requests||0,totalCost:a.data?.usage?.total?.formattedCost||"$0.00",todayCost:`$${(a.data?.limits?.currentDailyCost||0).toFixed(2)}`,modelStats:h}}}catch(r){return{success:!1,error:r instanceof Error?r.message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"}}}function d$(r){return r.toLocaleString("en-US")}var gr="tako-cli",H="0.1.15";function Jm(r,m){let a=r.split(".").map(Number),e=m.split(".").map(Number);for(let t=0;t<3;t++){let h=a[t]||0,$=e[t]||0;if(h>$)return 1;if(h<$)return-1}return 0}async function Qm(){try{let r=await Y(),m=await fetch(`${r}/${gr}/latest`,{signal:AbortSignal.timeout(5000)});if(!m.ok)return null;return(await m.json()).version||null}catch{return null}}async function jm(){let r=await Qm();if(!r)return{hasUpdate:!1,currentVersion:H};return{hasUpdate:Jm(r,H)>0,latestVersion:r,currentVersion:H}}async function Ym(r){let m=f();m.start(`\u6B63\u5728\u66F4\u65B0\u5230 v${r}...`);try{let a=await Y(),e=Bun.spawn([p,"add","-g",`${gr}@latest`,"--registry",a],{stdout:"pipe",stderr:"pipe"});if(await e.exited,e.exitCode===0)return m.stop(`\u66F4\u65B0\u6210\u529F\uFF01\u5DF2\u66F4\u65B0\u5230 v${r}`),!0;else{let t=await new Response(e.stderr).text();return m.stop(`\u66F4\u65B0\u5931\u8D25: ${t||"\u672A\u77E5\u9519\u8BEF"}`),!1}}catch(a){return m.stop(`\u66F4\u65B0\u5931\u8D25: ${a instanceof Error?a.message:"\u672A\u77E5\u9519\u8BEF"}`),!1}}async function lr(){try{let r=await jm();if(r.hasUpdate&&r.latestVersion){if(g.warn(`\u53D1\u73B0\u65B0\u7248\u672C v${r.latestVersion}\uFF08\u5F53\u524D v${H}\uFF09`),await Ym(r.latestVersion))g.info("\u8BF7\u91CD\u65B0\u542F\u52A8 Tako CLI \u4EE5\u4F7F\u7528\u65B0\u7248\u672C"),process.exit(0)}}catch{}}function Hm(){console.log(),console.log(` \uD83D\uDC19 Tako CLI v${H}`),console.log(" \x1B[90m\u6B22\u8FCE\u4F7F\u7528\uFF01\x1B[0m"),console.log()}async function dr(r=!1){if(!r)g.warn("\u672A\u68C0\u6D4B\u5230 API Key"),console.log();let m=await rr({message:r?"\u8BF7\u8F93\u5165\u65B0\u7684 API Key (cr_xxx):":"\u8BF7\u8F93\u5165\u4F60\u7684 API Key (cr_xxx):",placeholder:"cr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",validate(t){if(!t)return"\u8BF7\u8F93\u5165 API Key";if(!t.startsWith("cr_"))return"Key \u5FC5\u987B\u4EE5 cr_ \u5F00\u5934";if(t.length<10)return"Key \u683C\u5F0F\u4E0D\u6B63\u786E"}});if(X(m))return!1;let a=f();a.start("\u9A8C\u8BC1 Key \u4E2D...");let e=await ar(m);if(e.success)return a.stop("Key \u9A8C\u8BC1\u6210\u529F\uFF01\u5DF2\u4FDD\u5B58\u5230\u914D\u7F6E\u6587\u4EF6"),!0;else return a.stop(`\u9A8C\u8BC1\u5931\u8D25: ${e.error}`),!1}function Lm(r,m){let a=[];if(a.push(""),a.push(" \uD83D\uDCCA \u7528\u91CF\u7EDF\u8BA1"),a.push(""),a.push(` \u603B\u8C03\u7528\u6B21\u6570: ${d$(r.totalRequests)} \u6B21`),a.push(` \u603B\u6D88\u8D39: ${r.totalCost}`),a.push(` \u4ECA\u65E5\u6D88\u8D39: ${r.todayCost}`),r.modelStats.length>0)a.push(""),a.push(" \u6A21\u578B\u4F7F\u7528\u5206\u5E03 (\u4ECA\u65E5):"),r.modelStats.forEach((e,t)=>{let h=t===r.modelStats.length-1?"\u2514\u2500":"\u251C\u2500",$=e.model.length>25?e.model.slice(0,22)+"...":e.model;a.push(` ${h} ${$.padEnd(25)} ${d$(e.requests).padStart(6)} \u6B21 ${e.cost.padStart(8)}`)});return a.push(""),a.push(` \x1B[90m${m}s \u540E\u5237\u65B0 | \u6309\u4EFB\u610F\u952E\u8FD4\u56DE\x1B[0m`),a.join(`
51
+ `),a()},i=(v="")=>{h=v??h},c=(v)=>{let o=v>1?"Something went wrong":"Canceled";t&&b(o,v)};return process.on("uncaughtExceptionMonitor",()=>c(2)),process.on("unhandledRejection",()=>c(2)),process.on("SIGINT",()=>c(1)),process.on("SIGTERM",()=>c(1)),process.on("exit",c),{start:$,stop:b,message:i}};function wm(r){return r.startsWith("cr_")&&r.length>10}async function nm(r){try{let a=await(await fetch(`${M}/apiStats/api/get-key-id`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r})})).json();if(a.success&&a.data?.id)return{valid:!0,apiId:a.data.id};return{valid:!1,error:a.error||"Key \u9A8C\u8BC1\u5931\u8D25"}}catch(m){return{valid:!1,error:m instanceof Error?m.message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"}}}async function ar(r){if(!wm(r))return{success:!1,error:"Key \u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u5FC5\u987B\u4EE5 cr_ \u5F00\u5934"};let m=await nm(r);if(!m.valid)return{success:!1,error:m.error};return await P({apiKey:r,apiId:m.apiId}),{success:!0}}import{join as sr}from"path";var _=null,x$={cn:{npm:"https://registry.npmmirror.com",bun:"https://bun.sh/install",bunMirror:"https://registry.npmmirror.com/-/binary/bun"},global:{npm:"https://registry.npmjs.org",bun:"https://bun.sh/install",bunMirror:null}};async function k(){if(_)return _;let r=[pm,Sm,Mm];for(let m of r)try{let a=await Promise.race([m(),new Promise((e,t)=>setTimeout(()=>t(Error("timeout")),3000))]);if(a)return _=a,a}catch{}return _="cn","cn"}async function pm(){try{let r=await fetch("http://ip-api.com/json/?fields=countryCode",{signal:AbortSignal.timeout(2000)});if(!r.ok)return null;return(await r.json()).countryCode==="CN"?"cn":"global"}catch{return null}}async function Sm(){try{let r=await fetch("https://ipinfo.io/json",{signal:AbortSignal.timeout(2000)});if(!r.ok)return null;return(await r.json()).country==="CN"?"cn":"global"}catch{return null}}async function Mm(){try{let r=await fetch("https://api.ip.sb/geoip",{signal:AbortSignal.timeout(2000)});if(!r.ok)return null;return(await r.json()).country_code==="CN"?"cn":"global"}catch{return null}}async function qm(){let r=await k();return x$[r]}async function Y(){return(await qm()).npm}async function er(){if(await k()==="cn")return`curl -fsSL https://bun.sh/install | BUN_INSTALL_MIRROR="${x$.cn.bunMirror}" bash`;return"curl -fsSL https://bun.sh/install | bash"}async function tr(){let r=await k(),m=x$[r];if(r==="cn")g.info("\u68C0\u6D4B\u5230\u4E2D\u56FD\u5927\u9646\u7F51\u7EDC\uFF0C\u4F7F\u7528\u56FD\u5185\u955C\u50CF\u6E90"),g.message(` npm: ${m.npm}`);else g.info("\u4F7F\u7528\u56FD\u9645\u6E90")}var J=null;function Wm(r){return r.startsWith(Z)}async function br(){try{if(!await Bun.file(p).exists())return!1;let m=Bun.spawn([p,"--version"],{stdout:"pipe",stderr:"pipe"});return await m.exited,m.exitCode===0}catch{return!1}}async function fm(){if(process.platform==="win32")return!0;try{let m=Bun.spawn(["which","unzip"],{stdout:"pipe",stderr:"pipe"});if(await m.exited,m.exitCode===0)return!0}catch{}g.warn("\u6B63\u5728\u5B89\u88C5\u7CFB\u7EDF\u4F9D\u8D56 (unzip)...");let r=["apt-get update -qq && apt-get install -y -qq unzip","yum install -y -q unzip","dnf install -y -q unzip","pacman -S --noconfirm unzip","apk add --quiet unzip"];for(let m of r)try{let a=Bun.spawn(["bash","-c",`sudo ${m} 2>/dev/null || ${m}`],{stdout:"pipe",stderr:"pipe"});if(await a.exited,a.exitCode===0)return!0}catch{}return!1}async function Gm(){let r=f();if(!await fm())return g.error("\u8BF7\u5148\u624B\u52A8\u5B89\u88C5 unzip: apt install unzip / yum install unzip"),!1;await tr(),r.start("\u6B63\u5728\u5B89\u88C5 Tako \u4E13\u5C5E Bun \u8FD0\u884C\u65F6...");try{await(await import("fs/promises")).mkdir(Z,{recursive:!0});let a;if(process.platform==="win32"){let t=await k()==="cn"?'$env:BUN_INSTALL_MIRROR="https://registry.npmmirror.com/-/binary/bun"; ':"",h=`$env:BUN_INSTALL="${Z}"; ${t}irm bun.sh/install.ps1 | iex`;a=await Bun.spawn(["powershell","-Command",h],{stdout:"inherit",stderr:"inherit"}).exited}else{let e=await er(),t=`BUN_INSTALL="${Z}" ${e}`;a=await Bun.spawn(["bash","-c",t],{stdout:"inherit",stderr:"inherit"}).exited}if(a!==0)return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1;return J=p,r.stop("Tako \u4E13\u5C5E Bun \u5B89\u88C5\u5B8C\u6210"),g.info(`\u5B89\u88C5\u4F4D\u7F6E: ${Z}`),!0}catch(m){return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1}}async function Zm(){if(await br())return J=p,!0;return g.warn("\u672A\u68C0\u6D4B\u5230 Tako \u4E13\u5C5E Bun\uFF0C\u6B63\u5728\u81EA\u52A8\u5B89\u88C5..."),g.info("\uFF08\u4E0D\u4F1A\u5F71\u54CD\u60A8\u7CFB\u7EDF\u4E2D\u5DF2\u5B89\u88C5\u7684 Node.js \u6216 Bun\uFF09"),await Gm()}async function g$(){if(J){if(!Wm(J))J=p;return J}if(await br())return J=p,p;return p}async function cr(r){try{let m=await Y(),a=await fetch(`${m}/${r}/latest`);if(!a.ok)return null;return(await a.json()).version}catch{return null}}async function zm(r){return(await z()).installedClients[r.id]?.version||null}async function or(r){let m=I(r.id),a=sr(m,"package.json");try{return await Bun.file(a).exists()}catch{return!1}}async function ir(r){let m=await zm(r);if(!m)return!0;let a=await cr(r.package);if(!a)return!1;return m!==a}async function hr(r,m=!1){let a=f(),e=I(r.id);try{if(!await Zm())return{success:!1,error:"Tako \u4E13\u5C5E Bun \u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u6216\u624B\u52A8\u5220\u9664 ~/.tako/bun \u76EE\u5F55\u540E\u91CD\u8BD5"};let t=await or(r),h=m||await ir(r);if(t&&!h)return{success:!0};let $=t?"\u66F4\u65B0":"\u5B89\u88C5";a.start(`\u6B63\u5728${$} ${r.name}...`),await(await import("fs/promises")).mkdir(e,{recursive:!0});let i=sr(e,"package.json");if(!await Bun.file(i).exists())await Bun.write(i,JSON.stringify({name:`tako-${r.id}`,private:!0,dependencies:{}},null,2));let v=await g$(),o=await Y(),d=Bun.spawn([v,"add",r.package,"--registry",o],{cwd:e,stdout:"pipe",stderr:"pipe"});if(await d.exited!==0){let E=await new Response(d.stderr).text();return a.stop(`${$} ${r.name} \u5931\u8D25`),{success:!1,error:E}}let B=await cr(r.package);if(B){let E=await z();E.installedClients[r.id]={version:B,installedAt:new Date().toISOString()},await P(E)}return a.stop(`${r.name} ${$}\u5B8C\u6210`),{success:!0}}catch(t){return a.stop("\u64CD\u4F5C\u5931\u8D25"),{success:!1,error:t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}}}async function vr(r){if(!await or(r))return await hr(r);if(await ir(r))return await hr(r,!0);return{success:!0}}async function xr(r){try{let m=await vr(r);if(!m.success)return m;let a=await q$();if(!a)return{success:!1,error:"\u672A\u914D\u7F6E API Key"};if(r.setupConfigFiles)await r.setupConfigFiles(a);let e=Z$(r);if(!await Bun.file(e).exists())return{success:!1,error:`\u627E\u4E0D\u5230\u53EF\u6267\u884C\u6587\u4EF6: ${e}`};let h=r.getEnvVars(a),$={...process.env,...h};g.info(`\u542F\u52A8 ${r.name}...`);let b;if(r.runtime==="native")b=[e];else b=[await g$(),e];return await Bun.spawn(b,{env:$,stdio:["inherit","inherit","inherit"],cwd:process.cwd()}).exited,{success:!0}}catch(m){return{success:!1,error:m instanceof Error?m.message:"\u542F\u52A8\u5931\u8D25"}}}async function l$(){try{let r=await W$();if(!r)return{success:!1,error:"\u672A\u627E\u5230 API ID\uFF0C\u8BF7\u91CD\u65B0\u914D\u7F6E Key"};let a=await(await fetch(`${M}/apiStats/api/user-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r})})).json(),t=await(await fetch(`${M}/apiStats/api/user-model-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r,period:"daily"})})).json();if(!a.success)return{success:!1,error:a.error||a.message||"\u83B7\u53D6\u7EDF\u8BA1\u5931\u8D25"};let h=(t.data||[]).map(($)=>({model:$.model,requests:$.requests,cost:$.formatted?.total||"$0.00"}));return{success:!0,data:{totalRequests:a.data?.usage?.total?.requests||0,totalCost:a.data?.usage?.total?.formattedCost||"$0.00",todayCost:`$${(a.data?.limits?.currentDailyCost||0).toFixed(2)}`,modelStats:h}}}catch(r){return{success:!1,error:r instanceof Error?r.message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"}}}function d$(r){return r.toLocaleString("en-US")}var gr="tako-cli",H="0.1.17";function Jm(r,m){let a=r.split(".").map(Number),e=m.split(".").map(Number);for(let t=0;t<3;t++){let h=a[t]||0,$=e[t]||0;if(h>$)return 1;if(h<$)return-1}return 0}async function Qm(){try{let r=await Y(),m=await fetch(`${r}/${gr}/latest`,{signal:AbortSignal.timeout(5000)});if(!m.ok)return null;return(await m.json()).version||null}catch{return null}}async function jm(){let r=await Qm();if(!r)return{hasUpdate:!1,currentVersion:H};return{hasUpdate:Jm(r,H)>0,latestVersion:r,currentVersion:H}}async function Ym(r){let m=f();m.start(`\u6B63\u5728\u66F4\u65B0\u5230 v${r}...`);try{let a=await Y(),e=Bun.spawn([p,"add","-g",`${gr}@latest`,"--registry",a],{stdout:"pipe",stderr:"pipe"});if(await e.exited,e.exitCode===0)return m.stop(`\u66F4\u65B0\u6210\u529F\uFF01\u5DF2\u66F4\u65B0\u5230 v${r}`),!0;else{let t=await new Response(e.stderr).text();return m.stop(`\u66F4\u65B0\u5931\u8D25: ${t||"\u672A\u77E5\u9519\u8BEF"}`),!1}}catch(a){return m.stop(`\u66F4\u65B0\u5931\u8D25: ${a instanceof Error?a.message:"\u672A\u77E5\u9519\u8BEF"}`),!1}}async function lr(){try{let r=await jm();if(r.hasUpdate&&r.latestVersion){if(g.warn(`\u53D1\u73B0\u65B0\u7248\u672C v${r.latestVersion}\uFF08\u5F53\u524D v${H}\uFF09`),await Ym(r.latestVersion))g.info("\u8BF7\u91CD\u65B0\u542F\u52A8 Tako CLI \u4EE5\u4F7F\u7528\u65B0\u7248\u672C"),process.exit(0)}}catch{}}function Hm(){console.log(),console.log(` \uD83D\uDC19 Tako CLI v${H}`),console.log(" \x1B[90m\u6B22\u8FCE\u4F7F\u7528\uFF01\x1B[0m"),console.log()}async function dr(r=!1){if(!r)g.warn("\u672A\u68C0\u6D4B\u5230 API Key"),console.log();let m=await rr({message:r?"\u8BF7\u8F93\u5165\u65B0\u7684 API Key (cr_xxx):":"\u8BF7\u8F93\u5165\u4F60\u7684 API Key (cr_xxx):",placeholder:"cr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",validate(t){if(!t)return"\u8BF7\u8F93\u5165 API Key";if(!t.startsWith("cr_"))return"Key \u5FC5\u987B\u4EE5 cr_ \u5F00\u5934";if(t.length<10)return"Key \u683C\u5F0F\u4E0D\u6B63\u786E"}});if(X(m))return!1;let a=f();a.start("\u9A8C\u8BC1 Key \u4E2D...");let e=await ar(m);if(e.success)return a.stop("Key \u9A8C\u8BC1\u6210\u529F\uFF01\u5DF2\u4FDD\u5B58\u5230\u914D\u7F6E\u6587\u4EF6"),!0;else return a.stop(`\u9A8C\u8BC1\u5931\u8D25: ${e.error}`),!1}function Lm(r,m){let a=[];if(a.push(""),a.push(" \uD83D\uDCCA \u7528\u91CF\u7EDF\u8BA1"),a.push(""),a.push(` \u603B\u8C03\u7528\u6B21\u6570: ${d$(r.totalRequests)} \u6B21`),a.push(` \u603B\u6D88\u8D39: ${r.totalCost}`),a.push(` \u4ECA\u65E5\u6D88\u8D39: ${r.todayCost}`),r.modelStats.length>0)a.push(""),a.push(" \u6A21\u578B\u4F7F\u7528\u5206\u5E03 (\u4ECA\u65E5):"),r.modelStats.forEach((e,t)=>{let h=t===r.modelStats.length-1?"\u2514\u2500":"\u251C\u2500",$=e.model.length>25?e.model.slice(0,22)+"...":e.model;a.push(` ${h} ${$.padEnd(25)} ${d$(e.requests).padStart(6)} \u6B21 ${e.cost.padStart(8)}`)});return a.push(""),a.push(` \x1B[90m${m}s \u540E\u5237\u65B0 | \u6309\u4EFB\u610F\u952E\u8FD4\u56DE\x1B[0m`),a.join(`
54
52
  `)}async function Vm(){let m=f();m.start("\u83B7\u53D6\u7528\u91CF\u7EDF\u8BA1...");let a=await l$();if(!a.success){m.stop(`\u83B7\u53D6\u5931\u8D25: ${a.error}`);return}m.stop("");let e=10,t="",h=()=>{if(t){let b=t.split(`
55
53
  `).length;process.stdout.write(`\x1B[${b}A\x1B[0J`)}t=Lm(a.data,e),console.log(t)};h();let $=process.stdin.isRaw;if(process.stdin.isTTY)process.stdin.setRawMode(!0);return process.stdin.resume(),new Promise((b)=>{let i=!0,c=()=>{if(!i)return;i=!1,o(),b()},v=setInterval(async()=>{if(!i)return;if(e--,e<=0){e=10;let d=await l$();if(d.success)a=d}h()},1000),o=()=>{if(clearInterval(v),process.stdin.removeListener("data",c),process.stdin.isTTY)process.stdin.setRawMode($??!1);process.stdin.pause()};process.stdin.on("data",c)})}async function Xm(){let m=[...J$().map((e)=>({value:{type:"launch",client:e},label:`\u542F\u52A8 ${e.name}`,hint:e.package})),{value:{type:"stats"},label:"\u67E5\u770B\u7528\u91CF\u7EDF\u8BA1"},{value:{type:"config"},label:"\u914D\u7F6E API Key"},{value:{type:"exit"},label:"\u9000\u51FA"}],a=await mr({message:"\u8BF7\u9009\u62E9\u64CD\u4F5C:",options:m});if(X(a))return null;return a}async function km(r){switch(r.type){case"launch":let m=await xr(r.client);if(!m.success)g.error(m.error||"\u542F\u52A8\u5931\u8D25");return!0;case"stats":return await Vm(),!0;case"config":return await dr(!0),!0;case"exit":return!1}}async function yr(){if(Hm(),!await M$()){if(!await dr()){v$("\u518D\u89C1\uFF01");return}}while(!0){let m=await Xm();if(m===null)break;if(!await km(m))break}v$("\u518D\u89C1\uFF01")}async function Bm(){await lr(),await yr()}Bm().catch((r)=>{console.error("Tako CLI \u53D1\u751F\u9519\u8BEF:",r),process.exit(1)});
package/install.ps1 CHANGED
@@ -144,19 +144,29 @@ function Create-Command {
144
144
  New-Item -ItemType Directory -Force -Path $TAKO_BIN_DIR | Out-Null
145
145
 
146
146
  # 创建 tako.cmd 批处理文件
147
+ # 使用 ASCII 编码避免乱码问题
147
148
  $cmdContent = @"
148
149
  @echo off
149
150
  "$bun" "$TakoEntry" %*
151
+ exit /b %ERRORLEVEL%
150
152
  "@
151
- $cmdContent | Out-File -FilePath "$TAKO_BIN_DIR\tako.cmd" -Encoding ASCII
153
+
154
+ # 使用 ASCII 字节数组直接写入,避免编码问题
155
+ $bytes = [System.Text.Encoding]::ASCII.GetBytes($cmdContent)
156
+ [System.IO.File]::WriteAllBytes("$TAKO_BIN_DIR\tako.cmd", $bytes)
152
157
 
153
158
  # 创建 tako.ps1 PowerShell 脚本(可选)
154
159
  $ps1Content = @"
155
160
  & "$bun" "$TakoEntry" @args
161
+ exit `$LASTEXITCODE
156
162
  "@
157
- $ps1Content | Out-File -FilePath "$TAKO_BIN_DIR\tako.ps1" -Encoding UTF8
163
+ # PowerShell 脚本使用 UTF8 编码
164
+ $ps1Bytes = [System.Text.Encoding]::UTF8.GetBytes($ps1Content)
165
+ [System.IO.File]::WriteAllBytes("$TAKO_BIN_DIR\tako.ps1", $ps1Bytes)
158
166
 
159
- Write-Info "tako 命令已创建: $TAKO_BIN_DIR\tako.cmd"
167
+ Write-Info "tako 命令已创建:"
168
+ Write-Info " - $TAKO_BIN_DIR\tako.cmd"
169
+ Write-Info " - $TAKO_BIN_DIR\tako.ps1"
160
170
  }
161
171
 
162
172
  # 配置 PATH 环境变量
@@ -182,22 +192,39 @@ function Setup-Path {
182
192
 
183
193
  # 验证安装
184
194
  function Verify-Installation {
185
- # 刷新环境变量
195
+ # 刷新当前会话的环境变量
186
196
  $env:Path = "$TAKO_BIN_DIR;$env:Path"
187
197
 
188
198
  $takoCmd = "$TAKO_BIN_DIR\tako.cmd"
199
+ $takoCmdPs1 = "$TAKO_BIN_DIR\tako.ps1"
189
200
 
190
201
  if (Test-Path $takoCmd) {
191
202
  Write-Host ""
192
- Write-Info "安装成功!"
203
+ Write-Host "安装成功!" -ForegroundColor Green
193
204
  Write-Host ""
194
205
  Write-Host " 运行 'tako' 开始使用" -ForegroundColor Cyan
195
206
  Write-Host ""
196
- Write-Host " 注意: 如果 'tako' 命令无法识别,请重新打开终端或运行:" -ForegroundColor Yellow
197
- Write-Host " `$env:Path = `"$TAKO_BIN_DIR;`$env:Path`"" -ForegroundColor Cyan
207
+
208
+ # 测试 tako 命令是否可用
209
+ try {
210
+ $testResult = & $takoCmd --version 2>&1
211
+ if ($LASTEXITCODE -eq 0 -or $testResult) {
212
+ Write-Host " ✓ tako 命令已可用" -ForegroundColor Green
213
+ }
214
+ } catch {
215
+ Write-Host " 注意: 如果 'tako' 命令无法识别,请尝试:" -ForegroundColor Yellow
216
+ Write-Host ""
217
+ Write-Host " 1. 重新打开终端窗口 (推荐)" -ForegroundColor Cyan
218
+ Write-Host ""
219
+ Write-Host " 2. 或在当前终端运行:" -ForegroundColor Cyan
220
+ Write-Host " `$env:Path = `"$TAKO_BIN_DIR;`$env:Path`"" -ForegroundColor Gray
221
+ Write-Host ""
222
+ Write-Host " 3. 或直接使用完整路径:" -ForegroundColor Cyan
223
+ Write-Host " $takoCmd" -ForegroundColor Gray
224
+ }
198
225
  Write-Host ""
199
226
  } else {
200
- Write-Err "安装验证失败"
227
+ Write-Err "安装验证失败: tako.cmd 文件不存在"
201
228
  }
202
229
  }
203
230
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tako-cli",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Tako CLI - AI coding tools launcher",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,7 +14,7 @@
14
14
  "scripts": {
15
15
  "build": "bun run scripts/build.ts",
16
16
  "bump": "bun scripts/bump.ts",
17
- "release": "bun scripts/bump.ts patch && npm publish",
17
+ "release": "bun scripts/bump.ts patch && npm publish && bun scripts/sync-gitee.ts",
18
18
  "prepublishOnly": "bun run build"
19
19
  },
20
20
  "devDependencies": {