@lzg14/mimo-cli 0.1.4 → 0.1.7

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/mimo.js +37 -36
  2. package/package.json +1 -1
package/dist/mimo.js CHANGED
@@ -1,51 +1,52 @@
1
1
  #!/usr/bin/env node
2
- var C={SUCCESS:0,ERROR:1,USAGE:2,DATAERR:3};var r=class extends Error{constructor(t,i="ERROR",n=C.ERROR){super(t);this.code=i;this.exitCode=n;this.name="CLIError"}};function d(e){return`\x1B[2m${e}\x1B[0m`}function p(e){return`\x1B[1m${e}\x1B[0m`}function M(e){return`\x1B[32m${e}\x1B[0m`}function I(e){e instanceof r&&(console.error(`error: ${e.message}`),process.exit(e.exitCode)),e instanceof Error?(process.env.DEBUG?console.error(d(e.stack||e.message)):console.error(d(e.message)),console.error(p(`
3
- Run with --verbose for more details.`))):console.error("Unknown error:",e),process.exit(C.ERROR)}var b="0.1.4";var w=class{root={children:new Map};constructor(o){for(let[t,i]of Object.entries(o))this.register(t,i)}register(o,t){let i=o.split(" "),n=this.root;for(let s of i)n.children.has(s)||n.children.set(s,{children:new Map}),n=n.children.get(s);n.command=t}getAllCommands(){let o=[],t=i=>{i.command&&o.push(i.command);for(let n of i.children.values())t(n)};return t(this.root),o}resolve(o){let t=this.root,i=[];for(let n of o){let s=t.children.get(n);if(!s)break;if(t=s,i.push(n),t.command)return{command:t.command,extra:o.slice(i.length)}}return t.command?{command:t.command,extra:o.slice(i.length)}:null}getSuggestions(o){let t=this.root,i=[];for(let n of o){let s=t.children.get(n);if(!s)return i;t=s}for(let[n,s]of t.children)s.command?i.push(` ${n}`):i.push(` ${n}`);return i}};import{readFileSync as F,writeFileSync as D,existsSync as j}from"fs";import{dirname as J}from"path";import{mkdirSync as G}from"fs";var $={baseUrl:"https://api.xiaomimimo.com",model:"MiniMax-M2.7",output:"text",timeout:120,quiet:!1,verbose:!1};function k(){return`${process.env.HOME||process.env.USERPROFILE||""}/.mimo/config.json`}var f=null;function u(){if(f)return f;let e=k();if(!j(e))return f={...$},f;try{let o=F(e,"utf-8"),t=JSON.parse(o);f={...$,...t}}catch{f={...$}}return f}function y(e){let o=k(),t=J(o);j(t)||G(t,{recursive:!0});let n={...u(),...e};D(o,JSON.stringify(n,null,2),"utf-8"),f=n}var H={name:"chat",description:"Chat with MiMo models",usage:"mimo chat [options] [message]",examples:['mimo chat "Hello, who are you?"','mimo chat --model MiniMax-M2.7 "Explain quantum computing"',"mimo chat --no-stream"],options:[{flag:"--model <model>",description:"Model to use"},{flag:"--system <text>",description:"System prompt"},{flag:"--stream",description:"Enable streaming (default)"},{flag:"--no-stream",description:"Disable streaming"},{flag:"--json",description:"Output as JSON"}],async execute(e,o){let t=u(),i=o["api-key"]||t.apiKey;if(!i)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let n=e.join(" ")||o.message||"";if(!n)throw new r('Message is required. Usage: mimo chat "your message"');let s=o.model||t.model||"MiniMax-M2.7",a=o.stream!==!1&&o["no-stream"]!==!0,c=o.json===!0,g=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",l=await fetch(`${g}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({model:s,messages:[{role:"user",content:n}],stream:a})});if(!l.ok){let m=await l.text();throw new r(`API error: ${l.status} ${l.statusText}
4
- ${m}`)}if(a){let m=l.body?.getReader();if(!m)throw new r("No response body");process.stdout.write(`
5
- `);let h=new TextDecoder,x="";for(;;){let{done:v,value:B}=await m.read();if(v)break;let S=h.decode(B,{stream:!0});x+=S,process.stdout.write(S)}process.stdout.write(`
6
- `),c&&console.log(JSON.stringify({response:x,model:s,usage:{}}))}else{let m=await l.json(),h=m.choices?.[0]?.message?.content||"";console.log(c?JSON.stringify({response:h,model:s,usage:m.usage}):h)}}},A=H;var V={name:"models",description:"List available MiMo models",usage:"mimo models",async execute(e,o){let t=u(),i=o["api-key"]||t.apiKey;if(!i)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let n=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com";console.log(`
2
+ var $={SUCCESS:0,ERROR:1,USAGE:2,DATAERR:3};var r=class extends Error{constructor(t,n="ERROR",i=$.ERROR){super(t);this.code=n;this.exitCode=i;this.name="CLIError"}};function p(e){return`\x1B[2m${e}\x1B[0m`}function c(e){return`\x1B[1m${e}\x1B[0m`}function P(e){return`\x1B[32m${e}\x1B[0m`}function O(e){e instanceof r&&(console.error(`error: ${e.message}`),process.exit(e.exitCode)),e instanceof Error?(process.env.DEBUG?console.error(p(e.stack||e.message)):console.error(p(e.message)),console.error(c(`
3
+ Run with --verbose for more details.`))):console.error("Unknown error:",e),process.exit($.ERROR)}var v="0.1.7";var S=class{root={children:new Map};constructor(o){for(let[t,n]of Object.entries(o))this.register(t,n)}register(o,t){let n=o.split(" "),i=this.root;for(let s of n)i.children.has(s)||i.children.set(s,{children:new Map}),i=i.children.get(s);i.command=t}getAllCommands(){let o=[],t=n=>{n.command&&o.push(n.command);for(let i of n.children.values())t(i)};return t(this.root),o}resolve(o){let t=this.root,n=[];for(let i of o){let s=t.children.get(i);if(!s)break;if(t=s,n.push(i),t.command)return{command:t.command,extra:o.slice(n.length)}}return t.command?{command:t.command,extra:o.slice(n.length)}:null}getSuggestions(o){let t=this.root,n=[];for(let i of o){let s=t.children.get(i);if(!s)return n;t=s}for(let[i,s]of t.children)n.push(` ${i}`);return n}};import{readFileSync as X,writeFileSync as Y,existsSync as L}from"fs";import{dirname as Z}from"path";import{mkdirSync as oo}from"fs";var k={baseUrl:"https://api.xiaomimimo.com",model:"mimo-v2.5-pro",output:"text",timeout:120,quiet:!1,verbose:!1};function j(){return`${process.env.HOME||process.env.USERPROFILE||""}/.mimo/config.json`}var y=null;function l(){if(y)return y;let e=j();if(!L(e))return y={...k},y;try{let o=X(e,"utf-8"),t=JSON.parse(o);y={...k,...t}}catch{y={...k}}return process.env.MIMO_API_KEY&&(y.apiKey=process.env.MIMO_API_KEY),y}function b(e){let o=j(),t=Z(o);L(t)||oo(t,{recursive:!0});let i={...l(),...e};Y(o,JSON.stringify(i,null,2),"utf-8"),y=i}var eo={name:"chat",description:"Chat with MiMo models",usage:"mimo chat [options] [message]",examples:['mimo chat "Hello, who are you?"','mimo chat --model mimo-v2.5-pro "Explain quantum computing"',"mimo chat --no-stream"],options:[{flag:"--model <model>",description:"Model to use"},{flag:"--system <text>",description:"System prompt"},{flag:"--stream",description:"Enable streaming (default)"},{flag:"--no-stream",description:"Disable streaming"},{flag:"--json",description:"Output as JSON"}],async execute(e,o){let t=l(),n=o["api-key"]||t.apiKey;if(!n)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let i=e.join(" ")||o.message||"";if(!i)throw new r('Message is required. Usage: mimo chat "your message"');let s=o.model||t.model||"mimo-v2.5-pro",a=o.system||void 0,m=o.stream!==!1&&o["no-stream"]!==!0,g=o.json===!0,d=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",u=[];a&&u.push({role:"system",content:a}),u.push({role:"user",content:i});let x=await fetch(`${d}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},signal:AbortSignal.timeout(t.timeout*1e3),body:JSON.stringify({model:s,messages:u,stream:m})});if(!x.ok){let h=await x.text();throw new r(`API error: ${x.status} ${x.statusText}
4
+ ${h}`)}if(m){let h=x.body?.getReader();if(!h)throw new r("No response body");process.stdout.write(`
5
+ `);let f=new TextDecoder,w="",C="";for(;;){let{done:I,value:V}=await h.read();if(I)break;w+=f.decode(V,{stream:!0});let R=w.split(`
6
+ `);w=R.pop()||"";for(let Q of R){let T=Q.trim();if(T.startsWith("data:")){let M=T.slice(5).trim();if(M==="[DONE]")continue;try{let A=JSON.parse(M).choices?.[0]?.delta?.content||"";A&&(C+=A,process.stdout.write(A))}catch{}}}}process.stdout.write(`
7
+ `),g&&console.log(JSON.stringify({response:C,model:s}))}else{let h=await x.json(),f=h.choices?.[0]?.message?.content||"";console.log(g?JSON.stringify({response:f,model:s,usage:h.usage}):f)}}},U=eo;var to={name:"models",description:"List available MiMo models",usage:"mimo models",async execute(e,o){let t=l(),n=o["api-key"]||t.apiKey;if(!n)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let i=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com";console.log(`
7
8
  MiMo Models:
8
9
  \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
9
10
  Model Context Description
10
11
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
11
- MiniMax-M2.7 1M Most capable, best for complex tasks
12
- MiniMax-M2.5 256K Balanced performance
13
- MiniMax-M2 128K Cost effective
12
+ mimo-v2.5-pro 1M Most capable, best for complex tasks
13
+ mimo-v2.5 1M Fast, low-cost
14
+ mimo-v2-pro 256K High performance
15
+ mimo-v2-flash 1M Fast, low-cost (deprecated)
16
+ mimo-v2.5-asr - Speech recognition (ASR)
17
+ mimo-v2.5-tts - Speech synthesis (TTS)
14
18
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
15
- For more information: https://platform.minimax.chat
16
- `);try{let s=await fetch(`${n}/v1/models`,{method:"GET",headers:{Authorization:`Bearer ${i}`}});if(s.ok){let a=await s.json();if(a.models){console.log(`
17
- API Models:`);for(let c of a.models)console.log(` ${c.id.padEnd(20)} ${c.description||""}`)}}}catch{}}},E=V;var W={name:"auth login",description:"Login with API key",usage:"mimo auth login --api-key <key>",examples:["mimo auth login --api-key sk-xxxxx"],async execute(e,o){let t=o["api-key"];t||(console.error("Error: --api-key is required"),console.log(`
18
- Usage: mimo auth login --api-key <your-api-key>
19
-
20
- You can get your API key from: https://platform.minimax.chat
21
- `),process.exit(1)),y({apiKey:t}),console.log(p("Successfully logged in!")),console.log(d("API key saved to ~/.mimo/config.json"))}},R=W;var Q={name:"auth logout",description:"Logout and remove credentials",usage:"mimo auth logout",async execute(){y({apiKey:void 0}),console.log(p("Logged out successfully.")),console.log(d("Credentials removed from ~/.mimo/config.json"))}},T=Q;var X={name:"auth status",description:"Check authentication status",usage:"mimo auth status",async execute(){let e=u();e.apiKey?console.log(`
22
- ${p("Authentication Status:")} ${M("Logged in")}
23
- ${d("API Key:")} ${"*".repeat(20)}${e.apiKey.slice(-4)}
19
+ For more information: https://mimo.mi.com/docs
20
+ `);try{let s=await fetch(`${i}/v1/models`,{method:"GET",signal:AbortSignal.timeout(1e4),headers:{Authorization:`Bearer ${n}`}});if(s.ok){let a=await s.json();if(a.models){console.log(`
21
+ API Models:`);for(let m of a.models)console.log(` ${m.id.padEnd(20)} ${m.description||""}`)}}}catch{}}},N=to;var io={name:"auth login",description:"Login with API key",usage:"mimo auth login --api-key <key>",examples:["mimo auth login --api-key sk-xxxxx"],async execute(e,o){let t=o["api-key"];if(!t)throw new r(`--api-key is required. Get your key from: https://platform.xiaomimimo.com
22
+ Usage: mimo auth login --api-key <your-api-key>`);b({apiKey:t}),console.log(c("Successfully logged in!")),console.log(p("API key saved to ~/.mimo/config.json"))}},q=io;var no={name:"auth logout",description:"Logout and remove credentials",usage:"mimo auth logout",async execute(){b({apiKey:void 0}),console.log(c("Logged out successfully.")),console.log(p("Credentials removed from ~/.mimo/config.json"))}},K=no;var so={name:"auth status",description:"Check authentication status",usage:"mimo auth status",async execute(){let e=l();e.apiKey?console.log(`
23
+ ${c("Authentication Status:")} ${P("Logged in")}
24
+ ${p("API Key:")} ${"*".repeat(20)}${e.apiKey.slice(-4)}
24
25
  `):console.log(`
25
- ${p("Authentication Status:")} ${d("Not logged in")}
26
- ${d("Run:")} mimo auth login --api-key <your-key>
27
- `)}},P=X;var Y={name:"config",description:"Show CLI configuration",usage:"mimo config",examples:["mimo config"],async execute(){let e=u();console.log(`
28
- ${p("CLI Configuration:")}
29
- API Key: ${e.apiKey?d("**********"+e.apiKey.slice(-4)):d("not set")}
26
+ ${c("Authentication Status:")} ${p("Not logged in")}
27
+ ${p("Run:")} mimo auth login --api-key <your-key>
28
+ `)}},_=so;var ro={name:"config",description:"Show CLI configuration",usage:"mimo config",examples:["mimo config"],async execute(){let e=l();console.log(`
29
+ ${c("CLI Configuration:")}
30
+ API Key: ${e.apiKey?p("**********"+e.apiKey.slice(-4)):p("not set")}
30
31
  Base URL: ${e.baseUrl}
31
32
  Model: ${e.model}
32
33
  Output: ${e.output}
33
34
  Timeout: ${e.timeout}s
34
- `)}},U=Y;var Z={name:"config set",description:"Set a configuration value",usage:"mimo config set <key> <value>",examples:["mimo config set model MiniMax-M2.7","mimo config set timeout 60"],async execute(e){e.length<2&&(console.error("Usage: mimo config set <key> <value>"),process.exit(1));let[o,...t]=e,i=t.join(" "),n=["apiKey","baseUrl","model","output","timeout","quiet","verbose"];n.includes(o)||(console.error(`Invalid key: ${o}`),console.error(`Valid keys: ${n.join(", ")}`),process.exit(1));let s=i;o==="timeout"&&(s=parseInt(i,10),isNaN(s)&&(console.error("Timeout must be a number"),process.exit(1))),(o==="quiet"||o==="verbose")&&(s=i==="true"||i==="1"),y({[o]:s}),console.log(`Config updated: ${o} = ${i}`)}},L=Z;var oo={name:"speech synthesize",description:"Speech synthesis (TTS)",usage:"mimo speech synthesize --text <text> [--out <file>]",examples:['mimo speech synthesize --text "Hello world" --out output.mp3','mimo speech synthesize -t "\u4F60\u597D\u4E16\u754C" -o audio.mp3'],options:[{flag:"--text, -t <text>",description:"Text to synthesize"},{flag:"--out, -o <file>",description:"Output file (default: output.mp3)"},{flag:"--voice <name>",description:"Voice name"}],async execute(e,o){let t=u(),i=o["api-key"]||t.apiKey;if(!i)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let n=o.text||o.t||e.join(" ");if(!n)throw new r('Text is required. Usage: mimo speech synthesize --text "your text"');let s=o.out||o.o||"output.mp3",a=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",c=o.voice||"female-qn";console.log("Synthesizing speech...");let g=await fetch(`${a}/v1/t2a_v2`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({model:"speech-02-hd",text:n,stream:!1,voice_setting:{voice_id:c}})});if(!g.ok){let h=await g.text();throw new r(`API error: ${g.status} ${g.statusText}
35
- ${h}`)}let l=await g.arrayBuffer(),{writeFileSync:m}=await import("fs");m(s,Buffer.from(l)),console.log(`Audio saved to: ${s}`)}},N=oo;var eo={name:"search query",description:"Web search",usage:"mimo search query <query>",examples:['mimo search query "latest news about AI"','mimo search "weather in Beijing"'],async execute(e,o){let t=u(),i=o["api-key"]||t.apiKey;if(!i)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let n=e.join(" ");if(!n)throw new r('Query is required. Usage: mimo search query "your question"');let s=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",a=await fetch(`${s}/v1/coding_plan/search`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({query:n,top_k:10})});if(!a.ok){let l=await a.text();throw new r(`API error: ${a.status} ${a.statusText}
36
- ${l}`)}let g=(await a.json()).data?.results||[];if(g.length===0){console.log("No results found.");return}console.log(`
37
- Search Results for: "${n}"
38
- `);for(let l=0;l<g.length;l++){let m=g[l];console.log(`${l+1}. ${m.title||"No title"}`),m.url&&console.log(` ${m.url}`),m.snippet&&console.log(` ${m.snippet.substring(0,200)}...`),console.log()}}},O=eo;var to={name:"vision describe",description:"Describe images (VLM)",usage:"mimo vision describe --image <path> [--prompt <text>]",examples:['mimo vision describe --image photo.png --prompt "Describe this image"','mimo vision describe -i image.jpg -p "What is in this picture?"'],options:[{flag:"--image, -i <path>",description:"Image file path"},{flag:"--prompt, -p <text>",description:"Question about the image"}],async execute(e,o){let t=u(),i=o["api-key"]||t.apiKey;if(!i)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let n=o.image||o.i,s=o.prompt||o.p||e.join(" ")||"Describe this image";if(!n)throw new r("Image path is required. Usage: mimo vision describe --image <path>");let a=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",{readFileSync:c}=await import("fs"),l=c(n).toString("base64"),m=await fetch(`${a}/v1/coding_plan/vlm`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({model:"MiniMax-VL-01",messages:[{role:"user",content:[{type:"image_url",image_url:`data:image/jpeg;base64,${l}`},{type:"text",text:s}]}]})});if(!m.ok){let v=await m.text();throw new r(`API error: ${m.status} ${m.statusText}
39
- ${v}`)}let x=(await m.json()).choices?.[0]?.message?.content||"No description available";console.log(x)}},q=to;var no={name:"quota show",description:"Show token usage and quota",usage:"mimo quota show",async execute(e,o){let t=u(),i=o["api-key"]||t.apiKey;if(!i)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let n=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",s=await fetch(`${n}/v1/token_plan/remains`,{method:"GET",headers:{Authorization:`Bearer ${i}`}});if(!s.ok){let c=await s.text();throw new r(`API error: ${s.status} ${s.statusText}
40
- ${c}`)}let a=await s.json();if(console.log(`
35
+ `)}},z=ro;var ao={name:"config set",description:"Set a configuration value",usage:"mimo config set <key> <value>",examples:["mimo config set model mimo-v2.5-pro","mimo config set timeout 60"],async execute(e){if(e.length<2)throw new r("Usage: mimo config set <key> <value>");let[o,...t]=e,n=t.join(" "),i=["apiKey","baseUrl","model","output","timeout","quiet","verbose"];if(!i.includes(o))throw new r(`Invalid key: ${o}. Valid keys: ${i.join(", ")}`);let s=n;if(o==="timeout"&&(s=parseInt(n,10),isNaN(s)))throw new r("Timeout must be a number");if(o==="output"&&!["text","json"].includes(n))throw new r('Output must be "text" or "json"');(o==="quiet"||o==="verbose")&&(s=n==="true"||n==="1"),b({[o]:s}),console.log(`Config updated: ${o} = ${n}`)}},F=ao;import{writeFileSync as mo}from"fs";var co={name:"speech synthesize",description:"Speech synthesis (TTS)",usage:"mimo speech synthesize --text <text> [--out <file>]",examples:['mimo speech synthesize --text "Hello world" --out output.mp3','mimo speech synthesize -t "\u4F60\u597D\u4E16\u754C" -o audio.mp3'],options:[{flag:"--text, -t <text>",description:"Text to synthesize"},{flag:"--out, -o <file>",description:"Output file (default: output.mp3)"},{flag:"--voice <name>",description:"Voice name"}],async execute(e,o){let t=l(),n=o["api-key"]||t.apiKey;if(!n)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let i=o.text||o.t||e.join(" ");if(!i)throw new r('Text is required. Usage: mimo speech synthesize --text "your text"');let s=o.out||o.o||"output.mp3",a=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",m=o.voice||"female-qn";console.log("Synthesizing speech...");let g=await fetch(`${a}/v1/t2a_v2`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},signal:AbortSignal.timeout(t.timeout*1e3),body:JSON.stringify({text:i,stream:!1,voice_setting:{voice_id:m}})});if(!g.ok){let u=await g.text();throw new r(`API error: ${g.status} ${g.statusText}
36
+ ${u}`)}let d=await g.arrayBuffer();mo(s,Buffer.from(d)),console.log(`Audio saved to: ${s}`)}},B=co;var lo={name:"search query",description:"Web search",usage:"mimo search query <query>",examples:['mimo search query "latest news about AI"','mimo search "weather in Beijing"'],async execute(e,o){let t=l(),n=o["api-key"]||t.apiKey;if(!n)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let i=e.join(" ");if(!i)throw new r('Query is required. Usage: mimo search query "your question"');let s=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",a=await fetch(`${s}/v1/coding_plan/search`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},signal:AbortSignal.timeout(t.timeout*1e3),body:JSON.stringify({top_k:10})});if(!a.ok){let d=await a.text();throw new r(`API error: ${a.status} ${a.statusText}
37
+ ${d}`)}let g=(await a.json()).data?.results||[];if(g.length===0){console.log("No results found.");return}console.log(`
38
+ Search Results for: "${i}"
39
+ `);for(let d=0;d<g.length;d++){let u=g[d];console.log(`${d+1}. ${u.title||"No title"}`),u.url&&console.log(` ${u.url}`),u.snippet&&console.log(` ${u.snippet.substring(0,200)}...`),console.log()}}},D=lo;import{readFile as po,access as uo}from"fs/promises";import{parse as go,resolve as J,isAbsolute as fo}from"path";var ho=10*1024*1024,yo={name:"vision describe",description:"Describe images (VLM)",usage:"mimo vision describe --image <path> [--prompt <text>]",examples:['mimo vision describe --image photo.png --prompt "Describe this image"','mimo vision describe -i image.jpg -p "What is in this picture?"'],options:[{flag:"--image, -i <path>",description:"Image file path"},{flag:"--prompt, -p <text>",description:"Question about the image"}],async execute(e,o){let t=l(),n=o["api-key"]||t.apiKey;if(!n)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let i=o.image||o.i,s=o.prompt||o.p||e.join(" ")||"Describe this image";if(!i)throw new r("Image path is required. Usage: mimo vision describe --image <path>");let a=fo(i)?J(i):J(process.cwd(),i);try{await uo(a)}catch{throw new r(`Image file not found: ${i}`)}let{ext:m}=go(a),d={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp"}[m.toLowerCase()]||"image/jpeg",u=await po(a);if(u.length>ho)throw new r(`Image too large: ${(u.length/1024/1024).toFixed(1)}MB (max 10MB)`);let x=u.toString("base64"),h=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",f=await fetch(`${h}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},signal:AbortSignal.timeout(t.timeout*1e3),body:JSON.stringify({model:"mimo-v2.5",messages:[{role:"user",content:[{type:"image_url",image_url:`data:${d};base64,${x}`},{type:"text",text:s}]}]})});if(!f.ok){let I=await f.text();throw new r(`API error: ${f.status} ${f.statusText}
40
+ ${I}`)}let C=(await f.json()).choices?.[0]?.message?.content||"No description available";console.log(C)}},G=yo;var xo={name:"quota show",description:"Show token usage and quota",usage:"mimo quota show",async execute(e,o){let t=l(),n=o["api-key"]||t.apiKey;if(!n)throw new r('API key not found. Run "mimo auth login --api-key <key>" first.');let i=o["base-url"]||t.baseUrl||"https://api.xiaomimimo.com",s=await fetch(`${i}/v1/token_plan/remains`,{method:"GET",signal:AbortSignal.timeout(t.timeout*1e3),headers:{Authorization:`Bearer ${n}`}});if(!s.ok){let m=await s.text();throw new r(`API error: ${s.status} ${s.statusText}
41
+ ${m}`)}let a=await s.json();if(console.log(`
41
42
  Token Plan Quota:
42
43
  \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
43
- `),a.data)for(let c of a.data)console.log(`Model: ${c.model_name||"N/A"}`),console.log(`Remaining: ${c.remaining||0}`),console.log(`Total: ${c.total||0}`),console.log(`Reset at: ${c.reset_at||"N/A"}`),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");else console.log(JSON.stringify(a,null,2))}},K=no;var io={name:"help",description:"Show help information",usage:"mimo help [command]",examples:["mimo help","mimo help chat"],async execute(e){if(e.length>0){console.log(`Run 'mimo " + args[0] + " --help' for command help.`);return}so()}};function so(){console.log(`
44
- ${p("mimo")} ${d("v"+b)} Xiaomi MiMo CLI
44
+ `),a.data)for(let m of a.data)console.log(`Model: ${m.model_name||"N/A"}`),console.log(`Remaining: ${m.remaining||0}`),console.log(`Total: ${m.total||0}`),console.log(`Reset at: ${m.reset_at||"N/A"}`),console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");else console.log(JSON.stringify(a,null,2))}},W=xo;var bo={name:"help",description:"Show help information",usage:"mimo help [command]",examples:["mimo help","mimo help chat"],async execute(e){if(e.length>0){console.log(`Run 'mimo ${e[0]} --help' for command help.`);return}wo()}};function wo(){console.log(`
45
+ ${c("mimo")} ${p("v"+v)} Xiaomi MiMo CLI
45
46
 
46
- ${p("Usage:")} mimo <command> [flags]
47
+ ${c("Usage:")} mimo <command> [flags]
47
48
 
48
- ${p("Commands:")}
49
+ ${c("Commands:")}
49
50
  chat Text chat with MiMo models
50
51
  models List available models
51
52
  auth Authentication (login, logout, status)
@@ -55,7 +56,7 @@ ${p("Commands:")}
55
56
  vision Image understanding
56
57
  quota Show token usage
57
58
 
58
- ${p("Global Flags:")}
59
+ ${c("Global Flags:")}
59
60
  --api-key <key> API key
60
61
  --base-url <url> API base URL
61
62
  --output <format> Output format: text, json
@@ -64,7 +65,7 @@ ${p("Global Flags:")}
64
65
  --help Show help
65
66
  --version Show version
66
67
 
67
- ${p("Getting Help:")}
68
+ ${c("Getting Help:")}
68
69
  Add --help after any command.
69
70
  Example: mimo chat --help
70
- `)}var _=io;var z=new w({chat:A,models:E,"auth login":R,"auth logout":T,"auth status":P,config:U,"config set":L,"speech synthesize":N,"search query":O,"vision describe":q,"quota show":K,help:_});process.stdout.on("error",()=>{});process.stderr.on("error",()=>{});function ro(e){let o=[],t=[],i={},n=0;for(;n<e.length;){let s=e[n];if(s.startsWith("--")){let a=s.slice(2);n+1<e.length&&!e[n+1].startsWith("-")?i[a]=e[++n]:i[a]=!0}else if(s.startsWith("-")&&s.length>1){let a=s.slice(1);n+1<e.length&&!e[n+1].startsWith("-")?i[a]=e[++n]:i[a]=!0}else o.length===0?o.push(s):t.push(s);n++}return{commandPath:o,extra:t,flags:i}}async function ao(){let e=process.argv.slice(2);if(e.length===0||e[0]==="help"||e[0]==="--help"||e[0]==="-h"){let s=z.resolve(["help"]);s&&await s.command.execute(s.extra,{});return}if(e[0]==="--version"||e[0]==="-v"){console.log(`mimo v${b}`);return}let{commandPath:o,extra:t,flags:i}=ro(e),n=z.resolve(o);n||(console.error(`Unknown command: ${o.join(" ")}`),console.error("Run 'mimo help' for usage."),process.exit(1));try{await n.command.execute(t,i)}catch(s){I(s)}}ao();
71
+ `)}var H=bo;var E=new S({chat:U,models:N,"auth login":q,"auth logout":K,"auth status":_,config:z,"config set":F,"speech synthesize":B,"search query":D,"vision describe":G,"quota show":W,help:H});process.stdout.on("error",()=>{});process.stderr.on("error",()=>{});function Co(e){let o=[],t=[],n={},i=0,s=!1;for(;i<e.length;){let a=e[i];if((a.startsWith("--")||a.startsWith("-")&&a.length>1)&&(s=!0),!s&&!a.startsWith("-")){let m=[...o,a];if(E.resolve(m)){o.push(a),i++;continue}o.length>0&&(s=!0)}if(a.startsWith("--")){let m=a.slice(2);i+1<e.length&&!e[i+1].startsWith("-")?n[m]=e[++i]:n[m]=!0}else if(a.startsWith("-")&&a.length>1){let m=a.slice(1);i+1<e.length&&!e[i+1].startsWith("-")?n[m]=e[++i]:n[m]=!0}else t.push(a);i++}return{commandPath:o,extra:t,flags:n}}async function $o(){let e=process.argv.slice(2);if(e.length===0||e[0]==="help"||e[0]==="--help"||e[0]==="-h"){let s=E.resolve(["help"]);s&&await s.command.execute(s.extra,{});return}if(e[0]==="--version"||e[0]==="-v"){console.log(`mimo v${v}`);return}let{commandPath:o,extra:t,flags:n}=Co(e),i=E.resolve(o);i||(console.error(`Unknown command: ${o.join(" ")}`),console.error("Run 'mimo help' for usage."),process.exit(1));try{await i.command.execute(t,n)}catch(s){O(s)}}$o();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lzg14/mimo-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.7",
4
4
  "description": "Command-line tool for Xiaomi MiMo models",
5
5
  "type": "module",
6
6
  "engines": {