@muxoai/cli 0.1.1 → 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 (3) hide show
  1. package/README.md +11 -0
  2. package/dist/index.js +66 -4
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -43,10 +43,21 @@ muxo logs [workflow] Execution history
43
43
  muxo steps <instanceId> Per-step log for one execution
44
44
  muxo login Store your key in the OS keychain
45
45
  muxo mcp Stdio MCP proxy for agents
46
+ muxo ui Launch the interactive TUI dashboard
46
47
  ```
47
48
 
48
49
  Global flags: `--json`, `--quiet`, `--debug`.
49
50
 
51
+ ## Dashboard
52
+
53
+ ```bash
54
+ muxo ui
55
+ ```
56
+
57
+ A full-screen TUI (from [`@muxoai/tui`](https://www.npmjs.com/package/@muxoai/tui))
58
+ with tabs for overview + budget, capabilities, workflows, runs, keys, and
59
+ credits. Keyboard-first, mouse-friendly.
60
+
50
61
  ## Agent-first
51
62
 
52
63
  Point any MCP client at `https://api.muxo.ai/mcp` (Bearer auth), or use the
package/dist/index.js CHANGED
@@ -396,6 +396,26 @@ function landingPage(title) {
396
396
  </html>
397
397
  `;
398
398
  }
399
+ async function harnessManifest(intent, project) {
400
+ const base = process.env.MUXO_HARNESS_URL;
401
+ if (base === void 0 || base.trim() === "") return void 0;
402
+ try {
403
+ const res = await fetch(`${base.replace(/\/+$/, "")}/architect`, {
404
+ method: "POST",
405
+ headers: { "content-type": "application/json" },
406
+ body: JSON.stringify({ intent, project }),
407
+ signal: AbortSignal.timeout(18e4)
408
+ });
409
+ if (!res.ok) return void 0;
410
+ const body = await res.json();
411
+ const yaml = body.data?.yaml;
412
+ if (typeof yaml !== "string" || yaml.trim() === "") return void 0;
413
+ if (!validateManifest(yaml).ok) return void 0;
414
+ return { yaml, source: "harness" };
415
+ } catch {
416
+ return void 0;
417
+ }
418
+ }
399
419
  async function architectManifest(intent, project, opts) {
400
420
  const key = await resolveKey();
401
421
  if (key === void 0) return void 0;
@@ -417,7 +437,7 @@ async function init(intent, opts) {
417
437
  let source = "template";
418
438
  if (it !== "") {
419
439
  try {
420
- const designed = await architectManifest(it, project, opts);
440
+ const designed = await harnessManifest(it, project) ?? await architectManifest(it, project, opts);
421
441
  if (designed !== void 0) {
422
442
  text = designed.yaml;
423
443
  source = designed.source;
@@ -428,7 +448,8 @@ async function init(intent, opts) {
428
448
  const tpl = matchTemplate(it);
429
449
  if (text === void 0) text = renderManifest(project, it, tpl);
430
450
  await writeFile2("muxo.yaml", text, "utf8");
431
- info(`wrote muxo.yaml${source === "architect" ? " (designed by the muxo architect)" : ""}`, opts);
451
+ const designedBy = source === "harness" ? " (designed by the muxo harness)" : source === "architect" ? " (designed by the muxo architect)" : "";
452
+ info(`wrote muxo.yaml${designedBy}`, opts);
432
453
  const parsed = validateManifest(text);
433
454
  const bundles = parsed.ok && parsed.manifest !== void 0 ? Object.keys(parsed.manifest.bundles ?? {}) : Object.keys(tpl.bundles);
434
455
  if (bundles.length > 0) {
@@ -1046,9 +1067,10 @@ async function capabilities(opts) {
1046
1067
  const rows = data2.capabilities ?? [];
1047
1068
  for (const c of rows) {
1048
1069
  const providers = c.backends.map((b) => b.configured ? b.provider : `${b.provider}*`).join(", ");
1049
- console.log(`${c.available ? "ok " : "-- "}${c.name.padEnd(20)} ${providers}`);
1070
+ console.log(`${c.available ? "ok " : "-- "}${(c.friendly ?? c.name).padEnd(18)} ${c.name.padEnd(22)} ${providers}`);
1050
1071
  }
1051
1072
  console.log("\n* = not configured (missing runtime secrets)");
1073
+ console.log("friendly names work anywhere a capability name does (REST, MCP, CLI, SDK)");
1052
1074
  });
1053
1075
  }
1054
1076
 
@@ -1200,9 +1222,22 @@ var STATIC_TOOLS = [
1200
1222
  { name: "vector_search", description: "Vector search. Inputs: query (required), k?." },
1201
1223
  { name: "email_send", description: "Send an email. Inputs: to, subject, body (all required)." },
1202
1224
  { name: "observability_log", description: "Log an event. Inputs: level (required), message (required)." },
1203
- { name: "queue_emit", description: "Emit an event to a queue. Inputs: topic (required), payload (required)." }
1225
+ { name: "queue_emit", description: "Emit an event to a queue. Inputs: topic (required), payload (required)." },
1226
+ { name: "llm_image", description: "Generate an image from a prompt. Inputs: prompt (required), size?, model?." },
1227
+ { name: "llm_stt", description: "Transcribe audio to text. Inputs: audio_url or audio_base64 (required), model?." },
1228
+ { name: "sms_send", description: "Send an SMS. Inputs: to (required), body (required), from?." },
1229
+ { name: "analytics_track", description: "Track an analytics event. Inputs: event (required), distinct_id?, properties?." },
1230
+ { name: "appsearch_query", description: "Full-text search an app index. Inputs: query (required), index?, limit?." },
1231
+ { name: "memory_store", description: "Store a memory. Inputs: content (required), metadata?." },
1232
+ { name: "memory_search", description: "Search stored memories. Inputs: query (required), k?." },
1233
+ { name: "featureflags_evaluate", description: "Evaluate a feature flag. Inputs: flag (required), context?." },
1234
+ { name: "video_generate", description: "Generate a video from a prompt. Inputs: prompt (required), avatar_id?, voice_id?." },
1235
+ { name: "auth_users", description: "Manage users. Inputs: action (create|get|list|delete), id?, email?, password?, metadata?." },
1236
+ { name: "payments_charge", description: "Accept a payment from an agent (Stripe PaymentIntents / MPP). Inputs: amount (required), currency?, payment_method_types?, payment_method?, confirm?, metadata?." },
1237
+ { name: "payments_refund", description: "Refund a payment. Inputs: payment_intent (required), amount?, reason?." }
1204
1238
  ];
1205
1239
  function excluded(tool) {
1240
+ if (process.env.MUXO_MCP_EXPOSE_ALL === "true") return false;
1206
1241
  return tool.startsWith("deploy_") || tool === "domains_register" || tool === "compute_container";
1207
1242
  }
1208
1243
  function toToolName(capability) {
@@ -1330,6 +1365,27 @@ async function mcp(opts) {
1330
1365
  return 0;
1331
1366
  }
1332
1367
 
1368
+ // src/commands/ui.ts
1369
+ async function ui(opts) {
1370
+ if (process.stdout.isTTY !== true) {
1371
+ console.error("error: `muxo ui` needs an interactive terminal (TTY)");
1372
+ return 1;
1373
+ }
1374
+ let mod;
1375
+ try {
1376
+ mod = await import("@muxoai/tui");
1377
+ } catch (err) {
1378
+ const message = err instanceof Error ? err.message : String(err);
1379
+ if (/Cannot find (module|package)|ERR_MODULE_NOT_FOUND/.test(message)) {
1380
+ console.error("error: @muxoai/tui is not installed \u2014 run `npm i -g @muxoai/tui`");
1381
+ return 1;
1382
+ }
1383
+ throw err;
1384
+ }
1385
+ await mod.run({ baseUrl: baseUrl(), key: await resolveKey(), debug: opts.debug });
1386
+ return 0;
1387
+ }
1388
+
1333
1389
  // src/index.ts
1334
1390
  function flags(cmd) {
1335
1391
  cmd.option("--json", "structured JSON output").option("--quiet", "suppress non-essential output").option("--debug", "log requests to stderr");
@@ -1343,6 +1399,7 @@ Examples:
1343
1399
  muxo run hn-scraper --param max_items=3
1344
1400
  muxo call web.search --data '{"query":"agent infra","limit":3}'
1345
1401
  muxo logs && muxo steps <instanceId>
1402
+ muxo ui # interactive dashboard
1346
1403
 
1347
1404
  Auth: export MUXO_KEY=mk_... Endpoint: export MUXO_API_BASE=https://api.muxo.ai/v1
1348
1405
  Docs: https://api.muxo.ai/docs/quickstart`);
@@ -1466,6 +1523,11 @@ Docs: https://api.muxo.ai/docs/quickstart`);
1466
1523
  mcpCmd.description("Stdio MCP proxy wrapping the muxo API").action(async (opts) => {
1467
1524
  process.exitCode = await mcp(opts);
1468
1525
  });
1526
+ const uiCmd = program.command("ui");
1527
+ flags(uiCmd);
1528
+ uiCmd.description("Launch the interactive TUI dashboard (status, capabilities, workflows, runs, keys, credits)").action(async (opts) => {
1529
+ process.exitCode = await ui(opts);
1530
+ });
1469
1531
  await program.parseAsync(process.argv);
1470
1532
  }
1471
1533
  main().catch((err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muxoai/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Muxo CLI: one key for your whole stack — scaffold, validate, apply, run, and monitor agent workflows.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -39,7 +39,8 @@
39
39
  "prepublishOnly": "npm run build"
40
40
  },
41
41
  "dependencies": {
42
- "@muxoai/core": "^0.1.1",
42
+ "@muxoai/core": "^0.1.2",
43
+ "@muxoai/tui": "^0.1.0",
43
44
  "commander": "^12.0.0",
44
45
  "yaml": "^2.4.0",
45
46
  "zod": "^3.23.0"