@wirecat/cli-template 0.9.0 → 0.10.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.
Files changed (110) hide show
  1. package/.github/workflows/ci.yml +1 -0
  2. package/.github/workflows/release.yml +63 -0
  3. package/CHANGELOG.md +42 -1
  4. package/bin/release +5 -3
  5. package/dist/bin/clidev.js +34 -12
  6. package/dist/bundle/all-profiles-XHC7BG3P.js +24 -0
  7. package/dist/bundle/anthropic-N6B3ZZHQ.js +70 -0
  8. package/dist/bundle/bun-HUJLS7KP.js +169 -0
  9. package/dist/bundle/bun-sqlite-OWFO2TVR.js +69 -0
  10. package/dist/bundle/chunk-222FANS2.js +161 -0
  11. package/dist/bundle/chunk-2CFBHYFA.js +884 -0
  12. package/dist/bundle/chunk-2KQZ24GI.js +82 -0
  13. package/dist/bundle/chunk-2TBVT4SZ.js +31 -0
  14. package/dist/bundle/chunk-437W3Z2M.js +76 -0
  15. package/dist/bundle/chunk-4QRLPOJ7.js +18 -0
  16. package/dist/bundle/chunk-54AJONOM.js +54 -0
  17. package/dist/bundle/chunk-5D4AEUVA.js +24783 -0
  18. package/dist/bundle/chunk-6CBWO7OF.js +73 -0
  19. package/dist/bundle/chunk-75LVQQEK.js +35782 -0
  20. package/dist/bundle/chunk-7RB76E2L.js +264 -0
  21. package/dist/bundle/chunk-7RXBN7HP.js +63 -0
  22. package/dist/bundle/chunk-ABP7FDMJ.js +122 -0
  23. package/dist/bundle/chunk-ADLS6FVG.js +24600 -0
  24. package/dist/bundle/chunk-AP7QKYBG.js +3531 -0
  25. package/dist/bundle/chunk-ASMH7JWZ.js +288 -0
  26. package/dist/bundle/chunk-B4EED2RF.js +100 -0
  27. package/dist/bundle/chunk-B4LM2B6F.js +1900 -0
  28. package/dist/bundle/chunk-BDSDQCV4.js +281 -0
  29. package/dist/bundle/chunk-DFDN6AUB.js +21 -0
  30. package/dist/bundle/chunk-DMCN22H6.js +35 -0
  31. package/dist/bundle/chunk-E42W72PQ.js +151 -0
  32. package/dist/bundle/chunk-EFHLQXG6.js +5104 -0
  33. package/dist/bundle/chunk-FIHDGZIB.js +34352 -0
  34. package/dist/bundle/chunk-FWVKHD2L.js +48 -0
  35. package/dist/bundle/chunk-FXS3X76A.js +193 -0
  36. package/dist/bundle/chunk-HTQTIKWP.js +928 -0
  37. package/dist/bundle/chunk-IJ3IA7EK.js +24 -0
  38. package/dist/bundle/chunk-JEBSORH7.js +3379 -0
  39. package/dist/bundle/chunk-JTTW5ZKF.js +45 -0
  40. package/dist/bundle/chunk-LSEF4QC3.js +3075 -0
  41. package/dist/bundle/chunk-LY7GS2YI.js +58 -0
  42. package/dist/bundle/chunk-MFS52LTZ.js +570 -0
  43. package/dist/bundle/chunk-MNSD5BX2.js +78 -0
  44. package/dist/bundle/chunk-MTGLJCAZ.js +24 -0
  45. package/dist/bundle/chunk-MZVV2JZT.js +744 -0
  46. package/dist/bundle/chunk-NE3NSB5O.js +8341 -0
  47. package/dist/bundle/chunk-NTLPDH76.js +440 -0
  48. package/dist/bundle/chunk-O3PBQVAB.js +447 -0
  49. package/dist/bundle/chunk-O5EHUB2V.js +2 -0
  50. package/dist/bundle/chunk-O5LMDQTO.js +82 -0
  51. package/dist/bundle/chunk-OPJ24VGH.js +1028 -0
  52. package/dist/bundle/chunk-OPPMGPFW.js +164 -0
  53. package/dist/bundle/chunk-QGNNMPUB.js +158 -0
  54. package/dist/bundle/chunk-QVJLOUQB.js +2 -0
  55. package/dist/bundle/chunk-S57AMKLX.js +6848 -0
  56. package/dist/bundle/chunk-TARN7CHN.js +215 -0
  57. package/dist/bundle/chunk-TJLGI3N6.js +1095 -0
  58. package/dist/bundle/chunk-VMTM46FH.js +7532 -0
  59. package/dist/bundle/chunk-W2IDKBNB.js +2315 -0
  60. package/dist/bundle/chunk-XFXBXQBS.js +630 -0
  61. package/dist/bundle/chunk-Y5E2WNWB.js +35 -0
  62. package/dist/bundle/chunk-ZVVMGPBJ.js +50 -0
  63. package/dist/bundle/clidev.js +22 -0
  64. package/dist/bundle/command-contract-PEM3S634.js +29 -0
  65. package/dist/bundle/dist-ESHIQU4M.js +7577 -0
  66. package/dist/bundle/echarts-2QGL2JP5.js +42501 -0
  67. package/dist/bundle/embed-HHAAGHA6.js +35 -0
  68. package/dist/bundle/embedder-W2OGVVYH.js +108 -0
  69. package/dist/bundle/first-run-WCJUDUBU.js +23 -0
  70. package/dist/bundle/first-screen-U4DFUKUC.js +27 -0
  71. package/dist/bundle/instructions-OTZHT6NV.js +9 -0
  72. package/dist/bundle/mcp-OQBZXELQ.js +165 -0
  73. package/dist/bundle/mcp-VVF6J7SQ.js +151 -0
  74. package/dist/bundle/mcp-Y7VCIZ2J.js +78 -0
  75. package/dist/bundle/node-P4E63KXA.js +2340 -0
  76. package/dist/bundle/node-SYD4GX5O.js +176 -0
  77. package/dist/bundle/node-TLZSIHIJ.js +21 -0
  78. package/dist/bundle/node-sqlite-X2DGRFOZ.js +45 -0
  79. package/dist/bundle/oauth-42M34GQ5.js +17 -0
  80. package/dist/bundle/open-SWXRCDLN.js +19 -0
  81. package/dist/bundle/process-KAFGXZ7Q.js +91 -0
  82. package/dist/bundle/program-EHR4G7VN.js +16967 -0
  83. package/dist/bundle/prompt-ZQTMHRGX.js +12 -0
  84. package/dist/bundle/recognize-TTED4SE3.js +190 -0
  85. package/dist/bundle/remote-C37XJ4BP.js +26 -0
  86. package/dist/bundle/rerank-APFZAMQL.js +49 -0
  87. package/dist/bundle/serve-DDPIHDVZ.js +19 -0
  88. package/dist/bundle/server-L5GNG7KC.js +793 -0
  89. package/dist/bundle/server-LKVYA2AE.js +39 -0
  90. package/dist/bundle/state-WWPPHERF.js +33 -0
  91. package/dist/bundle/store-H6UIA4PK.js +120 -0
  92. package/dist/bundle/store-maintenance-command-EYBT64A2.js +40 -0
  93. package/dist/version.d.ts +1 -1
  94. package/dist/version.d.ts.map +1 -1
  95. package/dist/version.js +1 -1
  96. package/dist/version.js.map +1 -1
  97. package/docs/commands.md +9 -13
  98. package/docs/dev/TESTING.md +8 -0
  99. package/docs/dev/reference-clis.md +7 -5
  100. package/docs/dev/skills/release/SKILL.md +9 -6
  101. package/docs/dev/skills/release/fresh-audit.md +4 -0
  102. package/kit/dist/new.js +1 -0
  103. package/package.json +7 -5
  104. package/scripts/audit.sh +3 -2
  105. package/scripts/smoke-bundle.ts +63 -0
  106. package/scripts/version-level.test.ts +17 -1
  107. package/scripts/version-level.ts +35 -7
  108. package/skills/clidev-cli/SKILL.md +8 -0
  109. package/src/version.ts +1 -1
  110. package/lint/baseline/unknown-verb.json +0 -1
@@ -0,0 +1,39 @@
1
+ import { createRequire as __bundleRequire } from "node:module";
2
+ const require = __bundleRequire(import.meta.url);
3
+ import {
4
+ createBotServer,
5
+ serveBotOverStdio
6
+ } from "./chunk-QGNNMPUB.js";
7
+ import "./chunk-IJ3IA7EK.js";
8
+ import "./chunk-JEBSORH7.js";
9
+ import "./chunk-MZVV2JZT.js";
10
+ import "./chunk-XFXBXQBS.js";
11
+ import "./chunk-FIHDGZIB.js";
12
+ import "./chunk-O5LMDQTO.js";
13
+ import "./chunk-E42W72PQ.js";
14
+ import "./chunk-MFS52LTZ.js";
15
+ import "./chunk-5D4AEUVA.js";
16
+ import "./chunk-75LVQQEK.js";
17
+ import "./chunk-W2IDKBNB.js";
18
+ import "./chunk-ABP7FDMJ.js";
19
+ import "./chunk-JTTW5ZKF.js";
20
+ import "./chunk-AP7QKYBG.js";
21
+ import "./chunk-VMTM46FH.js";
22
+ import "./chunk-NTLPDH76.js";
23
+ import "./chunk-54AJONOM.js";
24
+ import "./chunk-7RXBN7HP.js";
25
+ import "./chunk-LSEF4QC3.js";
26
+ import "./chunk-O5EHUB2V.js";
27
+ import "./chunk-2CFBHYFA.js";
28
+ import "./chunk-OPJ24VGH.js";
29
+ import "./chunk-7RB76E2L.js";
30
+ import "./chunk-4QRLPOJ7.js";
31
+ import "./chunk-B4EED2RF.js";
32
+ import "./chunk-EFHLQXG6.js";
33
+ import "./chunk-Y5E2WNWB.js";
34
+ import "./chunk-S57AMKLX.js";
35
+ import "./chunk-ZVVMGPBJ.js";
36
+ export {
37
+ createBotServer,
38
+ serveBotOverStdio
39
+ };
@@ -0,0 +1,33 @@
1
+ import { createRequire as __bundleRequire } from "node:module";
2
+ const require = __bundleRequire(import.meta.url);
3
+ import {
4
+ ACCESS_SECONDS,
5
+ REFRESH_SECONDS,
6
+ httpLaunchFile,
7
+ httpLock,
8
+ httpLockFile,
9
+ httpLogFile,
10
+ mcpHttpMarker,
11
+ readHttpLaunch,
12
+ readHttpLock,
13
+ readStored,
14
+ signedInClients
15
+ } from "./chunk-222FANS2.js";
16
+ import "./chunk-6CBWO7OF.js";
17
+ import "./chunk-7RXBN7HP.js";
18
+ import "./chunk-EFHLQXG6.js";
19
+ import "./chunk-Y5E2WNWB.js";
20
+ import "./chunk-ZVVMGPBJ.js";
21
+ export {
22
+ ACCESS_SECONDS,
23
+ REFRESH_SECONDS,
24
+ httpLaunchFile,
25
+ httpLock,
26
+ httpLockFile,
27
+ httpLogFile,
28
+ mcpHttpMarker,
29
+ readHttpLaunch,
30
+ readHttpLock,
31
+ readStored,
32
+ signedInClients
33
+ };
@@ -0,0 +1,120 @@
1
+ import { createRequire as __bundleRequire } from "node:module";
2
+ const require = __bundleRequire(import.meta.url);
3
+ import {
4
+ AGENDA_COLUMNS,
5
+ BACKFILL_ON_OPEN,
6
+ CHAT_COLUMNS,
7
+ CHAT_LIST_KEY,
8
+ CONVERSATION_COLUMNS,
9
+ DEFAULT_AGENT_CLOSE,
10
+ DEFAULT_FIRST_PASS_PER_CHAT,
11
+ MENTION_QUERY,
12
+ MENTION_STATUSES,
13
+ OTHER_SOURCES,
14
+ TRACKED_CHAT_COLUMNS,
15
+ accountGroupsOf,
16
+ attachmentColumns,
17
+ drainNoteIndex,
18
+ dropAllUnusedVectors,
19
+ fetchedKey,
20
+ fileFacts,
21
+ fillSearchIndex,
22
+ fillStems,
23
+ firstPassPerChatOf,
24
+ historyStartKey,
25
+ inboxKey,
26
+ involvementStoreOver,
27
+ messageOfEmail,
28
+ noteIndexState,
29
+ openSqlite,
30
+ openStore,
31
+ orphanPointers,
32
+ pendingNormalization,
33
+ queryFilter,
34
+ readStoreTables,
35
+ registerProvider,
36
+ resetAttachmentWords,
37
+ resetNoteIndex,
38
+ resetSearchIndex,
39
+ resetStems,
40
+ rowCounts,
41
+ saveStorePhoneCountries,
42
+ savedAgentClose,
43
+ savedFirstPassPerChat,
44
+ savedPhoneCountries,
45
+ savedStemmers,
46
+ savedTaskCategories,
47
+ searchIndexState,
48
+ stemmerCache,
49
+ stemmersOrigin,
50
+ stemsState,
51
+ storeClients,
52
+ storeContents,
53
+ threadConversation,
54
+ titlePart,
55
+ vectorIndexCounts
56
+ } from "./chunk-75LVQQEK.js";
57
+ import "./chunk-W2IDKBNB.js";
58
+ import "./chunk-LSEF4QC3.js";
59
+ import "./chunk-O5EHUB2V.js";
60
+ import "./chunk-2CFBHYFA.js";
61
+ import "./chunk-4QRLPOJ7.js";
62
+ import "./chunk-B4EED2RF.js";
63
+ import "./chunk-EFHLQXG6.js";
64
+ import "./chunk-Y5E2WNWB.js";
65
+ import "./chunk-S57AMKLX.js";
66
+ import "./chunk-ZVVMGPBJ.js";
67
+ export {
68
+ AGENDA_COLUMNS,
69
+ BACKFILL_ON_OPEN,
70
+ CHAT_COLUMNS,
71
+ CHAT_LIST_KEY,
72
+ CONVERSATION_COLUMNS,
73
+ DEFAULT_AGENT_CLOSE,
74
+ DEFAULT_FIRST_PASS_PER_CHAT,
75
+ MENTION_QUERY,
76
+ MENTION_STATUSES,
77
+ OTHER_SOURCES,
78
+ TRACKED_CHAT_COLUMNS,
79
+ accountGroupsOf,
80
+ attachmentColumns,
81
+ drainNoteIndex,
82
+ dropAllUnusedVectors,
83
+ fetchedKey,
84
+ fileFacts,
85
+ fillSearchIndex,
86
+ fillStems,
87
+ firstPassPerChatOf,
88
+ historyStartKey,
89
+ inboxKey,
90
+ involvementStoreOver,
91
+ messageOfEmail,
92
+ noteIndexState,
93
+ openSqlite,
94
+ openStore,
95
+ orphanPointers,
96
+ pendingNormalization,
97
+ queryFilter,
98
+ readStoreTables,
99
+ registerProvider,
100
+ resetAttachmentWords,
101
+ resetNoteIndex,
102
+ resetSearchIndex,
103
+ resetStems,
104
+ rowCounts,
105
+ saveStorePhoneCountries,
106
+ savedAgentClose,
107
+ savedFirstPassPerChat,
108
+ savedPhoneCountries,
109
+ savedStemmers,
110
+ savedTaskCategories,
111
+ searchIndexState,
112
+ stemmerCache,
113
+ stemmersOrigin,
114
+ stemsState,
115
+ storeClients,
116
+ storeContents,
117
+ threadConversation,
118
+ titlePart,
119
+ vectorIndexCounts
120
+ };
@@ -0,0 +1,40 @@
1
+ import { createRequire as __bundleRequire } from "node:module";
2
+ const require = __bundleRequire(import.meta.url);
3
+ import {
4
+ buildStems,
5
+ storeMaintenanceCommands,
6
+ storeSummary
7
+ } from "./chunk-NE3NSB5O.js";
8
+ import "./chunk-B4LM2B6F.js";
9
+ import "./chunk-FIHDGZIB.js";
10
+ import "./chunk-2KQZ24GI.js";
11
+ import "./chunk-O5LMDQTO.js";
12
+ import "./chunk-HTQTIKWP.js";
13
+ import "./chunk-E42W72PQ.js";
14
+ import "./chunk-MFS52LTZ.js";
15
+ import "./chunk-6CBWO7OF.js";
16
+ import "./chunk-75LVQQEK.js";
17
+ import "./chunk-W2IDKBNB.js";
18
+ import "./chunk-ABP7FDMJ.js";
19
+ import "./chunk-2TBVT4SZ.js";
20
+ import "./chunk-JTTW5ZKF.js";
21
+ import "./chunk-VMTM46FH.js";
22
+ import "./chunk-NTLPDH76.js";
23
+ import "./chunk-54AJONOM.js";
24
+ import "./chunk-7RXBN7HP.js";
25
+ import "./chunk-LSEF4QC3.js";
26
+ import "./chunk-O5EHUB2V.js";
27
+ import "./chunk-2CFBHYFA.js";
28
+ import "./chunk-OPJ24VGH.js";
29
+ import "./chunk-7RB76E2L.js";
30
+ import "./chunk-4QRLPOJ7.js";
31
+ import "./chunk-B4EED2RF.js";
32
+ import "./chunk-EFHLQXG6.js";
33
+ import "./chunk-Y5E2WNWB.js";
34
+ import "./chunk-S57AMKLX.js";
35
+ import "./chunk-ZVVMGPBJ.js";
36
+ export {
37
+ buildStems,
38
+ storeMaintenanceCommands,
39
+ storeSummary
40
+ };
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.9.0";
1
+ export declare const VERSION = "0.10.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAA"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAA"}
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "0.9.0";
1
+ export const VERSION = "0.10.0";
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAA"}
package/docs/commands.md CHANGED
@@ -29,8 +29,8 @@ lists the profiles on this computer.
29
29
  | `--full` | found items with their whole text and every provider field. |
30
30
  | `--dry-run` | preview parsed arguments and permissions before running the action. |
31
31
  | `--yes` | go ahead without the question an ask level puts before a write. |
32
- | `--record` | keep this run, with the command as typed and secrets hidden; record_input false leaves the typed words out. |
33
- | `--no-record` | do not keep it, whatever the configuration says. |
32
+ | `--record` | keep this run even where the config says record false; record_input false leaves the typed words out. |
33
+ | `--no-record` | do not keep this run, even if it fails. |
34
34
 
35
35
  ## `clidev commands`
36
36
 
@@ -70,23 +70,19 @@ the instructions an agent is given for this tool
70
70
 
71
71
  ### `clidev skill show`
72
72
 
73
- print SKILL.md — `clidev skill install` puts it where Claude Code, Codex and Gemini CLI look for it; --for prints the copy already there
73
+ print SKILL.md — `clidev skill install` puts it where Claude Code, Codex, Gemini CLI and OpenClaw look for it, and where Hermes does on request; --for prints the copy already there
74
74
 
75
75
  ```sh
76
- clidev skill show [name] [options]
76
+ clidev skill show [options]
77
77
  ```
78
78
 
79
- | Argument | | What it is |
80
- |---|---|---|
81
- | `name` | optional | one of the skills shipped for a task: follow-ups, link-conversations. |
82
-
83
79
  | Option | What it does |
84
80
  |---|---|
85
81
  | `--for <agents>` | print the copy installed for these agents instead of this version's. One of: `claude`, `agents`. |
86
82
 
87
83
  **Returns:** print the tool's instructions for AI agents
88
84
 
89
- **Example:** `clidev skill show`, `clidev skill show follow-ups`
85
+ **Example:** `clidev skill show`
90
86
 
91
87
  ### `clidev skill install`
92
88
 
@@ -255,7 +251,7 @@ clidev config set <setting> <value> [options]
255
251
 
256
252
  | Argument | | What it is |
257
253
  |---|---|---|
258
- | `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>. |
254
+ | `setting` | required | one of: limit, timeout_ms, color, record, record_input, keep_runs_for_days, keep_successful_runs_for_days, runs_size_limit_mb, permissions, requests_per_minute, speech_model, picture_search, search_reranker, embedding_provider, embedding_model, embedding_base_url, embedding_dims, models, update_check, skill_hint, search_stemmers.cyrillic, search_stemmers.latin. |
259
255
  | `value` | required | a number, true or false; for a group tg:work,max:Alice,email:me@x. |
260
256
 
261
257
  | Option | What it does |
@@ -280,7 +276,7 @@ clidev config unset <setting> [options]
280
276
 
281
277
  | Argument | | What it is |
282
278
  |---|---|---|
283
- | `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>. |
279
+ | `setting` | required | one of: limit, timeout_ms, color, record, record_input, keep_runs_for_days, keep_successful_runs_for_days, runs_size_limit_mb, permissions, requests_per_minute, speech_model, picture_search, search_reranker, embedding_provider, embedding_model, embedding_base_url, embedding_dims, models, update_check, skill_hint, search_stemmers.cyrillic, search_stemmers.latin. |
284
280
 
285
281
  | Option | What it does |
286
282
  |---|---|
@@ -313,7 +309,7 @@ clidev runs list [query] [options]
313
309
  | `--limit <n>` | how many to show. Default: `20`. |
314
310
  | `--page <n>` | which page, starting at 1. Default: `1`. |
315
311
 
316
- **Returns:** run — run_id, command, started_at, status, cli_version, profile, completed_at, requests, and 20 more; every field: clidev commands info runs list
312
+ **Returns:** run — run_id, command, started_at, status, cli_version, profile, completed_at, requests, and 23 more; every field: clidev commands info runs list
317
313
 
318
314
  **Example:** `clidev personal runs list --limit 10`
319
315
 
@@ -333,7 +329,7 @@ clidev runs show <run-id> [options]
333
329
  |---|---|
334
330
  | `--problems` | only failed responses, warnings and crashes. |
335
331
 
336
- **Returns:** run details — run_id, command, started_at, status, cli_version, directory, event_count, events, and 19 more; every field: clidev commands info runs show
332
+ **Returns:** run details — run_id, command, started_at, status, cli_version, directory, event_count, events, and 22 more; every field: clidev commands info runs show
337
333
 
338
334
  **Example:** `clidev personal runs show run-101`
339
335
 
@@ -20,3 +20,11 @@ How the tests run, and what they never touch. The rules are the handbook's
20
20
  [drive-cli does](https://github.com/WireCatLabs/drive-cli/blob/150b105569a98fbd0d4b66349305ad84128adfda/package.json#L37), and remove the skip.
21
21
  - `pnpm smoke` installs the packed package into a temporary folder and runs it offline.
22
22
  - `pnpm audit:commands` audits the command tree beside the latest published WireCat CLIs.
23
+
24
+ ## The bundle a user installs
25
+
26
+ `pnpm build` compiles `src/` with `tsc`, then cli-base's `cli-dev bundle`
27
+ ([WC-LAY-10](https://github.com/WireCatLabs/cli-base/blob/main/docs/standards/layout.md))
28
+ bundles `dist/bin/clidev.js` into `dist/bundle/` and makes the bin a loader. The vitest suite runs
29
+ against `src/`, so `scripts/smoke-bundle.ts` is the proof the bundle works: `pnpm smoke:node` runs it
30
+ under Node and `pnpm smoke:bun` under Bun, both in CI.
@@ -7,13 +7,14 @@ the first question of the [design interview](skills/design-interview/SKILL.md):
7
7
  | --- | --- |
8
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
+ | calendar | [gcal-cli](https://github.com/WireCatLabs/gcal-cli) |
10
11
  | meetings | [zoom-cli](https://github.com/WireCatLabs/zoom-cli) |
11
12
  | notes | [cli-memo](https://github.com/WireCatLabs/cli-memo) |
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
+ | mail, 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
14
 
14
15
  A messenger CLI sets `messenger: true` in `src/identity.ts`, and `new --category messenger` writes it. Every other
15
16
  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
+ and senders, and `config` lists none of cli-core's messenger settings.
17
18
 
18
19
  cli-core keeps a provider registry (WC-ARCH-21). A CLI whose provider is not built into cli-core writes its entry on
19
20
  every run that opens the shared store: `await store.accounts.registerProvider({ name, kind, aliases, command })`, on the
@@ -21,10 +22,11 @@ store that `openStore` from `@wirecat/cli-core/store` returns
21
22
  ([`AccountsStore`](https://github.com/WireCatLabs/cli-core/blob/185718d3212cda9bb026e09809760979fe31a1e6/src/store/accounts.ts#L40-L41),
22
23
  cli-core 0.459.0). `@wirecat/cli-core/store` does not export a `registerProvider` function. `kind` is one of
23
24
  `messages`, `mail`, `notes`, `documents`, `meetings` or `events`. Until the CLI has run once on a computer, `search`
24
- there leaves its accounts out and lists them under `skipped`. Of the reference CLIs, none makes this call: cli-core
25
- already knows their providers, from its
25
+ there leaves its accounts out and lists them under `skipped`. Of the reference CLIs, only gcal-cli makes this call: cli-core
26
+ already knows the others' providers, from its
26
27
  [seed list](https://github.com/WireCatLabs/cli-core/blob/185718d3212cda9bb026e09809760979fe31a1e6/src/domain/providers.ts#L17-L29)
27
28
  and, for Drive, its
28
29
  [document providers](https://github.com/WireCatLabs/cli-core/blob/185718d3212cda9bb026e09809760979fe31a1e6/src/domain/providers.ts#L50).
29
- [gcal-cli](https://github.com/WireCatLabs/gcal-cli/blob/14e27c45e6dc204cde8adcd9e4fa6aa069745335/src/store.ts) does. The skeleton opens no store and
30
+ [gcal-cli](https://github.com/WireCatLabs/gcal-cli/blob/14e27c45e6dc204cde8adcd9e4fa6aa069745335/src/store.ts) registers
31
+ its own. The skeleton opens no store and
30
32
  has no provider, so it registers nothing; the call comes with the CLI's first store code.
@@ -1,13 +1,13 @@
1
1
  ---
2
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, «выпуск», «выпустить версию».
3
+ description: Release this CLI — run release:check, write the changelog under the handbook's headings, check the docs against what changed, raise the version in a pull request, merge it and publish with bin/release from GitHub Actions. Use when asked to release, prepare a release, cut a version, «выпуск», «выпустить версию».
4
4
  ---
5
5
 
6
6
  # Release
7
7
 
8
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`.
9
+ (`WC-REL-<n>`), which wins over this skill. An agent prepares the release, merges the release pull request and runs
10
+ `bin/release`, which publishes from GitHub Actions. Only the first release is the owner's, from this computer.
11
11
 
12
12
  1. **What changed.** In a worktree off `origin/main`: `git log --oneline "$(git describe --tags --abbrev=0 origin/main)..origin/main"`. The
13
13
  `docs/commands.md` diff shows what a cli-core or cli-base release changed in the commands.
@@ -24,10 +24,13 @@ and runs `bin/release`.
24
24
  before `1.0.0` this narrows `WC-REL-7`: a section with `Changed — may break callers` or `Removed` raises the minor
25
25
  (`0.1.8` to `0.2.0`), and so does one with `Added`; only a section of `Fixed`, `Security` or docs raises the patch.
26
26
  From `1.0.0`, a breaking change raises the major. `pnpm version:check` refuses a dated section whose number is
27
- raised less than its headings need. Set the next version in `package.json`, run `pnpm version:sync`, date the
27
+ raised less than its headings need, and when `bin/release` moves to the next free number on npm it raises that
28
+ number to the level the headings need. Set the next version in `package.json`, run `pnpm version:sync`, date the
28
29
  section as `## <version> — DD.MM.YYYY`, run `pnpm release:check` again, and open the pull request
29
30
  `chore(release): <version>`.
30
- 7. **The owner** merges it and runs `bin/release` on a clean `main`. `bin/release --local` publishes from this
31
- computer when GitHub Actions cannot, with `NPM_TOKEN`, the npm token in the keyring, or the owner's own npm login.
31
+ 7. **The publish.** Merge it when its checks pass, then run `bin/release` on a clean `main`: it starts
32
+ `release.yml` and follows it (`WC-REL-11`). A messenger CLI also needs the owner's signed release report
33
+ (`WC-REL-10`). Never `bin/release --local`: that is the owner's, for the first release before npm trusts
34
+ `release.yml`, with `NPM_TOKEN`, the npm token in the keyring, or the owner's own npm login.
32
35
  The keyring is read only when `NPM_KEYRING_ACCOUNT` names the account the token is stored under (service `npm`);
33
36
  there is no default account. When that lookup fails, `bin/release` stops; it does not fall back to the npm login.
@@ -9,6 +9,10 @@ You audit a WireCat CLI repository, in the current folder. Use only three source
9
9
  `node_modules/@wirecat/cli-base/docs/standards/README.md`, the repository itself, and the cli-base workflow files its
10
10
  own workflows pin (WC-CI-8). Do not read plans, journals or earlier reviews. Run `pnpm install` first if `node_modules` is missing.
11
11
 
12
+ Never use the owner's accounts. Do not sign in, and run the built CLI only with every config, state and cache folder
13
+ moved to a temporary folder and `DBUS_SESSION_BUS_ADDRESS=disabled:`, so it cannot reach the system keyring (removing
14
+ the variable is not enough). Run no command that writes to a service: no `--yes`, no `api` call that changes data.
15
+
12
16
  Check the repository against every handbook page that applies to it: the code, the docs, the configs and the
13
17
  workflows. You may run the package scripts. Change nothing.
14
18
 
package/kit/dist/new.js CHANGED
@@ -10,6 +10,7 @@ const run = promisify(execFile);
10
10
  const REFERENCES = {
11
11
  messenger: ["whatsapp-cli", "tg-cli", "max-cli"],
12
12
  files: ["drive-cli"],
13
+ calendar: ["gcal-cli"],
13
14
  meetings: ["zoom-cli"],
14
15
  notes: ["cli-memo"],
15
16
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-template",
3
- "version": "0.9.0",
3
+ "version": "0.10.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",
@@ -50,7 +50,7 @@
50
50
  "gitignore"
51
51
  ],
52
52
  "scripts": {
53
- "build": "tsc --build --force && pnpm kit:build",
53
+ "build": "tsc --build --force && cli-dev bundle --bin dist/bin/clidev.js && pnpm kit:build",
54
54
  "typecheck": "tsc --build --force --emitDeclarationOnly && tsc -p tsconfig.test.json && tsc -p tsconfig.scripts.json && pnpm kit:typecheck",
55
55
  "lint": "biome check .",
56
56
  "lint:fix": "biome check --write .",
@@ -61,7 +61,8 @@
61
61
  "generate": "pnpm build && node --experimental-strip-types scripts/commands.ts",
62
62
  "generate:check": "pnpm build && node --experimental-strip-types scripts/commands.ts --check",
63
63
  "smoke": "node --experimental-strip-types scripts/smoke.ts",
64
- "smoke:bun": "bun scripts/smoke.ts",
64
+ "smoke:bun": "bun scripts/smoke.ts && bun scripts/smoke-bundle.ts",
65
+ "smoke:node": "node --experimental-strip-types scripts/smoke-bundle.ts",
65
66
  "package:check": "pnpm smoke",
66
67
  "docs:check": "cli-dev docs-check --rules scripts/docs-rules.ts --pages && pnpm docs:spell && rumdl check --config config/wirecat/rumdl.toml README.md SECURITY.md CHANGELOG.md CLAUDE.md AGENTS.md docs/*.md docs/dev/*.md && pnpm docs:lint && pnpm kit:docs",
67
68
  "docs:lint": "markdownlint-cli2",
@@ -84,8 +85,8 @@
84
85
  },
85
86
  "dependencies": {
86
87
  "@modelcontextprotocol/server": "2.4.0",
87
- "@wirecat/cli-base": "0.63.0",
88
- "@wirecat/cli-core": "0.463.0",
88
+ "@wirecat/cli-base": "0.65.0",
89
+ "@wirecat/cli-core": "0.469.0",
89
90
  "commander": "15.0.0"
90
91
  },
91
92
  "devDependencies": {
@@ -98,6 +99,7 @@
98
99
  "@vitest/coverage-v8": "5.0.5",
99
100
  "@wirecat/cli-testing": "0.5.3",
100
101
  "cspell": "10.4.0",
102
+ "esbuild": "0.28.2",
101
103
  "lefthook": "2.2.2",
102
104
  "markdownlint-cli2": "0.24.0",
103
105
  "rumdl": "0.3.0",
package/scripts/audit.sh CHANGED
@@ -11,12 +11,13 @@ trap 'rm -rf "$scratch"' EXIT
11
11
  export HOME="$scratch/home" MESSAGING_STORE="$scratch/store" WIRECAT_STATE_DIR="$scratch/state"
12
12
  mkdir -p "$HOME"
13
13
  npm install -g --prefix "$scratch/prefix" --ignore-scripts --no-audit --no-fund --loglevel error \
14
- @wirecat/tg-cli @wirecat/max-cli @wirecat/whatsapp-cli @wirecat/cli-memo @wirecat/drive-cli @wirecat/zoom-cli
14
+ @wirecat/tg-cli @wirecat/max-cli @wirecat/whatsapp-cli @wirecat/cli-memo @wirecat/drive-cli @wirecat/zoom-cli \
15
+ @wirecat/gcal-cli
15
16
  bin="$scratch/prefix/bin"
16
17
  others=()
17
18
  # A groups file replaces cli-base's PARITY_GROUPS. The template keeps one because it is in no group of cli-base's.
18
19
  [ -f "$root/config/parity-groups.json" ] && others+=(--groups "$root/config/parity-groups.json")
19
- for cli in tg max wa memo drive zm; do
20
+ for cli in tg max wa memo drive zm gcal; do
20
21
  [ "$cli" = "$command" ] || others+=(--cli "$bin/$cli")
21
22
  done
22
23
  "$root/node_modules/.bin/cli-dev" audit --cli "$root/dist/bin/$command.js" "${others[@]}" --for "$command" \
@@ -0,0 +1,63 @@
1
+ /**
2
+ * The published bin is a loader for `dist/bundle/` (cli-base's `cli-dev bundle`, WC-LAY-10). This runs it, with
3
+ * directories of its own, under Node (`pnpm smoke:node`) and Bun (`pnpm smoke:bun`): the vitest suite runs against
4
+ * `src/`, so this is the proof the bundle a user installs works.
5
+ *
6
+ * pnpm build && pnpm smoke:node
7
+ */
8
+ import { spawnSync } from "node:child_process"
9
+ import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs"
10
+ import { tmpdir } from "node:os"
11
+ import { join } from "node:path"
12
+
13
+ const COMMAND = "clidev"
14
+ const PREFIX = "CLIDEV"
15
+
16
+ const runtime = typeof (globalThis as { Bun?: unknown }).Bun === "undefined" ? "node" : "bun"
17
+ const failures: string[] = []
18
+ const check = (what: string, condition: boolean) => {
19
+ if (!condition) failures.push(what)
20
+ }
21
+
22
+ // Overridden directories also move the keyring entry, so nothing here reads the owner's accounts or store.
23
+ const isolated = mkdtempSync(join(tmpdir(), `${COMMAND}-bundle-smoke-`))
24
+ const run = (args: string[], env: Record<string, string> = {}) =>
25
+ spawnSync(process.execPath, [`dist/bin/${COMMAND}.js`, ...args], {
26
+ encoding: "utf8",
27
+ env: {
28
+ ...process.env,
29
+ [`${PREFIX}_CONFIG_DIR`]: join(isolated, "config"),
30
+ [`${PREFIX}_STATE_DIR`]: join(isolated, "state"),
31
+ [`${PREFIX}_CACHE_DIR`]: join(isolated, "cache"),
32
+ [`${PREFIX}_NO_UPDATE_CHECK`]: "1",
33
+ MESSAGING_STORE: join(isolated, "store.db"),
34
+ ...env,
35
+ },
36
+ })
37
+
38
+ const loader = readFileSync(`dist/bin/${COMMAND}.js`, "utf8")
39
+ check("the bin starts the bundle", loader.includes(`import("../bundle/${COMMAND}.js")`))
40
+ const preloaded = [...loader.matchAll(/"\.\.\/bundle\/([^"]+)"/g)].map(([, chunk]) => chunk ?? "")
41
+ check(
42
+ "a server preloads only chunks the bundle has",
43
+ preloaded.length > 1 && preloaded.every((chunk) => existsSync(join("dist/bundle", chunk))),
44
+ )
45
+
46
+ const version = run(["--version"])
47
+ check("--version prints a version and nothing else", /^\d+\.\d+\.\d+\n$/.test(version.stdout) && version.stderr === "")
48
+ const recorded = run(["--version"], { [`${PREFIX}_TEST_ARGV_LOG`]: join(isolated, "argv.jsonl") })
49
+ check("the loader's --version is the bundle's", recorded.stdout === version.stdout)
50
+ check("--help names the command", run(["--help"]).stdout.includes(`Usage: ${COMMAND}`))
51
+ check("skill show prints the SKILL.md the package ships", run(["skill", "show"]).stdout.startsWith("---"))
52
+ check(
53
+ "doctor finds the document readers",
54
+ run(["doctor", "--json"]).stdout.includes('"files":{"checked":true,"ok":true'),
55
+ )
56
+ rmSync(isolated, { recursive: true, force: true })
57
+
58
+ if (failures.length > 0) {
59
+ console.error(`${COMMAND} bundle smoke FAILED under ${runtime}:`)
60
+ for (const failure of failures) console.error(` - ${failure}`)
61
+ process.exit(1)
62
+ }
63
+ console.log(`${COMMAND} bundle smoke passed under ${runtime}`)
@@ -1,5 +1,5 @@
1
1
  import { expect, it } from "vitest"
2
- import { versionLevelProblem } from "./version-level.js"
2
+ import { nextVersion, versionLevelProblem } from "./version-level.js"
3
3
 
4
4
  const changelog = (version: string, headings: string[], previous = "0.1.8") =>
5
5
  [`## ${version} — 26.10.2026`, ...headings.flatMap((h) => [`### ${h}`, "- x"]), `## ${previous} — 25.10.2026`].join(
@@ -28,3 +28,19 @@ it("refuses a patch release that adds something", () => {
28
28
  it("checks nothing while the top section is Unreleased", () => {
29
29
  expect(versionLevelProblem("## Unreleased\n\n### Removed\n\n- x\n\n## 0.1.8 — 25.10.2026\n")).toBeUndefined()
30
30
  })
31
+
32
+ const unreleased = (headings: string[], previous = "0.1.1") =>
33
+ ["## Unreleased", ...headings.flatMap((h) => [`### ${h}`, "- x"]), `## ${previous} — 29.10.2026`].join("\n")
34
+
35
+ it.each([
36
+ [["Fixed"], "0.1.2", "0.1.2"],
37
+ [["Added"], "0.1.2", "0.2.0"],
38
+ [["Removed"], "0.1.2", "0.2.0"],
39
+ [["Added"], "0.3.1", "0.3.1"],
40
+ ])("raises the next free number for %j from %s to %s", (headings, next, expected) => {
41
+ expect(nextVersion(unreleased(headings), next)).toBe(expected)
42
+ })
43
+
44
+ it("raises a 1.x release that may break callers to the next major", () => {
45
+ expect(nextVersion(unreleased(["Changed — may break callers"], "1.4.2"), "1.4.3")).toBe("2.0.0")
46
+ })
@@ -21,13 +21,35 @@ const needed = (version: string, section: string): Level => {
21
21
  return /^### Added$/m.test(section) ? "minor" : "patch"
22
22
  }
23
23
 
24
+ const raise = (from: string, level: Level) => {
25
+ const [a = 0, b = 0, c = 0] = parse(from)
26
+ if (level === "major") return `${a + 1}.0.0`
27
+ return level === "minor" ? `${a}.${b + 1}.0` : `${a}.${b}.${c + 1}`
28
+ }
29
+
30
+ const later = (x: string, y: string) => {
31
+ const [a, b] = [parse(x), parse(y)]
32
+ const i = a.findIndex((n, k) => n !== b[k])
33
+ return i === -1 || (a[i] ?? 0) > (b[i] ?? 0) ? x : y
34
+ }
35
+
36
+ const sections = (changelog: string) => {
37
+ const [top, below] = [...changelog.matchAll(/^## (\S+).*$/gm)]
38
+ if (!top || !below?.[1]) return undefined
39
+ return { version: top[1], previous: below[1], section: changelog.slice(top.index, below.index) }
40
+ }
41
+
42
+ // The next free number on npm is a patch; the top section may need a minor or major over the version below it.
43
+ export const nextVersion = (changelog: string, next: string): string => {
44
+ const parts = sections(changelog)
45
+ if (!parts) return next
46
+ return later(next, raise(parts.previous, needed(next, parts.section)))
47
+ }
48
+
24
49
  export const versionLevelProblem = (changelog: string): string | undefined => {
25
- const headings = [...changelog.matchAll(/^## (\S+).*$/gm)]
26
- const [top, below] = headings
27
- const version = top?.[1]
28
- const previous = below?.[1]
29
- if (!top || !below || !version || !previous || !/^\d+\.\d+\.\d+$/.test(version)) return undefined
30
- const section = changelog.slice(top.index, below.index)
50
+ const parts = sections(changelog)
51
+ if (!parts?.version || !/^\d+\.\d+\.\d+$/.test(parts.version)) return undefined
52
+ const { version, previous, section } = parts
31
53
  const want = needed(version, section)
32
54
  const got = raised(previous, version)
33
55
  if (LEVELS.indexOf(got) >= LEVELS.indexOf(want)) return undefined
@@ -35,7 +57,13 @@ export const versionLevelProblem = (changelog: string): string | undefined => {
35
57
  }
36
58
 
37
59
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
38
- const problem = versionLevelProblem(readFileSync(resolve(import.meta.dirname, "../CHANGELOG.md"), "utf8"))
60
+ const changelog = readFileSync(resolve(import.meta.dirname, "../CHANGELOG.md"), "utf8")
61
+ const [flag, next] = process.argv.slice(2)
62
+ if (flag === "--next" && next) {
63
+ console.log(nextVersion(changelog, next))
64
+ process.exit(0)
65
+ }
66
+ const problem = versionLevelProblem(changelog)
39
67
  if (problem) {
40
68
  console.error(`${problem} (docs/dev/skills/release/SKILL.md, step 6)`)
41
69
  process.exit(1)