@wirecat/cli-base 0.76.0 → 0.77.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/CHANGELOG.md CHANGED
@@ -8,6 +8,20 @@ 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.77.0 — 05.11.2026
12
+
13
+ ### Added
14
+
15
+ - **The vocabulary has cli-core's schedule words and memo's `findings`, as the commands name them.** The resource
16
+ `schedule` (a profile's saved timers; the tool's own background work stays `jobs`), the verbs `agent` and `command`
17
+ (save a timer that starts an agent, or runs one of the tool's commands) and `exec` (what the timer itself starts;
18
+ a person uses `run`), and the collection `findings` (what an agent read in mail, staged for the owner; what it
19
+ proposes to do stays `actions`). The owner ruled to add the words as they are rather than rename the commands,
20
+ so the command lint checks them instead of skipping them. What to watch for: every CLI that mounts
21
+ `schedule` (tg, max, gcal, mail, memo, cli-core itself) and memo's `mail findings` has these in
22
+ `lint/baseline/unknown-verb.json` and `unknown-resource.json`; they are stale after the bump and fail the lint
23
+ until removed (WC-TOOL-16).
24
+
11
25
  ## 0.76.0 — 04.11.2026
12
26
 
13
27
  ### Changed — may break callers
@@ -192,6 +192,10 @@ const verbs = [
192
192
  ["move", "move a thing to another place in the source: a file to a folder, an event to a calendar"],
193
193
  ["copy", "copy a file in the source"],
194
194
  ["run", "run a saved job once, now, as its timer would"],
195
+ ["exec", "what a timer itself starts: one saved schedule, from its file; a person uses run"],
196
+ // schedule's creators are named for what the timer starts; the owner kept these names over `create --kind`.
197
+ ["agent", "save a timer that starts an agent with a prompt, read-only; a verb under schedule, never a resource"],
198
+ ["command", "save a timer that runs one of this tool's own commands; a verb under schedule"],
195
199
  ["claim", "take a thing for a while so no other agent works it at once; the claim lapses by itself"],
196
200
  ["release", "give back what claim took, before it lapses"],
197
201
  ["merge", "fold a duplicate into the thing that stays; nothing is deleted"],
@@ -262,6 +266,10 @@ const collections = [
262
266
  ["recordings", "the files a provider recorded of a meeting"],
263
267
  ["jobs", "work this tool runs in the background or on a timer"],
264
268
  ["actions", "what an agent proposes to do; the owner confirms or rejects each"],
269
+ [
270
+ "findings",
271
+ "what an agent read in stored mail, staged in batches with citations; nothing is recorded until the owner confirms. What it proposes to do is actions",
272
+ ],
265
273
  ["agents", "the agents whose actions are recorded in the shared store"],
266
274
  ["reminders", "scheduled notices about stored work, claimed and acknowledged with delivery receipts"],
267
275
  ["key-documents", "selected source documents that a project keeps as its starting references"],
@@ -304,6 +312,10 @@ const singulars = [
304
312
  ["privacy", "who may find, see, call or add the account"],
305
313
  ["metadata", "a profile's cached source attributes"],
306
314
  ["auth", "the credentials a bot profile uses: its token and the secrets beside it"],
315
+ [
316
+ "schedule",
317
+ "a profile's timers the owner saved, each running a command of this tool or an agent; the tool's own background work is jobs",
318
+ ],
307
319
  ];
308
320
  const views = [
309
321
  ["tree", "the parent and child hierarchy of stored sources"],
@@ -39,7 +39,7 @@ the four steps that need a person. A new CLI is ready for its first release when
39
39
  | [Store](store.md) | `STORE` | 14 | Store areas, account scope, migrations, test isolation |
40
40
  | [Data model](data-model.md) | `DATA` | 9 | Core entities, entities and source records, `external_id`, field names, links and duplicates, files, calendar entries |
41
41
  | [Testing](testing.md) | `TEST` | 17 | Sandbox, no network, no real waits, leak tests, coverage, contracts, test matrix, parity |
42
- | [Security](security.md) | `SECR` | 23 | Secrets, logs, keyring, argv, error text, untrusted text, scanners, workflow hardening, reporting, OAuth sign-in, meeting secrets, keyring in moved-folder runs |
42
+ | [Security](security.md) | `SECR` | 24 | Secrets, logs, keyring, argv, error text, untrusted text, scanners, workflow hardening, reporting, OAuth sign-in and which app it uses, meeting secrets, keyring in moved-folder runs |
43
43
  | [Documents](docs.md) | `DOC` | 21 | User pages and developer pages, generated pages, current facts, changelog, repository page |
44
44
  | [Comparisons](comparisons.md) | `CMP` | 11 | Which tools a comparison page lists, rows as user tasks, agents and safety, where others are better, proof of marks |
45
45
  | [Releases](releases.md) | `REL` | 15 | `bin/release`, the release lock, versions, the owner's yes, trusted publishing |
@@ -22,6 +22,13 @@ A "messenger CLI" below is one of the CLIs that share cli-core's messenger comma
22
22
  catalogue and parity manifest stay in cli-core
23
23
  [`docs/dev/STANDARD.md`](https://github.com/WireCatLabs/cli-core/blob/main/docs/dev/STANDARD.md).
24
24
 
25
+ ### Who follows these rules today
26
+
27
+ WC-CMD-30: cli-core's shared settings declare every shared scalar setting and give `config migrate`, so tg, max, wa,
28
+ mail and gcal follow once they take the cli-core release after 0.561.0. Their own settings (max's `serve` and
29
+ `transcribe_model`, for example) are not declared yet. drive's first-run file holds them all, but drive's own
30
+ `config` has no `migrate` and its writes do not fill the file. zm declares nothing yet.
31
+
25
32
  ## Paths and words
26
33
 
27
34
  ### WC-CMD-1 · Build every path as resource first, then a verb or a view
@@ -402,11 +409,7 @@ plain read never rewrites the file.
402
409
  it as `false (default)`.
403
410
  - **Exceptions:** lists and sections that need fields no default can give (accounts, folders, permissions) get no
404
411
  placeholder. A secret is never declared, since `config show` prints every value. A setting whose absence means
405
- something no value says (no timeout, the terminal decides colour) is not declared either. Known gaps, as of
406
- 2026-11-03: cli-core's shared settings declare every shared scalar setting and give `config migrate`, so tg, max,
407
- wa, mail and gcal follow once they take the cli-core release after 0.561.0; their own settings (max's `serve` and
408
- `transcribe_model`, for example) are not declared yet. drive's first-run file holds them all, but drive's own
409
- `config` has no `migrate` and its writes do not fill the file. zm declares nothing yet.
412
+ something no value says (no timeout, the terminal decides colour) is not declared either.
410
413
  - **Applies to:** all CLIs. **Since:** cli-base 0.76.0. **Rulings:** none.
411
414
 
412
415
  ## References
@@ -194,8 +194,12 @@ An agent never deletes a message for everyone, and never ends the owner's other
194
194
  ### WC-PERM-12 · `<PREFIX>_READ_ONLY` refuses every write
195
195
 
196
196
  When this variable is set, every write answers `permission_error`, whatever `permissions` or a flag say. So does a
197
- command that writes only on this machine, unless cli-core marks it `destroysNothing`; a new local write is refused
198
- until someone marks it. Logging in or out and a change to what a later run may do (a schedule, a setting, the
197
+ command that writes only on this machine, unless cli-core marks it `destroysNothing` or it is of the propose tier; a
198
+ new local write is refused until someone marks it. The propose tier is a closed list, cli-core's `PROPOSE_COMMANDS`:
199
+ `messages acknowledge` and `mail findings add`. A command passes as a proposal only when it is marked `proposesOnly`
200
+ and its path ends with a listed one; it stages something the owner decides, or moves its caller's own processing
201
+ mark, and nothing else. Adding a path widens what a read-only agent can write, so each addition is reviewed on its
202
+ own. Logging in or out and a change to what a later run may do (a schedule, a setting, the
199
203
  recipient list) are refused too. A `--dry-run` preview still runs.
200
204
 
201
205
  - **Why:** an unattended agent needs one switch that the config file and `--permission` cannot undo, and that also
@@ -209,7 +213,8 @@ recipient list) are refused too. A `--dry-run` preview still runs.
209
213
  other command, an MCP session included (cli-core 0.343.0). Local writes marked `destroysNothing` run: what the store
210
214
  rebuilds (`store reindex`, `mentions rebuild`), a new file (`store backup`, `store export`, `stats charts`), and the
211
215
  task writes the follow-ups skill makes on a timer, where `tasks close` only suggests the close to the owner.
212
- Embedding and analysis on this machine run; sending text to an outside service for them is refused.
216
+ A read-only scheduled mail agent stages what it read with `mail findings add` and moves its mark with
217
+ `messages acknowledge`; nothing it staged is recorded until the owner confirms. Embedding and analysis on this machine run; sending text to an outside service for them is refused.
213
218
  - **Applies to:** messenger CLIs. **Since:** cli-base 0.41.0. **Rulings:** none.
214
219
 
215
220
  ### WC-PERM-13 · Every write passes the write guard before it leaves
@@ -373,6 +373,46 @@ store and runs no search. A CLI declares its provider and may replace any step.
373
373
  owner, 2026-10-30 (share the keyring entry, do not multiply it); owner, 2026-10-31 (do not replace it: a test of a
374
374
  new session writes a temporary entry and cleans it up).
375
375
 
376
+ ### WC-SECR-25 · Sign in with WireCat's app by default, and let the owner choose their own
377
+
378
+ Every provider sign-in uses WireCat's OAuth app unless the owner names another. That app is read from
379
+ `constants.json` ([WC-ARCH-23](architecture.md#wc-arch-23--a-value-that-ships-with-the-package-lives-in-the-layers-constantsjson)):
380
+ cli-core's layer for Google and Microsoft, a tool's own layer for a provider only that tool uses, such as Zoom.
381
+
382
+ - **Which app, first match wins:**
383
+ 1. `session start --client-file <json>` or `--client-id <id>`;
384
+ 2. `<TOOL>_<PROVIDER>_CLIENT_ID`, plus `<TOOL>_<PROVIDER>_CLIENT_SECRET` where the provider needs a secret. A
385
+ secret without an id is a `configuration_error`;
386
+ 3. the account's config key `<provider>.client_id`;
387
+ 4. WireCat's app.
388
+ - **Stored with the account.** The app a sign-in used is saved with that account, so refresh and revoke use the same
389
+ app even after the default changes.
390
+ - **Reported by `doctor`,** per provider: `oauth_client: { client: "wirecat" | "own" | null, source: "flag" | "env" |
391
+ "config" | "constants" | null }`. A null client comes with a one-line reason.
392
+ - **Desktop.** A sign-in from wirecat-desktop offers WireCat's app, with a "Use my own app" choice that writes the same
393
+ override as step 2 or 3.
394
+ - **A shipped secret** is allowed only where the provider documents the client as public, and the tool's gitleaks
395
+ allowlist names it by value ([WC-SECR-17](#wc-secr-17--a-gitleaks-rule-covers-each-secret-shape-a-cli-handles)).
396
+ Google's token endpoint refuses a Desktop app client without its secret (tested 2026-11-04), although
397
+ [Google's guide](https://developers.google.com/identity/protocols/oauth2/native-app) calls desktop apps public
398
+ clients that cannot keep secrets. So a Google app ships its id and secret; a Microsoft public client ships its id
399
+ only.
400
+ - **A provider with no WireCat app yet** says so in `doctor` (a null client and its reason) and in its docs, and still
401
+ keeps the order, the stored app and the report above.
402
+
403
+ - **Why:** an owner should sign in without creating an app first, and still be able to use their own; a token
404
+ refreshed with a different app than the one that issued it fails.
405
+ - **Enforced by:** `cli-core: src/oauth/client-file.test.ts`.
406
+ - **Example:** `gcal personal session start` uses WireCat's Google app and `doctor` reports
407
+ `{ client: "wirecat", source: "constants" }`; with `GCAL_GOOGLE_CLIENT_ID` and `GCAL_GOOGLE_CLIENT_SECRET` set it
408
+ reports `{ client: "own", source: "env" }`.
409
+ - **Exceptions:** known gaps, as of 2026-11-04: mail has no WireCat default for Google; zoom has no WireCat app until
410
+ Zoom Marketplace approves one; no tool reads the per-account `google.client_id` key yet; mail's Microsoft key is
411
+ named `microsoft_client_id`; `doctor` reports no `source` yet. gcal's default came from a file CI wrote from a
412
+ secret; cli-core's `constants.json` replaces it from its next release.
413
+ - **Applies to:** every CLI that signs in with OAuth, and wirecat-desktop. **Since:** cli-base 0.76.1.
414
+ **Rulings:** owner, 2026-11-04.
415
+
376
416
  ## Sources
377
417
 
378
418
  These documents explain the rules on this page in more detail. Where one of them disagrees with this page, this page
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-base",
3
- "version": "0.76.0",
3
+ "version": "0.77.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",