@wirecat/cli-base 0.50.0 → 0.50.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.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,29 @@ Versions before 0.8.0 are in the [git tags](https://github.com/WireCatLabs/cli-b
8
8
  Every entry says what changed as a caller sees it, why, and what to watch for — the rules are
9
9
  [`docs/dev/CONVENTIONS.md`](docs/dev/CONVENTIONS.md#the-changelog).
10
10
 
11
+ ## 0.50.2 — 23.10.2026
12
+
13
+ ### Added
14
+
15
+ - **The vocabulary has the words a messenger's bot commands use.** Verbs `answer`, `action` and `watch`; views `me`
16
+ and `between`; resources `callbacks`, `webhooks`, `templates`, `media` and the singular `auth`; flags `--secret`
17
+ (which secret beside a bot token to keep) and `--store-token`. The owner approved them for the shared bot commands
18
+ tg, max and wa mount, so `unknown-verb`, `unknown-resource` and `option-role` stop reporting those commands. A CLI
19
+ whose baseline lists them sees "stale baseline entry" and removes the lines.
20
+
21
+ - The messenger vocabulary names sign-in sessions, cached metadata, conversations, analysis work and statistics views precisely. Decryption and retry keep distinct meanings; model categories and alternate spellings still use existing words in command migrations.
22
+
23
+ - The flag vocabulary distinguishes analysis and embedding providers, recorded-consent identities, tag ownership claims, stored-answer models and saved reply-template policies. It also declares the disappearing-message duration, admin-only chat settings, photo removal and sticker-file input with explicit roles.
24
+
25
+ ## 0.50.1 — 23.10.2026
26
+
27
+ ### Fixed
28
+
29
+ - **Joined-path hints can retain a profile.** `refuseJoinedPath` accepts an optional display prefix so hosts can preserve the caller's profile in the corrected invocation. Existing two-argument calls stay valid.
30
+ - **Skill commands have concise summaries.** Detailed installation paths remain in their descriptions, while help and discovery show short task names.
31
+
32
+ - **Secret checks follow the checked revision.** Shared CI, security and release checks scan its complete reachable history. An unrelated fetched branch can no longer fail a clean pull request.
33
+
11
34
  ## 0.50.0 — 22.10.2026
12
35
 
13
36
  ### Changed — may break callers
@@ -16,6 +16,7 @@ export * from "./registry.js";
16
16
  /**
17
17
  * Refuses a command path that arrived as one argument — `"projects add" --help`, what a zsh loop over
18
18
  * `$c` passes. Commander settles `--help` for an unknown word before any hook runs and prints the root
19
- * help, so the words are checked before parsing. Pass the words after a leading profile, if any.
19
+ * help, so the words are checked before parsing. Pass the words after a leading profile, if any;
20
+ * `prefix` keeps those caller-supplied words between the tool name and path in the hint.
20
21
  */
21
- export declare const refuseJoinedPath: (root: Command, args: readonly string[]) => void;
22
+ export declare const refuseJoinedPath: (root: Command, args: readonly string[], prefix?: readonly string[]) => void;
@@ -5,9 +5,10 @@ export * from "./registry.js";
5
5
  /**
6
6
  * Refuses a command path that arrived as one argument — `"projects add" --help`, what a zsh loop over
7
7
  * `$c` passes. Commander settles `--help` for an unknown word before any hook runs and prints the root
8
- * help, so the words are checked before parsing. Pass the words after a leading profile, if any.
8
+ * help, so the words are checked before parsing. Pass the words after a leading profile, if any;
9
+ * `prefix` keeps those caller-supplied words between the tool name and path in the hint.
9
10
  */
10
- export const refuseJoinedPath = (root, args) => {
11
+ export const refuseJoinedPath = (root, args, prefix = []) => {
11
12
  let command = root;
12
13
  const path = [];
13
14
  for (const arg of args) {
@@ -18,7 +19,7 @@ export const refuseJoinedPath = (root, args) => {
18
19
  if (next === undefined)
19
20
  return;
20
21
  if (rest.length > 0)
21
- throw new CliError("validation_error", `"${arg}" was given as one argument; run: ${[root.name(), ...path, first, ...rest].join(" ")}`);
22
+ throw new CliError("validation_error", `"${arg}" was given as one argument; run: ${[root.name(), ...prefix, ...path, first, ...rest].join(" ")}`);
22
23
  path.push(first);
23
24
  command = next;
24
25
  }
@@ -100,7 +100,9 @@ export const skillCommand = (app, skill, environment, more = {}) => {
100
100
  return json === true || jsonl === true;
101
101
  };
102
102
  const named = Object.keys(more);
103
- const show = annotate(command.command("show"), { effects: { remote: "none", local: "read" } }).description(`print SKILL.md — \`${app.command} skill install\` puts it where Claude Code, Codex and Gemini CLI look for it`);
103
+ const show = annotate(command.command("show"), { effects: { remote: "none", local: "read" } })
104
+ .summary("print the tool's instructions for AI agents")
105
+ .description(`print SKILL.md — \`${app.command} skill install\` puts it where Claude Code, Codex and Gemini CLI look for it`);
104
106
  if (named.length > 0)
105
107
  show.argument("[name]", `one of the skills shipped for a task: ${named.join(", ")}`);
106
108
  show.action(function (given) {
@@ -122,6 +124,7 @@ export const skillCommand = (app, skill, environment, more = {}) => {
122
124
  streams.data(content);
123
125
  });
124
126
  annotate(command.command("install"), { effects: { remote: "none", local: "write" } })
127
+ .summary("install the tool's instructions for AI agents")
125
128
  .description(`write SKILL.md to ~/.claude/skills/${app.appName}/ (Claude Code) and ~/.agents/skills/${app.appName}/ (Codex, Gemini CLI)`)
126
129
  .addOption(new Option("--for <agents>", "which agents to install for").choices(["claude", "agents", "all"]).default("all"))
127
130
  .action(function ({ for: chosen }) {
@@ -1,4 +1,80 @@
1
1
  export const WHAT_FLAGS = [
2
+ {
3
+ name: "--analysis-provider",
4
+ value: "<provider>",
5
+ role: "mode",
6
+ type: "choice",
7
+ meaning: "who analyses the selected text: the calling agent or a configured model service",
8
+ },
9
+ {
10
+ name: "--embedding-provider",
11
+ value: "<provider>",
12
+ role: "mode",
13
+ type: "choice",
14
+ meaning: "who computes embeddings: a local model or a configured remote model service",
15
+ },
16
+ {
17
+ name: "--consent-provider",
18
+ value: "<identity>",
19
+ role: "target",
20
+ type: "string",
21
+ meaning: "the exact model-service identity whose recorded consent is being removed",
22
+ },
23
+ {
24
+ name: "--claim",
25
+ value: "<claim>",
26
+ role: "target",
27
+ type: "choice",
28
+ meaning: "the ownership claim to remove from a tag: manual or auto",
29
+ },
30
+ {
31
+ name: "--answer-model",
32
+ value: "<model>",
33
+ role: "target",
34
+ type: "string",
35
+ meaning: "remove only stored analysis answers made by this model; does not run a model",
36
+ },
37
+ {
38
+ name: "--template-mode",
39
+ value: "<mode>",
40
+ role: "value",
41
+ type: "choice",
42
+ meaning: "the saved reply template's policy: fill-only or may-reword",
43
+ },
44
+ {
45
+ name: "--disappear-after",
46
+ value: "<duration|off>",
47
+ role: "value",
48
+ type: "duration",
49
+ meaning: "how long a new chat message is kept after sending; off keeps messages",
50
+ },
51
+ {
52
+ name: "--only-admins-edit-info",
53
+ value: "<on|off>",
54
+ role: "value",
55
+ type: "choice",
56
+ meaning: "only admins may change the chat's name, photo and description",
57
+ },
58
+ {
59
+ name: "--only-admins-send",
60
+ value: "<on|off>",
61
+ role: "value",
62
+ type: "choice",
63
+ meaning: "only admins may send messages to the chat",
64
+ },
65
+ {
66
+ name: "--remove-photo",
67
+ role: "value",
68
+ type: "switch",
69
+ meaning: "remove the chat's photo; not with a replacement photo",
70
+ },
71
+ {
72
+ name: "--sticker-file",
73
+ value: "<file>",
74
+ role: "value",
75
+ type: "path",
76
+ meaning: "a local sticker file to send as a message",
77
+ },
2
78
  {
3
79
  name: "--target-store",
4
80
  value: "<file>",
@@ -316,6 +392,20 @@ export const WHAT_FLAGS = [
316
392
  type: "string",
317
393
  meaning: "what it acts on, as a reference: msg:, chat:, person:, task:, …",
318
394
  },
395
+ {
396
+ name: "--secret",
397
+ value: "<name>",
398
+ role: "target",
399
+ type: "choice",
400
+ meaning: "which secret beside a bot's token to keep, typed at a hidden prompt; never the secret itself",
401
+ },
402
+ {
403
+ name: "--store-token",
404
+ value: "<profile>",
405
+ role: "action",
406
+ type: "string",
407
+ meaning: "keep a token an operation returns only in this bot profile's keyring; never print it",
408
+ },
319
409
  { name: "--task", value: "<id>", role: "target", type: "id", meaning: "a task, by id" },
320
410
  { name: "--to", value: "<chat>", role: "target", type: "id", meaning: "the chat it goes to" },
321
411
  { name: "--topic", value: "<id>", role: "target", type: "id", meaning: "the forum topic, in a chat that has topics" },
@@ -152,6 +152,9 @@ const verbs = [
152
152
  ["star", "mark a message so the owner finds it again; only the owner sees the star"],
153
153
  ["unstar", "take the owner's star off a message"],
154
154
  ["vote", "answer a poll"],
155
+ ["answer", "reply to a button someone pressed under a bot's message"],
156
+ ["action", "show what a bot is doing in a chat, such as typing, for a few seconds"],
157
+ ["watch", "follow new events as they come, and keep them"],
155
158
  ["close", "close a thing that stays: a poll, a task"],
156
159
  ["join", "join a chat"],
157
160
  ["leave", "leave a chat"],
@@ -176,6 +179,8 @@ const verbs = [
176
179
  ["unmerge", "undo a merge"],
177
180
  ["defer", "leave a decision undecided, for the owner"],
178
181
  ["embed", "compute the vectors a meaning search reads, for what is stored and has none"],
182
+ ["decrypt", "write an unencrypted copy of a file sealed by the tool, using the supplied password"],
183
+ ["retry", "start a fresh attempt at partial or failed work, retaining the previous attempt"],
179
184
  ];
180
185
  const replaces = {
181
186
  list: ["ls"],
@@ -237,6 +242,23 @@ const collections = [
237
242
  ["mentions", "phones, e-mail addresses, links and documents found in stored text, each where it was written"],
238
243
  ["images", "pictures in stored messages, searched by what they show"],
239
244
  ["duplicates", "pairs of things that may be one, each waiting for a decision"],
245
+ ["sessions", "devices and applications signed in to an account"],
246
+ ["folders", "named groupings of chats or source files"],
247
+ ["links", "stored or source-provided connections between selected things"],
248
+ ["requests", "requests waiting for an explicit decision"],
249
+ ["rules", "saved rules the owner applies to selected things"],
250
+ ["conversations", "derived stretches of chat messages grouped by topic"],
251
+ ["batches", "bounded work packets submitted or waiting for processing"],
252
+ ["consents", "recorded permission to process selected data with a specified service"],
253
+ ["embeddings", "vectors computed from stored content for similarity search"],
254
+ ["reports", "saved reports about selected data or a tool's state"],
255
+ ["keys", "credentials for a selected external service"],
256
+ ["counters", "stored observations of source counts, with their freshness"],
257
+ ["gaps", "ranges a source could contain that the local store does not hold"],
258
+ ["callbacks", "button presses a bot received and may answer"],
259
+ ["webhooks", "addresses a messenger pushes a bot's updates to"],
260
+ ["templates", "messages a business has approved in advance, the only kind some messengers deliver late"],
261
+ ["media", "files people sent, held by the messenger under an id"],
240
262
  ];
241
263
  const singulars = [
242
264
  ["session", "this tool's login"],
@@ -251,6 +273,8 @@ const singulars = [
251
273
  ["vocabulary", "the owner's catalogue of canonical names, with their aliases"],
252
274
  ["api", "the source's own API, one command per operation"],
253
275
  ["privacy", "who may find, see, call or add the account"],
276
+ ["metadata", "a profile's cached source attributes"],
277
+ ["auth", "the credentials a bot profile uses: its token and the secrets beside it"],
254
278
  ];
255
279
  const views = [
256
280
  ["tree", "the parent and child hierarchy of stored sources"],
@@ -270,6 +294,17 @@ const views = [
270
294
  ["categories", "the categories a thing takes, with what each means"],
271
295
  ["domains", "the internet domains links point to, most linked first"],
272
296
  ["places", "the street addresses confirmed as places, most mentioned first"],
297
+ ["comments", "replies attached to a selected source item"],
298
+ ["links", "links held for a selected thing"],
299
+ ["voters", "people whose recorded votes are visible for a selected poll"],
300
+ ["charts", "time series drawn from selected statistics, optionally rendered to a file"],
301
+ ["newcomers", "members observed joining during the selected time window"],
302
+ ["retention", "whether members of a selected cohort remain or return over time"],
303
+ ["responses", "observed replies between participants and the time taken to answer"],
304
+ ["discussion", "source posts compared by known views and observed discussion replies"],
305
+ ["unanswered", "questions without an observed qualifying answer"],
306
+ ["me", "the account a profile's token belongs to"],
307
+ ["between", "the messages between two given messages of one chat"],
273
308
  ];
274
309
  const roots = [
275
310
  ["batch", "run bounded explicitly registered reads with independent correlated answers"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-base",
3
- "version": "0.50.0",
3
+ "version": "0.50.2",
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",