@scm-js/cli 0.8.9 → 0.8.10

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.
@@ -1,4 +1,4 @@
1
- Third-party notices for scmjs 0.8.9
1
+ Third-party notices for scmjs 0.8.10
2
2
 
3
3
  scmjs is MIT-licensed (LICENSE). It is built into one file from scmJS's own code and the
4
4
  packages below, whose license texts this file carries. Who wrote what, and where the
package/dist/scmjs.mjs CHANGED
@@ -6856,13 +6856,44 @@ document.getElementById("go").onclick = go;
6856
6856
  }
6857
6857
  //#endregion
6858
6858
  //#region cli/src/about.ts
6859
- /** `scmjs about`: this build, who made it, the machine it runs on, the desktop app and Docker, and where everything is. */
6860
- var VERSION = "0.8.9";
6861
- var COMMIT = "0469680";
6859
+ /** `scmjs about`: this build and whether npm has a newer one, who made it, the machine it runs on, the desktop app and Docker, and where everything is. */
6860
+ var VERSION = "0.8.10";
6861
+ var COMMIT = "6cf22f8";
6862
6862
  var BUILT = "2026-11-06";
6863
- function aboutReport() {
6863
+ var PACKAGE = "@scm-js/cli";
6864
+ /** a < b, for x.y.z versions (a prerelease or build suffix is ignored). */
6865
+ function olderThan(a, b) {
6866
+ const n = (v) => v.split(/[-+]/)[0].split(".").map((x) => Number(x) || 0);
6867
+ const [x, y] = [n(a), n(b)];
6868
+ for (let i = 0; i < 3; i++) if ((x[i] ?? 0) !== (y[i] ?? 0)) return (x[i] ?? 0) < (y[i] ?? 0);
6869
+ return false;
6870
+ }
6871
+ /** The newest version on npm, or null when npm could not be asked (offline, slow): two seconds at most. */
6872
+ async function newestVersion() {
6873
+ try {
6874
+ const res = await fetch(`https://registry.npmjs.org/${PACKAGE}/latest`, {
6875
+ signal: AbortSignal.timeout(2e3),
6876
+ headers: { accept: "application/json" }
6877
+ });
6878
+ if (!res.ok) return null;
6879
+ const v = (await res.json()).version;
6880
+ return typeof v === "string" ? v : null;
6881
+ } catch {
6882
+ return null;
6883
+ }
6884
+ }
6885
+ /** About's "Newest" row: the update to install, this one, or what npm has when this is newer (a build from a clone). */
6886
+ function newestLine(version, latest) {
6887
+ if (latest === null) return import_picocolors.default.dim("could not ask npm");
6888
+ if (olderThan(version, latest)) return `${import_picocolors.default.yellow(latest)}${dot}npm install -g ${PACKAGE}@latest`;
6889
+ return import_picocolors.default.dim(latest === version ? "this one" : `${latest} on npm`);
6890
+ }
6891
+ async function aboutReport() {
6892
+ const latest = await newestVersion();
6864
6893
  return {
6865
6894
  version: VERSION,
6895
+ latest,
6896
+ outdated: latest !== null && olderThan("0.8.10", latest),
6866
6897
  commit: COMMIT,
6867
6898
  built: BUILT,
6868
6899
  node: process.version,
@@ -6902,6 +6933,7 @@ function printAbout(r) {
6902
6933
  r.commit && `commit ${r.commit}`,
6903
6934
  r.built && `built ${r.built}`
6904
6935
  ].filter(Boolean).join(dot)],
6936
+ ["Newest", newestLine(r.version, r.latest)],
6905
6937
  ["Node", `${r.node}${dot}${r.platform}`],
6906
6938
  ["Desktop app", r.desktopApp ?? import_picocolors.default.dim("not found (scmjs … open uses the browser)")],
6907
6939
  ["Docker", r.docker ? `${r.docker}` : import_picocolors.default.dim("not found (scmjs bot needs it)")],
@@ -16215,12 +16247,16 @@ for (const stream of [process.stdout, process.stderr]) stream.on("error", (e) =>
16215
16247
  if (e.code === "EPIPE") process.exit(process.exitCode ?? 0);
16216
16248
  else throw e;
16217
16249
  });
16218
- var program = new Command$1("scmjs").description("StarCraft: Brood War maps, replays, plugins and bots from the command line").version(VERSION, "-v, --version", "print the version").helpOption("-h, --help", "show help for a command").addOption(new Option("--no-color", "plain text, no colour (also NO_COLOR=1)")).showSuggestionAfterError().helpCommand("help [command]", "show help for a command").configureOutput({ outputError: (text, write) => write(text.replace(/^error: /, `${mark.error} `)) }).showHelpAfterError(import_picocolors.default.dim("(scmjs --help lists the commands)")).configureHelp({
16250
+ var program = new Command$1("scmjs").description("StarCraft: Brood War maps, replays, plugins and bots from the command line").version(VERSION, "-v, --version", "print the version").helpOption("-h, --help", "show help for a command").addOption(new Option("--no-color", "plain text, no colour (also NO_COLOR=1)")).showSuggestionAfterError().commandsGroup("This tool:").helpCommand("help [command]", "show help for a command").configureOutput({ outputError: (text, write) => write(text.replace(/^error: /, `${mark.error} `)) }).showHelpAfterError(import_picocolors.default.dim("(scmjs --help lists the commands)")).configureHelp({
16219
16251
  styleTitle: (s) => import_picocolors.default.bold(s),
16220
16252
  styleCommandText: (s) => import_picocolors.default.cyan(s),
16221
16253
  styleSubcommandText: (s) => import_picocolors.default.cyan(s),
16222
16254
  styleArgumentText: (s) => import_picocolors.default.yellow(s),
16223
- styleOptionText: (s) => import_picocolors.default.green(s)
16255
+ styleOptionText: (s) => import_picocolors.default.green(s),
16256
+ subcommandTerm: (cmd) => {
16257
+ const subs = cmd.commands.map((c) => c.name()).filter((n) => n !== "help");
16258
+ return subs.length ? `${cmd.name()} ${subs.join("|")}` : new Help$1().subcommandTerm(cmd).replace(" [options]", "");
16259
+ }
16224
16260
  }).addHelpText("after", () => `
16225
16261
  ${import_picocolors.default.bold("Examples:")}
16226
16262
  ${import_picocolors.default.dim("$")} scmjs info "(2)Destination.scx" what a map or a replay holds
@@ -16231,15 +16267,11 @@ ${import_picocolors.default.bold("Examples:")}
16231
16267
  ${import_picocolors.default.dim("$")} scmjs about this version, and where things are
16232
16268
 
16233
16269
  ${import_picocolors.default.dim("Docs: https://docs.scmjs.dev")}`);
16234
- program.command("about").description("this version of scmjs, and where things are").addOption(json).action((o) => {
16235
- const r = aboutReport();
16236
- print(...o.json ? [JSON.stringify(r, null, 2)] : printAbout(r));
16237
- });
16238
- program.command("info").description("what a map, replay or bot file holds").argument("<files...>", "maps (.scm .scx .chk), replays (.rep) or bots (.scmbot)").addOption(json).action(async (files, o) => void await eachFile(files, !!o.json, async (input) => {
16270
+ program.command("info").description("what a map, replay or bot file holds").helpGroup("Maps and replays:").argument("<files...>", "maps (.scm .scx .chk), replays (.rep) or bots (.scmbot)").addOption(json).action(async (files, o) => void await eachFile(files, !!o.json, async (input) => {
16239
16271
  const kind = expectKind(input, "map", "replay", "bot");
16240
16272
  return kind === "map" ? mapInfo(input) : kind === "replay" ? replayInfo(input) : botInfo(input);
16241
16273
  }));
16242
- var map = program.command("map").description("read, check and open maps");
16274
+ var map = program.command("map").description("read, check and open maps").helpGroup("Maps and replays:");
16243
16275
  map.command("info").description("a map's size, players, units, triggers and its check").argument("<maps...>").addOption(json).action(async (files, o) => void await eachFile(files, !!o.json, mapInfo));
16244
16276
  map.command("check").description("Check Map, as the editor's: errors, then warnings").argument("<maps...>").addOption(json).option("--all", "list notes too, not only errors and warnings").option("--strict", "fail on warnings as well as errors").addHelpText("after", `\nExits 1 when a map has errors (or warnings, with --strict): fit for a CI step.`).action(async (files, o) => {
16245
16277
  const reports = await eachFile(files, !!o.json, async (input) => {
@@ -16266,14 +16298,14 @@ map.command("open").description("open a map in the scmJS app, or the editor in y
16266
16298
  expectKind(input, "map");
16267
16299
  await openInScmjs(input, o);
16268
16300
  });
16269
- var replay = program.command("replay").description("read and open replays");
16301
+ var replay = program.command("replay").description("read and open replays").helpGroup("Maps and replays:");
16270
16302
  replay.command("info").description("who played, on what map, for how long, at what APM").argument("<replays...>").addOption(json).action(async (files, o) => void await eachFile(files, !!o.json, replayInfo));
16271
16303
  replay.command("open").description("watch a replay in the scmJS app, or the editor in your browser").argument("<replay>").option("--browser", "the editor in the browser, even with the app installed").addOption(new Option("--editor <url>", "the editor's address (SCMJS_EDITOR_URL)").hideHelp()).action(async (file, o) => {
16272
16304
  const input = await readInput(file);
16273
16305
  expectKind(input, "replay");
16274
16306
  await openInScmjs(input, o);
16275
16307
  });
16276
- var plugin = program.command("plugin").description("write a plugin for the editor: start one, check it, run it");
16308
+ var plugin = program.command("plugin").description("start, check and run a plugin for the editor").helpGroup("Plugins and bots:");
16277
16309
  plugin.command("new").description("a plugin to start from, in a new folder").argument("[name]", "the plugin's name, such as \"Base Check\"").option("--dir <folder>", "the folder to write it in (default plugin-<id>)").action((name, o) => {
16278
16310
  const made = newPlugin({
16279
16311
  name,
@@ -16297,7 +16329,7 @@ plugin.command("dev").description("the editor with your plugin, reloaded on ever
16297
16329
  editor: o.editor
16298
16330
  });
16299
16331
  });
16300
- var bot = program.command("bot").description("build your own BWAPI bot for scmjs.dev/play (needs Docker)").addHelpText("after", () => `
16332
+ var bot = program.command("bot").description("build a BWAPI bot for scmjs.dev/play (Docker)").helpGroup("Plugins and bots:").addHelpText("after", () => `
16301
16333
  Run these in your bot's folder. The toolchain is a Docker image, downloaded the first time.
16302
16334
  A built bot is added on the play page: Options → Community bots → Add a bot from a file…
16303
16335
 
@@ -16314,8 +16346,13 @@ bot.command("build").description("out/<key>.scmbot, to add on the play page").ac
16314
16346
  bot.command("update").description("the newest toolchain, the one the play page expects").action(async () => {
16315
16347
  await updateBot();
16316
16348
  });
16349
+ program.command("about").description("this version, any newer one, and links").helpGroup("This tool:").addOption(json).action(async (o) => {
16350
+ const r = await aboutReport();
16351
+ print(...o.json ? [JSON.stringify(r, null, 2)] : printAbout(r));
16352
+ });
16317
16353
  try {
16318
- await program.parseAsync();
16354
+ if (process.argv.length <= 2) program.outputHelp();
16355
+ else await program.parseAsync();
16319
16356
  } catch (e) {
16320
16357
  if (e instanceof CliError) {
16321
16358
  fail(e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scm-js/cli",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "description": "StarCraft: Brood War maps, replays and bots from the command line: what a map or replay holds, Check Map, opening them in scmJS, and building a BWAPI bot for the play page",
5
5
  "keywords": [
6
6
  "starcraft",