@mosse-ai/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 (2) hide show
  1. package/dist/index.js +415 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22626,9 +22626,9 @@ var InboxWaitTool = {
22626
22626
  summary: "Wait quietly for a realtime Inbox event for the signed-in user's ID (server checks ownership). Read Inbox before waiting and after every result, including timeout/reconnect, to recover missed events. Timeout is normal: do not send a chat update for it. This bounded call does not wake an idle host or schedule another turn. Coalesce new notifications; do not repeatedly report already handled items.",
22627
22627
  input: external_exports.strictObject({ userId: external_exports.uuid(), timeoutMs: external_exports.number().int().min(1e3).max(25e3).default(25e3) }),
22628
22628
  effect: "read",
22629
- transport: { kind: "stream" },
22629
+ transport: { kind: "rest", method: "GET", path: "/api/inbox/wait" },
22630
22630
  mcpName: "inbox_wait",
22631
- cliOmitted: "long-poll needs a streaming endpoint; MD-461 \u672C\u8F6E\u4E0D\u7ED9 CLI(MD-462 \u4E4B\u540E\u53E6\u8BAE)"
22631
+ cli: { path: ["inbox", "wait"], example: "mosse inbox wait --timeout-ms 25000 --json" }
22632
22632
  };
22633
22633
  var SESSION_TOOLS = [
22634
22634
  WorkspaceListTool,
@@ -23159,7 +23159,7 @@ function buildCommandTree(options = {}) {
23159
23159
  }
23160
23160
 
23161
23161
  // src/api.ts
23162
- var CLI_VERSION = true ? "0.1.0" : "0.0.0";
23162
+ var CLI_VERSION = true ? "0.1.2" : "0.0.0";
23163
23163
  var CLI_USER_AGENT = `mosse-cli/${CLI_VERSION}`;
23164
23164
  async function callApi(request) {
23165
23165
  const headers = {
@@ -23615,9 +23615,182 @@ function packagedSkillMd(version3 = CLI_VERSION) {
23615
23615
  return renderSkillMd(buildCommandTree({ sessionTools: SESSION_TOOLS }), version3);
23616
23616
  }
23617
23617
 
23618
+ // src/completions.ts
23619
+ var COMPLETION_SHELLS = ["bash", "zsh", "fish"];
23620
+ var LOCAL_COMMANDS = [
23621
+ "auth login",
23622
+ "auth logout",
23623
+ "auth status",
23624
+ "auth token",
23625
+ "auth whoami",
23626
+ "skill",
23627
+ "skill install",
23628
+ "skill status",
23629
+ "skill upgrade",
23630
+ "doctor",
23631
+ "completions",
23632
+ "update",
23633
+ "help",
23634
+ "inbox list",
23635
+ "inbox read",
23636
+ "workspace list"
23637
+ ];
23638
+ var GLOBAL_FLAGS = [
23639
+ "--json",
23640
+ "--format",
23641
+ "--workspace",
23642
+ "--dry-run",
23643
+ "--yes",
23644
+ "--help",
23645
+ "--version",
23646
+ "--api-url",
23647
+ "--token"
23648
+ ];
23649
+ function completionWords(tree) {
23650
+ const words = new Set(LOCAL_COMMANDS);
23651
+ for (const command of tree.commands) {
23652
+ for (let length = 1; length <= command.path.length; length += 1) words.add(command.path.slice(0, length).join(" "));
23653
+ }
23654
+ for (const flag of GLOBAL_FLAGS) words.add(flag);
23655
+ return [...words].sort((a, b) => a.localeCompare(b));
23656
+ }
23657
+ var quote = (value) => `'${value.replaceAll("'", `'\\''`)}'`;
23658
+ function bashScript(words) {
23659
+ const list = words.map(quote).join(" ");
23660
+ return `# bash completion for mosse (generated by \`mosse completions bash\`)
23661
+ _mosse_complete() {
23662
+ local cur prefix candidate rest next i
23663
+ cur="\${COMP_WORDS[COMP_CWORD]}"
23664
+ prefix=""
23665
+ for ((i = 1; i < COMP_CWORD; i++)); do
23666
+ prefix+="\${COMP_WORDS[i]} "
23667
+ done
23668
+ prefix="\${prefix% }"
23669
+ COMPREPLY=()
23670
+ for candidate in ${list}; do
23671
+ if [[ -z "$prefix" ]]; then
23672
+ rest="$candidate"
23673
+ else
23674
+ [[ "$candidate" == "$prefix "* ]] || continue
23675
+ rest="\${candidate#"$prefix "}"
23676
+ fi
23677
+ next="\${rest%% *}"
23678
+ [[ -z "$next" ]] && continue
23679
+ if [[ "$next" == "$cur"* ]]; then
23680
+ COMPREPLY+=("$next")
23681
+ fi
23682
+ done
23683
+ # \u53BB\u91CD(\u540C\u4E00\u5C42\u53EF\u80FD\u6765\u81EA\u591A\u6761\u547D\u4EE4)
23684
+ if ((\${#COMPREPLY[@]} > 0)); then
23685
+ COMPREPLY=($(printf '%s\\n' "\${COMPREPLY[@]}" | sort -u))
23686
+ fi
23687
+ }
23688
+ complete -o nosort -F _mosse_complete mosse
23689
+ `;
23690
+ }
23691
+ function zshScript(words) {
23692
+ const list = words.map(quote).join(" ");
23693
+ return `#compdef mosse (generated by \`mosse completions zsh\`)
23694
+ _mosse() {
23695
+ local -a candidates
23696
+ candidates=(${list})
23697
+ local prefix rest next cur
23698
+ cur="\${words[CURRENT]}"
23699
+ prefix=""
23700
+ local i
23701
+ for ((i = 2; i < CURRENT; i++)); do
23702
+ prefix+="\${words[i]} "
23703
+ done
23704
+ prefix="\${prefix% }"
23705
+ if [[ -z "$prefix" ]]; then
23706
+ _describe -t commands 'mosse command' candidates
23707
+ return
23708
+ fi
23709
+ local -a matches
23710
+ for candidate in "\${candidates[@]}"; do
23711
+ [[ "$candidate" == "$prefix "* ]] || continue
23712
+ rest="\${candidate#"$prefix "}"
23713
+ next="\${rest%% *}"
23714
+ [[ -z "$next" ]] && continue
23715
+ matches+=("$next")
23716
+ done
23717
+ if ((\${#matches[@]} > 0)); then
23718
+ compadd -a matches
23719
+ fi
23720
+ }
23721
+ _mosse "$@"
23722
+ `;
23723
+ }
23724
+ function fishScript(words) {
23725
+ const list = words.map(quote).join(" ");
23726
+ return `# fish completion for mosse (generated by \`mosse completions fish\`)
23727
+ function __mosse_complete
23728
+ set -l tokens (commandline -opc)
23729
+ set -e tokens[1]
23730
+ set -l prefix (string join " " $tokens)
23731
+ for candidate in ${list}
23732
+ if test -n "$prefix"
23733
+ string match -q -- "$prefix *" $candidate; or continue
23734
+ set -l rest (string replace -- "$prefix " "" $candidate)
23735
+ set -l next (string split -m 1 " " $rest)[1]
23736
+ echo $next
23737
+ else
23738
+ echo (string split -m 1 " " $candidate)[1]
23739
+ end
23740
+ end | sort -u
23741
+ end
23742
+ complete -c mosse -f -a '(__mosse_complete)'
23743
+ `;
23744
+ }
23745
+ function renderCompletions(tree, shell) {
23746
+ const words = completionWords(tree);
23747
+ if (shell === "bash") return bashScript(words);
23748
+ if (shell === "zsh") return zshScript(words);
23749
+ return fishScript(words);
23750
+ }
23751
+
23752
+ // src/help.ts
23753
+ function editDistance(a, b) {
23754
+ const rows = a.length + 1;
23755
+ const cols = b.length + 1;
23756
+ let prev = Array.from({ length: cols }, (_, i) => i);
23757
+ for (let i = 1; i < rows; i += 1) {
23758
+ const next = [i];
23759
+ for (let j = 1; j < cols; j += 1) {
23760
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
23761
+ next[j] = Math.min(prev[j] + 1, next[j - 1] + 1, prev[j - 1] + cost);
23762
+ }
23763
+ prev = next;
23764
+ }
23765
+ return prev[b.length];
23766
+ }
23767
+ function suggestCommands(tree, tokens, limit2 = 3) {
23768
+ const typed = tokens.join(" ");
23769
+ if (!typed) return [];
23770
+ const typedTokens = new Set(tokens);
23771
+ const scored = tree.commands.map((command) => {
23772
+ const path = command.path.join(" ");
23773
+ const overlap = command.path.filter((segment) => typedTokens.has(segment)).length;
23774
+ const distance = editDistance(typed, path);
23775
+ const startsWith = path.startsWith(typed) ? 1 : 0;
23776
+ return { command, score: distance - overlap * 2 - startsWith * 2 };
23777
+ }).filter((entry) => entry.score <= 4).sort((a, b) => a.score - b.score || a.command.path.length - b.command.path.length);
23778
+ return scored.slice(0, limit2).map((entry) => entry.command);
23779
+ }
23780
+ function searchCommands(tree, query) {
23781
+ const q = query.trim().toLowerCase();
23782
+ if (!q) return [];
23783
+ return tree.commands.filter(
23784
+ (command) => command.path.join(" ").includes(q) || command.summary.toLowerCase().includes(q)
23785
+ );
23786
+ }
23787
+
23618
23788
  // src/cli.ts
23619
23789
  var EXIT_USAGE = 2;
23620
23790
  var EXIT_AUTH = 3;
23791
+ var EXIT_NOT_FOUND = 4;
23792
+ var INBOX_WAIT_DEFAULT_MS = 25e3;
23793
+ var INBOX_WAIT_MAX_MS = 25e3;
23621
23794
  var UsageError = class extends Error {
23622
23795
  };
23623
23796
  function fullTree() {
@@ -23715,12 +23888,12 @@ function suggestFlag(name, flags) {
23715
23888
  let best = null;
23716
23889
  for (const flag of flags) {
23717
23890
  const candidate = flag.name.replace(/^--/, "").replace(/-/g, "");
23718
- const distance = editDistance(target, candidate);
23891
+ const distance = editDistance2(target, candidate);
23719
23892
  if (distance <= 2 && (!best || distance < best.distance)) best = { name: flag.name, distance };
23720
23893
  }
23721
23894
  return best ? `; did you mean ${best.name}?` : "";
23722
23895
  }
23723
- function editDistance(a, b) {
23896
+ function editDistance2(a, b) {
23724
23897
  const rows = a.length + 1;
23725
23898
  const cols = b.length + 1;
23726
23899
  let prev = Array.from({ length: cols }, (_, j) => j);
@@ -23897,11 +24070,31 @@ async function runCli(argv, deps) {
23897
24070
  }
23898
24071
  const envWorkspace = deps.env.MOSSE_WORKSPACE?.trim();
23899
24072
  const workspaceOf = () => globals.workspace ?? envWorkspace;
23900
- const { head, tail } = splitHead(rest);
24073
+ const effective = rest[0] === "workspace" && rest[1] === "list" ? ["auth", "whoami"].concat(rest.slice(2)) : rest;
24074
+ if (rest[0] === "workspace" && rest.length === 1) {
24075
+ deps.stdout(workspaceHelp(tree));
24076
+ return 0;
24077
+ }
24078
+ const { head, tail } = splitHead(effective);
24079
+ const rootHelp = () => `${tree.rootHelp}
24080
+ Local commands:
24081
+ auth <login|logout|status|token> credentials (not part of the tool surface)
24082
+ skill [install|status|upgrade] agent cheatsheet (mosse skill for the one-pager)
24083
+ doctor local environment check
24084
+ completions <bash|zsh|fish> shell completion script
24085
+ workspace list list workspaces (alias of auth whoami)
24086
+ inbox wait [--timeout-ms <ms>] long-poll one inbox notification (exit 4 on timeout)
24087
+ update check npm for a newer @mosse-ai/cli
24088
+ help [query] search commands by path / description
24089
+ `;
23901
24090
  if (!head.length) {
23902
- deps.stdout(tree.rootHelp);
24091
+ deps.stdout(rootHelp());
23903
24092
  return 0;
23904
24093
  }
24094
+ if (head[0] === "inbox" && head[1] === "wait") return handleInboxWait(rest.slice(2), deps, config2, globals);
24095
+ if (head[0] === "update") return handleUpdate(rest.slice(1), deps, globals);
24096
+ if (head[0] === "help") return handleHelpSearch(rest.slice(1), deps, tree, rootHelp());
24097
+ if (head[0] === "completions") return handleCompletions(rest.slice(1), deps, tree, globals);
23905
24098
  if (head[0] === "skill") return handleSkill(rest.slice(1), deps, configPath, config2, tree, globals);
23906
24099
  if (head[0] === "doctor") return handleDoctor(deps, config2, globals);
23907
24100
  if (head[0] === "auth" && (head[1] === void 0 || AUTH_SUBCOMMANDS.has(head[1])))
@@ -23912,7 +24105,11 @@ async function runCli(argv, deps) {
23912
24105
  deps.stdout(renderGroupHelp(tree.commands, head));
23913
24106
  return 0;
23914
24107
  }
23915
- deps.stderr(structuredError(globals, EXIT_USAGE, "unknown_command", `no such command: mosse ${head.join(" ")}`));
24108
+ const suggestions = suggestCommands(tree, head);
24109
+ const hint = suggestions.length ? `; did you mean: ${suggestions.map((item) => `mosse ${item.path.join(" ")}`).join(", ")}` : "";
24110
+ deps.stderr(
24111
+ structuredError(globals, EXIT_USAGE, "unknown_command", `no such command: mosse ${head.join(" ")}${hint}`)
24112
+ );
23916
24113
  deps.stderr(tree.rootHelp);
23917
24114
  return EXIT_USAGE;
23918
24115
  }
@@ -24075,6 +24272,216 @@ function sessionPath(tool, input2) {
24075
24272
  return encodeURIComponent(String(value));
24076
24273
  });
24077
24274
  }
24275
+ async function handleUpdate(args, deps, globals) {
24276
+ if (args[0] === "--help" || args[0] === "-h") {
24277
+ deps.stdout("mosse update\n\n\u68C0\u67E5 npm \u4E0A\u7684\u6700\u65B0\u7248;\u4E0D\u81EA\u52A8\u5B89\u88C5,\u53EA\u6253\u5370\u5347\u7EA7\u547D\u4EE4\u3002\n");
24278
+ return 0;
24279
+ }
24280
+ const registry2 = "https://registry.npmjs.org/@mosse-ai/cli/latest";
24281
+ let latest;
24282
+ try {
24283
+ const response = await deps.fetch(registry2, { headers: { accept: "application/json" } });
24284
+ if (!response.ok) throw new Error(`registry responded ${response.status}`);
24285
+ const body = await response.json();
24286
+ if (!body.version) throw new Error("registry response has no version");
24287
+ latest = body.version;
24288
+ } catch (error62) {
24289
+ deps.stderr(
24290
+ structuredError(
24291
+ globals,
24292
+ 1,
24293
+ "update_check_failed",
24294
+ `could not check the npm registry: ${error62.message}`
24295
+ )
24296
+ );
24297
+ return 1;
24298
+ }
24299
+ const upToDate = compareVersions(latest, CLI_VERSION) <= 0;
24300
+ if (globals.json !== void 0) {
24301
+ deps.stdout(renderOutput({ current: CLI_VERSION, latest, upToDate }, outputOptions(globals)));
24302
+ } else {
24303
+ deps.stdout(
24304
+ upToDate ? `mosse ${CLI_VERSION} is up to date (latest ${latest})` : `mosse ${CLI_VERSION} \u2192 ${latest} available
24305
+ npm i -g @mosse-ai/cli@${latest}
24306
+ # or: npx @mosse-ai/cli@latest <command>`
24307
+ );
24308
+ }
24309
+ return 0;
24310
+ }
24311
+ function compareVersions(a, b) {
24312
+ const pa = a.split(".").map((part) => Number(part) || 0);
24313
+ const pb = b.split(".").map((part) => Number(part) || 0);
24314
+ for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {
24315
+ const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
24316
+ if (diff !== 0) return diff;
24317
+ }
24318
+ return 0;
24319
+ }
24320
+ async function handleHelpSearch(args, deps, tree, root) {
24321
+ const query = args.filter((arg) => !arg.startsWith("-")).join(" ").trim();
24322
+ if (!query) {
24323
+ deps.stdout(root);
24324
+ return 0;
24325
+ }
24326
+ const matches = searchCommands(tree, query);
24327
+ if (!matches.length) {
24328
+ deps.stderr(`no commands match "${query}" (try \`mosse --help\`)`);
24329
+ return 0;
24330
+ }
24331
+ deps.stdout(matches.map((command) => `mosse ${command.path.join(" ")}
24332
+ ${command.summary}`).join("\n\n"));
24333
+ return 0;
24334
+ }
24335
+ async function handleInboxWait(args, deps, config2, globals) {
24336
+ if (args[0] === "--help" || args[0] === "-h") {
24337
+ deps.stdout(
24338
+ [
24339
+ "mosse inbox wait [options]",
24340
+ "",
24341
+ "\u957F\u8F6E\u8BE2\u7B49\u4E00\u6761\u6536\u4EF6\u7BB1\u901A\u77E5(\u4E0E MCP \u7684 inbox_wait \u540C\u4E00\u8BED\u4E49)\u3002",
24342
+ "",
24343
+ "Options:",
24344
+ " --timeout-ms <ms> \u7B49\u5F85\u4E0A\u9650 1000\u201325000(\u9ED8\u8BA4 25000;--timeout \u662F\u522B\u540D)",
24345
+ " --user-id <uuid> token \u6240\u6709\u8005(\u7F3A\u7701\u81EA\u52A8\u4ECE token \u89E3\u6790)",
24346
+ " --workspace <id> \u5DE5\u4F5C\u533A(\u7F3A\u7701\u6309 token \u552F\u4E00 workspace \u63A8\u65AD)",
24347
+ "",
24348
+ "\u9000\u51FA\u7801:0 \u6536\u5230\u901A\u77E5 \xB7 2 \u7528\u6CD5 \xB7 3 \u8BA4\u8BC1/\u6743\u9650 \xB7 4 \u8D85\u65F6(\u672A\u6536\u5230\u901A\u77E5)",
24349
+ ""
24350
+ ].join("\n")
24351
+ );
24352
+ return 0;
24353
+ }
24354
+ let timeoutMs = INBOX_WAIT_DEFAULT_MS;
24355
+ let userId;
24356
+ for (let i = 0; i < args.length; i += 1) {
24357
+ const arg = args[i];
24358
+ if (arg === "--timeout-ms" || arg === "--timeout") {
24359
+ const raw = args[i + 1];
24360
+ i += 1;
24361
+ timeoutMs = Number(raw);
24362
+ if (!Number.isInteger(timeoutMs) || timeoutMs < 1e3 || timeoutMs > INBOX_WAIT_MAX_MS)
24363
+ return waitUsage(deps, globals, `--timeout-ms must be an integer between 1000 and ${INBOX_WAIT_MAX_MS}`);
24364
+ } else if (arg === "--user-id") {
24365
+ userId = args[i + 1];
24366
+ i += 1;
24367
+ if (!userId) return waitUsage(deps, globals, "--user-id needs a value");
24368
+ } else {
24369
+ return waitUsage(deps, globals, `unknown flag: ${arg}`);
24370
+ }
24371
+ }
24372
+ const apiUrl = globals.apiUrl ?? deps.env.MOSSE_API_URL?.trim() ?? config2.apiUrl ?? DEFAULT_API_URL;
24373
+ const token = globals.token ?? deps.env.MOSSE_TOKEN?.trim() ?? hostConfigOf(config2, apiUrl).token;
24374
+ if (!token) {
24375
+ deps.stderr(structuredError(globals, EXIT_AUTH, "unauthenticated", "run `mosse auth login` (or set MOSSE_TOKEN)"));
24376
+ return EXIT_AUTH;
24377
+ }
24378
+ let workspaceId = globals.workspace?.trim() || deps.env.MOSSE_WORKSPACE?.trim() || void 0;
24379
+ if (!userId || !workspaceId) {
24380
+ const listed = await callApi({ fetchImpl: deps.fetch, apiUrl, method: "GET", path: "/api/me/workspaces", token });
24381
+ if (!listed.ok) {
24382
+ const exit = exitCodeForStatus(listed.status);
24383
+ deps.stderr(structuredError(globals, exit, listed.error, withHttpHint(listed.message)));
24384
+ return exit;
24385
+ }
24386
+ const body = listed.body;
24387
+ userId = userId ?? body.userId;
24388
+ if (!userId) {
24389
+ deps.stderr(structuredError(globals, 1, "internal", "token lookup returned no userId"));
24390
+ return 1;
24391
+ }
24392
+ const workspaces = body.workspaces ?? [];
24393
+ if (!workspaceId) {
24394
+ if (workspaces.length === 1) workspaceId = workspaces[0].id;
24395
+ else if (workspaces.length === 0) {
24396
+ deps.stderr(structuredError(globals, EXIT_AUTH, "no_workspace", "this token cannot use any workspace"));
24397
+ return EXIT_AUTH;
24398
+ } else {
24399
+ const list = workspaces.map((workspace) => `${workspace.id} (${workspace.name})`).join(", ");
24400
+ deps.stderr(
24401
+ structuredError(
24402
+ globals,
24403
+ EXIT_USAGE,
24404
+ "workspace_required",
24405
+ `this token covers several workspaces; pass --workspace. Available: ${list}`
24406
+ )
24407
+ );
24408
+ return EXIT_USAGE;
24409
+ }
24410
+ }
24411
+ }
24412
+ const result = await callApi({
24413
+ fetchImpl: deps.fetch,
24414
+ apiUrl,
24415
+ method: "GET",
24416
+ path: `/api/inbox/wait?timeoutMs=${timeoutMs}`,
24417
+ token,
24418
+ ...workspaceId ? { workspaceId } : {}
24419
+ });
24420
+ if (!result.ok) {
24421
+ const exit = exitCodeForStatus(result.status);
24422
+ deps.stderr(structuredError(globals, exit, result.error, withHttpHint(result.message)));
24423
+ return exit;
24424
+ }
24425
+ const status = result.body.status;
24426
+ if (globals.json !== void 0) deps.stdout(renderOutput(result.body, outputOptions(globals)));
24427
+ else deps.stdout(status === "notification" ? "notification" : "timeout");
24428
+ if (status === "timeout") {
24429
+ deps.stderr("inbox wait timed out (no notification)");
24430
+ return EXIT_NOT_FOUND;
24431
+ }
24432
+ return 0;
24433
+ }
24434
+ function waitUsage(deps, globals, message) {
24435
+ deps.stderr(structuredError(globals, EXIT_USAGE, "usage", message));
24436
+ return EXIT_USAGE;
24437
+ }
24438
+ function workspaceHelp(tree) {
24439
+ const whoami2 = tree.byPath.get("auth whoami");
24440
+ return [
24441
+ "mosse workspace \u2014 workspaces available to this token",
24442
+ "",
24443
+ " mosse workspace list [--json] list workspaces (alias of `mosse auth whoami`)",
24444
+ "",
24445
+ whoami2 ? whoami2.help.trim() : "",
24446
+ ""
24447
+ ].join("\n");
24448
+ }
24449
+ async function handleCompletions(args, deps, tree, globals) {
24450
+ const shell = args[0];
24451
+ if (!shell || shell === "--help" || shell === "-h") {
24452
+ deps.stdout(
24453
+ [
24454
+ "mosse completions <shell>",
24455
+ "",
24456
+ "\u6253\u5370 shell \u8865\u5168\u811A\u672C(\u547D\u4EE4\u8BCD\u8868\u4E0E help / skill \u540C\u6E90)\u3002",
24457
+ "",
24458
+ `Shells: ${COMPLETION_SHELLS.join(", ")}`,
24459
+ "",
24460
+ " # zsh",
24461
+ ' mosse completions zsh > "${fpath[1]}/_mosse"',
24462
+ " # bash",
24463
+ " mosse completions bash > /etc/bash_completion.d/mosse",
24464
+ " # fish",
24465
+ " mosse completions fish > ~/.config/fish/completions/mosse.fish",
24466
+ ""
24467
+ ].join("\n")
24468
+ );
24469
+ return 0;
24470
+ }
24471
+ if (!COMPLETION_SHELLS.includes(shell)) {
24472
+ deps.stderr(
24473
+ structuredError(
24474
+ globals,
24475
+ EXIT_USAGE,
24476
+ "usage",
24477
+ `unknown shell: ${shell} (expected ${COMPLETION_SHELLS.join("|")})`
24478
+ )
24479
+ );
24480
+ return EXIT_USAGE;
24481
+ }
24482
+ deps.stdout(renderCompletions(tree, shell));
24483
+ return 0;
24484
+ }
24078
24485
  async function handleSkill(tokens, deps, configPath, _config, tree, globals) {
24079
24486
  const flagValue = (name) => {
24080
24487
  for (let i = 0; i < tokens.length; i += 1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mosse-ai/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mosse": "./dist/index.js"