tako-cli 0.1.30 → 0.1.31
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 +2 -2
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ ${a.default.gray(D)} ${r}
|
|
|
48
48
|
`)}
|
|
49
49
|
`)},info:(r)=>{d.message(r,{symbol:a.default.blue(Mm)})},success:(r)=>{d.message(r,{symbol:a.default.green(pm)})},step:(r)=>{d.message(r,{symbol:a.default.green(M$)})},warn:(r)=>{d.message(r,{symbol:a.default.yellow(qm)})},warning:(r)=>{d.warn(r)},error:(r)=>{d.message(r,{symbol:a.default.red(Wm)})}},Q=()=>{const r=l$?["\u25D2","\u25D0","\u25D3","\u25D1"]:["\u2022","o","O","0"],m=l$?80:120;let b,h,v=!1,x="";const $=(w="")=>{v=!0,b=hr(),x=w.replace(/\.+$/,""),process.stdout.write(`${a.default.gray(l)}
|
|
50
50
|
`);let s=0,i=0;h=setInterval(()=>{const J=a.default.magenta(r[s]),P=".".repeat(Math.floor(i)).slice(0,3);process.stdout.write(L.cursor.move(-999,0)),process.stdout.write(L.erase.down(1)),process.stdout.write(`${J} ${x}${P}`),s=s+1<r.length?s+1:0,i=i<r.length?i+0.125:0},m)},c=(w="",s=0)=>{x=w??x,v=!1,clearInterval(h);const i=s===0?a.default.green(M$):s===1?a.default.red(vr):a.default.red(xr);process.stdout.write(L.cursor.move(-999,0)),process.stdout.write(L.erase.down(1)),process.stdout.write(`${i} ${x}
|
|
51
|
-
`),b()},g=(w="")=>{x=w??x},o=(w)=>{const s=w>1?"Something went wrong":"Canceled";v&&c(s,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:c,message:g}};function Zm(r){return r.startsWith("cr_")&&r.length>10}async function zm(r){try{const b=await(await fetch(`${z}/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 yr} from"path";async function U(){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 U();return q$[r]}async function j(){return(await Jm()).npm}async function gr(){if(await U()==="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 dr(){const r=await U(),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(p).exists())return!1;const m=Bun.spawn([p,"--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 jm(){const r=Q();if(!await Xm())return d.error("\u8BF7\u5148\u624B\u52A8\u5B89\u88C5 unzip: apt install unzip / yum install unzip"),!1;await dr(),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 U()==="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 gr(),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 V=p,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 Vm(){if(await er())return V=p,!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 jm()}async function W$(){if(V){if(!Hm(V))V=p;return V}if(await er())return V=p,p;return p}async function tr(r){try{const m=await j(),b=await fetch(`${m}/${r}/latest`);if(!b.ok)return null;return(await b.json()).version}catch{return null}}async function fm(r){return(await X()).installedClients[r.id]?.version||null}async function ir(r){const m=k(r.id),b=yr(m,"package.json");try{return await Bun.file(b).exists()}catch{return!1}}async function lr(r){const m=await fm(r);if(!m)return!0;const b=await tr(r.package);if(!b)return!1;return m!==b}async function wr(r,m=!1){const b=Q(),h=k(r.id);try{if(!await Vm())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 lr(r);if(v&&!x)return{success:!0};const $=v?"\u66F4\u65B0":"\u5B89\u88C5";b.start(`\u6B63\u5728${$} ${r.name}...`),await(await import("fs/promises")).mkdir(h,{recursive:!0});const g=yr(h,"package.json");if(!await Bun.file(g).exists())await Bun.write(g,JSON.stringify({name:`tako-${r.id}`,private:!0,dependencies:{}},null,2));const w=await W$(),s=await j(),i=Bun.spawn([w,"add",r.package,"--registry",s],{cwd:h,stdout:"pipe",stderr:"pipe"});if(await i.exited!==0){const K=await new Response(i.stderr).text();return b.stop(`${$} ${r.name} \u5931\u8D25`),{success:!1,error:K}}const P=await tr(r.package);if(P){const K=await X();K.installedClients[r.id]={version:P,installedAt:(new Date()).toISOString()},await N(K)}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 Mr(r){if(!await ir(r))return await wr(r);if(await lr(r))return await wr(r,!0);return{success:!0}}var V=null;async function T(r){try{const m=await Mr(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=L$(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 c;if(r.runtime==="native")c=[h];else c=[await W$(),h];return await Bun.spawn(c,{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 G$(){try{const r=await V$();if(!r)return{success:!1,error:"\u672A\u627E\u5230 API ID\uFF0C\u8BF7\u91CD\u65B0\u914D\u7F6E Key"};const b=await(await fetch(`${z}/apiStats/api/user-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r})})).json(),v=await(await fetch(`${z}/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 S} from"path";var Lm=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 j(),m=await fetch(`${r}/${z$}/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:B};return{hasUpdate:Lm(r,B)>0,latestVersion:r,currentVersion:B}}async function pr(){const r=await import("fs/promises"),m=S(G,"bin"),b=S(m,"tako"),h=S(Z,"node_modules/tako-cli/dist/index.js");if(await r.mkdir(m,{recursive:!0}),process.platform==="win32"){const x=`@echo off\r\n"${p}" "${h}" %*\r\n`;await r.writeFile(S(m,"tako.cmd"),x)}else{const x=`#!/bin/bash\nexec "${p}" "${h}" "\$@"\n`;await r.writeFile(b,x,{mode:493})}}async function nm(r){const m=Q();m.start(`\u6B63\u5728\u66F4\u65B0\u5230 v${r}...`);try{const b=await j(),h=await import("fs/promises");await h.mkdir(Z,{recursive:!0});const v=S(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([p,"add",`${z$}@latest`,"--registry",b],{cwd:Z,stdout:"pipe",stderr:"pipe"});if(await x.exited,x.exitCode===0)return await pr(),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");try{const m=await j();await r.mkdir(Z,{recursive:!0});const b=S(Z,"package.json");try{await r.access(b)}catch{await r.writeFile(b,JSON.stringify({name:"tako-local",private:!0},null,2))}const h=Bun.spawn([p,"add",`${z$}@latest`,"--registry",m],{cwd:Z,stdout:"pipe",stderr:"pipe"});return await h.exited,h.exitCode===0}catch{return!1}}async function Um(){const r=await import("fs/promises"),m=S(G,"bin"),b=S(m,"tako"),h=S(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 $=Q();if($.start("\u6B63\u5728\u5B89\u88C5\u5230\u672C\u5730\u76EE\u5F55..."),!await Em())return $.stop("\u672C\u5730\u5B89\u88C5\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8FC1\u79FB"),!1;$.stop("\u672C\u5730\u5B89\u88C5\u5B8C\u6210")}return await pr(),!0}}catch{}return!1}async function r$(){try{if(await Um())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${B}\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 z$="tako-cli",B="0.1.30";var Tm=function(){console.log(),console.log(` \uD83D\uDC19 Tako CLI v${B}`),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 cr({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(E(m))return!1;const b=Q();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 Pm=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 Km(){const m=Q();m.start("\u83B7\u53D6\u7528\u91CF\u7EDF\u8BA1...");let b=await G$();if(!b.success){m.stop(`\u83B7\u53D6\u5931\u8D25: ${b.error}`);return}m.stop("");let h=10,v="";const x=()=>{if(v){const c=v.split("\n").length;process.stdout.write(`\x1B[${c}A\x1B[0J`)}v=Pm(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((c)=>{let g=!0;const o=()=>{if(!g)return;g=!1,s(),c()},w=setInterval(async()=>{if(!g)return;if(h--,h<=0){h=10;const i=await G$();if(i.success)b=i}x()},1000),s=()=>{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 Om(){const m=[...B$().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 or({message:"\u8BF7\u9009\u62E9\u64CD\u4F5C:",options:m});if(E(b))return null;return b}async function Nm(r){switch(r.type){case"launch":const m=await T(r.client);if(!m.success)d.error(m.error||"\u542F\u52A8\u5931\u8D25");return!0;case"stats":return await Km(),!0;case"config":return await qr(!0),!0;case"exit":return!1}}async function Wr(){if(Tm(),!await X$()){if(!await qr()){p$("\u518D\u89C1\uFF01");return}}while(!0){const m=await Om();if(m===null)break;if(!await Nm(m))break}p$("\u518D\u89C1\uFF01")}var Am=function(){console.log(`
|
|
51
|
+
`),b()},g=(w="")=>{x=w??x},o=(w)=>{const s=w>1?"Something went wrong":"Canceled";v&&c(s,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:c,message:g}};function Zm(r){return r.startsWith("cr_")&&r.length>10}async function zm(r){try{const b=await(await fetch(`${z}/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 yr} from"path";async function U(){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 U();return q$[r]}async function j(){return(await Jm()).npm}async function gr(){if(await U()==="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 dr(){const r=await U(),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(p).exists())return!1;const m=Bun.spawn([p,"--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 jm(){const r=Q();if(!await Xm())return d.error("\u8BF7\u5148\u624B\u52A8\u5B89\u88C5 unzip: apt install unzip / yum install unzip"),!1;await dr(),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 U()==="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 gr(),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 V=p,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 Vm(){if(await er())return V=p,!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 jm()}async function W$(){if(V){if(!Hm(V))V=p;return V}if(await er())return V=p,p;return p}async function tr(r){try{const m=await j(),b=await fetch(`${m}/${r}/latest`);if(!b.ok)return null;return(await b.json()).version}catch{return null}}async function fm(r){return(await X()).installedClients[r.id]?.version||null}async function ir(r){const m=k(r.id),b=yr(m,"package.json");try{return await Bun.file(b).exists()}catch{return!1}}async function lr(r){const m=await fm(r);if(!m)return!0;const b=await tr(r.package);if(!b)return!1;return m!==b}async function wr(r,m=!1){const b=Q(),h=k(r.id);try{if(!await Vm())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 lr(r);if(v&&!x)return{success:!0};const $=v?"\u66F4\u65B0":"\u5B89\u88C5";b.start(`\u6B63\u5728${$} ${r.name}...`),await(await import("fs/promises")).mkdir(h,{recursive:!0});const g=yr(h,"package.json");if(!await Bun.file(g).exists())await Bun.write(g,JSON.stringify({name:`tako-${r.id}`,private:!0,dependencies:{}},null,2));const w=await W$(),s=await j(),i=Bun.spawn([w,"add",r.package,"--registry",s],{cwd:h,stdout:"pipe",stderr:"pipe"});if(await i.exited!==0){const K=await new Response(i.stderr).text();return b.stop(`${$} ${r.name} \u5931\u8D25`),{success:!1,error:K}}const P=await tr(r.package);if(P){const K=await X();K.installedClients[r.id]={version:P,installedAt:(new Date()).toISOString()},await N(K)}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 Mr(r){if(!await ir(r))return await wr(r);if(await lr(r))return await wr(r,!0);return{success:!0}}var V=null;async function T(r){try{const m=await Mr(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=L$(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 c;if(r.runtime==="native")c=[h];else c=[await W$(),h];return await Bun.spawn(c,{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 G$(){try{const r=await V$();if(!r)return{success:!1,error:"\u672A\u627E\u5230 API ID\uFF0C\u8BF7\u91CD\u65B0\u914D\u7F6E Key"};const b=await(await fetch(`${z}/apiStats/api/user-stats`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiId:r})})).json(),v=await(await fetch(`${z}/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 S} from"path";var Lm=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 j(),m=await fetch(`${r}/${z$}/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:B};return{hasUpdate:Lm(r,B)>0,latestVersion:r,currentVersion:B}}async function pr(){const r=await import("fs/promises"),m=S(G,"bin"),b=S(m,"tako"),h=S(Z,"node_modules/tako-cli/dist/index.js");if(await r.mkdir(m,{recursive:!0}),process.platform==="win32"){const x=`@echo off\r\n"${p}" "${h}" %*\r\n`;await r.writeFile(S(m,"tako.cmd"),x)}else{const x=`#!/bin/bash\nexec "${p}" "${h}" "\$@"\n`;await r.writeFile(b,x,{mode:493})}}async function nm(r){const m=Q();m.start(`\u6B63\u5728\u66F4\u65B0\u5230 v${r}...`);try{const b=await j(),h=await import("fs/promises");await h.mkdir(Z,{recursive:!0});const v=S(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([p,"add",`${z$}@latest`,"--registry",b],{cwd:Z,stdout:"pipe",stderr:"pipe"});if(await x.exited,x.exitCode===0)return await pr(),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");try{const m=await j();await r.mkdir(Z,{recursive:!0});const b=S(Z,"package.json");try{await r.access(b)}catch{await r.writeFile(b,JSON.stringify({name:"tako-local",private:!0},null,2))}const h=Bun.spawn([p,"add",`${z$}@latest`,"--registry",m],{cwd:Z,stdout:"pipe",stderr:"pipe"});return await h.exited,h.exitCode===0}catch{return!1}}async function Um(){const r=await import("fs/promises"),m=S(G,"bin"),b=S(m,"tako"),h=S(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 $=Q();if($.start("\u6B63\u5728\u5B89\u88C5\u5230\u672C\u5730\u76EE\u5F55..."),!await Em())return $.stop("\u672C\u5730\u5B89\u88C5\u5931\u8D25\uFF0C\u8DF3\u8FC7\u8FC1\u79FB"),!1;$.stop("\u672C\u5730\u5B89\u88C5\u5B8C\u6210")}return await pr(),!0}}catch{}return!1}async function r$(){try{if(await Um())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${B}\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 z$="tako-cli",B="0.1.31";var Tm=function(){console.log(),console.log(` \uD83D\uDC19 Tako CLI v${B}`),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 cr({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(E(m))return!1;const b=Q();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 Pm=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 Km(){const m=Q();m.start("\u83B7\u53D6\u7528\u91CF\u7EDF\u8BA1...");let b=await G$();if(!b.success){m.stop(`\u83B7\u53D6\u5931\u8D25: ${b.error}`);return}m.stop("");let h=10,v="";const x=()=>{if(v){const c=v.split("\n").length;process.stdout.write(`\x1B[${c}A\x1B[0J`)}v=Pm(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((c)=>{let g=!0;const o=()=>{if(!g)return;g=!1,s(),c()},w=setInterval(async()=>{if(!g)return;if(h--,h<=0){h=10;const i=await G$();if(i.success)b=i}x()},1000),s=()=>{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 Om(){const m=[...B$().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 or({message:"\u8BF7\u9009\u62E9\u64CD\u4F5C:",options:m});if(E(b))return null;return b}async function Nm(r){switch(r.type){case"launch":const m=await T(r.client);if(!m.success)d.error(m.error||"\u542F\u52A8\u5931\u8D25");return!0;case"stats":return await Km(),!0;case"config":return await qr(!0),!0;case"exit":return!1}}async function Wr(){if(Tm(),!await X$()){if(!await qr()){p$("\u518D\u89C1\uFF01");return}}while(!0){const m=await Om();if(m===null)break;if(!await Nm(m))break}p$("\u518D\u89C1\uFF01")}var Am=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 Rm(){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")){Am();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 T(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 T(m);if(!b.success)console.error(b.error),process.exit(1);return}await r$(),await Wr()}var Gr="0.1.
|
|
68
|
+
`)};async function Rm(){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")){Am();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 T(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 T(m);if(!b.success)console.error(b.error),process.exit(1);return}await r$(),await Wr()}var Gr="0.1.31";Rm().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.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Tako CLI - AI coding tools launcher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"test:e2e": "bash scripts/test-install.sh",
|
|
23
23
|
"test:watch": "bun test --watch",
|
|
24
24
|
"test:coverage": "bun test --coverage",
|
|
25
|
-
"release": "bun run test:pre-release && bun scripts/bump.ts patch && npm publish && ./scripts/sync-gitee.sh",
|
|
25
|
+
"release": "bun run test:pre-release && bun scripts/bump.ts patch && npm publish --registry https://registry.npmjs.org && ./scripts/sync-gitee.sh",
|
|
26
26
|
"prepublishOnly": "bun run build"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
@@ -36,4 +36,4 @@
|
|
|
36
36
|
"codex"
|
|
37
37
|
],
|
|
38
38
|
"license": "UNLICENSED"
|
|
39
|
-
}
|
|
39
|
+
}
|