@wirecat/cli-base 0.65.5 → 0.66.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.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The part of `wcat` a CLI loads on every start, kept to Node built-ins: answering `--wcat-describe`, handing over to
3
+ * the dispatcher when the launcher asks, and otherwise checking the `wcat` launcher with a few `stat` calls.
4
+ */
5
+ import { fileURLToPath } from "node:url";
6
+ import { describeAnswer } from "./describe.js";
7
+ import { binFolder, ensureLauncher } from "./launcher.js";
8
+ import { DESCRIBE_FLAG, DISPATCH_FLAG } from "./names.js";
9
+ /**
10
+ * The first call in a CLI's bin, before its program loads:
11
+ *
12
+ * ```ts
13
+ * const { code } = await wcatStart({ command: "tg", version, description })
14
+ * if (code !== undefined) process.exitCode = code
15
+ * else await startCli(…)
16
+ * ```
17
+ *
18
+ * - `wcat-tg --wcat-describe` prints the tool's description as JSON for `wcat --help`.
19
+ * - `wcat-tg --wcat-dispatch …`, which only the launcher passes, runs `wcat …`.
20
+ * - Any other start makes sure the `wcat` launcher in the tool's bin folder works: a few `stat` calls when it does.
21
+ */
22
+ export const wcatStart = async (tool, io = {}) => {
23
+ const argv = io.argv ?? process.argv;
24
+ const env = io.env ?? process.env;
25
+ const platform = io.platform ?? process.platform;
26
+ const stdout = io.stdout ?? process.stdout;
27
+ const [first, ...rest] = argv.slice(2);
28
+ if (first === DESCRIBE_FLAG) {
29
+ stdout.write(`${JSON.stringify(describeAnswer(tool))}\n`);
30
+ return { code: 0 };
31
+ }
32
+ if (first === DISPATCH_FLAG) {
33
+ const { runWcat } = await import("./dispatch.js");
34
+ const code = await runWcat(rest, { env, platform, stdout, stderr: io.stderr ?? process.stderr, self: tool });
35
+ return { code };
36
+ }
37
+ const folder = binFolder({
38
+ name: tool.command,
39
+ argv1: argv[1],
40
+ script: io.script ?? fileURLToPath(import.meta.url),
41
+ env,
42
+ platform,
43
+ });
44
+ return folder ? { launcher: ensureLauncher({ ...folder, platform }) } : {};
45
+ };
@@ -29,7 +29,7 @@ the four steps that need a person. A new CLI is ready for its first release when
29
29
  |---|---|---:|---|
30
30
  | [Toolchain](toolchain.md) | `TOOL` | 20 | TypeScript, Biome, grit plugins, size caps, import cycles, spelling, Markdown, Go |
31
31
  | [Layout](layout.md) | `LAY` | 10 | Repository layout, entry points, exports, file size, one job per file, splitting a unit, the bundled bin |
32
- | [Commands](commands.md) | `CMD` | 28 | Paths, vocabulary, flags, arguments, effects, lifetime, query, help, external references |
32
+ | [Commands](commands.md) | `CMD` | 29 | Paths, vocabulary, flags, arguments, effects, lifetime, query, help, external references, joining `wcat` |
33
33
  | [Output](output.md) | `OUT` | 23 | Data on stdout only, envelopes, errors, exit codes, partial answers, projection |
34
34
  | [MCP](mcp.md) | `MCP` | 13 | The MCP tools, how they come from commands, what each permission shows |
35
35
  | [Accounts](accounts.md) | `ACCT` | 12 | The explicit profile, reads across accounts, scope flags, linked identities, sign-in commands |
@@ -7,7 +7,7 @@ lifetime it declares, the entity it prints, the query language for lists, the `m
7
7
 
8
8
  Rule ids on this page are `WC-CMD-<n>`. How to read a rule, how ids work and which rule wins are in the
9
9
  [index](README.md). What a command prints is on the [output](output.md) page. How long it runs and how it ends is on
10
- the [lifecycle](lifecycle.md) page.
10
+ the [lifecycle](lifecycle.md) page. How a CLI joins the `wcat` command is under "Joining `wcat`" below.
11
11
 
12
12
  The words themselves are not copied here. They live in the cli-base registries, and `cli-dev lint` reads them from
13
13
  there:
@@ -360,6 +360,25 @@ The references, each for its own part:
360
360
  requirement.
361
361
  - **Applies to:** all CLIs. **Since:** cli-base 0.43.0. **Rulings:** none.
362
362
 
363
+ ## Joining `wcat`
364
+
365
+ ### WC-CMD-29 · Answer `--wcat-describe`, and take no name WireCat reserves
366
+
367
+ - **Why:** `wcat <name>` runs any `wcat-<name>` program on PATH, and `wcat --help` lists each one with what it says
368
+ about itself. A name WireCat reserves would be taken over by WireCat's own tool or by a `wcat` command.
369
+ - **Enforced by:** `src/dev/wcat-lint.ts`.
370
+ - **Example:** the bin's first call is `wcatStart({ command: "gcal", version, description, docs })` from
371
+ `@wirecat/cli-base/wcat/start`. `wcat-gcal --wcat-describe` then prints
372
+ `{"wcat_describe":1,"name":"gcal","version":"1.2.0","description":"…","docs_url":"…"}`. `cli-dev lint` warns when a
373
+ `"bin"` key does not start with `wcat-`, when a package outside `@wirecat/` takes a name from `RESERVED_NAMES` in
374
+ `@wirecat/cli-base/wcat` (`tg`, `max`, `wa`, `zm`, `drive`, `memo`, `mail`, `email`, `wcat` and the built-in commands
375
+ `help`, `version`, `shortcuts`, `doctor`, `update`, `upgrade`, `app`), and, with `--cli`, when the built CLI does not
376
+ answer `--wcat-describe`.
377
+ - **Exceptions:** a CLI keeps its short `"bin"` name beside `wcat-<name>` until callers have moved to the new name; the
378
+ warning stays until then.
379
+ - **Applies to:** all CLIs, and third-party CLIs that join `wcat`. **Since:** cli-base 0.66.0. **Rulings:** NEED-149,
380
+ NEED-153, NEED-154.
381
+
363
382
  ## Sources
364
383
 
365
384
  These documents explain the rules on this page in more detail. Where one of them disagrees with this page, this page
@@ -70,6 +70,32 @@ A template-owned page that is wrong for this CLI is a gap in cli-template, under
70
70
  wrong sentence: fix it there, and `upgrade` brings the fix. Change it in the CLI only where the CLI must differ for
71
71
  good; `upgrade` then asks before it touches the change.
72
72
 
73
+ ## Naming the CLI and joining `wcat`
74
+
75
+ `wcat <name> …` runs a command named `wcat-<name>` from PATH, the way `git foo` runs `git-foo`. Any CLI joins by
76
+ installing that command; nothing else is registered anywhere.
77
+
78
+ - **The name.** Lower-case letters, digits and `-`, starting with a letter. WireCat reserves its own tools' names and
79
+ `wcat`'s built-in commands: `RESERVED_NAMES` in `@wirecat/cli-base/wcat` holds the list, and
80
+ [WC-CMD-29](commands.md#wc-cmd-29--answer---wcat-describe-and-take-no-name-wirecat-reserves) asks a CLI outside
81
+ WireCat not to take one.
82
+ - **The command.** `"bin": { "wcat-<name>": "dist/bin/<name>.js" }`. `cli-dev lint` warns about a `"bin"` key without
83
+ the `wcat-` prefix. The template still writes the short name, and moves to `wcat-<name>` in a later release.
84
+ - **The description `wcat --help` shows.** Call `wcatStart` first in the bin, before the program loads:
85
+
86
+ ```ts
87
+ import { wcatStart } from "@wirecat/cli-base/wcat/start"
88
+
89
+ const { code } = await wcatStart({ command: "gcal", version, description, docs: "https://example.com/gcal" })
90
+ if (code !== undefined) process.exitCode = code
91
+ else await startCli(…)
92
+ ```
93
+
94
+ It answers `--wcat-describe`, runs `wcat` when the `wcat` launcher starts the tool, and on any other start makes sure
95
+ the `wcat` launcher in the tool's bin folder works. `cli-dev lint --cli` warns when the built CLI does not answer.
96
+ - **The short name.** `wcat shortcuts add <name>` makes `<name>` a shortcut to `wcat-<name>`, only when no program on
97
+ PATH has that name. A CLI does not install its short name itself.
98
+
73
99
  ## Four steps that need a person
74
100
 
75
101
  `new` prints these at the end.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-base",
3
- "version": "0.65.5",
3
+ "version": "0.66.0",
4
4
  "description": "The parts every command line tool needs: output modes, terminal rendering, error model, exit codes, credentials, clocks",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Viacheslav Ptsarev",
@@ -90,6 +90,14 @@
90
90
  "types": "./dist/standards/tables.d.ts",
91
91
  "default": "./dist/standards/tables.js"
92
92
  },
93
+ "./wcat": {
94
+ "types": "./dist/wcat/index.d.ts",
95
+ "default": "./dist/wcat/index.js"
96
+ },
97
+ "./wcat/start": {
98
+ "types": "./dist/wcat/start.d.ts",
99
+ "default": "./dist/wcat/start.js"
100
+ },
93
101
  "./biome": "./config/biome.base.json",
94
102
  "./tsconfig.base.json": "./config/tsconfig.base.json",
95
103
  "./tsconfig.test.json": "./config/tsconfig.test.json",