tako-cli 0.1.32 → 0.1.33

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.
Files changed (2) hide show
  1. package/dist/index.js +2 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ ${c.default.gray(D)} ${r}
48
48
  `)}
49
49
  `)},info:(r)=>{d.message(r,{symbol:c.default.blue(pm)})},success:(r)=>{d.message(r,{symbol:c.default.green(lm)})},step:(r)=>{d.message(r,{symbol:c.default.green(p$)})},warn:(r)=>{d.message(r,{symbol:c.default.yellow(qm)})},warning:(r)=>{d.warn(r)},error:(r)=>{d.message(r,{symbol:c.default.red(Wm)})}},S=()=>{const r=M$?["\u25D2","\u25D0","\u25D3","\u25D1"]:["\u2022","o","O","0"],m=M$?80:120;let b,h,v=!1,x="";const $=(w="")=>{v=!0,b=vr(),x=w.replace(/\.+$/,""),process.stdout.write(`${c.default.gray(M)}
50
50
  `);let g=0,i=0;h=setInterval(()=>{const J=c.default.magenta(r[g]),K=".".repeat(Math.floor(i)).slice(0,3);process.stdout.write(B.cursor.move(-999,0)),process.stdout.write(B.erase.down(1)),process.stdout.write(`${J} ${x}${K}`),g=g+1<r.length?g+1:0,i=i<r.length?i+0.125:0},m)},a=(w="",g=0)=>{x=w??x,v=!1,clearInterval(h);const i=g===0?c.default.green(p$):g===1?c.default.red(xr):c.default.red(ar);process.stdout.write(B.cursor.move(-999,0)),process.stdout.write(B.erase.down(1)),process.stdout.write(`${i} ${x}
51
- `),b()},s=(w="")=>{x=w??x},o=(w)=>{const g=w>1?"Something went wrong":"Canceled";v&&a(g,w)};return process.on("uncaughtExceptionMonitor",()=>o(2)),process.on("unhandledRejection",()=>o(2)),process.on("SIGINT",()=>o(1)),process.on("SIGTERM",()=>o(1)),process.on("exit",o),{start:$,stop:a,message:s}};function Zm(r){return r.startsWith("cr_")&&r.length>10}async function zm(r){try{const b=await(await fetch(`${Q}/apiStats/api/get-key-id`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r})})).json();if(b.success&&b.data?.id)return{valid:!0,apiId:b.data.id};return{valid:!1,error:b.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 sr(r){if(!Zm(r))return{success:!1,error:"Key \u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u5FC5\u987B\u4EE5 cr_ \u5F00\u5934"};const m=await zm(r);if(!m.valid)return{success:!1,error:m.error};return await N({apiKey:r,apiId:m.apiId}),{success:!0}}import{join as W$} from"path";async function T(){if($$)return $$;const r=[Qm,Sm,Ym];for(let m of r)try{const b=await Promise.race([m(),new Promise((h,v)=>setTimeout(()=>v(new Error("timeout")),3000))]);if(b)return $$=b,b}catch{}return $$="cn","cn"}async function Qm(){try{const 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{const 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 Ym(){try{const 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 Jm(){const r=await T();return q$[r]}async function V(){return(await Jm()).npm}async function dr(){if(await T()==="cn")return`curl -fsSL https://bun.sh/install | BUN_INSTALL_MIRROR="${q$.cn.bunMirror}" bash`;return"curl -fsSL https://bun.sh/install | bash"}async function wr(){const r=await T(),m=q$[r];if(r==="cn")d.info("\u68C0\u6D4B\u5230\u4E2D\u56FD\u5927\u9646\u7F51\u7EDC\uFF0C\u4F7F\u7528\u56FD\u5185\u955C\u50CF\u6E90"),d.message(` npm: ${m.npm}`);else d.info("\u4F7F\u7528\u56FD\u9645\u6E90")}var $$=null,q$={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}};var Hm=function(r){return r.startsWith(H)};async function er(){try{if(!await Bun.file(l).exists())return!1;const m=Bun.spawn([l,"--version"],{stdout:"pipe",stderr:"pipe"});return await m.exited,m.exitCode===0}catch{return!1}}async function Xm(){if(process.platform==="win32")return!0;try{const m=Bun.spawn(["which","unzip"],{stdout:"pipe",stderr:"pipe"});if(await m.exited,m.exitCode===0)return!0}catch{}d.warn("\u6B63\u5728\u5B89\u88C5\u7CFB\u7EDF\u4F9D\u8D56 (unzip)...");const 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{const b=Bun.spawn(["bash","-c",`sudo ${m} 2>/dev/null || ${m}`],{stdout:"pipe",stderr:"pipe"});if(await b.exited,b.exitCode===0)return!0}catch{}return!1}async function Vm(){const r=S();if(!await Xm())return d.error("\u8BF7\u5148\u624B\u52A8\u5B89\u88C5 unzip: apt install unzip / yum install unzip"),!1;await wr(),r.start("\u6B63\u5728\u5B89\u88C5 Tako \u4E13\u5C5E Bun \u8FD0\u884C\u65F6...");try{await(await import("fs/promises")).mkdir(H,{recursive:!0});let b;if(process.platform==="win32"){const v=await T()==="cn"?'$env:BUN_INSTALL_MIRROR="https://registry.npmmirror.com/-/binary/bun"; ':"",x=`\$env:BUN_INSTALL="${H}"; ${v}irm bun.sh/install.ps1 | iex`;b=await Bun.spawn(["powershell","-Command",x],{stdout:"inherit",stderr:"inherit"}).exited}else{const h=await dr(),v=`BUN_INSTALL="${H}" ${h}`;b=await Bun.spawn(["bash","-c",v],{stdout:"inherit",stderr:"inherit"}).exited}if(b!==0)return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1;return j=l,r.stop("Tako \u4E13\u5C5E Bun \u5B89\u88C5\u5B8C\u6210"),d.info(`\u5B89\u88C5\u4F4D\u7F6E: ${H}`),!0}catch(m){return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1}}async function jm(){if(await er())return j=l,!0;return d.warn("\u672A\u68C0\u6D4B\u5230 Tako \u4E13\u5C5E Bun\uFF0C\u6B63\u5728\u81EA\u52A8\u5B89\u88C5..."),d.info("\uFF08\u4E0D\u4F1A\u5F71\u54CD\u60A8\u7CFB\u7EDF\u4E2D\u5DF2\u5B89\u88C5\u7684 Node.js \u6216 Bun\uFF09"),await Vm()}async function G$(){if(j){if(!Hm(j))j=l;return j}if(await er())return j=l,l;return l}async function tr(r){try{const m=await V(),b=await fetch(`${m}/${r}/latest`);if(!b.ok)return null;return(await b.json()).version}catch{return null}}async function Lm(r){return(await X()).installedClients[r.id]?.version||null}async function ir(r){const m=n(r.id),b=W$(m,"package.json");try{return await Bun.file(b).exists()}catch{return!1}}async function Mr(r){const m=await Lm(r);if(!m)return!0;const b=await tr(r.package);if(!b)return!1;return m!==b}async function yr(r,m=!1){const b=S(),h=n(r.id);try{if(!await jm())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"};const v=await ir(r),x=m||await Mr(r);if(v&&!x)return{success:!0};const $=v?"\u66F4\u65B0":"\u5B89\u88C5";b.start(`\u6B63\u5728${$} ${r.name}...`);const a=await import("fs/promises");await a.mkdir(h,{recursive:!0});const s=W$(h,"package.json");if(!await Bun.file(s).exists())await Bun.write(s,JSON.stringify({name:`tako-${r.id}`,private:!0,dependencies:{}},null,2));const w=await G$(),g=await V();if(v){const L=W$(h,"bun.lock");try{await a.unlink(L)}catch{}}const i=Bun.spawn([w,"add",`${r.package}@latest`],{cwd:h,stdout:"pipe",stderr:"pipe",env:{...process.env,BUN_CONFIG_REGISTRY:g}});if(await i.exited!==0){const L=await new Response(i.stderr).text();return b.stop(`${$} ${r.name} \u5931\u8D25`),{success:!1,error:L}}const K=await tr(r.package);if(K){const L=await X();L.installedClients[r.id]={version:K,installedAt:(new Date()).toISOString()},await N(L)}return b.stop(`${r.name} ${$}\u5B8C\u6210`),{success:!0}}catch(v){return b.stop("\u64CD\u4F5C\u5931\u8D25"),{success:!1,error:v instanceof Error?v.message:"\u672A\u77E5\u9519\u8BEF"}}}async function pr(r){if(!await ir(r))return await yr(r);if(await Mr(r))return await yr(r,!0);return{success:!0}}var j=null;async function P(r){try{const m=await pr(r);if(!m.success)return m;const b=await j$();if(!b)return{success:!1,error:"\u672A\u914D\u7F6E API Key"};if(r.setupConfigFiles)await r.setupConfigFiles(b);let h=await f$(r);if(!h)h=B$(r);if(!await Bun.file(h).exists())return{success:!1,error:`\u627E\u4E0D\u5230\u53EF\u6267\u884C\u6587\u4EF6: ${h}`};const x=r.getEnvVars(b),$={...process.env,...x};d.info(`\u542F\u52A8 ${r.name}...`);let a;if(r.runtime==="native")a=[h];else a=[await G$(),h];return await Bun.spawn(a,{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 Z$(){try{const r=await L$();if(!r)return{success:!1,error:"\u672A\u627E\u5230 API ID\uFF0C\u8BF7\u91CD\u65B0\u914D\u7F6E Key"};const b=await(await fetch(`${Q}/apiStats/api/user-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r})})).json(),v=await(await fetch(`${Q}/apiStats/api/user-model-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r,period:"daily"})})).json();if(!b.success)return{success:!1,error:b.error||b.message||"\u83B7\u53D6\u7EDF\u8BA1\u5931\u8D25"};const x=(v.data||[]).map(($)=>({model:$.model,requests:$.requests,cost:$.formatted?.total||"$0.00"}));return{success:!0,data:{totalRequests:b.data?.usage?.total?.requests||0,totalCost:b.data?.usage?.total?.formattedCost||"$0.00",todayCost:`\$${(b.data?.limits?.currentDailyCost||0).toFixed(2)}`,modelStats:x}}}catch(r){return{success:!1,error:r instanceof Error?r.message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"}}}function z$(r){return r.toLocaleString("en-US")}import{join as z} from"path";var fm=function(r,m){const b=r.split(".").map(Number),h=m.split(".").map(Number);for(let v=0;v<3;v++){const x=b[v]||0,$=h[v]||0;if(x>$)return 1;if(x<$)return-1}return 0};async function Bm(){try{const r=await V(),m=await fetch(`${r}/${Q$}/latest`,{signal:AbortSignal.timeout(5000)});if(!m.ok)return null;return(await m.json()).version||null}catch{return null}}async function km(){const r=await Bm();if(!r)return{hasUpdate:!1,currentVersion:k};return{hasUpdate:fm(r,k)>0,latestVersion:r,currentVersion:k}}async function lr(){const r=await import("fs/promises"),m=z(G,"bin"),b=z(m,"tako"),h=z(Z,"node_modules/tako-cli/dist/index.js");if(await r.mkdir(m,{recursive:!0}),process.platform==="win32"){const x=`@echo off\r\n"${l}" "${h}" %*\r\n`;await r.writeFile(z(m,"tako.cmd"),x)}else{const x=`#!/bin/bash\nexec "${l}" "${h}" "\$@"\n`;await r.writeFile(b,x,{mode:493})}}async function nm(r){const m=S();m.start(`\u6B63\u5728\u66F4\u65B0\u5230 v${r}...`);try{const b=await V(),h=await import("fs/promises");await h.mkdir(Z,{recursive:!0});const v=z(Z,"package.json");try{await h.access(v)}catch{await h.writeFile(v,JSON.stringify({name:"tako-local",private:!0},null,2))}const x=Bun.spawn([l,"update",Q$,"--latest"],{cwd:Z,stdout:"pipe",stderr:"pipe",env:{...process.env,BUN_CONFIG_REGISTRY:b}});if(await x.exited,x.exitCode===0)return await lr(),m.stop(`\u66F4\u65B0\u6210\u529F\uFF01\u5DF2\u66F4\u65B0\u5230 v${r}`),!0;else{const $=await new Response(x.stderr).text();return m.stop(`\u66F4\u65B0\u5931\u8D25: ${$||"\u672A\u77E5\u9519\u8BEF"}`),!1}}catch(b){return m.stop(`\u66F4\u65B0\u5931\u8D25: ${b instanceof Error?b.message:"\u672A\u77E5\u9519\u8BEF"}`),!1}}async function Em(){const r=await import("fs/promises"),m=z(Z,"bun.lock");try{await r.unlink(m)}catch{}}async function Um(){const r=await import("fs/promises");try{const m=await V();await r.mkdir(Z,{recursive:!0});const b=z(Z,"package.json");try{await r.access(b)}catch{await r.writeFile(b,JSON.stringify({name:"tako-local",private:!0},null,2))}await Em();const h=Bun.spawn([l,"add",`${Q$}@latest`],{cwd:Z,stdout:"pipe",stderr:"pipe",env:{...process.env,BUN_CONFIG_REGISTRY:m}});return await h.exited,h.exitCode===0}catch{return!1}}async function Tm(){const r=await import("fs/promises"),m=z(G,"bin"),b=z(m,"tako"),h=z(Z,"node_modules/tako-cli/dist/index.js");try{const v=await r.readFile(b,"utf-8");if(v.includes("bun run tako-cli")||v.includes("run tako-cli")){d.info("\u68C0\u6D4B\u5230\u65E7\u7248\u5B89\u88C5\u65B9\u5F0F\uFF0C\u6B63\u5728\u8FC1\u79FB...");let x=!1;try{await r.access(h),x=!0}catch{x=!1}if(!x){const $=S();if($.start("\u6B63\u5728\u5B89\u88C5\u5230\u672C\u5730\u76EE\u5F55..."),!await Um())return $.stop("\u672C\u5730\u5B89\u88C5\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8FC1\u79FB"),!1;$.stop("\u672C\u5730\u5B89\u88C5\u5B8C\u6210")}return await lr(),!0}}catch{}return!1}async function r$(){try{if(await Tm())d.info("\u68C0\u6D4B\u5230\u65E7\u7248\u5B89\u88C5\uFF0C\u5DF2\u5B8C\u6210\u8FC1\u79FB\uFF0C\u8BF7\u91CD\u65B0\u542F\u52A8 Tako CLI"),process.exit(0);const m=await km();if(m.hasUpdate&&m.latestVersion){if(d.warn(`\u53D1\u73B0\u65B0\u7248\u672C v${m.latestVersion}\uFF08\u5F53\u524D v${k}\uFF09`),await nm(m.latestVersion))d.info("\u8BF7\u91CD\u65B0\u542F\u52A8 Tako CLI \u4EE5\u4F7F\u7528\u65B0\u7248\u672C"),process.exit(0)}}catch{}}var Q$="tako-cli",k="0.1.32";var Pm=function(){console.log(),console.log(` \uD83D\uDC19 Tako CLI v${k}`),console.log(" \x1B[90m\u6B22\u8FCE\u4F7F\u7528\uFF01\x1B[0m"),console.log()};async function qr(r=!1){if(!r)d.warn("\u672A\u68C0\u6D4B\u5230 API Key"),console.log();const m=await or({message:r?"\u8BF7\u8F93\u5165\u65B0\u7684 API Key (cr_xxx):":"\u8BF7\u8F93\u5165\u4F60\u7684 API Key (cr_xxx):",placeholder:"cr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",validate(v){if(!v)return"\u8BF7\u8F93\u5165 API Key";if(!v.startsWith("cr_"))return"Key \u5FC5\u987B\u4EE5 cr_ \u5F00\u5934";if(v.length<10)return"Key \u683C\u5F0F\u4E0D\u6B63\u786E"}});if(U(m))return!1;const b=S();b.start("\u9A8C\u8BC1 Key \u4E2D...");const h=await sr(m);if(h.success)return b.stop("Key \u9A8C\u8BC1\u6210\u529F\uFF01\u5DF2\u4FDD\u5B58\u5230\u914D\u7F6E\u6587\u4EF6"),!0;else return b.stop(`\u9A8C\u8BC1\u5931\u8D25: ${h.error}`),!1}var Km=function(r,m){const b=[];if(b.push(""),b.push(" \uD83D\uDCCA \u7528\u91CF\u7EDF\u8BA1"),b.push(""),b.push(` \u603B\u8C03\u7528\u6B21\u6570: ${z$(r.totalRequests)} \u6B21`),b.push(` \u603B\u6D88\u8D39: ${r.totalCost}`),b.push(` \u4ECA\u65E5\u6D88\u8D39: ${r.todayCost}`),r.modelStats.length>0)b.push(""),b.push(" \u6A21\u578B\u4F7F\u7528\u5206\u5E03 (\u4ECA\u65E5):"),r.modelStats.forEach((h,v)=>{const x=v===r.modelStats.length-1?"\u2514\u2500":"\u251C\u2500",$=h.model.length>25?h.model.slice(0,22)+"...":h.model;b.push(` ${x} ${$.padEnd(25)} ${z$(h.requests).padStart(6)} \u6B21 ${h.cost.padStart(8)}`)});return b.push(""),b.push(` \x1B[90m${m}s \u540E\u5237\u65B0 | \u6309\u4EFB\u610F\u952E\u8FD4\u56DE\x1B[0m`),b.join("\n")};async function Om(){const m=S();m.start("\u83B7\u53D6\u7528\u91CF\u7EDF\u8BA1...");let b=await Z$();if(!b.success){m.stop(`\u83B7\u53D6\u5931\u8D25: ${b.error}`);return}m.stop("");let h=10,v="";const x=()=>{if(v){const a=v.split("\n").length;process.stdout.write(`\x1B[${a}A\x1B[0J`)}v=Km(b.data,h),console.log(v)};x();const $=process.stdin.isRaw;if(process.stdin.isTTY)process.stdin.setRawMode(!0);return process.stdin.resume(),new Promise((a)=>{let s=!0;const o=()=>{if(!s)return;s=!1,g(),a()},w=setInterval(async()=>{if(!s)return;if(h--,h<=0){h=10;const i=await Z$();if(i.success)b=i}x()},1000),g=()=>{if(clearInterval(w),process.stdin.removeListener("data",o),process.stdin.isTTY)process.stdin.setRawMode($??!1);process.stdin.pause()};process.stdin.on("data",o)})}async function Nm(){const m=[...k$().map((h)=>({value:{type:"launch",client:h},label:`\u542F\u52A8 ${h.name}`,hint:h.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"}],b=await gr({message:"\u8BF7\u9009\u62E9\u64CD\u4F5C:",options:m});if(U(b))return null;return b}async function Am(r){switch(r.type){case"launch":const m=await P(r.client);if(!m.success)d.error(m.error||"\u542F\u52A8\u5931\u8D25");return!0;case"stats":return await Om(),!0;case"config":return await qr(!0),!0;case"exit":return!1}}async function Wr(){if(Pm(),!await V$()){if(!await qr()){l$("\u518D\u89C1\uFF01");return}}while(!0){const m=await Nm();if(m===null)break;if(!await Am(m))break}l$("\u518D\u89C1\uFF01")}var Rm=function(){console.log(`
51
+ `),b()},s=(w="")=>{x=w??x},o=(w)=>{const g=w>1?"Something went wrong":"Canceled";v&&a(g,w)};return process.on("uncaughtExceptionMonitor",()=>o(2)),process.on("unhandledRejection",()=>o(2)),process.on("SIGINT",()=>o(1)),process.on("SIGTERM",()=>o(1)),process.on("exit",o),{start:$,stop:a,message:s}};function Zm(r){return r.startsWith("cr_")&&r.length>10}async function zm(r){try{const b=await(await fetch(`${Q}/apiStats/api/get-key-id`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r})})).json();if(b.success&&b.data?.id)return{valid:!0,apiId:b.data.id};return{valid:!1,error:b.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 sr(r){if(!Zm(r))return{success:!1,error:"Key \u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u5FC5\u987B\u4EE5 cr_ \u5F00\u5934"};const m=await zm(r);if(!m.valid)return{success:!1,error:m.error};return await N({apiKey:r,apiId:m.apiId}),{success:!0}}import{join as W$} from"path";async function T(){if($$)return $$;const r=[Qm,Sm,Ym];for(let m of r)try{const b=await Promise.race([m(),new Promise((h,v)=>setTimeout(()=>v(new Error("timeout")),3000))]);if(b)return $$=b,b}catch{}return $$="cn","cn"}async function Qm(){try{const 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{const 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 Ym(){try{const 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 Jm(){const r=await T();return q$[r]}async function V(){return(await Jm()).npm}async function dr(){if(await T()==="cn")return`curl -fsSL https://bun.sh/install | BUN_INSTALL_MIRROR="${q$.cn.bunMirror}" bash`;return"curl -fsSL https://bun.sh/install | bash"}async function wr(){const r=await T(),m=q$[r];if(r==="cn")d.info("\u68C0\u6D4B\u5230\u4E2D\u56FD\u5927\u9646\u7F51\u7EDC\uFF0C\u4F7F\u7528\u56FD\u5185\u955C\u50CF\u6E90"),d.message(` npm: ${m.npm}`);else d.info("\u4F7F\u7528\u56FD\u9645\u6E90")}var $$=null,q$={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}};var Hm=function(r){return r.startsWith(H)};async function er(){try{if(!await Bun.file(l).exists())return!1;const m=Bun.spawn([l,"--version"],{stdout:"pipe",stderr:"pipe"});return await m.exited,m.exitCode===0}catch{return!1}}async function Xm(){if(process.platform==="win32")return!0;try{const m=Bun.spawn(["which","unzip"],{stdout:"pipe",stderr:"pipe"});if(await m.exited,m.exitCode===0)return!0}catch{}d.warn("\u6B63\u5728\u5B89\u88C5\u7CFB\u7EDF\u4F9D\u8D56 (unzip)...");const 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{const b=Bun.spawn(["bash","-c",`sudo ${m} 2>/dev/null || ${m}`],{stdout:"pipe",stderr:"pipe"});if(await b.exited,b.exitCode===0)return!0}catch{}return!1}async function Vm(){const r=S();if(!await Xm())return d.error("\u8BF7\u5148\u624B\u52A8\u5B89\u88C5 unzip: apt install unzip / yum install unzip"),!1;await wr(),r.start("\u6B63\u5728\u5B89\u88C5 Tako \u4E13\u5C5E Bun \u8FD0\u884C\u65F6...");try{await(await import("fs/promises")).mkdir(H,{recursive:!0});let b;if(process.platform==="win32"){const v=await T()==="cn"?'$env:BUN_INSTALL_MIRROR="https://registry.npmmirror.com/-/binary/bun"; ':"",x=`\$env:BUN_INSTALL="${H}"; ${v}irm bun.sh/install.ps1 | iex`;b=await Bun.spawn(["powershell","-Command",x],{stdout:"inherit",stderr:"inherit"}).exited}else{const h=await dr(),v=`BUN_INSTALL="${H}" ${h}`;b=await Bun.spawn(["bash","-c",v],{stdout:"inherit",stderr:"inherit"}).exited}if(b!==0)return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1;return j=l,r.stop("Tako \u4E13\u5C5E Bun \u5B89\u88C5\u5B8C\u6210"),d.info(`\u5B89\u88C5\u4F4D\u7F6E: ${H}`),!0}catch(m){return r.stop("Bun \u5B89\u88C5\u5931\u8D25"),!1}}async function jm(){if(await er())return j=l,!0;return d.warn("\u672A\u68C0\u6D4B\u5230 Tako \u4E13\u5C5E Bun\uFF0C\u6B63\u5728\u81EA\u52A8\u5B89\u88C5..."),d.info("\uFF08\u4E0D\u4F1A\u5F71\u54CD\u60A8\u7CFB\u7EDF\u4E2D\u5DF2\u5B89\u88C5\u7684 Node.js \u6216 Bun\uFF09"),await Vm()}async function G$(){if(j){if(!Hm(j))j=l;return j}if(await er())return j=l,l;return l}async function tr(r){try{const m=await V(),b=await fetch(`${m}/${r}/latest`);if(!b.ok)return null;return(await b.json()).version}catch{return null}}async function Lm(r){return(await X()).installedClients[r.id]?.version||null}async function ir(r){const m=n(r.id),b=W$(m,"package.json");try{return await Bun.file(b).exists()}catch{return!1}}async function Mr(r){const m=await Lm(r);if(!m)return!0;const b=await tr(r.package);if(!b)return!1;return m!==b}async function yr(r,m=!1){const b=S(),h=n(r.id);try{if(!await jm())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"};const v=await ir(r),x=m||await Mr(r);if(v&&!x)return{success:!0};const $=v?"\u66F4\u65B0":"\u5B89\u88C5";b.start(`\u6B63\u5728${$} ${r.name}...`);const a=await import("fs/promises");await a.mkdir(h,{recursive:!0});const s=W$(h,"package.json");if(!await Bun.file(s).exists())await Bun.write(s,JSON.stringify({name:`tako-${r.id}`,private:!0,dependencies:{}},null,2));const w=await G$(),g=await V();if(v){const L=W$(h,"bun.lock");try{await a.unlink(L)}catch{}}const i=Bun.spawn([w,"add",`${r.package}@latest`],{cwd:h,stdout:"pipe",stderr:"pipe",env:{...process.env,BUN_CONFIG_REGISTRY:g}});if(await i.exited!==0){const L=await new Response(i.stderr).text();return b.stop(`${$} ${r.name} \u5931\u8D25`),{success:!1,error:L}}const K=await tr(r.package);if(K){const L=await X();L.installedClients[r.id]={version:K,installedAt:(new Date()).toISOString()},await N(L)}return b.stop(`${r.name} ${$}\u5B8C\u6210`),{success:!0}}catch(v){return b.stop("\u64CD\u4F5C\u5931\u8D25"),{success:!1,error:v instanceof Error?v.message:"\u672A\u77E5\u9519\u8BEF"}}}async function pr(r){if(!await ir(r))return await yr(r);if(await Mr(r))return await yr(r,!0);return{success:!0}}var j=null;async function P(r){try{const m=await pr(r);if(!m.success)return m;const b=await j$();if(!b)return{success:!1,error:"\u672A\u914D\u7F6E API Key"};if(r.setupConfigFiles)await r.setupConfigFiles(b);let h=await f$(r);if(!h)h=B$(r);if(!await Bun.file(h).exists())return{success:!1,error:`\u627E\u4E0D\u5230\u53EF\u6267\u884C\u6587\u4EF6: ${h}`};const x=r.getEnvVars(b),$={...process.env,...x};d.info(`\u542F\u52A8 ${r.name}...`);let a;if(r.runtime==="native")a=[h];else a=[await G$(),h];return await Bun.spawn(a,{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 Z$(){try{const r=await L$();if(!r)return{success:!1,error:"\u672A\u627E\u5230 API ID\uFF0C\u8BF7\u91CD\u65B0\u914D\u7F6E Key"};const b=await(await fetch(`${Q}/apiStats/api/user-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r})})).json(),v=await(await fetch(`${Q}/apiStats/api/user-model-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r,period:"daily"})})).json();if(!b.success)return{success:!1,error:b.error||b.message||"\u83B7\u53D6\u7EDF\u8BA1\u5931\u8D25"};const x=(v.data||[]).map(($)=>({model:$.model,requests:$.requests,cost:$.formatted?.total||"$0.00"}));return{success:!0,data:{totalRequests:b.data?.usage?.total?.requests||0,totalCost:b.data?.usage?.total?.formattedCost||"$0.00",todayCost:`\$${(b.data?.limits?.currentDailyCost||0).toFixed(2)}`,modelStats:x}}}catch(r){return{success:!1,error:r instanceof Error?r.message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"}}}function z$(r){return r.toLocaleString("en-US")}import{join as z} from"path";var fm=function(r,m){const b=r.split(".").map(Number),h=m.split(".").map(Number);for(let v=0;v<3;v++){const x=b[v]||0,$=h[v]||0;if(x>$)return 1;if(x<$)return-1}return 0};async function Bm(){try{const r=await V(),m=await fetch(`${r}/${Q$}/latest`,{signal:AbortSignal.timeout(5000)});if(!m.ok)return null;return(await m.json()).version||null}catch{return null}}async function km(){const r=await Bm();if(!r)return{hasUpdate:!1,currentVersion:k};return{hasUpdate:fm(r,k)>0,latestVersion:r,currentVersion:k}}async function lr(){const r=await import("fs/promises"),m=z(G,"bin"),b=z(m,"tako"),h=z(Z,"node_modules/tako-cli/dist/index.js");if(await r.mkdir(m,{recursive:!0}),process.platform==="win32"){const x=`@echo off\r\n"${l}" "${h}" %*\r\n`;await r.writeFile(z(m,"tako.cmd"),x)}else{const x=`#!/bin/bash\nexec "${l}" "${h}" "\$@"\n`;await r.writeFile(b,x,{mode:493})}}async function nm(r){const m=S();m.start(`\u6B63\u5728\u66F4\u65B0\u5230 v${r}...`);try{const b=await V(),h=await import("fs/promises");await h.mkdir(Z,{recursive:!0});const v=z(Z,"package.json");try{await h.access(v)}catch{await h.writeFile(v,JSON.stringify({name:"tako-local",private:!0},null,2))}const x=Bun.spawn([l,"update",Q$,"--latest"],{cwd:Z,stdout:"pipe",stderr:"pipe",env:{...process.env,BUN_CONFIG_REGISTRY:b}});if(await x.exited,x.exitCode===0)return await lr(),m.stop(`\u66F4\u65B0\u6210\u529F\uFF01\u5DF2\u66F4\u65B0\u5230 v${r}`),!0;else{const $=await new Response(x.stderr).text();return m.stop(`\u66F4\u65B0\u5931\u8D25: ${$||"\u672A\u77E5\u9519\u8BEF"}`),!1}}catch(b){return m.stop(`\u66F4\u65B0\u5931\u8D25: ${b instanceof Error?b.message:"\u672A\u77E5\u9519\u8BEF"}`),!1}}async function Em(){const r=await import("fs/promises"),m=z(Z,"bun.lock");try{await r.unlink(m)}catch{}}async function Um(){const r=await import("fs/promises");try{const m=await V();await r.mkdir(Z,{recursive:!0});const b=z(Z,"package.json");try{await r.access(b)}catch{await r.writeFile(b,JSON.stringify({name:"tako-local",private:!0},null,2))}await Em();const h=Bun.spawn([l,"add",`${Q$}@latest`],{cwd:Z,stdout:"pipe",stderr:"pipe",env:{...process.env,BUN_CONFIG_REGISTRY:m}});return await h.exited,h.exitCode===0}catch{return!1}}async function Tm(){const r=await import("fs/promises"),m=z(G,"bin"),b=z(m,"tako"),h=z(Z,"node_modules/tako-cli/dist/index.js");try{const v=await r.readFile(b,"utf-8");if(v.includes("bun run tako-cli")||v.includes("run tako-cli")){d.info("\u68C0\u6D4B\u5230\u65E7\u7248\u5B89\u88C5\u65B9\u5F0F\uFF0C\u6B63\u5728\u8FC1\u79FB...");let x=!1;try{await r.access(h),x=!0}catch{x=!1}if(!x){const $=S();if($.start("\u6B63\u5728\u5B89\u88C5\u5230\u672C\u5730\u76EE\u5F55..."),!await Um())return $.stop("\u672C\u5730\u5B89\u88C5\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8FC1\u79FB"),!1;$.stop("\u672C\u5730\u5B89\u88C5\u5B8C\u6210")}return await lr(),!0}}catch{}return!1}async function r$(){try{if(await Tm())d.info("\u68C0\u6D4B\u5230\u65E7\u7248\u5B89\u88C5\uFF0C\u5DF2\u5B8C\u6210\u8FC1\u79FB\uFF0C\u8BF7\u91CD\u65B0\u542F\u52A8 Tako CLI"),process.exit(0);const m=await km();if(m.hasUpdate&&m.latestVersion){if(d.warn(`\u53D1\u73B0\u65B0\u7248\u672C v${m.latestVersion}\uFF08\u5F53\u524D v${k}\uFF09`),await nm(m.latestVersion))d.info("\u8BF7\u91CD\u65B0\u542F\u52A8 Tako CLI \u4EE5\u4F7F\u7528\u65B0\u7248\u672C"),process.exit(0)}}catch{}}var Q$="tako-cli",k="0.1.33";var Pm=function(){console.log(),console.log(` \uD83D\uDC19 Tako CLI v${k}`),console.log(" \x1B[90m\u6B22\u8FCE\u4F7F\u7528\uFF01\x1B[0m"),console.log()};async function qr(r=!1){if(!r)d.warn("\u672A\u68C0\u6D4B\u5230 API Key"),console.log();const m=await or({message:r?"\u8BF7\u8F93\u5165\u65B0\u7684 API Key (cr_xxx):":"\u8BF7\u8F93\u5165\u4F60\u7684 API Key (cr_xxx):",placeholder:"cr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",validate(v){if(!v)return"\u8BF7\u8F93\u5165 API Key";if(!v.startsWith("cr_"))return"Key \u5FC5\u987B\u4EE5 cr_ \u5F00\u5934";if(v.length<10)return"Key \u683C\u5F0F\u4E0D\u6B63\u786E"}});if(U(m))return!1;const b=S();b.start("\u9A8C\u8BC1 Key \u4E2D...");const h=await sr(m);if(h.success)return b.stop("Key \u9A8C\u8BC1\u6210\u529F\uFF01\u5DF2\u4FDD\u5B58\u5230\u914D\u7F6E\u6587\u4EF6"),!0;else return b.stop(`\u9A8C\u8BC1\u5931\u8D25: ${h.error}`),!1}var Km=function(r,m){const b=[];if(b.push(""),b.push(" \uD83D\uDCCA \u7528\u91CF\u7EDF\u8BA1"),b.push(""),b.push(` \u603B\u8C03\u7528\u6B21\u6570: ${z$(r.totalRequests)} \u6B21`),b.push(` \u603B\u6D88\u8D39: ${r.totalCost}`),b.push(` \u4ECA\u65E5\u6D88\u8D39: ${r.todayCost}`),r.modelStats.length>0)b.push(""),b.push(" \u6A21\u578B\u4F7F\u7528\u5206\u5E03 (\u4ECA\u65E5):"),r.modelStats.forEach((h,v)=>{const x=v===r.modelStats.length-1?"\u2514\u2500":"\u251C\u2500",$=h.model.length>25?h.model.slice(0,22)+"...":h.model;b.push(` ${x} ${$.padEnd(25)} ${z$(h.requests).padStart(6)} \u6B21 ${h.cost.padStart(8)}`)});return b.push(""),b.push(` \x1B[90m${m}s \u540E\u5237\u65B0 | \u6309\u4EFB\u610F\u952E\u8FD4\u56DE\x1B[0m`),b.join("\n")};async function Om(){const m=S();m.start("\u83B7\u53D6\u7528\u91CF\u7EDF\u8BA1...");let b=await Z$();if(!b.success){m.stop(`\u83B7\u53D6\u5931\u8D25: ${b.error}`);return}m.stop("");let h=10,v="";const x=()=>{if(v){const a=v.split("\n").length;process.stdout.write(`\x1B[${a}A\x1B[0J`)}v=Km(b.data,h),console.log(v)};x();const $=process.stdin.isRaw;if(process.stdin.isTTY)process.stdin.setRawMode(!0);return process.stdin.resume(),new Promise((a)=>{let s=!0;const o=()=>{if(!s)return;s=!1,g(),a()},w=setInterval(async()=>{if(!s)return;if(h--,h<=0){h=10;const i=await Z$();if(i.success)b=i}x()},1000),g=()=>{if(clearInterval(w),process.stdin.removeListener("data",o),process.stdin.isTTY)process.stdin.setRawMode($??!1);process.stdin.pause()};process.stdin.on("data",o)})}async function Nm(){const m=[...k$().map((h)=>({value:{type:"launch",client:h},label:`\u542F\u52A8 ${h.name}`,hint:h.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"}],b=await gr({message:"\u8BF7\u9009\u62E9\u64CD\u4F5C:",options:m});if(U(b))return null;return b}async function Am(r){switch(r.type){case"launch":const m=await P(r.client);if(!m.success)d.error(m.error||"\u542F\u52A8\u5931\u8D25");return!0;case"stats":return await Om(),!0;case"config":return await qr(!0),!0;case"exit":return!1}}async function Wr(){if(Pm(),!await V$()){if(!await qr()){l$("\u518D\u89C1\uFF01");return}}while(!0){const m=await Nm();if(m===null)break;if(!await Am(m))break}l$("\u518D\u89C1\uFF01")}var Rm=function(){console.log(`
52
52
  Tako CLI v${Gr}
53
53
 
54
54
  \u7528\u6CD5: tako [\u9009\u9879] [\u547D\u4EE4]
@@ -65,4 +65,4 @@ Tako CLI v${Gr}
65
65
  tako \u4EA4\u4E92\u5F0F\u9009\u62E9\u5DE5\u5177
66
66
  tako --claude \u76F4\u63A5\u542F\u52A8 Claude Code
67
67
  tako --codex \u76F4\u63A5\u542F\u52A8 Codex
68
- `)};async function Im(){const r=process.argv.slice(2);if(r.includes("-v")||r.includes("--version")){console.log(`Tako CLI v${Gr}`);return}if(r.includes("-h")||r.includes("--help")){Rm();return}if(r.includes("--claude")){const m=v$("claude-code");if(!m)console.error("Claude Code \u5BA2\u6237\u7AEF\u672A\u627E\u5230"),process.exit(1);await r$();const b=await P(m);if(!b.success)console.error(b.error),process.exit(1);return}if(r.includes("--codex")){const m=v$("codex");if(!m)console.error("Codex \u5BA2\u6237\u7AEF\u672A\u627E\u5230"),process.exit(1);await r$();const b=await P(m);if(!b.success)console.error(b.error),process.exit(1);return}await r$(),await Wr()}var Gr="0.1.32";Im().catch((r)=>{console.error("Tako CLI \u53D1\u751F\u9519\u8BEF:",r),process.exit(1)});
68
+ `)};async function Im(){const r=process.argv.slice(2);if(r.includes("-v")||r.includes("--version")){console.log(`Tako CLI v${Gr}`);return}if(r.includes("-h")||r.includes("--help")){Rm();return}if(r.includes("--claude")){const m=v$("claude-code");if(!m)console.error("Claude Code \u5BA2\u6237\u7AEF\u672A\u627E\u5230"),process.exit(1);await r$();const b=await P(m);if(!b.success)console.error(b.error),process.exit(1);return}if(r.includes("--codex")){const m=v$("codex");if(!m)console.error("Codex \u5BA2\u6237\u7AEF\u672A\u627E\u5230"),process.exit(1);await r$();const b=await P(m);if(!b.success)console.error(b.error),process.exit(1);return}await r$(),await Wr()}var Gr="0.1.33";Im().catch((r)=>{console.error("Tako CLI \u53D1\u751F\u9519\u8BEF:",r),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tako-cli",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "description": "Tako CLI - AI coding tools launcher",
5
5
  "type": "module",
6
6
  "bin": {