@wirecat/cli-template 0.2.0 → 0.3.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
@@ -3,7 +3,32 @@
3
3
  Notable changes to `@wirecat/cli-template`. One section per version, newest first; versions follow
4
4
  [semantic versioning](https://semver.org), so before `1.0.0` the skeleton may still change.
5
5
 
6
- <!-- cspell:words katex smol -->
6
+ <!-- cspell:words katex smol whatsapp -->
7
+
8
+ ## 0.3.0 — 26.10.2026
9
+
10
+ ### Changed — may break callers
11
+
12
+ - **The skeleton runs on cli-core 0.439.0; cli-base stays at 0.59.0.** A run record now keeps the command line as
13
+ typed, so `runs show` tells what was run; a secret is still `[redacted]`. The new setting `record_input`
14
+ (`config set record_input false`) brings back the masking of every typed word. `config set` and `config unset` list
15
+ `record_input`, so a CLI's help snapshot changes once. A test or page of a CLI that says a run never holds what was
16
+ typed needs updating. An argument or option that carries a secret is marked with `secretInput()` from
17
+ `@wirecat/cli-core/cli`; the skeleton has none to mark.
18
+
19
+ ### Security
20
+
21
+ - **A first word refused as a profile no longer reaches the run record** as the run's `profile`, and an error that
22
+ quotes `--token=…` or `password=…` no longer keeps the value (from cli-core 0.438.0 and 0.439.0).
23
+
24
+ ### Fixed
25
+
26
+ - **`docs/dev/reference-clis.md` links the evidence for what it says about other repositories**, no longer calls
27
+ whatsapp-cli the handbook's worked example, points a mail CLI at cli-memo's mail import, and no longer says `config`
28
+ hides messenger settings when `messenger` is `false`.
29
+ - **`pnpm release:check` also runs `security:no-leak` and `package:check`**, which only `bin/release --local` ran.
30
+ `package.json` is copied once, so a CLI adds both to its own `release:check` by hand.
31
+ - **`SECURITY.md` asks never to send a session** beside a token, a password and private content.
7
32
 
8
33
  ## 0.2.0 — 26.10.2026
9
34
 
package/SECURITY.md CHANGED
@@ -5,8 +5,8 @@ Please report a security problem privately — never in a public issue:
5
5
  - by email: [hello@wirecat.dev](mailto:hello@wirecat.dev);
6
6
  - or through [GitHub's private vulnerability reporting](https://github.com/WireCatLabs/cli-template/security/advisories/new).
7
7
 
8
- Say what you saw, how to repeat it, and the version (`clidev --version`). Never send a token, a password or anyone's
9
- private content.
8
+ Say what you saw, how to repeat it, and the version (`clidev --version`). Never send a token, a password, a session or
9
+ anyone's private content.
10
10
 
11
11
  What `clidev` keeps on your computer: the [shared security page](https://wirecat.dev/en/docs/security) and
12
12
  [docs/security.md](docs/security.md).
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.2.0";
1
+ export declare const VERSION = "0.3.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "0.2.0";
1
+ export const VERSION = "0.3.0";
2
2
  //# sourceMappingURL=version.js.map
package/docs/commands.md CHANGED
@@ -182,7 +182,7 @@ clidev config set <setting> <value> [options]
182
182
 
183
183
  | Argument | | What it is |
184
184
  |---|---|---|
185
- | `setting` | required | one of: limit, timeout_ms, color, record, keep_runs_for_days, permissions, sends_per_hour, requests_per_minute, transcribe_with, speech_model, search_catch_up, picture_search, search_reranker, embedding_provider, embedding_model, embedding_base_url, embedding_dims, models, read_other_bots, update_check, skill_hint, search_stemmers.cyrillic, search_stemmers.latin, phone_countries, task_categories.<name>, task_agent_close, task_agent_close_min, task_first_pass_per_chat, account_groups.<name>. |
185
+ | `setting` | required | one of: limit, timeout_ms, color, record, record_input, keep_runs_for_days, permissions, sends_per_hour, requests_per_minute, transcribe_with, speech_model, search_catch_up, picture_search, search_reranker, embedding_provider, embedding_model, embedding_base_url, embedding_dims, models, read_other_bots, update_check, skill_hint, search_stemmers.cyrillic, search_stemmers.latin, phone_countries, task_categories.<name>, task_agent_close, task_agent_close_min, task_first_pass_per_chat, account_groups.<name>. |
186
186
  | `value` | required | a number, true or false; for a group tg:work,max:Alice,email:me@x. |
187
187
 
188
188
  | Option | What it does |
@@ -207,7 +207,7 @@ clidev config unset <setting> [options]
207
207
 
208
208
  | Argument | | What it is |
209
209
  |---|---|---|
210
- | `setting` | required | one of: limit, timeout_ms, color, record, keep_runs_for_days, permissions, sends_per_hour, requests_per_minute, transcribe_with, speech_model, search_catch_up, picture_search, search_reranker, embedding_provider, embedding_model, embedding_base_url, embedding_dims, models, read_other_bots, update_check, skill_hint, search_stemmers.cyrillic, search_stemmers.latin, phone_countries, task_categories.<name>, task_agent_close, task_agent_close_min, task_first_pass_per_chat, account_groups.<name>. |
210
+ | `setting` | required | one of: limit, timeout_ms, color, record, record_input, keep_runs_for_days, permissions, sends_per_hour, requests_per_minute, transcribe_with, speech_model, search_catch_up, picture_search, search_reranker, embedding_provider, embedding_model, embedding_base_url, embedding_dims, models, read_other_bots, update_check, skill_hint, search_stemmers.cyrillic, search_stemmers.latin, phone_countries, task_categories.<name>, task_agent_close, task_agent_close_min, task_first_pass_per_chat, account_groups.<name>. |
211
211
 
212
212
  | Option | What it does |
213
213
  |---|---|
@@ -16,3 +16,9 @@ clidev personal config unset limit
16
16
  `permissions` decides what a command may do for this profile: `allow`, `ask`, `readonly` or `deny`, per permission
17
17
  key. Over MCP there is no one to ask, so `ask` lets the command run. `CLIDEV_READ_ONLY=1` refuses every write, whatever
18
18
  the permissions say.
19
+
20
+ ## Run records
21
+
22
+ A command that fails is kept as a run, for `clidev runs list` and `runs show`. `record_input` decides whether a run
23
+ keeps the words you typed; it is `true` unless you set it to `false`. Secrets are masked either way; see
24
+ [Security](security.md).
@@ -5,19 +5,20 @@ the first question of the [design interview](skills/design-interview/SKILL.md):
5
5
 
6
6
  | Category | Learn from |
7
7
  | --- | --- |
8
- | messenger | [whatsapp-cli](https://github.com/WireCatLabs/whatsapp-cli), the handbook's worked example; then [tg-cli](https://github.com/WireCatLabs/tg-cli) and [max-cli](https://github.com/WireCatLabs/max-cli) |
8
+ | messenger | [whatsapp-cli](https://github.com/WireCatLabs/whatsapp-cli), then [tg-cli](https://github.com/WireCatLabs/tg-cli) and [max-cli](https://github.com/WireCatLabs/max-cli) |
9
9
  | files and documents | [drive-cli](https://github.com/WireCatLabs/drive-cli) |
10
10
  | meetings | [zoom-cli](https://github.com/WireCatLabs/zoom-cli) |
11
11
  | notes | [cli-memo](https://github.com/WireCatLabs/cli-memo) |
12
- | mail, calendar, other | none yet: pick the nearest one with the owner |
12
+ | mail, calendar, other | none of its own yet: pick the nearest one with the owner. cli-memo [imports mail](https://github.com/WireCatLabs/cli-memo/blob/c2d21254ab360aed7149a3250d17e879283aa603/docs/mail.md) |
13
13
 
14
14
  A messenger CLI sets `messenger: true` in `src/identity.ts`, and `new --category messenger` writes it. Every other
15
- category keeps the template's `messenger: false`, so the shared help, `commands` and `config` do not speak of chats,
16
- messages and senders.
15
+ category keeps the template's `messenger: false`, so the shared help and `commands` do not speak of chats, messages
16
+ and senders. `config` still lists cli-core's messenger settings, such as `sends_per_hour` and `read_other_bots`.
17
17
 
18
18
  cli-core keeps a provider registry (WC-ARCH-21). A CLI whose provider is not built into cli-core calls
19
19
  `registerProvider(store, { name, kind, aliases, command })` from `@wirecat/cli-core/store` on every run that opens
20
20
  the shared store. `kind` is one of `messages`, `mail`, `notes`, `documents`, `meetings` or `events`. Until the CLI
21
21
  has run once on a computer, `search` there leaves its accounts out and lists them under `skipped`. The reference CLIs
22
- do not show this call: their providers are built into cli-core. The skeleton opens no store and has no provider, so
23
- it registers nothing; the call comes with the CLI's first store code.
22
+ do not show this call: cli-core already knows their providers, from its [seed list](https://github.com/WireCatLabs/cli-core/blob/6d8f415a6ba3124679741f57d3c22ee0f236e8bf/src/domain/providers.ts#L17-L29) and, for Drive, its
23
+ [document providers](https://github.com/WireCatLabs/cli-core/blob/6d8f415a6ba3124679741f57d3c22ee0f236e8bf/src/domain/providers.ts#L50) (cli-core 0.439.0). `grep -rl registerProvider` over a clone of each of the six finds no call. The skeleton opens no store and has no provider, so it registers nothing; the call comes with
24
+ the CLI's first store code.
@@ -21,7 +21,9 @@ go to the further questions.
21
21
  5. **How do people filter what they find?** by time · by person · by container (chat, folder, calendar) · by words in
22
22
  the text · by status or label · other; several allowed.
23
23
  6. **What must never reach the store, a log or the output?** tokens and passwords · one-time codes and passcodes ·
24
- links that carry a secret · the full content, keep only metadata · other; several allowed.
24
+ links that carry a secret · the full content, keep only metadata · other; several allowed. A run record keeps
25
+ the words typed on the command line: an argument or option that carries such a value is marked with
26
+ `secretInput()` from `@wirecat/cli-core/cli`.
25
27
  7. **What untrusted input arrives?** messages from other people · files and attachments · links · names and titles set
26
28
  by others · none · other; several allowed.
27
29
 
package/docs/security.md CHANGED
@@ -6,6 +6,10 @@ What WireCat CLIs share — the keyring, permissions, MCP and what never reaches
6
6
  `clidev` keeps its settings in `config.json` and its state in the folders `clidev doctor` shows. It sends nothing
7
7
  to any service yet.
8
8
 
9
+ A run record keeps the command line as you typed it, so `clidev runs show` tells you what was run. A secret is still
10
+ stored as `[redacted]`: an option named like a token or password, a password in a link, a long opaque string. To
11
+ keep none of the words you type, run `clidev personal config set record_input false`.
12
+
9
13
  `config.json` is saved readable by you only (`0600`), and its folder is created for you only (`0700`). A file or
10
14
  folder made by an older version may be open to other users of the computer: `clidev doctor` lists each under
11
15
  `files.problems` and prints the `chmod` that fixes it. Windows is not checked. Report a vulnerability as [SECURITY.md](https://github.com/WireCatLabs/cli-template/blob/main/SECURITY.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-template",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Start a new WireCat CLI: a working skeleton on cli-base and cli-core, copied by new and kept current by upgrade",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Viacheslav Ptsarev",
@@ -73,7 +73,7 @@
73
73
  "lint:commands": "pnpm build && cli-dev lint --cli dist/bin/clidev.js",
74
74
  "audit:commands": "pnpm build && bash scripts/audit.sh",
75
75
  "ci:quick": "pnpm typecheck && pnpm build && pnpm lint:commands",
76
- "release:check": "pnpm standards:check && pnpm lint && pnpm typecheck && pnpm test:coverage && pnpm lint:commands && pnpm audit:commands && pnpm contracts:check && pnpm test:matrix:check && pnpm docs:check && pnpm generate:check && pnpm version:check",
76
+ "release:check": "pnpm standards:check && pnpm lint && pnpm typecheck && pnpm test:coverage && pnpm lint:commands && pnpm audit:commands && pnpm contracts:check && pnpm test:matrix:check && pnpm docs:check && pnpm generate:check && pnpm version:check && pnpm security:no-leak && pnpm package:check",
77
77
  "prepare": "lefthook install || true",
78
78
  "prepack": "pnpm build",
79
79
  "docs:spell": "cspell lint --config cspell.json --no-progress --no-summary README.md SECURITY.md CHANGELOG.md 'docs/*.md'",
@@ -85,7 +85,7 @@
85
85
  "dependencies": {
86
86
  "@modelcontextprotocol/server": "2.4.0",
87
87
  "@wirecat/cli-base": "0.59.0",
88
- "@wirecat/cli-core": "0.437.0",
88
+ "@wirecat/cli-core": "0.439.0",
89
89
  "commander": "15.0.0"
90
90
  },
91
91
  "devDependencies": {
@@ -142,3 +142,17 @@ it("keeps a failed command as a run, and runs list, show and path read it back",
142
142
  expect(path.code).toBe(0)
143
143
  expect(path.out).toContain(id)
144
144
  })
145
+
146
+ it("a failed run keeps the words typed, and record_input false masks them", async () => {
147
+ const keptArgv = async (words: string) => {
148
+ expect((await ran(["personal", "skill", "show", words])).code).toBe(2)
149
+ const { out } = await ran(["runs", "list", "--limit", "50", "--json"])
150
+ return JSON.parse(out).items.map((run: { argv: string[] }) => run.argv)
151
+ }
152
+ expect(await keptArgv("weekly report")).toContainEqual(["personal", "skill", "show", "weekly report"])
153
+ expect((await ran(["personal", "config", "set", "record_input", "false"])).code).toBe(0)
154
+ const masked = await keptArgv("monthly report")
155
+ expect(JSON.stringify(masked)).not.toContain("monthly report")
156
+ expect(masked).toContainEqual(["personal", "skill", "show", "[redacted]"])
157
+ expect((await ran(["personal", "config", "unset", "record_input"])).code).toBe(0)
158
+ })
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.2.0"
1
+ export const VERSION = "0.3.0"