@takazudo/zudo-doc 5.18.2 → 5.19.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
@@ -4,6 +4,19 @@ All notable changes to `@takazudo/zudo-doc` are documented in this file.
4
4
 
5
5
  The format is based on Keep a Changelog, and release notes are generated from the changelog MDX pages.
6
6
 
7
+ ## [5.19.1] - 2026-09-08
8
+
9
+ ### Other Changes
10
+
11
+ - Updated the zfb peer and development dependency family to 2.16.0 (`47c149385`). The upstream release carries one bug fix: zfb's esbuild version-gate spawn (`ensure_binary_verified`) now retries on `ETXTBSY` through zfb-build's existing retry loop instead of a bare `.output()`, so a build no longer dies with `Text file busy (os error 26)` on the first exec of a binary a packaged zfb has only just written to a tempdir. `@takazudo/zfb-md-wasm` changes only its README — every shipped artifact keeps its 2.15.1 byte size — and no public API, export, config default, or engine requirement moves.
12
+ - Raised the `@takazudo/zdtp` peer floor to `^0.5.2` (`47c149385`). The upstream release is additive for this consumer: a stable `data-zdtp-action` attribute on the header actions, and a fix keying popover and header items by that action id instead of by display label. There is no storage-key or config-shape migration, and the vendored design-token-panel constants mirror stays conformant against the real `@takazudo/zdtp/constants` leaf.
13
+
14
+ ## [5.19.0] - 2026-09-07
15
+
16
+ ### Bug Fixes
17
+
18
+ - The `gen-z-index` and `gen-component-tokens` bins report a descriptive error instead of a raw Node stack trace. A missing input file now names the path and says which file it is, while `EACCES` / `EISDIR` keep their own message rather than collapsing into a misleading "not found", and a top-level handler prints the message to stderr and exits 1 for any deliberate throw. A non-`Error` throw prints its string form rather than a bare `undefined`. (83a4c6f7a, 134248eba)
19
+
7
20
  ## [5.18.2] - 2026-09-06
8
21
 
9
22
  ### Bug Fixes
@@ -45,6 +45,11 @@ const TOKENS_PATH = resolve(PKG_ROOT, "src/config/component-tokens.ts");
45
45
  const CONTENT_CSS_PATH = resolve(PKG_ROOT, "src/content.css");
46
46
  const FEATURES_CSS_PATH = resolve(PKG_ROOT, "src/features.css");
47
47
 
48
+ // Repo-relative label for TOKENS_PATH, matching the SURFACES table's relPath
49
+ // convention below — used only in the missing-file message so it never
50
+ // embeds this machine's absolute path.
51
+ const TOKENS_REL_PATH = "packages/zudo-doc/src/config/component-tokens.ts";
52
+
48
53
  // Default marker pair = the content-surface block. Kept under the original
49
54
  // names so buildBlock/replaceBlock default to the content block, preserving the
50
55
  // byte-identical content.css output (and the existing unit-test call sites).
@@ -259,10 +264,30 @@ export function replaceBlock(
259
264
  return css.slice(0, lineStart) + block + css.slice(lineEnd);
260
265
  }
261
266
 
267
+ /**
268
+ * Reads a package-owned file, translating a missing file into a message that
269
+ * names both which file (`label`) and its repo-relative path (`relPath`) —
270
+ * these paths are absolute constants (see TOKENS_PATH/SURFACES above), so the
271
+ * relative label is what keeps the message free of a machine-specific path.
272
+ * Only ENOENT is translated: EACCES/EISDIR etc. are real, distinct failures
273
+ * (a permissions problem or "that's a directory") that a "not found" message
274
+ * would misreport, so they propagate unchanged with Node's own message.
275
+ */
276
+ function readNamedFile(absPath, relPath, label) {
277
+ try {
278
+ return readFileSync(absPath, "utf8");
279
+ } catch (error) {
280
+ if (error.code === "ENOENT") {
281
+ throw new Error(`${label} file not found at ${relPath}`);
282
+ }
283
+ throw error;
284
+ }
285
+ }
286
+
262
287
  function main() {
263
288
  const check = process.argv.includes("--check");
264
289
 
265
- const tokensSrc = readFileSync(TOKENS_PATH, "utf8");
290
+ const tokensSrc = readNamedFile(TOKENS_PATH, TOKENS_REL_PATH, "tokens");
266
291
  const tokens = parseTokens(tokensSrc);
267
292
  const routes = routeBySurface(tokens);
268
293
 
@@ -277,7 +302,7 @@ function main() {
277
302
  `${target.surface}: ${surfaceTokens.length} token(s), ${selectorCount} selector(s)`,
278
303
  );
279
304
 
280
- const css = readFileSync(target.cssPath, "utf8");
305
+ const css = readNamedFile(target.cssPath, target.relPath, "css");
281
306
  const block = buildBlock(surfaceTokens, target.beginMarker, target.endMarker);
282
307
  const next = replaceBlock(
283
308
  css,
@@ -344,5 +369,21 @@ function isDirectInvocation() {
344
369
  }
345
370
 
346
371
  if (isDirectInvocation()) {
347
- process.exit(main());
372
+ // Turns any Error thrown by main() (the readNamedFile guard, the parser's
373
+ // loud-failure throws, or replaceBlock's missing-markers throw) into a
374
+ // single readable stderr line instead of a raw Node stack trace. This also
375
+ // hides the stack for a genuine *programming* error, not just a user-input
376
+ // one — an accepted CLI tradeoff, not an accident: the process still exits
377
+ // 1 and nothing is swallowed, but a future reader debugging an internal
378
+ // crash needs to call the exported `main()` directly (or temporarily
379
+ // remove this try/catch) to see the stack. Exit codes are unchanged:
380
+ // main()'s own return value (0 or 1) still flows through process.exit on
381
+ // the success path; only an uncaught throw is newly turned into exit(1)
382
+ // with a message.
383
+ try {
384
+ process.exit(main());
385
+ } catch (error) {
386
+ console.error(error instanceof Error ? error.message : String(error));
387
+ process.exit(1);
388
+ }
348
389
  }
@@ -1023,6 +1023,26 @@ export function buildMdTable(tiers, options = {}) {
1023
1023
  return lines.join("\n");
1024
1024
  }
1025
1025
 
1026
+ /**
1027
+ * Reads a user-supplied file, translating a missing file into a message that
1028
+ * names both which file (`label`) and where it looked (`asGivenPath` — the
1029
+ * as-given path, never the resolved absolute one, matching the convention
1030
+ * documented on `main()` below). Only ENOENT is translated: EACCES/EISDIR
1031
+ * etc. are real, distinct failures (a permissions problem or "that's a
1032
+ * directory") that a "not found" message would misreport, so they propagate
1033
+ * unchanged with Node's own message.
1034
+ */
1035
+ function readNamedFile(absPath, asGivenPath, label) {
1036
+ try {
1037
+ return readFileSync(absPath, "utf8");
1038
+ } catch (error) {
1039
+ if (error.code === "ENOENT") {
1040
+ throw new Error(`${label} file not found at ${asGivenPath}`);
1041
+ }
1042
+ throw error;
1043
+ }
1044
+ }
1045
+
1026
1046
  /**
1027
1047
  * CLI entrypoint. `argv` defaults to the real process argv (minus the node/
1028
1048
  * script prefix) so `isDirectInvocation()` below can call `main()` with no
@@ -1052,8 +1072,8 @@ export function main(argv = process.argv.slice(2)) {
1052
1072
  const tokensAbsPath = resolve(root, tokensPath);
1053
1073
  const cssAbsPath = resolve(root, cssPath);
1054
1074
 
1055
- const tokensSrc = readFileSync(tokensAbsPath, "utf8");
1056
- const css = readFileSync(cssAbsPath, "utf8");
1075
+ const tokensSrc = readNamedFile(tokensAbsPath, tokensPath, "tokens");
1076
+ const css = readNamedFile(cssAbsPath, cssPath, "css");
1057
1077
 
1058
1078
  const tiers = parseTiers(tokensSrc, tokensPath);
1059
1079
  const block = buildBlock(tiers, { tokensPath, cssPath, themeWrapper });
@@ -1064,7 +1084,7 @@ export function main(argv = process.argv.slice(2)) {
1064
1084
  let nextMd;
1065
1085
  if (mdTablePath !== undefined) {
1066
1086
  mdAbsPath = resolve(root, mdTablePath);
1067
- mdSrc = readFileSync(mdAbsPath, "utf8");
1087
+ mdSrc = readNamedFile(mdAbsPath, mdTablePath, "md-table");
1068
1088
  const mdBlock = buildMdTable(tiers, { tokensPath });
1069
1089
  nextMd = replaceBlock(
1070
1090
  mdSrc,
@@ -1141,5 +1161,20 @@ function isDirectInvocation() {
1141
1161
  }
1142
1162
 
1143
1163
  if (isDirectInvocation()) {
1144
- process.exit(main());
1164
+ // Turns any Error thrown by main() (there are ~17 deliberate `throw new
1165
+ // Error(...)` call sites above, plus the readNamedFile guard) into a single
1166
+ // readable stderr line instead of a raw Node stack trace. This also hides
1167
+ // the stack for a genuine *programming* error, not just a user-input one —
1168
+ // an accepted CLI tradeoff, not an accident: the process still exits 1 and
1169
+ // nothing is swallowed, but a future reader debugging an internal crash
1170
+ // needs to call the exported `main()` directly (or temporarily remove this
1171
+ // try/catch) to see the stack. Exit codes are unchanged: main()'s own
1172
+ // return value (0 or 1) still flows through process.exit on the success
1173
+ // path; only an uncaught throw is newly turned into exit(1) with a message.
1174
+ try {
1175
+ process.exit(main());
1176
+ } catch (error) {
1177
+ console.error(error instanceof Error ? error.message : String(error));
1178
+ process.exit(1);
1179
+ }
1145
1180
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takazudo/zudo-doc",
3
- "version": "5.18.2",
3
+ "version": "5.19.1",
4
4
  "type": "module",
5
5
  "description": "zudo-doc framework primitives layer that sits on top of zfb's engine — sidebar, theme, TOC, breadcrumb, layouts, head injection, View Transitions, SSR-skip wrappers (per ADR-003).",
6
6
  "license": "MIT",
@@ -667,10 +667,10 @@
667
667
  "CHANGELOG.md"
668
668
  ],
669
669
  "peerDependencies": {
670
- "@takazudo/zdtp": "^0.5.1",
671
- "@takazudo/zfb": "^2.15.1",
672
- "@takazudo/zfb-md-wasm": "^2.15.1",
673
- "@takazudo/zfb-runtime": "^2.15.1",
670
+ "@takazudo/zdtp": "^0.5.2",
671
+ "@takazudo/zfb": "^2.16.0",
672
+ "@takazudo/zfb-md-wasm": "^2.16.0",
673
+ "@takazudo/zfb-runtime": "^2.16.0",
674
674
  "@takazudo/zudo-doc-history-server": "^5.17.2",
675
675
  "diff": "^8.0.0",
676
676
  "katex": "^0.16.0",
@@ -706,9 +706,9 @@
706
706
  "yaml": "^2.9.0"
707
707
  },
708
708
  "devDependencies": {
709
- "@takazudo/zfb": "2.15.1",
710
- "@takazudo/zfb-md-wasm": "2.15.1",
711
- "@takazudo/zfb-runtime": "2.15.1",
709
+ "@takazudo/zfb": "2.16.0",
710
+ "@takazudo/zfb-md-wasm": "2.16.0",
711
+ "@takazudo/zfb-runtime": "2.16.0",
712
712
  "@types/fs-extra": "^11.0.4",
713
713
  "@types/minimist": "^1.2.5",
714
714
  "@types/node": "^25.3.5",
@@ -720,7 +720,7 @@
720
720
  "typescript": "^5.0.0",
721
721
  "vitest": "^4.1.0",
722
722
  "zod": "^4.3.6",
723
- "@takazudo/zudo-doc-history-server": "5.18.2"
723
+ "@takazudo/zudo-doc-history-server": "5.19.1"
724
724
  },
725
725
  "scripts": {
726
726
  "gen:search-widget-script": "node scripts/gen-search-widget-script.mjs",