@wirecat/cli-template 0.0.0-stage → 0.1.1

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.
Files changed (132) hide show
  1. package/.github/dependabot.yml +23 -0
  2. package/.github/workflows/changelog-guard.yml +12 -0
  3. package/.github/workflows/ci.yml +88 -0
  4. package/.github/workflows/main.yml +17 -0
  5. package/.github/workflows/monthly.yml +28 -0
  6. package/.github/workflows/pr.yml +19 -0
  7. package/.github/workflows/release.yml +191 -0
  8. package/.github/workflows/standards.yml +51 -0
  9. package/.gitleaks.toml +5 -0
  10. package/.markdownlint-cli2.jsonc +7 -0
  11. package/.vale.ini +5 -0
  12. package/AGENTS.md +27 -0
  13. package/CHANGELOG.md +31 -0
  14. package/CLAUDE.md +17 -0
  15. package/LICENSE +204 -0
  16. package/README.md +52 -2
  17. package/SECURITY.md +15 -0
  18. package/bin/release +139 -0
  19. package/biome.json +6 -0
  20. package/config/wirecat/LICENSE +204 -0
  21. package/config/wirecat/biome.base.json +157 -0
  22. package/config/wirecat/check.mjs +41 -0
  23. package/config/wirecat/cspell.json +80 -0
  24. package/config/wirecat/lefthook.yml +26 -0
  25. package/config/wirecat/manifest.json +37 -0
  26. package/config/wirecat/markdownlint.json +10 -0
  27. package/config/wirecat/no-deep-wirecat-import.grit +15 -0
  28. package/config/wirecat/no-exec-interpolation.grit +17 -0
  29. package/config/wirecat/no-new-function.grit +8 -0
  30. package/config/wirecat/no-shell-true.grit +8 -0
  31. package/config/wirecat/no-sqlite-driver.grit +15 -0
  32. package/config/wirecat/no-unbounded-spread.grit +10 -0
  33. package/config/wirecat/release-lock-info.mjs +71 -0
  34. package/config/wirecat/release-lock.sh +34 -0
  35. package/config/wirecat/rumdl.toml +9 -0
  36. package/contracts/help.snap +16 -0
  37. package/contracts/mcp-tools.json +922 -0
  38. package/contracts/no-leak.json +3 -0
  39. package/contracts/plan.json +50 -0
  40. package/cspell.json +10 -0
  41. package/dist/bin/app.d.ts +3 -0
  42. package/dist/bin/app.d.ts.map +1 -0
  43. package/dist/bin/app.js +14 -0
  44. package/dist/bin/app.js.map +1 -0
  45. package/dist/commands/doctor.d.ts +23 -0
  46. package/dist/commands/doctor.d.ts.map +1 -0
  47. package/dist/commands/doctor.js +44 -0
  48. package/dist/commands/doctor.js.map +1 -0
  49. package/dist/commands/mcp.d.ts +3 -0
  50. package/dist/commands/mcp.d.ts.map +1 -0
  51. package/dist/commands/mcp.js +36 -0
  52. package/dist/commands/mcp.js.map +1 -0
  53. package/dist/config.d.ts +3 -0
  54. package/dist/config.d.ts.map +1 -0
  55. package/dist/config.js +4 -0
  56. package/dist/config.js.map +1 -0
  57. package/dist/identity.d.ts +5 -0
  58. package/dist/identity.d.ts.map +1 -0
  59. package/dist/identity.js +12 -0
  60. package/dist/identity.js.map +1 -0
  61. package/dist/index.d.ts +3 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +3 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/mcp.d.ts +19 -0
  66. package/dist/mcp.d.ts.map +1 -0
  67. package/dist/mcp.js +62 -0
  68. package/dist/mcp.js.map +1 -0
  69. package/dist/program.d.ts +6 -0
  70. package/dist/program.d.ts.map +1 -0
  71. package/dist/program.js +37 -0
  72. package/dist/program.js.map +1 -0
  73. package/dist/version.d.ts +2 -0
  74. package/dist/version.d.ts.map +1 -0
  75. package/dist/version.js +2 -0
  76. package/dist/version.js.map +1 -0
  77. package/docs/commands.md +227 -0
  78. package/docs/configuration.md +18 -0
  79. package/docs/dev/DESIGN.md +13 -0
  80. package/docs/dev/TESTING.md +16 -0
  81. package/docs/dev/design-questions.md +24 -0
  82. package/docs/dev/reference-clis.md +15 -0
  83. package/docs/dev/skills/design-interview/SKILL.md +34 -0
  84. package/docs/dev/skills/release/SKILL.md +24 -0
  85. package/docs/dev/test-matrix.md +52 -0
  86. package/docs/index.md +7 -0
  87. package/docs/installation.md +17 -0
  88. package/docs/meta.json +18 -0
  89. package/docs/security.md +8 -0
  90. package/docs/troubleshooting.md +14 -0
  91. package/docs/usage.md +31 -0
  92. package/gitignore +44 -0
  93. package/kit/README.md +127 -0
  94. package/kit/dist/interview.js +170 -0
  95. package/kit/dist/main.js +70 -0
  96. package/kit/dist/manifest.js +111 -0
  97. package/kit/dist/new.js +256 -0
  98. package/kit/dist/rename.js +36 -0
  99. package/kit/dist/source.js +98 -0
  100. package/kit/dist/upgrade.js +230 -0
  101. package/kit/tsconfig.json +17 -0
  102. package/kit/tsconfig.test.json +5 -0
  103. package/lefthook.yml +2 -0
  104. package/lint/baseline/.gitkeep +0 -0
  105. package/lint/overrides.json +1 -0
  106. package/package.json +106 -4
  107. package/pnpm-workspace.yaml +6 -0
  108. package/scripts/audit.sh +22 -0
  109. package/scripts/command-program.ts +1 -0
  110. package/scripts/commands.ts +39 -0
  111. package/scripts/smoke.ts +56 -0
  112. package/scripts/test-matrix-untested.ts +12 -0
  113. package/skills/app-cli/SKILL.md +21 -0
  114. package/src/bin/app.ts +13 -0
  115. package/src/commands/doctor.ts +45 -0
  116. package/src/commands/mcp.ts +38 -0
  117. package/src/config.ts +4 -0
  118. package/src/identity.ts +15 -0
  119. package/src/index.ts +2 -0
  120. package/src/mcp.test.ts +84 -0
  121. package/src/mcp.ts +82 -0
  122. package/src/program.test.ts +66 -0
  123. package/src/program.ts +53 -0
  124. package/src/roots.test.ts +80 -0
  125. package/src/testing/argv-log.ts +1 -0
  126. package/src/testing/sandbox.ts +25 -0
  127. package/src/version.ts +1 -0
  128. package/template.json +40 -0
  129. package/tsconfig.json +9 -0
  130. package/tsconfig.scripts.json +1 -0
  131. package/tsconfig.test.json +1 -0
  132. package/vitest.config.ts +19 -0
@@ -0,0 +1,227 @@
1
+ <!-- Generated from the command tree by pnpm generate. Do not edit. -->
2
+
3
+ # Commands
4
+
5
+ Every command, option and exit code, generated from the program itself. For the same list as JSON, run
6
+ `app commands --json`.
7
+
8
+ **The first word is the profile**, a name you choose: `app personal doctor`. `APP_PROFILE`
9
+ does the same for a whole shell session. No profile is assumed: a command that uses an account stops without one and
10
+ lists the profiles on this computer.
11
+
12
+ ## Options for every command
13
+
14
+ | Option | What it does |
15
+ |---|---|
16
+ | `-V, --version` | output the version number. |
17
+ | `-v, --verbose` | more detail in what is shown: -v ids, -vv everything we know. Default: `0`. |
18
+ | `--json` | machine-readable output: one JSON value on stdout; --json=id,text keeps only those fields. |
19
+ | `--jsonl` | machine-readable output: one JSON object per line, for streaming and jq. |
20
+ | `--quiet` | diagnostics off; a failure is still said. |
21
+ | `--trace` | the connection's own log lines on stderr — never message content. |
22
+ | `--debug` | on a failure, its whole record — cause and stack — in place of the short line. |
23
+ | `--timeout <duration>` | give up on the whole command after this — 30s, 2m, 500ms. |
24
+ | `--offline` | answer from what was recorded and never connect; fails if nothing was. |
25
+ | `--no-input` | never prompt or open interactive login; piped input remains available. |
26
+ | `--max-input-bytes <bytes>` | maximum buffered input bytes (default: 16777216). |
27
+ | `--max-output-bytes <bytes>` | maximum machine output bytes (default: 4194304; 0 disables). |
28
+ | `--brief` | found messages as reference, title, time, sender and excerpt only. |
29
+ | `--full` | found messages with their whole text and every provider field. |
30
+ | `--dry-run` | preview parsed arguments and permissions before running the action. |
31
+ | `--yes` | go ahead without the question an ask level puts before a write. |
32
+ | `--record` | keep this run — ids and timings, never message content. |
33
+ | `--no-record` | do not keep it, whatever the configuration says. |
34
+
35
+ ## `app commands`
36
+
37
+ every command by section; --json prints its contract, one path per call
38
+
39
+ ### `app commands info`
40
+
41
+ one command contract, or all schemas, error reasons and explicit overrides
42
+
43
+ ```sh
44
+ app commands info [path]
45
+ ```
46
+
47
+ | Argument | | What it is |
48
+ |---|---|---|
49
+ | `path` | optional | one command path; without one, export schemas, error reasons and explicit overrides. |
50
+
51
+ **Returns:** one command contract, or all schemas, error reasons and explicit overrides
52
+
53
+ **Example:** `app commands info messages list`
54
+
55
+ ## `app doctor`
56
+
57
+ check this installation: version, paths, config, profiles; no keyring or network
58
+
59
+ ```sh
60
+ app doctor
61
+ ```
62
+
63
+ **Returns:** check this installation: version, paths, config, profiles; no keyring or network
64
+
65
+ **Example:** `app personal doctor`, `app personal doctor --json`
66
+
67
+ ## `app skill`
68
+
69
+ the instructions an agent is given for this tool
70
+
71
+ ### `app skill show`
72
+
73
+ print SKILL.md — `app skill install` puts it where Claude Code, Codex and Gemini CLI look for it
74
+
75
+ ```sh
76
+ app skill show [name]
77
+ ```
78
+
79
+ | Argument | | What it is |
80
+ |---|---|---|
81
+ | `name` | optional | one of the skills shipped for a task: follow-ups, link-conversations. |
82
+
83
+ **Returns:** print the tool's instructions for AI agents
84
+
85
+ **Example:** `app skill show`, `app skill show follow-ups`
86
+
87
+ ### `app skill install`
88
+
89
+ write SKILL.md to \~/.claude/skills/app-cli/ (Claude Code) and \~/.agents/skills/app-cli/ (Codex, Gemini CLI)
90
+
91
+ **Changes something on this computer only.**
92
+
93
+ ```sh
94
+ app skill install [options]
95
+ ```
96
+
97
+ | Option | What it does |
98
+ |---|---|
99
+ | `--for <agents>` | which agents to install for. One of: `claude`, `agents`, `all`. Default: `all`. |
100
+
101
+ **Returns:** install the tool's instructions for AI agents
102
+
103
+ **Example:** `app skill install --for agents`
104
+
105
+ ## `app mcp`
106
+
107
+ serve this profile's commands to an agent over MCP, on stdin and stdout, writes included; the profile's permissions decide — `claude mcp add app -- app personal mcp`
108
+
109
+ **Changes something in the service.**
110
+
111
+ ```sh
112
+ app mcp
113
+ ```
114
+
115
+ **Returns:** serve this profile's commands to an AI agent
116
+
117
+ **Example:** `app personal mcp`
118
+
119
+ ## `app upgrade`
120
+
121
+ upgrade app with the package manager that installed it; --check only looks
122
+
123
+ **Changes something on this computer only.**
124
+
125
+ ```sh
126
+ app upgrade [options]
127
+ ```
128
+
129
+ | Option | What it does |
130
+ |---|---|
131
+ | `--check` | say whether a newer version exists, and install nothing. |
132
+
133
+ **Returns:** upgrade app with the package manager that installed it; --check only looks
134
+
135
+ **Example:** `app upgrade --check`, `app upgrade`
136
+
137
+ ## `app config`
138
+
139
+ the settings in force, and where each one came from
140
+
141
+ ### `app config show`
142
+
143
+ the profile, the profiles that exist, and each setting with where it came from
144
+
145
+ ```sh
146
+ app config show [options]
147
+ ```
148
+
149
+ | Option | What it does |
150
+ |---|---|
151
+ | `--bot` | the settings a bot command on this profile gets, rather than the personal account's. |
152
+
153
+ **Returns:** the profile, the profiles that exist, and each setting with where it came from
154
+
155
+ **Example:** `app personal config show`
156
+
157
+ ### `app config set`
158
+
159
+ save a setting to the configuration file
160
+
161
+ **Changes something on this computer only.**
162
+
163
+ ```sh
164
+ app config set <setting> <value> [options]
165
+ ```
166
+
167
+ | Argument | | What it is |
168
+ |---|---|---|
169
+ | `setting` | required | one of: limit, timeout_ms, color, sender_colors, record, keep_runs_for_days, permissions, sends_per_hour, requests_per_minute, transcribe_with, speech_model, search_catch_up, picture_search, embedding_provider, embedding_model, embedding_base_url, embedding_dims, analysis_provider, analysis_model, analysis_base_url, 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>. |
170
+ | `value` | required | a number, true or false, or for allow a list like send,reaction; for a group tg:work,max:Alice,email:me@x. |
171
+
172
+ | Option | What it does |
173
+ |---|---|
174
+ | `--defaults` | change what every profile gets, rather than this profile. |
175
+ | `--personal` | only for personal accounts — the personal section of the file. |
176
+ | `--bot` | only for bots — the bot section of the file. |
177
+
178
+ **Returns:** save a setting to the configuration file
179
+
180
+ **Example:** `app personal config set limit 20`
181
+
182
+ ### `app config unset`
183
+
184
+ remove a setting from the configuration file
185
+
186
+ **Changes something on this computer only.**
187
+
188
+ ```sh
189
+ app config unset <setting> [options]
190
+ ```
191
+
192
+ | Argument | | What it is |
193
+ |---|---|---|
194
+ | `setting` | required | one of: limit, timeout_ms, color, sender_colors, record, keep_runs_for_days, permissions, sends_per_hour, requests_per_minute, transcribe_with, speech_model, search_catch_up, picture_search, embedding_provider, embedding_model, embedding_base_url, embedding_dims, analysis_provider, analysis_model, analysis_base_url, models, read_other_bots, update_check, skill_hint, default_profile, 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>. |
195
+
196
+ | Option | What it does |
197
+ |---|---|
198
+ | `--defaults` | change what every profile gets, rather than this profile. |
199
+ | `--personal` | only for personal accounts — the personal section of the file. |
200
+ | `--bot` | only for bots — the bot section of the file. |
201
+
202
+ **Returns:** remove a setting from the configuration file
203
+
204
+ **Example:** `app personal config unset limit`
205
+
206
+ ## Exit codes
207
+
208
+ Branch on the code, not on the text: the text can change, the code does not.
209
+
210
+ | Code | When |
211
+ |---|---|
212
+ | `0` | it worked |
213
+ | `2` | `validation_error` |
214
+ | `3` | `configuration_error` |
215
+ | `4` | `authentication_error` |
216
+ | `5` | `permission_error` |
217
+ | `6` | `not_found` |
218
+ | `7` | `confirmation_required` |
219
+ | `8` | `rate_limited` |
220
+ | `9` | `timeout` |
221
+ | `10` | `network_error` |
222
+ | `11` | `provider_error` |
223
+ | `12` | `provider_unavailable` |
224
+ | `13` | `invalid_response` |
225
+ | `14` | `outcome_unknown` |
226
+ | `130` | `cancelled` |
227
+ | `1` | anything else |
@@ -0,0 +1,18 @@
1
+ # Settings
2
+
3
+ Settings live in one file, `config.json`, in the folder `app personal doctor` shows. Each profile has its own part,
4
+ and `defaults` apply to every profile. This page lists how to see and change them.
5
+
6
+ ```sh
7
+ app personal config show
8
+ app personal config set limit 50
9
+ app personal config unset limit
10
+ ```
11
+
12
+ `config show` lists each setting and where it came from: the file, a variable or the default.
13
+
14
+ ## Permissions
15
+
16
+ `permissions` decides what a command may do for this profile: `allow`, `ask`, `readonly` or `deny`, per permission
17
+ key. Over MCP there is no one to ask, so `ask` lets the command run. `APP_READ_ONLY=1` refuses every write, whatever
18
+ the permissions say.
@@ -0,0 +1,13 @@
1
+ # Design
2
+
3
+ `npx @wirecat/cli-template new` writes this page from the answers to the
4
+ [design interview](skills/design-interview/SKILL.md). It is empty in the template: ask the interview and write the
5
+ answers here before building anything.
6
+
7
+ ## Answers
8
+
9
+ Not answered yet.
10
+
11
+ ## Open questions for the owner
12
+
13
+ None yet.
@@ -0,0 +1,16 @@
1
+ # Testing
2
+
3
+ How the tests run, and what they never touch. The rules are the handbook's
4
+ [Testing page](../../node_modules/@wirecat/cli-base/docs/standards/testing.md).
5
+
6
+ - `pnpm test` runs vitest. `@wirecat/cli-base/testing/setup` gives each test file its own temporary home folder, a
7
+ keyring that throws and no network; `src/testing/sandbox.ts` points this CLI's config, state, cache and the shared
8
+ store into that folder.
9
+ - `pnpm test:coverage` adds the coverage floor in `vitest.config.ts`.
10
+ - Each run logs the command lines the tests drove (`coverage/argv.jsonl`). `pnpm test:matrix` turns that log into
11
+ [test-matrix.md](test-matrix.md); a command or option no test drives needs a reason in
12
+ `scripts/test-matrix-untested.ts`.
13
+ - `pnpm contracts:check` runs the built CLI against `contracts/plan.json`: help, discovery, errors and the MCP tool
14
+ list. `cli-contract contracts/plan.json --update` rewrites the snapshots; review the diff.
15
+ - `pnpm smoke` installs the packed package into a temporary folder and runs it offline.
16
+ - `pnpm audit:commands` audits the command tree beside the latest published WireCat CLIs.
@@ -0,0 +1,24 @@
1
+ # Further design questions
2
+
3
+ Ask these only when the reference CLI does not already answer them, after the seven questions of the
4
+ [design interview](skills/design-interview/SKILL.md). Write each answer into [DESIGN.md](DESIGN.md).
5
+
6
+ ## Storing, indexing, syncing and deleting
7
+
8
+ 1. Which of the service's records are kept locally, and which core entity does each become (people, events,
9
+ documents, files, messages, meetings)? (WC-DATA-1, WC-DATA-2)
10
+ 2. How does it sync: everything each time, from a cursor, or by change token? On demand, on a schedule, or kept
11
+ running?
12
+ 3. When the service deletes something, what happens here? Proposed: mark it deleted, keep it, never wipe. (WC-DATA-7)
13
+ 4. Can the person delete local data themselves, and how much: one record, one account, everything?
14
+
15
+ ## Search
16
+
17
+ 1. What should a search find: titles only, the full text, names of people?
18
+ 2. Should `search all` and `memo context <person>` show its records?
19
+ 3. What must work without a network?
20
+
21
+ ## Security
22
+
23
+ 1. Where are the secrets kept? Proposed: the system keyring. (WC-SECR)
24
+ 2. Which writes need a permission, and which are never allowed whatever the permissions? (WC-PERM)
@@ -0,0 +1,15 @@
1
+ # Reference CLIs
2
+
3
+ The template has no sample code. The agent that builds a new CLI learns from the WireCat CLI closest to it, picked by
4
+ the first question of the [design interview](skills/design-interview/SKILL.md):
5
+
6
+ | Category | Learn from |
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) |
9
+ | files and documents | [drive-cli](https://github.com/WireCatLabs/drive-cli) |
10
+ | meetings | [zoom-cli](https://github.com/WireCatLabs/zoom-cli) |
11
+ | notes | [cli-memo](https://github.com/WireCatLabs/cli-memo) |
12
+ | mail, calendar, other | none yet: pick the nearest one with the owner |
13
+
14
+ Until cli-core has a provider registry, a CLI made from this template is not listed as a provider of its own, and
15
+ `search` finds its records as messages.
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: design-interview
3
+ description: Ask the owner the seven design questions for a new WireCat CLI before building anything, then the further questions the reference CLI does not answer, and write the answers to docs/dev/DESIGN.md. Use when DESIGN.md has no answers, when asked to design or start the CLI, «спроектировать», «начать CLI».
4
+ ---
5
+
6
+ # Design interview
7
+
8
+ Ask before you build. Each question is multiple choice, and every one also takes "Other", typed by hand. Ask them in
9
+ this order, one at a time, and write each answer down as it comes. `npx @wirecat/cli-template new` asks the same
10
+ questions in a terminal and takes them as flags without one; when `DESIGN.md` already has the answers, read them and
11
+ go to the further questions.
12
+
13
+ 1. **What kind of tool is it?** messenger · mail · notes · files and documents · calendar · meetings · other. It
14
+ picks the reference CLI (see [Reference CLIs](../../reference-clis.md)).
15
+ 2. **Which languages is the content in?** Any languages, several allowed: the messages, documents or transcripts the
16
+ CLI handles. The answer picks the language-dependent parts: search stemming, the embedding and speech models.
17
+ 3. **How does a person sign in?** OAuth in the browser · an API token or key · a session (phone code, QR) · none ·
18
+ other.
19
+ 4. **What does the service offer to build on?** an official API with an official client library · official API
20
+ documentation only · nothing official · other.
21
+ 5. **How do people filter what they find?** by time · by person · by container (chat, folder, calendar) · by words in
22
+ the text · by status or label · other; several allowed.
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.
25
+ 7. **What untrusted input arrives?** messages from other people · files and attachments · links · names and titles set
26
+ by others · none · other; several allowed.
27
+
28
+ Then read the reference CLI and ask the [further questions](../../design-questions.md) it does not answer.
29
+
30
+ ## What to write
31
+
32
+ `docs/dev/DESIGN.md`: the seven answers, the reference CLI, the further answers, and a list of open questions for
33
+ the owner. Name the reference CLI in `AGENTS.md`, between the `cli-template:reference-cli` markers. Start building
34
+ only after the owner has read `DESIGN.md`.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: release
3
+ description: Prepare a release of this CLI for the owner to publish — run release:check, write the changelog under the handbook's headings, check the docs against what changed, raise the version in a pull request; the owner runs bin/release. Use when asked to release, prepare a release, cut a version, «выпуск», «выпустить версию».
4
+ ---
5
+
6
+ # Release
7
+
8
+ The rules are the handbook's [Releases page](../../../../node_modules/@wirecat/cli-base/docs/standards/releases.md)
9
+ (`WC-REL-<n>`), which wins over this skill. An agent prepares the release; the owner merges the release pull request
10
+ and runs `bin/release`.
11
+
12
+ 1. **What changed.** In a worktree off `origin/main`: `git log --oneline v<last version>..origin/main`. The
13
+ `docs/commands.md` diff shows what a cli-core or cli-base release changed in the commands.
14
+ 2. **The checks.** `pnpm release:check`. Before the version is raised, only the changelog's `## Unreleased` may be
15
+ left; report anything else and fix it in the release pull request.
16
+ 3. **The changelog.** Write `## Unreleased` under the handbook's headings, each at most once: `Added`,
17
+ `Changed — may break callers`, `Fixed`, `Security`, `Removed` (`WC-DOC-14` to `WC-DOC-18`). No internal ids.
18
+ 4. **The docs.** `README.md`, `docs/*.md` and `skills/app-cli/SKILL.md` state what the code does now (`WC-DOC-3`).
19
+ `pnpm generate` and `pnpm test:matrix` rewrite the generated pages (`WC-DOC-4`).
20
+ 5. **The version.** `npm view @wirecat/app-cli version` is what is published. Set the next version in
21
+ `package.json`, run `pnpm version:sync`, date the section as `## <version> — DD.MM.YYYY`, run
22
+ `pnpm release:check` again, and open the pull request `chore(release): <version>`.
23
+ 6. **The owner** merges it and runs `bin/release` on a clean `main`. `bin/release --local` publishes from this
24
+ computer when GitHub Actions cannot, with the owner's own npm login or `NPM_TOKEN`.
@@ -0,0 +1,52 @@
1
+ <!-- Generated by cli-dev test-matrix from the command tree and a test run. Do not edit; `pnpm test:matrix`. -->
2
+
3
+ # Test matrix
4
+
5
+ Every command and option of `app`, and whether an offline test drives it through the CLI. ✅ a test
6
+ ran it · ⛔ not tested offline, with the reason and where it is checked instead · ❌ nothing.
7
+ Measured from the test run (`coverage/argv.jsonl`), not searched for — see
8
+ [TESTING.md](TESTING.md) for how, and for the states and failures that cut across commands.
9
+
10
+ **37 ✅ · 2 ⛔ · 0 ❌** — 11 commands, 28 options.
11
+
12
+ | Command | Option | | Note |
13
+ |---|---|---|---|
14
+ | `commands` | | ✅ | |
15
+ | `commands info` | | ✅ | |
16
+ | `doctor` | | ✅ | |
17
+ | `skill show` | | ✅ | |
18
+ | `skill install` | | ✅ | |
19
+ | `skill install` | `--for` | ✅ | |
20
+ | `mcp` | | ✅ | |
21
+ | `upgrade` | | ✅ | |
22
+ | `upgrade` | `--check` | ✅ | |
23
+ | `config show` | | ✅ | |
24
+ | `config show` | `--bot` | ✅ | |
25
+ | `config set` | | ✅ | |
26
+ | `config set` | `--defaults` | ✅ | |
27
+ | `config set` | `--personal` | ✅ | |
28
+ | `config set` | `--bot` | ✅ | |
29
+ | `config unset` | | ✅ | |
30
+ | `config unset` | `--defaults` | ✅ | |
31
+ | `config unset` | `--personal` | ✅ | |
32
+ | `config unset` | `--bot` | ✅ | |
33
+ | `help` | | ✅ | |
34
+ | *global* | `--version` | ⛔ | Commander answers before any command runs, so the trace never sees it; `pnpm version:check` checks it |
35
+ | *global* | `--verbose` | ✅ | |
36
+ | *global* | `--json` | ✅ | |
37
+ | *global* | `--jsonl` | ✅ | |
38
+ | *global* | `--quiet` | ✅ | |
39
+ | *global* | `--trace` | ✅ | |
40
+ | *global* | `--debug` | ✅ | |
41
+ | *global* | `--timeout` | ✅ | |
42
+ | *global* | `--offline` | ✅ | |
43
+ | *global* | `--no-input` | ✅ | |
44
+ | *global* | `--max-input-bytes` | ✅ | |
45
+ | *global* | `--max-output-bytes` | ✅ | |
46
+ | *global* | `--brief` | ✅ | |
47
+ | *global* | `--full` | ✅ | |
48
+ | *global* | `--dry-run` | ✅ | |
49
+ | *global* | `--yes` | ✅ | |
50
+ | *global* | `--record` | ✅ | |
51
+ | *global* | `--no-record` | ✅ | |
52
+ | *global* | `--help-all` | ⛔ | Commander answers before any command runs, so the trace never sees it; contracts/help.snap covers help |
package/docs/index.md ADDED
@@ -0,0 +1,7 @@
1
+ # app
2
+
3
+ `app` brings a service to the terminal, to scripts and to AI agents. This page is where a reader starts: say what
4
+ the tool does, who it is for, and the first command to run. It will say that once the tool connects to its service.
5
+
6
+ Today it has the commands every WireCat CLI shares: `doctor`, `commands`, `config`, `skill`, `mcp` and `upgrade`.
7
+ Start with [installation](installation.md), then [usage](usage.md).
@@ -0,0 +1,17 @@
1
+ # Install
2
+
3
+ Install `app` once on each computer where you or an agent use it. You need Node.js 22.16 or later, or 24.
4
+
5
+ ```sh
6
+ npm install -g @wirecat/app-cli
7
+ app --version
8
+ ```
9
+
10
+ Check the installation, then pick a profile name for your account, such as `personal`:
11
+
12
+ ```sh
13
+ app personal doctor
14
+ ```
15
+
16
+ `doctor` needs no network and opens no keyring. It shows the version, where settings live and the profiles that
17
+ exist. Next: [use it](usage.md).
package/docs/meta.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "title": "app",
3
+ "pages": [
4
+ "---Start---",
5
+ "index",
6
+ "installation",
7
+ "---Guides---",
8
+ "usage",
9
+ "---Reference---",
10
+ "commands",
11
+ "configuration",
12
+ "---When something goes wrong---",
13
+ "troubleshooting",
14
+ "security",
15
+ "---Project---",
16
+ "changelog"
17
+ ]
18
+ }
@@ -0,0 +1,8 @@
1
+ # Security
2
+
3
+ What WireCat CLIs share — the keyring, permissions, MCP and what never reaches a log — is on the
4
+ [shared security page](https://wirecat.dev/en/docs/security). This page keeps only what is particular to `app`.
5
+
6
+ `app` keeps its settings in `config.json` and its state in the folders `app personal doctor` shows. It sends nothing
7
+ to any service yet. Report a vulnerability as [SECURITY.md](https://github.com/WireCatLabs/app-cli/blob/main/SECURITY.md)
8
+ says.
@@ -0,0 +1,14 @@
1
+ # When something goes wrong
2
+
3
+ Start with the symptom, run the check, then retry the command. Keep the error code and the profile name for a
4
+ support request.
5
+
6
+ | Symptom | What to do |
7
+ | --- | --- |
8
+ | Not sure what is set up | Run `app personal doctor`. It reads no keyring and uses no network. |
9
+ | `app` is not found | Open a new terminal, and check that npm's global folder is on `PATH`. |
10
+ | "name a profile" | Put the profile first, as in `app personal config show`, or set `APP_PROFILE`. |
11
+ | The settings file does not read | `doctor` names the file and the error. Fix it, or move it away and set the values again. |
12
+ | A write is refused | The profile's permissions or `APP_READ_ONLY` stop it; see [settings](configuration.md#permissions). |
13
+
14
+ Never paste a token, a password or private content into a support request.
package/docs/usage.md ADDED
@@ -0,0 +1,31 @@
1
+ # Use it
2
+
3
+ This page explains how a command is built, and how an agent uses the tool. Read it before your first command.
4
+
5
+ ## The profile comes first
6
+
7
+ A profile is a name you choose for one account. It is the first word of every command that uses an account:
8
+
9
+ ```sh
10
+ app personal config show
11
+ ```
12
+
13
+ `APP_PROFILE=personal` does the same for one shell session. No profile is ever assumed, not even the only one: a
14
+ command without one stops with exit code 2 and lists the profiles on this computer.
15
+
16
+ ## Output for scripts
17
+
18
+ Every command takes `--json`, and prints one JSON value on stdout. Errors are JSON on stderr, with a code to branch
19
+ on. The [command reference](commands.md) lists the codes.
20
+
21
+ ## Agents
22
+
23
+ `app skill install` puts the tool's skill where Claude Code, Codex and Gemini CLI look for it. `app personal mcp`
24
+ serves the profile's commands over MCP, on stdin and stdout:
25
+
26
+ ```sh
27
+ claude mcp add app -- app personal mcp
28
+ ```
29
+
30
+ The server offers every command, the ones that write included. The profile's permissions decide what runs; see
31
+ [settings](configuration.md#permissions).
package/gitignore ADDED
@@ -0,0 +1,44 @@
1
+ node_modules/
2
+ dist/
3
+ coverage/
4
+ *.tsbuildinfo
5
+ *.log
6
+ .DS_Store
7
+
8
+ # The working trail, kept on the machine doing the work: plans, the journal, the handoff.
9
+ /docs_ai/
10
+ /HANDOFF.md
11
+ .claude/settings.local.json
12
+ .rumdl_cache/
13
+
14
+ # Worktrees, when kept inside the main checkout: each a checkout of its own, never part of this one.
15
+ /.worktrees/
16
+
17
+ # What the Bash sandbox lays over these names in the working folder (character devices and empty
18
+ # folders, never on disk): without this, `git add -A` inside the sandbox fails on them.
19
+ /.bash_profile
20
+ /.bashrc
21
+ /.profile
22
+ /.zprofile
23
+ /.zshrc
24
+ /.gitconfig
25
+ /.gitmodules
26
+ /.ripgreprc
27
+ /.mcp.json
28
+ /.idea
29
+ /.vscode
30
+ /.claude/.cc-writes
31
+ /.claude/agents
32
+ /.claude/commands
33
+ /.claude/launch.json
34
+ /.claude/loop.md
35
+ /.claude/output-styles
36
+ /.claude/skills
37
+ /.claude/routines
38
+ /.claude/scheduled_tasks.json
39
+ /.claude/workflows
40
+
41
+ *.tgz
42
+ # The package's copy of this file, made by kit:build.
43
+ /gitignore
44
+ /CLEANUP.md