@wirecat/cli-base 0.55.0 → 0.55.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.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,21 @@ 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.55.1 — 25.10.2026
12
+
13
+ ### Fixed
14
+
15
+ - **`WC-ARCH-21` names the call that exists** ([Architecture](docs/standards/architecture.md)): a CLI registers its provider with `store.accounts.registerProvider(entry)`. The rule named a `registerProvider` import from `@wirecat/cli-core/store`, which cli-core 0.421.0 does not export.
16
+
17
+ - **`cli-dev changelog restore` no longer stops a release when the newest tag has no section of its own**
18
+ ([releases standard](docs/standards/releases.md#wc-rel-15--fold-a-late-pending-section-into-the-unpublished-version-before-publishing)).
19
+ A raise that renamed the previous section instead of dating `## Unreleased` leaves a tag whose changelog has no
20
+ `## <version> — ` heading, and the command threw on every later `bin/release`. Nothing was released under that
21
+ heading, so there is nothing to restore: the command now prints why on stderr and changes nothing.
22
+ `restoreReleased` from `@wirecat/cli-base/release` returns `undefined` in that case instead of throwing; a
23
+ changelog with no section for the tagged version still throws. A CLI that skipped the restore for this case can
24
+ drop the skip and pin this version.
25
+
11
26
  ## 0.55.0 — 25.10.2026
12
27
 
13
28
  ### Added
package/dist/dev/main.js CHANGED
@@ -10,6 +10,7 @@ import { parseArgs } from "node:util";
10
10
  import spawn from "cross-spawn";
11
11
  import * as v from "valibot";
12
12
  import { parseCommandsDocument } from "../commands/document.js";
13
+ import { taggedSection } from "../release/fold.js";
13
14
  import { changelogProblems, docsProblems, JOURNAL_IDS, markdownFiles, packageVersion, structureProblems, versionScript, } from "../release/index.js";
14
15
  import { AUDIT_BLOCKS, defineParityGroups, PARITY_GROUPS, REQUIRED_ROOTS } from "../standards/audit.js";
15
16
  import { defineReasons } from "../standards/errors.js";
@@ -123,6 +124,10 @@ const changelog = (args, io) => {
123
124
  if (action === "restore") {
124
125
  const shell = processShell(io.cwd);
125
126
  const tag = newestTag(shell, relative(io.cwd, file));
127
+ if (!taggedSection(tag.text, tag.version)) {
128
+ io.err(`v${tag.version}'s changelog has no section of its own; nothing to restore`);
129
+ return 0;
130
+ }
126
131
  const change = (text) => restoreChange(text, tag.text, tag.version, values.unreleased);
127
132
  if (values.land) {
128
133
  const landed = landChange({
@@ -13,12 +13,15 @@ export declare const foldUnreleased: (text: string, version: string, unreleased?
13
13
  * when no heading repeats there. The caller makes sure the version is not on npm.
14
14
  */
15
15
  export declare const mergeRepeatedHeadings: (text: string, version: string) => string | undefined;
16
+ /** The `## <version> — ` section of a changelog, or `undefined` when it has none. */
17
+ export declare const taggedSection: (text: string, version: string) => string | undefined;
16
18
  /**
17
19
  * Puts the section of `version`, the newest tagged one, back to its text in that tag. A pull request
18
20
  * checked before the version was dated or tagged and merged after it adds its entry there with no
19
21
  * guard to see it, though that code ships only in the next version: each such entry moves to the unreleased
20
22
  * section, after its entries under the same `###` heading. `undefined` when the section matches the tag the
21
- * way the changelog guard compares them.
23
+ * way the changelog guard compares them, or when the tag's changelog has no section for `version`: nothing was
24
+ * released under that heading, so there is nothing to restore.
22
25
  */
23
26
  export declare const restoreReleased: (text: string, tagText: string, version: string, unreleased?: string) => {
24
27
  text: string;
@@ -85,18 +85,21 @@ const entries = (section) => [...section.headings].flatMap(([heading, lines]) =>
85
85
  }
86
86
  return found;
87
87
  });
88
+ /** The `## <version> — ` section of a changelog, or `undefined` when it has none. */
89
+ export const taggedSection = (text, version) => text.split(/\n(?=## )/).find((block) => block.startsWith(`## ${version} — `));
88
90
  /**
89
91
  * Puts the section of `version`, the newest tagged one, back to its text in that tag. A pull request
90
92
  * checked before the version was dated or tagged and merged after it adds its entry there with no
91
93
  * guard to see it, though that code ships only in the next version: each such entry moves to the unreleased
92
94
  * section, after its entries under the same `###` heading. `undefined` when the section matches the tag the
93
- * way the changelog guard compares them.
95
+ * way the changelog guard compares them, or when the tag's changelog has no section for `version`: nothing was
96
+ * released under that heading, so there is nothing to restore.
94
97
  */
95
98
  export const restoreReleased = (text, tagText, version, unreleased = "Unreleased") => {
96
99
  const dated = (block) => block.startsWith(`## ${version} — `);
97
- const tagged = tagText.split(/\n(?=## )/).find(dated);
100
+ const tagged = taggedSection(tagText, version);
98
101
  if (!tagged)
99
- throw new Error(`the v${version} tag's changelog has no "## ${version} — " section`);
102
+ return undefined;
100
103
  const blocks = text.split(/\n(?=## )/);
101
104
  const index = blocks.findIndex(dated);
102
105
  if (index < 0)
@@ -206,8 +206,8 @@ at start-up and the `serve` relay are in [Lifecycle](lifecycle.md); the store's
206
206
 
207
207
  ### WC-ARCH-21 · A CLI registers its provider in the store; an unknown provider's rows are skipped, never guessed
208
208
 
209
- Every run, a CLI writes its provider's entry — `{ name, kind, aliases, command }` — with `registerProvider` from
210
- `@wirecat/cli-core/store`. cli-core reads its built-in providers plus the stored entries when the store opens, so
209
+ Every run, a CLI writes its provider's entry — `{ name, kind, aliases, command }` — with
210
+ `store.accounts.registerProvider(entry)` on the store from `openStore()` (`@wirecat/cli-core/store`). cli-core reads its built-in providers plus the stored entries when the store opens, so
211
211
  every other CLI knows the new provider's kind without a cli-core release. A row whose provider no entry names is left
212
212
  out of search and listed under `skipped`, with the hint to run that CLI once.
213
213
 
@@ -173,7 +173,9 @@ on the [CI](ci.md) page.
173
173
  section, through a pull request. Then, while npm does not have the version, `bin/release` runs
174
174
  `cli-dev changelog fold --land --version <x.y.z>`. It folds the pending section into the dated one, and merges any
175
175
  repeated `###` heading, through a pull request.
176
- - **Exceptions:** only the newest tag is compared; an older section that differs from its tag stays as it is.
176
+ - **Exceptions:** only the newest tag is compared; an older section that differs from its tag stays as it is. A
177
+ newest tag whose changelog has no section of its own has nothing to restore: the command says so and changes
178
+ nothing.
177
179
  - **Applies to:** all CLIs and shared libraries. **Since:** cli-base 0.41.0. **Rulings:** none.
178
180
 
179
181
  ### WC-REL-16 · The package ships only the files it names
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-base",
3
- "version": "0.55.0",
3
+ "version": "0.55.1",
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",