tako-cli 0.1.16 → 0.1.18

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.16";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.18";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
@@ -113,7 +113,8 @@ function Install-Tako {
113
113
  }
114
114
 
115
115
  # 安装 tako-cli
116
- & $bun add tako-cli --registry $registry
116
+ # 使用 Out-Host 确保输出不会作为返回值的一部分
117
+ & $bun add tako-cli --registry $registry | Out-Host
117
118
 
118
119
  if ($LASTEXITCODE -ne 0) {
119
120
  Write-Err "Tako CLI 安装失败"
@@ -144,20 +145,25 @@ function Create-Command {
144
145
  New-Item -ItemType Directory -Force -Path $TAKO_BIN_DIR | Out-Null
145
146
 
146
147
  # 创建 tako.cmd 批处理文件
147
- # 使用单引号 here-string 防止变量展开,然后手动替换
148
- $cmdTemplate = @'
148
+ # 使用 ASCII 编码避免乱码问题
149
+ $cmdContent = @"
149
150
  @echo off
150
- "{{BUN_PATH}}" "{{TAKO_ENTRY}}" %*
151
- '@
152
- $cmdContent = $cmdTemplate.Replace("{{BUN_PATH}}", $bun).Replace("{{TAKO_ENTRY}}", $TakoEntry)
153
- [System.IO.File]::WriteAllText("$TAKO_BIN_DIR\tako.cmd", $cmdContent)
151
+ "$bun" "$TakoEntry" %*
152
+ exit /b %ERRORLEVEL%
153
+ "@
154
+
155
+ # 使用 ASCII 字节数组直接写入,避免编码问题
156
+ $bytes = [System.Text.Encoding]::ASCII.GetBytes($cmdContent)
157
+ [System.IO.File]::WriteAllBytes("$TAKO_BIN_DIR\tako.cmd", $bytes)
154
158
 
155
159
  # 创建 tako.ps1 PowerShell 脚本(可选)
156
- $ps1Template = @'
157
- & "{{BUN_PATH}}" "{{TAKO_ENTRY}}" @args
158
- '@
159
- $ps1Content = $ps1Template.Replace("{{BUN_PATH}}", $bun).Replace("{{TAKO_ENTRY}}", $TakoEntry)
160
- [System.IO.File]::WriteAllText("$TAKO_BIN_DIR\tako.ps1", $ps1Content, [System.Text.Encoding]::UTF8)
160
+ $ps1Content = @"
161
+ & "$bun" "$TakoEntry" @args
162
+ exit `$LASTEXITCODE
163
+ "@
164
+ # PowerShell 脚本使用 UTF8 编码
165
+ $ps1Bytes = [System.Text.Encoding]::UTF8.GetBytes($ps1Content)
166
+ [System.IO.File]::WriteAllBytes("$TAKO_BIN_DIR\tako.ps1", $ps1Bytes)
161
167
 
162
168
  Write-Info "tako 命令已创建:"
163
169
  Write-Info " - $TAKO_BIN_DIR\tako.cmd"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tako-cli",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Tako CLI - AI coding tools launcher",
5
5
  "type": "module",
6
6
  "bin": {