mira-cli-ts 0.1.0

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 (3) hide show
  1. package/README.md +70 -0
  2. package/dist/cli.js +537 -0
  3. package/package.json +48 -0
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # mira-cli-ts
2
+
3
+ Mira CLI — a thin, zero-dependency wrapper around the Mira agent server.
4
+
5
+ > Mira is an open, provider-agnostic AI agent platform: hierarchical memory, tool-layer
6
+ > guardrails, file snapshots with undo, real LSP + MCP, and a cost-tracking gateway.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ # npm — the `mira` binary lands on your PATH
12
+ npm install -g mira-cli-ts
13
+
14
+ # or run without installing
15
+ npx mira-cli-ts --help
16
+ ```
17
+
18
+ Requires a running Mira server (`mira serve`). Point the CLI at it with `MIRA_API_URL`
19
+ (default `http://127.0.0.1:4096`):
20
+
21
+ ```bash
22
+ export MIRA_API_URL=http://127.0.0.1:4096
23
+ export MIRA_API_KEY=... # only if the server requires auth (MIRA_TOKEN / MIRA_API_KEYS)
24
+ ```
25
+
26
+ ## Commands
27
+
28
+ ```
29
+ mira serve [--port 4096] [--host 127.0.0.1] Start the daemon
30
+ mira session list List sessions
31
+ mira session create [--title ...] [--agent code|ask|plan] [--model ...]
32
+ mira session prompt --id <id> --prompt "..." Prompt a session (SSE stream)
33
+ mira session import --file ./export.json
34
+ mira session export --id <id> [--format json|md]
35
+ mira agent list / agent preview <name>
36
+ mira skill list
37
+ mira command list
38
+ mira tool list
39
+ mira mcp list
40
+ mira config get [key] / config set <key> <value>
41
+ mira finding list [--status open] / finding resolve <id>
42
+ mira manager
43
+ mira health
44
+ mira complete --prefix "..." [--suffix "..."] [--file path] Ghost-text completion
45
+ mira --help | --version
46
+ ```
47
+
48
+ ### Examples
49
+
50
+ ```bash
51
+ mira serve
52
+ mira session create --agent ask --title "Q&A"
53
+ mira session prompt --id abc --prompt "explain ./src/index.ts"
54
+ mira skill list
55
+ mira complete --prefix "function add(a,b) {"
56
+ ```
57
+
58
+ ## Server
59
+
60
+ Run the full server (bundled tool registry, LSP, MCP, memory, gateway) from the monorepo:
61
+
62
+ ```bash
63
+ git clone https://github.com/slab1/mira && cd mira
64
+ bun install
65
+ bun run dev # server :4096 · web :3000 · tui :3001
66
+ ```
67
+
68
+ ## License
69
+
70
+ MIT
package/dist/cli.js ADDED
@@ -0,0 +1,537 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+
4
+ // src/cli.ts
5
+ var VERSION = "0.1.0";
6
+ var DEFAULT_API = process.env.MIRA_API_URL ?? process.env.MIRA_APIURL ?? "http://127.0.0.1:4096";
7
+ function apiUrl() {
8
+ return (process.env.MIRA_API_URL ?? DEFAULT_API).replace(/\/$/, "");
9
+ }
10
+ function token() {
11
+ return process.env.MIRA_TOKEN ?? "";
12
+ }
13
+ function authHeaders() {
14
+ const t = token();
15
+ return t ? { Authorization: `Bearer ${t}` } : {};
16
+ }
17
+ async function apiFetch(path, init) {
18
+ const res = await fetch(`${apiUrl()}${path}`, {
19
+ ...init,
20
+ headers: { "Content-Type": "application/json", ...authHeaders(), ...init?.headers }
21
+ });
22
+ return res;
23
+ }
24
+ function printHelp() {
25
+ const help = `
26
+ mira \u2014 AI agent platform CLI (thin, 0.1.0)
27
+
28
+ Usage:
29
+ mira serve [--port 4096] [--host 127.0.0.1] [--daemon] Start daemon
30
+ mira session list List sessions
31
+ mira session create [--title "My Session"] [--agent code|ask|plan] [--model ...] Create session
32
+ mira session prompt --id <id> --prompt "hello" [--agent ask] [--model ...] Prompt (SSE stream)
33
+ mira session import --file ./export.json Import exported JSON
34
+ mira session export --id <id> [--format json|md] Export
35
+ mira session new [--title ...] [--agent ...] Alias for create
36
+ mira agent list List 15 agents (code/ask/plan + lane)
37
+ mira agent preview <name> Preview allowlist for agent
38
+ mira skill list List skills (SKILL.md packs)
39
+ mira command list List slash commands (/new, /compact, /models...)
40
+ mira tool list List 21 tools (read, write, orchestrate, browser...)
41
+ mira mcp list List MCP servers
42
+ mira config get [key] Get config (or filtered by key)
43
+ mira config set <key> <value> Set config (dot notation, JSON value)
44
+ mira finding list [--status open] [--limit 20] List findings
45
+ mira manager Active jobs + recent sessions
46
+ mira health Liveness (/healthz)
47
+ mira complete --prefix "..." [--suffix "..."] [--file path] Ghost-text completion
48
+ mira --help | -h Help
49
+ mira --version | -v Version
50
+
51
+ Env:
52
+ MIRA_API_URL server URL (default http://127.0.0.1:4096)
53
+ MIRA_TOKEN bearer token
54
+
55
+ Examples:
56
+ mira serve
57
+ mira session create --agent ask --title "Q&A"
58
+ mira session prompt --id abc --prompt "explain ./src/index.ts"
59
+ mira skill list
60
+ mira command list
61
+ mira tool list
62
+ mira complete --prefix "function add(a,b) {" --file src/math.ts
63
+ `.trim();
64
+ console.log(help);
65
+ }
66
+ function parseArgs(argv) {
67
+ const args = argv.slice(2);
68
+ if (args.length === 0 || args.includes("--help") || args.includes("-h"))
69
+ return { cmd: "help", sub: null, opts: {} };
70
+ if (args.includes("--version") || args.includes("-v"))
71
+ return { cmd: "version", sub: null, opts: {} };
72
+ const cmd = args[0] ?? "help";
73
+ const sub = args[1] && !args[1].startsWith("-") ? args[1] : null;
74
+ const opts = {};
75
+ for (let i = 1;i < args.length; i++) {
76
+ const a = args[i] ?? "";
77
+ if (a.startsWith("--")) {
78
+ const key = a.slice(2);
79
+ const next = args[i + 1];
80
+ if (next && !next.startsWith("-")) {
81
+ opts[key] = next;
82
+ i++;
83
+ } else {
84
+ opts[key] = true;
85
+ }
86
+ } else if (a.startsWith("-") && a.length === 2) {
87
+ const key = a.slice(1);
88
+ const next = args[i + 1];
89
+ if (next && !next.startsWith("-")) {
90
+ opts[key] = next;
91
+ i++;
92
+ } else {
93
+ opts[key] = true;
94
+ }
95
+ }
96
+ }
97
+ return { cmd, sub, opts };
98
+ }
99
+ async function cmdServe(opts) {
100
+ const port = String(opts.port ?? opts.p ?? process.env.PORT ?? "4096");
101
+ const host = String(opts.host ?? process.env.HOST ?? "127.0.0.1");
102
+ const daemon = Boolean(opts.daemon || opts.d);
103
+ if (daemon) {
104
+ console.log(`[mira] daemon mode not yet implemented \u2014 running foreground on ${host}:${port} (use pm2/bun --watch for now)`);
105
+ }
106
+ process.env.PORT = port;
107
+ process.env.HOST = host;
108
+ const serverDir = new URL("../../server", import.meta.url).pathname;
109
+ const proc = Bun.spawn(["bun", "run", "src/index.ts"], {
110
+ cwd: serverDir,
111
+ env: { ...process.env, PORT: port, HOST: host },
112
+ stdout: "inherit",
113
+ stderr: "inherit",
114
+ stdin: "inherit"
115
+ });
116
+ await proc.exited;
117
+ }
118
+ async function cmdSessionList() {
119
+ const res = await apiFetch("/session");
120
+ if (!res.ok) {
121
+ console.error(`session list failed: ${res.status} ${await res.text()}`);
122
+ process.exit(1);
123
+ }
124
+ const data = await res.json();
125
+ if (data.length === 0) {
126
+ console.log("No sessions");
127
+ return;
128
+ }
129
+ for (const s of data) {
130
+ console.log(`${String(s.id).slice(0, 8)} ${String(s.title ?? "")} ${String(s.model ?? "")} ${String(s.agent ?? "")} ${new Date(Number(s.updatedAt ?? s.createdAt ?? Date.now())).toISOString()}`);
131
+ }
132
+ }
133
+ async function cmdSessionCreate(opts) {
134
+ const body = {};
135
+ if (typeof opts.title === "string")
136
+ body.title = opts.title;
137
+ if (typeof opts.agent === "string")
138
+ body.agent = opts.agent;
139
+ if (typeof opts.model === "string")
140
+ body.model = opts.model;
141
+ const res = await apiFetch("/session", { method: "POST", body: JSON.stringify(body) });
142
+ if (!res.ok) {
143
+ console.error(`session create failed: ${res.status} ${await res.text()}`);
144
+ process.exit(1);
145
+ }
146
+ const data = await res.json();
147
+ console.log(JSON.stringify(data, null, 2));
148
+ }
149
+ async function cmdSessionPrompt(opts) {
150
+ const id = String(opts.id ?? opts.i ?? "");
151
+ const prompt = String(opts.prompt ?? opts.p ?? "");
152
+ if (!id || !prompt) {
153
+ console.error("session prompt requires --id <id> --prompt <text>");
154
+ process.exit(1);
155
+ }
156
+ const body = { prompt };
157
+ if (typeof opts.agent === "string")
158
+ body.agent = opts.agent;
159
+ if (typeof opts.model === "string")
160
+ body.model = opts.model;
161
+ if (typeof opts.maxSteps === "string")
162
+ body.maxSteps = Number(opts.maxSteps);
163
+ const res = await apiFetch(`/session/${id}/prompt`, { method: "POST", body: JSON.stringify(body), headers: { Accept: "text/event-stream" } });
164
+ if (!res.ok || !res.body) {
165
+ console.error(`prompt failed: ${res.status} ${await res.text()}`);
166
+ process.exit(1);
167
+ }
168
+ const reader = res.body.getReader();
169
+ const decoder = new TextDecoder;
170
+ let buf = "";
171
+ while (true) {
172
+ const { done, value } = await reader.read();
173
+ if (done)
174
+ break;
175
+ buf += decoder.decode(value, { stream: true });
176
+ const frames = buf.split(`
177
+
178
+ `);
179
+ buf = frames.pop() ?? "";
180
+ for (const f of frames) {
181
+ const eventMatch = f.match(/event:\s*(\S+)/);
182
+ const event = eventMatch ? eventMatch[1] : "";
183
+ const m = f.match(/data:\s*(.*)/);
184
+ if (!m)
185
+ continue;
186
+ try {
187
+ const j = JSON.parse(m[1] ?? "");
188
+ if (event === "text_delta") {
189
+ const d = j.delta ?? j.textDelta ?? j.text ?? "";
190
+ if (d)
191
+ process.stdout.write(String(d));
192
+ } else if (event === "error") {
193
+ if (j.error)
194
+ console.error(`
195
+ [error] ${String(j.error)}`);
196
+ } else if (event === "finish") {} else if (event === "tool_call" || event === "tool_result" || event === "step_start" || event === "step_finish") {} else {
197
+ const d = j.delta ?? "";
198
+ if (d && event !== "finish")
199
+ process.stdout.write(String(d));
200
+ if (j.error)
201
+ console.error(`
202
+ [error] ${String(j.error)}`);
203
+ }
204
+ } catch {
205
+ process.stdout.write(m[1] ?? "");
206
+ }
207
+ }
208
+ }
209
+ process.stdout.write(`
210
+ `);
211
+ }
212
+ async function cmdSessionImport(opts) {
213
+ const file = String(opts.file ?? opts.f ?? "");
214
+ if (!file) {
215
+ console.error("session import requires --file <path>");
216
+ process.exit(1);
217
+ }
218
+ const text = await Bun.file(file).text();
219
+ const json = JSON.parse(text);
220
+ const res = await apiFetch("/session/import", { method: "POST", body: JSON.stringify(json) });
221
+ if (!res.ok) {
222
+ console.error(`import failed: ${res.status} ${await res.text()}`);
223
+ process.exit(1);
224
+ }
225
+ console.log(JSON.stringify(await res.json(), null, 2));
226
+ }
227
+ async function cmdSessionExport(opts) {
228
+ const id = String(opts.id ?? opts.i ?? "");
229
+ if (!id) {
230
+ console.error("session export requires --id <id>");
231
+ process.exit(1);
232
+ }
233
+ const format = String(opts.format ?? "json");
234
+ const res = await apiFetch(`/session/${id}/export?format=${format}`);
235
+ if (!res.ok) {
236
+ console.error(`export failed: ${res.status} ${await res.text()}`);
237
+ process.exit(1);
238
+ }
239
+ console.log(await res.text());
240
+ }
241
+ async function cmdAgentList() {
242
+ const res = await apiFetch("/agents");
243
+ if (!res.ok) {
244
+ console.error(`agent list failed: ${res.status} ${await res.text()}`);
245
+ process.exit(1);
246
+ }
247
+ const data = await res.json();
248
+ for (const a of data) {
249
+ console.log(`${String(a.name)} [${String(a.permissions)}] ${String(a.model ?? "")} tools:${Array.isArray(a.tools) ? a.tools.join(",") : ""}`);
250
+ console.log(` ${String(a.description ?? "").slice(0, 120)}`);
251
+ }
252
+ }
253
+ async function cmdComplete(opts) {
254
+ const prefix = String(opts.prefix ?? "");
255
+ const suffix = String(opts.suffix ?? "");
256
+ const prompt = typeof opts.prompt === "string" ? String(opts.prompt) : undefined;
257
+ const file = typeof opts.file === "string" ? String(opts.file) : undefined;
258
+ const model = typeof opts.model === "string" ? String(opts.model) : undefined;
259
+ if (!prefix && !prompt) {
260
+ console.error("complete requires --prefix <text> or --prompt <text>");
261
+ process.exit(1);
262
+ }
263
+ const body = {};
264
+ if (prefix)
265
+ body.prefix = prefix;
266
+ if (suffix)
267
+ body.suffix = suffix;
268
+ if (prompt)
269
+ body.prompt = prompt;
270
+ if (file)
271
+ body.file = file;
272
+ if (model)
273
+ body.model = model;
274
+ const res = await apiFetch("/complete", { method: "POST", body: JSON.stringify(body) });
275
+ if (!res.ok) {
276
+ console.error(`complete failed: ${res.status} ${await res.text()}`);
277
+ process.exit(1);
278
+ }
279
+ const data = await res.json();
280
+ console.log(String(data.text ?? ""));
281
+ }
282
+ async function cmdManager() {
283
+ const res = await apiFetch("/manager");
284
+ if (!res.ok) {
285
+ console.error(`manager failed: ${res.status} ${await res.text()}`);
286
+ process.exit(1);
287
+ }
288
+ console.log(JSON.stringify(await res.json(), null, 2));
289
+ }
290
+ async function cmdSkillList() {
291
+ const res = await apiFetch("/skills");
292
+ if (!res.ok) {
293
+ console.error(`skill list failed: ${res.status} ${await res.text()}`);
294
+ process.exit(1);
295
+ }
296
+ const data = await res.json();
297
+ if (data.length === 0) {
298
+ console.log("No skills");
299
+ return;
300
+ }
301
+ for (const s of data)
302
+ console.log(s);
303
+ }
304
+ async function cmdCommandList() {
305
+ const res = await apiFetch("/commands");
306
+ if (!res.ok) {
307
+ console.error(`command list failed: ${res.status} ${await res.text()}`);
308
+ process.exit(1);
309
+ }
310
+ const data = await res.json();
311
+ for (const c of data) {
312
+ console.log(`${String(c.name).padEnd(20)} ${String(c.description ?? "")} [${String(c.source ?? "")}]${c.agent ? ` agent:${String(c.agent)}` : ""}`);
313
+ }
314
+ }
315
+ async function cmdToolList() {
316
+ const res = await apiFetch("/tools");
317
+ if (!res.ok) {
318
+ console.error(`tool list failed: ${res.status} ${await res.text()}`);
319
+ process.exit(1);
320
+ }
321
+ const data = await res.json();
322
+ for (const t of data) {
323
+ console.log(`${String(t.name).padEnd(25)} [${String(t.category)}] ${String(t.description ?? "").slice(0, 80)}`);
324
+ }
325
+ }
326
+ async function cmdMcpList() {
327
+ const res = await apiFetch("/mcp");
328
+ if (!res.ok) {
329
+ console.error(`mcp list failed: ${res.status} ${await res.text()}`);
330
+ process.exit(1);
331
+ }
332
+ console.log(JSON.stringify(await res.json(), null, 2));
333
+ }
334
+ async function cmdConfigGet(opts) {
335
+ const key = typeof opts.key === "string" ? String(opts.key) : typeof opts[0] === "string" ? String(opts[0]) : undefined;
336
+ const res = await apiFetch("/config");
337
+ if (!res.ok) {
338
+ console.error(`config get failed: ${res.status} ${await res.text()}`);
339
+ process.exit(1);
340
+ }
341
+ const data = await res.json();
342
+ if (key) {
343
+ const parts = key.split(".");
344
+ let cur = data;
345
+ for (const p of parts) {
346
+ if (cur && typeof cur === "object" && !Array.isArray(cur))
347
+ cur = cur[p];
348
+ else
349
+ cur = undefined;
350
+ }
351
+ console.log(JSON.stringify(cur ?? null, null, 2));
352
+ } else {
353
+ console.log(JSON.stringify(data, null, 2));
354
+ }
355
+ }
356
+ async function cmdConfigSet(opts) {
357
+ const args = Object.keys(opts).filter((k) => !["key", "value"].includes(k)).map((k) => String(opts[k]));
358
+ const key = typeof opts.key === "string" ? String(opts.key) : args[0];
359
+ const rawVal = typeof opts.value === "string" ? String(opts.value) : args[1];
360
+ if (!key || rawVal === undefined) {
361
+ console.error("config set requires <key> <value> \u2014 e.g. mira config set model openrouter/anthropic/claude-sonnet-4");
362
+ process.exit(1);
363
+ }
364
+ let value;
365
+ try {
366
+ value = JSON.parse(rawVal);
367
+ } catch {
368
+ value = rawVal;
369
+ }
370
+ const res = await apiFetch("/config", { method: "POST", body: JSON.stringify({ patch: { [key]: value } }) });
371
+ if (!res.ok) {
372
+ console.error(`config set failed: ${res.status} ${await res.text()}`);
373
+ process.exit(1);
374
+ }
375
+ console.log(JSON.stringify(await res.json(), null, 2));
376
+ }
377
+ async function cmdFindingList(opts) {
378
+ const status = typeof opts.status === "string" ? `?status=${String(opts.status)}` : "";
379
+ const limit = typeof opts.limit === "string" ? `${status ? "&" : "?"}limit=${String(opts.limit)}` : "";
380
+ const qs = `${status}${limit}`;
381
+ const res = await apiFetch(`/finding${qs}`);
382
+ if (!res.ok) {
383
+ console.error(`finding list failed: ${res.status} ${await res.text()}`);
384
+ process.exit(1);
385
+ }
386
+ console.log(JSON.stringify(await res.json(), null, 2));
387
+ }
388
+ async function cmdAgentPreview(opts) {
389
+ const name = String(opts.name ?? opts[0] ?? "");
390
+ if (!name) {
391
+ console.error("agent preview requires <name> \u2014 e.g. mira agent preview ask");
392
+ process.exit(1);
393
+ }
394
+ const res = await apiFetch(`/agents/${encodeURIComponent(name)}/preview`);
395
+ if (!res.ok) {
396
+ console.error(`agent preview failed: ${res.status} ${await res.text()}`);
397
+ process.exit(1);
398
+ }
399
+ console.log(JSON.stringify(await res.json(), null, 2));
400
+ }
401
+ async function cmdHealth() {
402
+ const res = await apiFetch("/healthz");
403
+ if (!res.ok) {
404
+ console.error(`health failed: ${res.status} ${await res.text()}`);
405
+ process.exit(1);
406
+ }
407
+ console.log(JSON.stringify(await res.json(), null, 2));
408
+ }
409
+ async function main() {
410
+ const rawCmd = Bun.argv[2] ?? "help";
411
+ if (rawCmd.startsWith("/")) {
412
+ console.log(`Slash commands are server-side: use via Web/TUI palette (/new, /help) \u2014 CLI maps some as: mira session new, mira skill list, mira command list`);
413
+ return;
414
+ }
415
+ const { cmd, sub, opts } = parseArgs(Bun.argv);
416
+ const positional = Bun.argv.slice(3).filter((a) => !a.startsWith("-"));
417
+ if (positional.length > 0 && !opts["name"] && !opts["key"] && !opts["value"]) {
418
+ positional.forEach((v, i) => {
419
+ opts[String(i)] = v;
420
+ });
421
+ if (!opts["name"] && positional[0])
422
+ opts["name"] = positional[0];
423
+ }
424
+ switch (cmd) {
425
+ case "version":
426
+ console.log(`mira ${VERSION}`);
427
+ return;
428
+ case "help":
429
+ printHelp();
430
+ return;
431
+ case "serve":
432
+ await cmdServe(opts);
433
+ return;
434
+ case "session":
435
+ if (sub === "list" || sub === null)
436
+ await cmdSessionList();
437
+ else if (sub === "create" || sub === "new")
438
+ await cmdSessionCreate(opts);
439
+ else if (sub === "prompt")
440
+ await cmdSessionPrompt(opts);
441
+ else if (sub === "import")
442
+ await cmdSessionImport(opts);
443
+ else if (sub === "export")
444
+ await cmdSessionExport(opts);
445
+ else {
446
+ console.error(`unknown session subcommand: ${sub ?? ""} \u2014 try: list, create, new, prompt, import, export`);
447
+ process.exit(1);
448
+ }
449
+ return;
450
+ case "new":
451
+ await cmdSessionCreate(opts);
452
+ return;
453
+ case "agent":
454
+ if (sub === "list" || sub === null)
455
+ await cmdAgentList();
456
+ else if (sub === "preview")
457
+ await cmdAgentPreview(opts);
458
+ else {
459
+ if (sub) {
460
+ opts["name"] = sub;
461
+ await cmdAgentPreview(opts);
462
+ return;
463
+ }
464
+ console.error(`unknown agent subcommand: ${sub}`);
465
+ process.exit(1);
466
+ }
467
+ return;
468
+ case "skill":
469
+ if (sub === "list" || sub === null)
470
+ await cmdSkillList();
471
+ else {
472
+ console.error(`unknown skill subcommand: ${sub}`);
473
+ process.exit(1);
474
+ }
475
+ return;
476
+ case "command":
477
+ if (sub === "list" || sub === null)
478
+ await cmdCommandList();
479
+ else {
480
+ console.error(`unknown command subcommand: ${sub}`);
481
+ process.exit(1);
482
+ }
483
+ return;
484
+ case "commands":
485
+ await cmdCommandList();
486
+ return;
487
+ case "tool":
488
+ case "tools":
489
+ await cmdToolList();
490
+ return;
491
+ case "mcp":
492
+ await cmdMcpList();
493
+ return;
494
+ case "config":
495
+ if (sub === "get" || sub === null)
496
+ await cmdConfigGet(opts);
497
+ else if (sub === "set")
498
+ await cmdConfigSet(opts);
499
+ else {
500
+ if (sub) {
501
+ opts["key"] = sub;
502
+ await cmdConfigGet(opts);
503
+ return;
504
+ }
505
+ console.error(`unknown config subcommand: ${sub}`);
506
+ process.exit(1);
507
+ }
508
+ return;
509
+ case "finding":
510
+ case "findings":
511
+ if (sub === "list" || sub === null)
512
+ await cmdFindingList(opts);
513
+ else {
514
+ console.error(`unknown finding subcommand: ${sub}`);
515
+ process.exit(1);
516
+ }
517
+ return;
518
+ case "complete":
519
+ case "autocomplete":
520
+ await cmdComplete(opts);
521
+ return;
522
+ case "manager":
523
+ await cmdManager();
524
+ return;
525
+ case "health":
526
+ await cmdHealth();
527
+ return;
528
+ default:
529
+ console.error(`unknown command: ${cmd}`);
530
+ printHelp();
531
+ process.exit(1);
532
+ }
533
+ }
534
+ main().catch((e) => {
535
+ console.error(String(e?.stack ?? e));
536
+ process.exit(1);
537
+ });
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "mira-cli-ts",
3
+ "version": "0.1.0",
4
+ "description": "Mira CLI — thin wrapper around @mira/server (serve + session/agent/complete)",
5
+ "type": "module",
6
+ "bin": {
7
+ "mira": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/slab1/mira.git"
18
+ },
19
+ "homepage": "https://github.com/slab1/mira#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/slab1/mira/issues"
22
+ },
23
+ "keywords": [
24
+ "mira",
25
+ "ai",
26
+ "agent",
27
+ "llm",
28
+ "cli",
29
+ "terminal",
30
+ "coding-agent"
31
+ ],
32
+ "engines": {
33
+ "node": ">=18",
34
+ "bun": ">=1.0"
35
+ },
36
+ "scripts": {
37
+ "build": "tsc --noEmit && bun build src/cli.ts --outdir dist --target bun --format esm",
38
+ "typecheck": "tsc --noEmit",
39
+ "dev": "tsc --watch --noEmit",
40
+ "prepublishOnly": "npm run build && npm run typecheck"
41
+ },
42
+ "dependencies": {},
43
+ "devDependencies": {
44
+ "typescript": "^5.8.0",
45
+ "bun-types": "latest",
46
+ "@types/bun": "latest"
47
+ }
48
+ }