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 +1 -3
- package/install.ps1 +35 -8
- package/package.json +2 -2
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
|
-
|
|
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
|
-
|
|
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 命令已创建:
|
|
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-
|
|
203
|
+
Write-Host " ✓ 安装成功!" -ForegroundColor Green
|
|
193
204
|
Write-Host ""
|
|
194
205
|
Write-Host " 运行 'tako' 开始使用" -ForegroundColor Cyan
|
|
195
206
|
Write-Host ""
|
|
196
|
-
|
|
197
|
-
|
|
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.
|
|
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": {
|