moshcode 0.26.0 → 0.28.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.
package/src/help.mjs CHANGED
@@ -103,6 +103,18 @@ function distance(a, b) {
103
103
  return prev[b.length];
104
104
  }
105
105
 
106
+ /**
107
+ * Commands that were renamed, and what they became.
108
+ *
109
+ * Edit distance cannot help here — `ticker` is nowhere near `stocks` — so a
110
+ * rename that isn't recorded leaves people with a bare "unknown command" for a
111
+ * verb that worked yesterday. This is deliberately *not* an alias table: the
112
+ * old name stays dead, it just says where its replacement went.
113
+ */
114
+ export const RENAMED_COMMANDS = {
115
+ ticker: "stocks",
116
+ };
117
+
106
118
  /**
107
119
  * The nearest command to something that is not one, or null.
108
120
  *
@@ -114,6 +126,8 @@ function distance(a, b) {
114
126
  export function suggest(input, extra = []) {
115
127
  const typed = String(input ?? "").toLowerCase();
116
128
  if (!typed) return null;
129
+ // A known rename beats any distance match — it is not a guess.
130
+ if (RENAMED_COMMANDS[typed]) return RENAMED_COMMANDS[typed];
117
131
  const candidates = [...CORE_CLI_COMMANDS.map((c) => c.name), ...extra]
118
132
  .filter((n) => !n.startsWith("-"));
119
133
 
package/src/plugins.mjs CHANGED
@@ -31,7 +31,12 @@ export const PLUGINS = [
31
31
  {
32
32
  name: "ticker",
33
33
  description: "equity research slash commands backed by advis0r.com",
34
- commands: ["/ticker", "/signals", "/research", "/lookup", "/reports", "/discover"],
34
+ commands: ["/stocks", "/signals", "/research", "/lookup", "/reports", "/discover"],
35
+ },
36
+ {
37
+ name: "crypto",
38
+ description: "crypto market data slash commands backed by advis0r.com",
39
+ commands: ["/crypto", "/quote", "/book", "/bars", "/spark", "/pairs", "/coin"],
35
40
  },
36
41
  ];
37
42
 
package/src/tui.mjs CHANGED
@@ -20,11 +20,12 @@ import { fetchMotdAd } from "./ads.mjs";
20
20
  import { runScript } from "./runtime.mjs";
21
21
  import { moshVocabulary } from "./commands.mjs";
22
22
  import { mcpCommand, pluginCommand, skillCommand } from "./integrations.mjs";
23
- import { tickerCommand } from "./advisor.mjs";
23
+ import { stocksCommand } from "./advisor.mjs";
24
+ import { cryptoCommand } from "./crypto.mjs";
24
25
  import { canOpenBrowser, openBrowser } from "./open-url.mjs";
25
26
  import { banner, hr, acid, ash, bone, dim, ok, err, warn, info, moshcodeVersion } from "./ui.mjs";
26
27
  import { CORE_CLI_COMMAND_NAMES } from "./cli-schema.mjs";
27
- import { findPitCommand, pitHelpModel, renderPitCommand, suggest, wantsHelp } from "./help.mjs";
28
+ import { RENAMED_COMMANDS, findPitCommand, pitHelpModel, renderPitCommand, suggest, wantsHelp } from "./help.mjs";
28
29
  import { openNewTab } from "./tabs.mjs";
29
30
 
30
31
  const PROMPT = () => acid("mosh ") + dim("▸ ");
@@ -672,10 +673,16 @@ export async function tui() {
672
673
  rl = mkrl();
673
674
  continue;
674
675
  }
675
- // `/ticker` renders in the pit rather than handing the terminal to a tool:
676
+ // `/stocks` renders in the pit rather than handing the terminal to a tool:
676
677
  // there is no advis0r binary to launch, only a public read-only API.
677
- if (cmd === "ticker" || cmd === "advisor") {
678
- await tickerCommand(rest, { openUrl: (url) => canOpenBrowser() && openBrowser(url) });
678
+ if (cmd === "stocks" || cmd === "advisor") {
679
+ await stocksCommand(rest, { openUrl: (url) => canOpenBrowser() && openBrowser(url) });
680
+ continue;
681
+ }
682
+ // `/crypto` renders in the pit for the same reason `/stocks` does: there is
683
+ // no crypto binary to hand the terminal to, only a public read-only API.
684
+ if (cmd === "crypto" || cmd === "coins") {
685
+ await cryptoCommand(rest, { openUrl: (url) => canOpenBrowser() && openBrowser(url) });
679
686
  continue;
680
687
  }
681
688
  if (cmd === "plugin" || cmd === "plugins") {
@@ -715,7 +722,12 @@ export async function tui() {
715
722
  rl = mkrl();
716
723
  continue;
717
724
  }
718
- console.log(err(`unknown command "${line}". /help for the list.`));
725
+ // A renamed verb gets pointed at its replacement; `/ticker` was a pit
726
+ // command for a release, so a bare "unknown command" is a dead end here.
727
+ const renamed = RENAMED_COMMANDS[cmd];
728
+ console.log(err(renamed
729
+ ? `unknown command "${line}" — /${cmd} is now /${renamed}.`
730
+ : `unknown command "${line}". /help for the list.`));
719
731
  }
720
732
 
721
733
  try { rl.close(); } catch { /* noop */ }