@lzg14/mimo-cli 0.1.0 → 0.1.2

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 (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +169 -0
  3. package/dist/mimo.js +65 -81
  4. package/package.json +1 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 lzg14
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # mimo-cli - Xiaomi MiMo CLI
2
+
3
+ Command-line tool for Xiaomi MiMo models. Text chat, speech synthesis, web search, and vision understanding.
4
+
5
+ ## Features
6
+
7
+ - **Chat** - Interactive text chat with MiMo models
8
+ - **Speech** - Text-to-speech synthesis (TTS)
9
+ - **Search** - Web search powered by MiMo
10
+ - **Vision** - Image understanding with VLM
11
+ - **Quota** - View token usage and quota
12
+
13
+ ## Requirements
14
+
15
+ - Node.js >= 18
16
+ - MiMo API key
17
+
18
+ ## Installation
19
+
20
+ ### npm
21
+
22
+ ```bash
23
+ npm install -g @lzg14/mimo-cli
24
+ ```
25
+
26
+ ### Build from source
27
+
28
+ ```bash
29
+ git clone https://github.com/lzg14/MiMo-cli.git
30
+ cd MiMo-cli
31
+ npm install
32
+ npm run build
33
+ npm link
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ```bash
39
+ # Login with API key
40
+ mimo auth login --api-key sk-xxxxx
41
+
42
+ # Text chat
43
+ mimo chat "Hello, who are you?"
44
+
45
+ # Speech synthesis
46
+ mimo speech synthesize --text "Hello world" --out output.mp3
47
+
48
+ # Web search
49
+ mimo search query "latest news about AI"
50
+
51
+ # Image understanding
52
+ mimo vision describe --image photo.png --prompt "Describe this image"
53
+
54
+ # Check quota
55
+ mimo quota show
56
+ ```
57
+
58
+ ## Commands
59
+
60
+ | Command | Description |
61
+ |---------|-------------|
62
+ | `mimo chat [options] [message]` | Chat with MiMo models |
63
+ | `mimo models` | List available models |
64
+ | `mimo auth login --api-key <key>` | Login with API key |
65
+ | `mimo auth logout` | Logout and remove credentials |
66
+ | `mimo auth status` | Check authentication status |
67
+ | `mimo config` | Show configuration |
68
+ | `mimo config set <key> <value>` | Set a configuration value |
69
+ | `mimo speech synthesize [options]` | Text-to-speech synthesis |
70
+ | `mimo search query <query>` | Web search |
71
+ | `mimo vision describe [options]` | Image understanding |
72
+ | `mimo quota show` | Show token usage |
73
+
74
+ ## Options
75
+
76
+ ### Global Flags
77
+
78
+ | Flag | Description |
79
+ |------|-------------|
80
+ | `--api-key <key>` | MiMo API key |
81
+ | `--base-url <url>` | API base URL |
82
+ | `--output <format>` | Output format: text, json |
83
+ | `--quiet` | Suppress non-essential output |
84
+ | `--verbose` | Print HTTP details |
85
+ | `--help` | Show help |
86
+ | `--version` | Show version |
87
+
88
+ ### Chat Options
89
+
90
+ | Flag | Description |
91
+ |------|-------------|
92
+ | `--model <model>` | Model to use |
93
+ | `--system <text>` | System prompt |
94
+ | `--stream` | Enable streaming (default) |
95
+ | `--no-stream` | Disable streaming |
96
+ | `--json` | Output as JSON |
97
+
98
+ ### Speech Options
99
+
100
+ | Flag | Description |
101
+ |------|-------------|
102
+ | `--text, -t <text>` | Text to synthesize |
103
+ | `--out, -o <file>` | Output audio file |
104
+ | `--voice <name>` | Voice name |
105
+
106
+ ### Vision Options
107
+
108
+ | Flag | Description |
109
+ |------|-------------|
110
+ | `--image, -i <path>` | Image file path |
111
+ | `--prompt, -p <text>` | Question about the image |
112
+
113
+ ## Configuration
114
+
115
+ Config file: `~/.mimo/config.json`
116
+
117
+ ```json
118
+ {
119
+ "apiKey": "sk-xxxxx",
120
+ "baseUrl": "https://api.xiaomimimo.com",
121
+ "model": "mimo-v2.5-pro",
122
+ "output": "text",
123
+ "timeout": 120
124
+ }
125
+ ```
126
+
127
+ Or use CLI commands:
128
+
129
+ ```bash
130
+ mimo config set model mimo-v2.5-pro
131
+ mimo config
132
+ ```
133
+
134
+ ## Environment Variables
135
+
136
+ | Variable | Description |
137
+ |----------|-------------|
138
+ | `MIMO_API_KEY` | API key |
139
+ | `HTTPS_PROXY` | HTTPS proxy URL |
140
+ | `HTTP_PROXY` | HTTP proxy URL |
141
+
142
+ ## Models
143
+
144
+ | Model | Context | Description |
145
+ |-------|---------|-------------|
146
+ | `mimo-v2.5-pro` | 1M | Most capable, best for complex tasks |
147
+ | `mimo-v2.5` | 1M | Fast, low-cost |
148
+ | `mimo-v2-pro` | 256K | High performance |
149
+ | `mimo-v2-flash` | 1M | Fast, low-cost (deprecated, will auto-migrate to V2.5) |
150
+
151
+ ## Development
152
+
153
+ ```bash
154
+ # Install dependencies
155
+ npm install
156
+
157
+ # Build
158
+ npm run build
159
+
160
+ # Run tests
161
+ npm test
162
+
163
+ # Type check
164
+ npm run typecheck
165
+ ```
166
+
167
+ ## License
168
+
169
+ MIT
package/dist/mimo.js CHANGED
@@ -1,86 +1,70 @@
1
- var fe=Object.defineProperty;var f=(t,e)=>()=>(t&&(e=t(t=0)),e);var ge=(t,e)=>{for(var o in e)fe(t,o,{get:e[o],enumerable:!0})};function O(t,e){let o={};for(let n=0;n<t.length;n++){let r=t[n];if(r==="--"){o._positional=t.slice(n+1);break}if(!r.startsWith("-")){o._positional||(o._positional=[]),o._positional.push(r);continue}let s=r.indexOf("=");if(s!==-1){let l=r.slice(0,s),p=r.slice(s+1);o[l.replace(/^--/,"").replace(/-/g,"_")]=p;continue}let a=r.replace(/^--/,"").replace(/-/g,"_"),i=e.find(l=>{let p=l.flag.split(" ")[0];return p===r||p===`--${a.replace(/_/g,"-")}`}),m=i?.flag.includes(" <")||i?.flag.includes(" ["),c=t[n+1];m&&c&&!c.startsWith("-")?(o[a]=c,n++):o[a]=!0}return o}function W(t,e){let o=[];for(let n of t){if(n.startsWith("-")||n==="--")break;o.push(n)}return o}function h(t){return t.base_url||t.baseUrl||"https://api.ds.com"}var b=f(()=>{"use strict"});var x,T=f(()=>{"use strict";x=class extends Error{code;suggestion;fields;constructor(e,o=1,n,r){super(e),this.name="CLIError",this.code=o,this.suggestion=n,this.fields=r}}});var w,I=f(()=>{"use strict";w={SUCCESS:0,USAGE:1,CONFIG:2,AUTH:3,NETWORK:4,API:5,TIMEOUT:6,ABORT:7,UNKNOWN:99}});var N,P=f(()=>{"use strict";N="0.1.0"});function d(t){return{name:t.name,description:t.description,usage:t.usage,options:t.options,examples:t.examples,apiDocs:t.apiDocs,execute:t.run}}var A,u=f(()=>{"use strict";A=[{flag:"--api-key <key>",description:"ds API key"},{flag:"--base-url <url>",description:"API base URL"},{flag:"--output <format>",description:"Output format: text, json"},{flag:"--timeout <seconds>",description:"Request timeout",type:"number"},{flag:"--quiet",description:"Suppress non-essential output"},{flag:"--verbose",description:"Print HTTP request/response details"},{flag:"--no-color",description:"Disable ANSI colors"},{flag:"--dry-run",description:"Dry run mode"},{flag:"--non-interactive",description:"Disable interactive prompts"},{flag:"--help",description:"Show help"},{flag:"--version",description:"Print version"}]});async function ue(t,e,o,n,r){let s=new AbortController,a=setTimeout(()=>s.abort(),n*1e3);try{let i=await fetch(`${t}/chat/completions`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(o),signal:s.signal});if(clearTimeout(a),!i.ok){let p=await i.text();throw new Error(`API error ${i.status}: ${p}`)}if(!i.body)throw new Error("No response body");let m=i.body.getReader(),c=new TextDecoder,l="";for(;;){let{done:p,value:g}=await m.read();if(p)break;l+=c.decode(g,{stream:!0});let k=l.split(`
2
- `);l=k.pop()||"";for(let E of k)if(E.startsWith("data: ")){let v=E.slice(6);if(v==="[DONE]")continue;try{let _=JSON.parse(v).choices?.[0]?.delta?.content;_&&process.stdout.write(_)}catch{}}}process.stdout.write(`
3
- `)}finally{clearTimeout(a)}}async function he(t,e,o,n,r){let s=new AbortController,a=setTimeout(()=>s.abort(),n*1e3);try{let i=await fetch(`${t}/chat/completions`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({...o,stream:!1}),signal:s.signal});if(clearTimeout(a),!i.ok){let l=await i.text();throw new Error(`API error ${i.status}: ${l}`)}let c=(await i.json()).choices?.[0]?.message;c?.reasoning_content&&r.verbose&&console.log(`[Reasoning]:
4
- `+c.reasoning_content+`
5
- `),c?.content&&console.log(c.content)}finally{clearTimeout(a)}}var H,M=f(()=>{"use strict";u();b();H=d({name:"chat",description:"Chat with DeepSeek models",usage:"ds chat [options] [message]",examples:['ds chat "Hello, who are you?"','ds chat --model deepseek-v4-flash "Explain quantum computing"',"ds chat --no-stream"],options:[{flag:"--model <model>",description:"Model to use (deepseek-chat, deepseek-v4-flash)"},{flag:"--system <text>",description:"System prompt"},{flag:"--think",description:"Enable reasoning mode"},{flag:"--no-think",description:"Disable reasoning mode"},{flag:"--thinking-effort <0-10>",description:"Reasoning effort level"},{flag:"--stream",description:"Enable streaming (default)"},{flag:"--no-stream",description:"Disable streaming"},{flag:"--temperature <number>",description:"Temperature (0-2)"},{flag:"--max-tokens <n>",description:"Max output tokens"},{flag:"--json",description:"Request JSON mode"},{flag:"--timeout <seconds>",description:"Request timeout"}],run:async(t,e)=>{let o=h(t),n=t.apiKey;if(!n)throw new Error("No API key. Set ds_API_KEY or run ds auth login");let r=e.model||t.model||"deepseek-chat",s=[];e.system&&s.push({role:"system",content:e.system});let a=e._positional||[];a.length>0&&s.push({role:"user",content:a.join(" ")}),s.length===0&&(process.stderr.write(`Error: No message provided. Usage: ds chat <message>
6
- `),process.exit(1));let i=e.stream!==!1&&e.no_stream===void 0,m=e.think!==void 0?!!e.think:t.thinking,c={model:r,messages:s,stream:i};e.temperature!==void 0&&(c.temperature=parseFloat(e.temperature)),e.max_tokens!==void 0&&(c.max_tokens=parseInt(e.max_tokens)),e.json&&(c.response_format={type:"json_object"});let l=e.timeout||t.timeout||120;if(e.dry_run){console.log(`[Dry run] POST ${o}/chat/completions`),console.log(JSON.stringify(c,null,2));return}i?await ue(o,n,c,l,e):await he(o,n,c,l,e)}})});var B,Y=f(()=>{"use strict";u();b();B=d({name:"models",description:"List available DeepSeek models",usage:"ds models [flags]",examples:["ds models","ds models --json"],options:[{flag:"--json",description:"Output in JSON format"}],run:async(t,e)=>{let o=h(t),n=t.apiKey;if(!n)throw new Error("No API key. Set ds_API_KEY or run ds auth login");if(e.dry_run){console.log(`[Dry run] GET ${o}/models`);return}let r=new AbortController,s=e.timeout||t.timeout||30,a=setTimeout(()=>r.abort(),s*1e3);try{let i=await fetch(`${o}/models`,{method:"GET",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},signal:r.signal});if(clearTimeout(a),!i.ok){let l=await i.text();throw new Error(`API error ${i.status}: ${l}`)}let m=await i.json();if(e.json){console.log(JSON.stringify(m,null,2));return}let c=m.data||[];console.log(`
7
- Available ds Models:
8
- `);for(let l of c){let p=l.created?new Date(l.created*1e3).toLocaleDateString():"";console.log(` ${l.id} ${l.object} ${p}`),l.owned_by&&console.log(` Owned by: ${l.owned_by}`)}console.log("")}finally{clearTimeout(a)}}})});var q,z=f(()=>{"use strict";u();b();q=d({name:"balance",description:"Check ds account balance",usage:"ds balance [flags]",examples:["ds balance","ds balance --json"],options:[{flag:"--json",description:"Output in JSON format"}],run:async(t,e)=>{let o=h(t),n=t.apiKey;if(!n)throw new Error("No API key. Set ds_API_KEY or run ds auth login");if(e.dry_run){console.log(`[Dry run] GET ${o}/user/balance`);return}let r=new AbortController,s=e.timeout||t.timeout||30,a=setTimeout(()=>r.abort(),s*1e3);try{let i=await fetch(`${o}/user/balance`,{method:"GET",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},signal:r.signal});if(clearTimeout(a),!i.ok){let l=await i.text();throw new Error(`API error ${i.status}: ${l}`)}let m=await i.json();if(e.json){console.log(JSON.stringify(m,null,2));return}let c=m.balance_infos||[];if(c.length===0){console.log(`
9
- No balance information available.
10
- `);return}console.log(`
11
- ds Account Balance:
12
- `);for(let l of c){let p=l.currency||"CNY",g=l.total_balance??l.balance??"N/A";console.log(` ${l.model||"Account"}: ${g} ${p}`)}console.log("")}finally{clearTimeout(a)}}})});var X,V=f(()=>{"use strict";u();b();X=d({name:"complete",description:"FIM code completion (Beta)",usage:"ds complete [flags] [--prompt <prefix>] [--suffix <suffix>]",examples:['ds complete --prompt "fn main()"','ds complete --prompt "class MyClass" --suffix "}"','ds complete --model deepseek-coder --prompt "import"'],options:[{flag:"--model <model>",description:"Model to use (default: deepseek-coder)"},{flag:"--prompt <text>",description:"Prefix text"},{flag:"--suffix <text>",description:"Suffix text"},{flag:"--max-tokens <n>",description:"Max output tokens"},{flag:"--temperature <number>",description:"Temperature (0-2)"},{flag:"--stream",description:"Enable streaming"},{flag:"--no-stream",description:"Disable streaming"}],run:async(t,e)=>{let o=h(t),n=t.apiKey;if(!n)throw new Error("No API key. Set ds_API_KEY or run ds auth login");let r=e.model||"deepseek-coder";if(e.dry_run){console.log(`[Dry run] POST ${o}/completions`);return}let s={model:r,stream:e.stream!==!1&&e.no_stream===void 0};e.prompt&&(s.prompt=e.prompt),e.suffix&&(s.suffix=e.suffix),e.max_tokens!==void 0&&(s.max_tokens=parseInt(e.max_tokens)),e.temperature!==void 0&&(s.temperature=parseFloat(e.temperature)),s.prompt||(process.stderr.write(`Error: --prompt is required for FIM completion
13
- `),process.exit(1));let a=new AbortController,i=e.timeout||t.timeout||60,m=setTimeout(()=>a.abort(),i*1e3);try{let c=await fetch(`${o}/completions`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify(s),signal:a.signal});if(clearTimeout(m),!c.ok){let p=await c.text();throw new Error(`API error ${c.status}: ${p}`)}if(s.stream){if(!c.body)throw new Error("No response body");let p=c.body.getReader(),g=new TextDecoder;for(;;){let{done:k,value:E}=await p.read();if(k)break;let j=g.decode(E,{stream:!0}).split(`
14
- `);for(let _ of j)if(_.startsWith("data: ")){let D=_.slice(6);if(D==="[DONE]")continue;try{let L=JSON.parse(D),J=L.choices?.[0]?.delta?.content||L.choices?.[0]?.text;J&&process.stdout.write(J)}catch{}}}process.stdout.write(`
15
- `)}else{let p=await c.json(),g=p.choices?.[0]?.text||p.choices?.[0]?.message?.content;g&&console.log(g)}}finally{clearTimeout(m)}}})});import{readFileSync as ye,writeFileSync as be,existsSync as Q,mkdirSync as xe}from"fs";import{homedir as we}from"os";import{join as Z}from"path";function y(){if(!Q(U))return{};try{let t=ye(U,"utf-8");return t.charCodeAt(0)===65279&&(t=t.slice(1)),JSON.parse(t)}catch{return{}}}function C(t){Q(F)||xe(F,{recursive:!0}),be(U,JSON.stringify(t,null,2),"utf-8")}function R(t){let e=y();return{apiKey:t.api_key||e.apiKey||process.env.ds_API_KEY,baseUrl:t.base_url||e.baseUrl||"https://api.ds.com",model:t.model||e.model||"deepseek-chat",output:t.output||e.output||"text",timeout:t.timeout||e.timeout,proxy:e.proxy||process.env.HTTPS_PROXY||process.env.HTTP_PROXY,thinking:t.thinking!==void 0?!!t.thinking:e.thinking,thinkingEffort:t.thinking_effort||e.thinkingEffort||3,stream:t.stream!==void 0?!!t.stream:!0}}var F,U,$=f(()=>{"use strict";F=Z(we(),".seek"),U=Z(F,"config.json")});import*as ee from"readline";var oe,te=f(()=>{"use strict";u();$();b();oe=d({name:"auth login",description:"Login with ds API key",usage:"ds auth login [flags]",examples:["ds auth login","ds auth login --key sk-xxxxx"],options:[{flag:"--key <api-key>",description:"API key (or enter interactively)"},{flag:"--base-url <url>",description:"API base URL"}],run:async(t,e)=>{let o=e.key;if(!o){let n=ee.createInterface({input:process.stdin,output:process.stderr});o=await new Promise(r=>{n.question("Enter your ds API key: ",s=>{n.close(),r(s.trim())})})}if(o||(process.stderr.write(`Error: API key is required
16
- `),process.exit(1)),e.dry_run){console.log(`[Dry run] Would save API key: ${o.slice(0,8)}...`);return}e.base_url?C({...t,apiKey:o,baseUrl:e.base_url}):C({...t,apiKey:o,baseUrl:h(t)}),console.log("[OK] API key saved successfully"),e.base_url&&console.log(` Base URL: ${e.base_url}`),console.log(` Run "ds models" to verify your credentials.
17
- `)}})});var ne,re=f(()=>{"use strict";u();$();ne=d({name:"auth logout",description:"Logout and remove stored credentials",usage:"ds auth logout",examples:["ds auth logout"],run:async(t,e)=>{if(e.dry_run){console.log("[Dry run] Would remove stored API key");return}let o=y();if(!o.apiKey&&!o.baseUrl){console.log(`No credentials stored.
18
- `);return}C({}),console.log(`[OK] Logged out successfully.
19
- `)}})});var se,ie=f(()=>{"use strict";u();$();se=d({name:"config show",description:"Show current configuration",usage:"ds config show [flags]",examples:["ds config show","ds config show --json"],options:[{flag:"--json",description:"Output in JSON format"}],run:async(t,e)=>{let o=y();if(e.json){console.log(JSON.stringify(o,null,2));return}console.log(`
20
- ds configuration:
21
- `),console.log(` API Key: ${o.apiKey?o.apiKey.slice(0,8)+"...":"(not set)"}`),console.log(` Base URL: ${o.baseUrl||"https://api.ds.com (default)"}`),console.log(` Model: ${o.model||"deepseek-chat (default)"}`),console.log(` Proxy: ${o.proxy||"(not set)"}`),console.log(""),console.log(" Environment variables:"),console.log(" ds_API_KEY -> API key"),console.log(" HTTPS_PROXY -> Proxy URL"),console.log(" HTTP_PROXY -> Proxy URL"),console.log("")}})});var ae,le=f(()=>{"use strict";u();$();ae=d({name:"config set",description:"Set a configuration value",usage:"ds config set <key> <value>",examples:["ds config set model deepseek-chat","ds config set proxy http://localhost:7890"],run:async(t,e)=>{let o=e._positional||[],[n,...r]=o;(!n||r.length===0)&&(process.stderr.write(`Error: Usage: ds config set <key> <value>
22
- `),process.exit(1));let s=r.join(" "),a=y(),m={model:"model","base-url":"baseUrl",base_url:"baseUrl",proxy:"proxy",timeout:"timeout",thinking:"thinking","thinking-effort":"thinkingEffort",thinking_effort:"thinkingEffort"}[n]||n;if(e.dry_run){console.log(`[Dry run] Would set ${m} = ${s}`);return}a[m]=s,C(a),console.log(`[OK] Set ${n} = ${s}
23
- `)}})});var ce,me=f(()=>{"use strict";u();ce=d({name:"help",description:"Show help information",usage:"ds help [command]",examples:["ds help","ds help chat","ds help models"],run:async(t,e)=>{let o=e._positional||[],{registry:n}=await Promise.resolve().then(()=>(G(),pe));n.printHelp(o,process.stdout)}})});var pe={};ge(pe,{registry:()=>S});var K,S,G=f(()=>{"use strict";T();I();P();M();Y();z();V();te();re();ie();le();me();K=class{root={children:new Map};constructor(e){for(let[o,n]of Object.entries(e))this.register(o,n)}register(e,o){let n=e.split(" "),r=this.root;for(let s of n)r.children.has(s)||r.children.set(s,{children:new Map}),r=r.children.get(s);r.command=o}resolve(e){let o=this.root,n=[];for(let r of e){let s=o.children.get(r);if(!s)break;o=s,n.push(r)}if(o.command)return{command:o.command,extra:e.slice(n.length)};if(n.length>0&&o.children.size>0&&o.children.has("show")){let r=o.children.get("show");if(r.command)return{command:r.command,extra:e.slice(n.length+1)}}if(n.length>0&&o.children.size===1){let[,r]=o.children.entries().next().value;if(r.command)return{command:r.command,extra:e.slice(n.length)}}if(n.length>0&&o.children.size>0){let r=Array.from(o.children.entries()).map(([s,a])=>{if(a.command)return` ${n.join(" ")} ${s} ${a.command.description}`;let i=Array.from(a.children.keys()).join(", ");return` ${n.join(" ")} ${s} [${i}]`}).join(`
24
- `);throw new x(`Unknown command: ds ${e.join(" ")}
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.0";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(`
7
+ MiMo Models:
8
+ \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
+ Model Context Description
10
+ \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
14
+ \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>
25
19
 
26
- Available commands:
27
- ${r}`,w.USAGE,`ds ${n.join(" ")} --help`)}throw new x(`Unknown command: ds ${e.join(" ")}`,w.USAGE,"ds --help")}bold=(e,o)=>o.isTTY?`\x1B[1m${e}\x1B[0m`:e;accent=(e,o)=>o.isTTY?`\x1B[38;2;103;58m${e}\x1B[0m`:e;dim=(e,o)=>o.isTTY?`\x1B[2m${e}\x1B[0m`:e;printHelp(e,o=process.stdout){if(e.length===0){this.printRootHelp(o);return}let n=this.root;for(let s of e){let a=n.children.get(s);if(!a){this.printRootHelp(o);return}n=a}if(n.command){this.printCommandHelp(n.command,o);return}let r=e.join(" ");o.write(`
28
- ${this.bold("Usage:",o)} ds ${r} <command> [flags]
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)}
24
+ `):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")}
30
+ Base URL: ${e.baseUrl}
31
+ Model: ${e.model}
32
+ Output: ${e.output}
33
+ 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(`
41
+ Token Plan Quota:
42
+ \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
29
45
 
30
- `),o.write(`${this.bold("Commands:",o)}
31
- `),this.printChildren(n,r,o),o.write(`
32
- `)}printRootHelp(e){let o=s=>this.bold(s,e),n=s=>this.accent(s,e),r=s=>this.dim(s,e);e.write(`
33
- ${o("ds")} ${n("v"+N)} Deepseek CLI
46
+ ${p("Usage:")} mimo <command> [flags]
34
47
 
35
- ${o("Usage:")} ds <command> [flags]
48
+ ${p("Commands:")}
49
+ chat Text chat with MiMo models
50
+ models List available models
51
+ auth Authentication (login, logout, status)
52
+ config CLI configuration (show, set)
53
+ speech Speech synthesis (TTS)
54
+ search Web search
55
+ vision Image understanding
56
+ quota Show token usage
36
57
 
37
- ${o("Commands:")}
38
- ${n("chat")} ${r("Text chat with DeepSeek models")}
39
- ${n("models")} ${r("List available models")}
40
- ${n("balance")} ${r("Check account balance")}
41
- ${n("complete")} ${r("FIM code completion (Beta)")}
42
- ${n("auth")} ${r("Authentication (login, logout)")}
43
- ${n("config")} ${r("CLI configuration (show, set)")}
58
+ ${p("Global Flags:")}
59
+ --api-key <key> API key
60
+ --base-url <url> API base URL
61
+ --output <format> Output format: text, json
62
+ --quiet Suppress non-essential output
63
+ --verbose Print HTTP details
64
+ --help Show help
65
+ --version Show version
44
66
 
45
- ${o("Global Flags:")}
46
- ${n("--api-key <key>")} ${r("API key (overrides env var)")}
47
- ${n("--base-url <url>")} ${r("API base URL")}
48
- ${n("--output <format>")} ${r("Output format: text, json")}
49
- ${n("--quiet")} ${r("Suppress non-essential output")}
50
- ${n("--verbose")} ${r("Print HTTP details")}
51
- ${n("--help")} ${r("Show help")}
52
-
53
- ${o("Getting Help:")}
54
- ${r("Add --help after any command.")}
55
- ${r("Example:")} ds chat --help
56
- `)}printCommandHelp(e,o){let n=a=>this.bold(a,o),r=a=>this.accent(a,o),s=a=>this.dim(a,o);if(o.write(`
57
- ${e.description}
58
- `),e.usage&&o.write(`${n("Usage:")} ${e.usage}
59
- `),e.options&&e.options.length>0){let a=Math.max(...e.options.map(i=>i.flag.length));o.write(`
60
- ${n("Options:")}
61
- `);for(let i of e.options)o.write(` ${r(i.flag.padEnd(a+2))} ${s(i.description)}
62
- `)}if(e.examples&&e.examples.length>0){o.write(`
63
- ${n("Examples:")}
64
- `);for(let a of e.examples)o.write(` ${s(a)}
65
- `)}o.write(`
66
- `)}printChildren(e,o,n){let r=[],s=(i,m)=>{for(let[c,l]of i.children)l.command&&r.push({fullName:`${m} ${c}`,description:l.command.description}),l.children.size>0&&s(l,`${m} ${c}`)};s(e,o);let a=Math.max(...r.map(i=>i.fullName.length));for(let{fullName:i,description:m}of r)n.write(` ${this.accent(i.padEnd(a),n)} ${this.dim(m,n)}
67
- `)}},S=new K({chat:H,models:B,balance:q,complete:X,"auth login":oe,"auth logout":ne,"config show":se,"config set":ae,help:ce})});b();G();u();T();I();function de(t){t instanceof x&&(t.suggestion?process.stderr.write(`
68
- \x1B[1merror:\x1B[0m ${t.message}
69
-
70
- -> ${t.suggestion}
71
-
72
- `):process.stderr.write(`
73
- \x1B[1merror:\x1B[0m ${t.message}
74
-
75
- `),(t.code==="ENOTFOUND"||t.code==="ECONNREFUSED")&&(process.stderr.write(`
76
- -> Check your network connection or proxy settings.
77
- `),process.stderr.write(` -> Or set a proxy: ds config set proxy http://localhost:7890
78
- `),process.exit(w.NETWORK)),process.exit(w.UNKNOWN)),process.stderr.write(`
79
- \x1B[1merror:\x1B[0m ${String(t)}
80
- `),process.exit(w.UNKNOWN)}$();P();process.on("SIGINT",()=>{process.stderr.write(`
81
- Interrupted. Exiting.
82
- `),process.exit(130)});process.stdout.on("error",()=>{});process.stderr.on("error",()=>{});var Ce=[["auth","logout"],["config","show"],["config","set"],["models"]];async function ke(){let t=process.argv.slice(2);(t.includes("--version")||t.includes("-v"))&&(console.log(`ds ${N}`),process.exit(0));let e=W(t,A),o=y(),n=process.env.HTTPS_PROXY||process.env.https_proxy||process.env.HTTP_PROXY||process.env.http_proxy||o.proxy;if((t.includes("--help")||t.includes("-h"))&&(S.printHelp(e,process.stderr),process.exit(0)),e.length===0){if(S.printHelp([],process.stderr),!!o.apiKey){let{command:p}=S.resolve(["balance"]),g=O(t,[...A]),k=R(g);await p.execute(k,g)}else process.stderr.write(` Not logged in.
83
- `),process.stderr.write(` ds auth login Login with your ds API key
84
-
85
- `);process.exit(0)}let{command:r,extra:s}=S.resolve(e),a=t.slice(e.length),i=O(a,[...A,...r.options??[]]);s.length>0&&(i._positional=s);let m=R(i);if(!Ce.some(l=>l.every((p,g)=>e[g]===p))&&!m.apiKey){let l=process.env.ds_API_KEY;l||(process.stderr.write(`Error: No API key found. Run "ds auth login" or set ds_API_KEY env var.
86
- `),process.exit(1)),m.apiKey=l}await r.execute(m,i)}ke().catch(de);
67
+ ${p("Getting Help:")}
68
+ Add --help after any command.
69
+ 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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lzg14/mimo-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Command-line tool for Xiaomi MiMo models",
5
5
  "type": "module",
6
6
  "engines": {