@wirecat/cli-base 0.60.0 → 0.61.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 +13 -0
- package/docs/standards/lifecycle.md +6 -3
- package/docs/standards/security.md +17 -3
- package/docs/standards/testing.md +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,19 @@ 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.61.0 — 26.10.2026
|
|
12
|
+
|
|
13
|
+
### Changed — may break callers
|
|
14
|
+
|
|
15
|
+
- **A run record keeps the command line as typed**
|
|
16
|
+
([Security](docs/standards/security.md#wc-secr-1--private-data-and-secrets-never-reach-a-log-a-fixture-or-a-committed-document)).
|
|
17
|
+
The handbook said a run record never holds message text; a run's `argv` now keeps the words typed, so the owner can
|
|
18
|
+
read back what was run. A secret stays hidden: an option or argument marked with cli-core's `secretInput(...)`, one
|
|
19
|
+
named for a token, password, secret, credential, cookie, authorization or API key, a password in a URL, a long
|
|
20
|
+
opaque string. `record_input: false` in a CLI's config masks as before. A CLI's tests that assert a typed marker is
|
|
21
|
+
absent from its run folder now look outside `argv` ([Testing](docs/standards/testing.md)), and a CLI's own document
|
|
22
|
+
that says its run log hides what was typed needs the same change.
|
|
23
|
+
|
|
11
24
|
## 0.60.0 — 26.10.2026
|
|
12
25
|
|
|
13
26
|
### Added
|
|
@@ -14,8 +14,8 @@ A "one-shot" command does one job and ends: most commands. A "long-running" comm
|
|
|
14
14
|
`lifetime: "persistent"` (it runs until it is stopped, such as `serve` or `watch`) or `lifetime: "interactive"` (it
|
|
15
15
|
waits for a person, such as a login).
|
|
16
16
|
|
|
17
|
-
A "run" is one command's record: what it was, how it ended, and its events, never content. The
|
|
18
|
-
run
|
|
17
|
+
A "run" is one command's record: what it was, as typed, how it ended, and its events, which never hold content. The
|
|
18
|
+
rules on what a run may hold are [WC-SECR-1](security.md#wc-secr-1--private-data-and-secrets-never-reach-a-log-a-fixture-or-a-committed-document)
|
|
19
19
|
and [WC-SECR-2](security.md#wc-secr-2--a-log-keeps-only-known-attribute-keys-and-hides-content-keys).
|
|
20
20
|
|
|
21
21
|
### Who follows these rules today
|
|
@@ -198,7 +198,10 @@ provider's limit as often as it ends. These three rules make the next run carry
|
|
|
198
198
|
### WC-LIFE-15 · Keep a run log through cli-core, and read it back with `runs`
|
|
199
199
|
|
|
200
200
|
A failed command is always kept as a run, unless the person turned recording off with `--no-record` or
|
|
201
|
-
`record: false` in the config.
|
|
201
|
+
`record: false` in the config. A run keeps the command line as typed, secrets hidden; `record_input: false` masks
|
|
202
|
+
every value that may be content
|
|
203
|
+
([WC-SECR-1](security.md#wc-secr-1--private-data-and-secrets-never-reach-a-log-a-fixture-or-a-committed-document)).
|
|
204
|
+
`--record` keeps every run of a command that does its work inside cli-core's run
|
|
202
205
|
(`context.run`, or `startRecording` in a program of its own). A run is a folder `<state>/runs/<day>/<run_id>/` with
|
|
203
206
|
`run.json` and `events.jsonl`, one log record per line. `runs list` and `runs show` read it.
|
|
204
207
|
|
|
@@ -21,13 +21,27 @@ Rule ids on this page are `WC-SECR-<n>`. How to read a rule, how ids work and wh
|
|
|
21
21
|
### WC-SECR-1 · Private data and secrets never reach a log, a fixture or a committed document
|
|
22
22
|
|
|
23
23
|
Command output is the only place where a message the owner asked to read may appear. A log, a run record, a test
|
|
24
|
-
fixture, a document and a commit message never hold message text, a token or a phone number
|
|
24
|
+
fixture, a document and a commit message never hold message text, a token or a phone number — with one exception:
|
|
25
|
+
a run record keeps the command line the person typed.
|
|
26
|
+
|
|
27
|
+
A run record's `argv` keeps the words as typed by default, so the history of what was run can be read back. A secret
|
|
28
|
+
in them is always `[redacted]`: the value of an option or argument the CLI marks with cli-core's `secretInput(...)`,
|
|
29
|
+
one whose name says token, password, secret, credential, cookie, authorization or API key, a password inside a URL,
|
|
30
|
+
and a long opaque string. `record_input: false` in the CLI's config masks every value that may be content, and a
|
|
31
|
+
config that will not load masks the same way. A problem report sent to other people (`doctor reports create`) masks
|
|
32
|
+
the typed words always.
|
|
25
33
|
|
|
26
34
|
- **Why:** a log or a repository is copied and kept far longer than anyone remembers; private data in it is a leak.
|
|
27
35
|
- **Enforced by:** `node-ci.yml:secrets`.
|
|
28
36
|
- **Example:** a log line says `{ "event": "send", "outcome": "sent", "count": 1 }`, not the text that was sent.
|
|
29
|
-
|
|
30
|
-
-
|
|
37
|
+
`tg messages send Mom "see you at 5"` is kept in its run as typed; `tg bot api set-webhook --body '{…}'` keeps
|
|
38
|
+
`--body [redacted]`, since cli-core marks `--body` with `secretInput`. A CLI's own option that takes a secret is
|
|
39
|
+
declared `secretInput(new Option("--pin <code>"))` — although under
|
|
40
|
+
[WC-SECR-5](#wc-secr-5--a-secret-is-never-taken-on-the-command-line) such an option should not exist.
|
|
41
|
+
- **Exceptions:** a run record's `argv`, as above: messaging CLIs already keep every message in the store, so the
|
|
42
|
+
words typed are not hidden from the owner's own run log. The scanners catch secrets of known shapes; message text
|
|
43
|
+
and names elsewhere are caught only in review.
|
|
44
|
+
- **Applies to:** all CLIs. **Since:** cli-base 0.41.0. **Rulings:** NEED-1829.
|
|
31
45
|
|
|
32
46
|
### WC-SECR-2 · A log keeps only known attribute keys, and hides content keys
|
|
33
47
|
|
|
@@ -124,7 +124,8 @@ and which run after merge is in [CI](ci.md).
|
|
|
124
124
|
- **Enforced by:** review only.
|
|
125
125
|
- **Example:** test data is visibly fake: `synthetic text ${id}`, the phone number `+71234567890`, the device id
|
|
126
126
|
`00000000-0000-0000-0000-000000000001`, `your-token-here`. Content that must stay hidden carries a unique marker,
|
|
127
|
-
and the test asserts that the marker is absent from output, errors and run events
|
|
127
|
+
and the test asserts that the marker is absent from output, errors and run events (a run's `argv` keeps what was
|
|
128
|
+
typed, so a marker typed on the command line is looked for outside it), while the id is present:
|
|
128
129
|
`expect(err).not.toContain(token)`. The positive check stops the test from passing by recording nothing.
|
|
129
130
|
- **Exceptions:** none.
|
|
130
131
|
- **Applies to:** all CLIs. **Since:** cli-base 0.41.0. **Rulings:** none.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirecat/cli-base",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.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",
|