@outfitter/tooling 0.2.4 → 0.3.3

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 (56) hide show
  1. package/README.md +69 -1
  2. package/biome.json +1 -1
  3. package/dist/cli/index.js +163 -24
  4. package/dist/index.d.ts +79 -4
  5. package/dist/index.js +17 -6
  6. package/dist/shared/chunk-cmde0fwx.js +421 -0
  7. package/package.json +14 -7
  8. package/registry/registry.json +6 -6
  9. package/dist/cli/check-boundary-invocations.d.ts +0 -34
  10. package/dist/cli/check-boundary-invocations.js +0 -14
  11. package/dist/cli/check-bunup-registry.d.ts +0 -36
  12. package/dist/cli/check-bunup-registry.js +0 -12
  13. package/dist/cli/check-changeset.d.ts +0 -64
  14. package/dist/cli/check-changeset.js +0 -14
  15. package/dist/cli/check-clean-tree.d.ts +0 -36
  16. package/dist/cli/check-clean-tree.js +0 -14
  17. package/dist/cli/check-exports.d.ts +0 -2
  18. package/dist/cli/check-exports.js +0 -14
  19. package/dist/cli/check-readme-imports.d.ts +0 -61
  20. package/dist/cli/check-readme-imports.js +0 -198
  21. package/dist/cli/check.d.ts +0 -19
  22. package/dist/cli/check.js +0 -10
  23. package/dist/cli/fix.d.ts +0 -19
  24. package/dist/cli/fix.js +0 -10
  25. package/dist/cli/init.d.ts +0 -31
  26. package/dist/cli/init.js +0 -12
  27. package/dist/cli/pre-push.d.ts +0 -41
  28. package/dist/cli/pre-push.js +0 -20
  29. package/dist/cli/upgrade-bun.d.ts +0 -8
  30. package/dist/cli/upgrade-bun.js +0 -8
  31. package/dist/registry/build.d.ts +0 -6
  32. package/dist/registry/build.js +0 -147
  33. package/dist/registry/index.d.ts +0 -3
  34. package/dist/registry/index.js +0 -13
  35. package/dist/registry/schema.d.ts +0 -2
  36. package/dist/registry/schema.js +0 -12
  37. package/dist/shared/@outfitter/tooling-0x5q15ec.js +0 -21
  38. package/dist/shared/@outfitter/tooling-1y8w5ahg.js +0 -70
  39. package/dist/shared/@outfitter/tooling-3w8vr2w3.js +0 -94
  40. package/dist/shared/@outfitter/tooling-8sd32ts6.js +0 -277
  41. package/dist/shared/@outfitter/tooling-9errkcvk.js +0 -21
  42. package/dist/shared/@outfitter/tooling-9vs606gq.d.ts +0 -3
  43. package/dist/shared/@outfitter/tooling-9yzd08v1.js +0 -146
  44. package/dist/shared/@outfitter/tooling-ctmgnap5.js +0 -19
  45. package/dist/shared/@outfitter/tooling-dvwh9qve.js +0 -4
  46. package/dist/shared/@outfitter/tooling-enjcenja.js +0 -229
  47. package/dist/shared/@outfitter/tooling-g83d0kjv.js +0 -23
  48. package/dist/shared/@outfitter/tooling-kcvs6mys.js +0 -1
  49. package/dist/shared/@outfitter/tooling-mxwc1n8w.js +0 -68
  50. package/dist/shared/@outfitter/tooling-r9976n43.js +0 -100
  51. package/dist/shared/@outfitter/tooling-sjm8nebx.d.ts +0 -109
  52. package/dist/shared/@outfitter/tooling-t17gnh9b.js +0 -78
  53. package/dist/shared/@outfitter/tooling-wesswf21.d.ts +0 -59
  54. package/dist/shared/chunk-8aenrm6f.js +0 -18
  55. package/dist/version.d.ts +0 -2
  56. package/dist/version.js +0 -8
package/README.md CHANGED
@@ -98,6 +98,75 @@ bunx @outfitter/tooling check-boundary-invocations
98
98
  When this fails, replace direct source execution with canonical command surfaces
99
99
  (`outfitter repo ...` in monorepo scripts, or package bins for standalone use).
100
100
 
101
+ ### `tooling check-bunup-registry`
102
+
103
+ Validate that packages using `bunup --filter` are registered in `bunup.config.ts`.
104
+
105
+ ```bash
106
+ bunx @outfitter/tooling check-bunup-registry
107
+ ```
108
+
109
+ ### `tooling check-changeset`
110
+
111
+ Validate that PRs touching package source include a changeset.
112
+
113
+ ```bash
114
+ bunx @outfitter/tooling check-changeset
115
+
116
+ # Skip the check (e.g. for non-package changes)
117
+ bunx @outfitter/tooling check-changeset --skip
118
+ ```
119
+
120
+ ### `tooling check-exports`
121
+
122
+ Validate that `package.json` exports match source entry points.
123
+
124
+ ```bash
125
+ bunx @outfitter/tooling check-exports
126
+
127
+ # Machine-readable output
128
+ bunx @outfitter/tooling check-exports --json
129
+ ```
130
+
131
+ ### `tooling check-tsdoc`
132
+
133
+ Check TSDoc coverage on exported declarations.
134
+
135
+ ```bash
136
+ bunx @outfitter/tooling check-tsdoc
137
+
138
+ # Check specific packages
139
+ bunx @outfitter/tooling check-tsdoc packages/cli packages/contracts
140
+
141
+ # Strict mode with coverage threshold
142
+ bunx @outfitter/tooling check-tsdoc --strict --min-coverage 80
143
+
144
+ # JSON output
145
+ bunx @outfitter/tooling check-tsdoc --json
146
+ ```
147
+
148
+ ### `tooling check-clean-tree`
149
+
150
+ Assert the working tree is clean (no modified or untracked files).
151
+
152
+ ```bash
153
+ bunx @outfitter/tooling check-clean-tree
154
+
155
+ # Check specific paths only
156
+ bunx @outfitter/tooling check-clean-tree --paths packages/cli packages/contracts
157
+ ```
158
+
159
+ ### `tooling check-readme-imports`
160
+
161
+ Validate that README import examples match package exports.
162
+
163
+ ```bash
164
+ bunx @outfitter/tooling check-readme-imports
165
+
166
+ # Machine-readable output
167
+ bunx @outfitter/tooling check-readme-imports --json
168
+ ```
169
+
101
170
  ## Configuration Presets
102
171
 
103
172
  ### Biome
@@ -188,7 +257,6 @@ bun run apps/outfitter/src/cli.ts repo check boundary-invocations --cwd .
188
257
 
189
258
  - [@outfitter/contracts](../contracts/README.md) — Result types and error patterns
190
259
  - [@outfitter/cli](../cli/README.md) — CLI framework
191
- - [@outfitter/kit](../kit/README.md) — Version coordination
192
260
 
193
261
  ## License
194
262
 
package/biome.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.3.12/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.4.4/schema.json",
3
3
  "root": false,
4
4
  "javascript": {
5
5
  "globals": ["Bun"]
package/dist/cli/index.js CHANGED
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env bun
2
2
  import {
3
- VERSION
4
- } from "../shared/chunk-8aenrm6f.js";
3
+ VERSION,
4
+ analyzeSourceFile,
5
+ calculateCoverage,
6
+ runCheckTsdoc
7
+ } from "../shared/chunk-cmde0fwx.js";
5
8
  import {
6
9
  __require
7
10
  } from "../shared/chunk-3s189drz.js";
@@ -205,6 +208,8 @@ Add the missing entries to ${COLORS.blue}bunup.config.ts${COLORS.reset} defineWo
205
208
  }
206
209
 
207
210
  // src/cli/check-changeset.ts
211
+ import { existsSync, readFileSync } from "node:fs";
212
+ import { join } from "node:path";
208
213
  function getChangedPackagePaths(files) {
209
214
  const packageNames = new Set;
210
215
  const pattern = /^packages\/([^/]+)\/src\//;
@@ -236,6 +241,73 @@ function checkChangesetRequired(changedPackages, changesetFiles) {
236
241
  }
237
242
  return { ok: false, missingFor: changedPackages };
238
243
  }
244
+ function parseIgnoredPackagesFromChangesetConfig(jsonContent) {
245
+ try {
246
+ const parsed = JSON.parse(jsonContent);
247
+ if (!Array.isArray(parsed.ignore)) {
248
+ return [];
249
+ }
250
+ return parsed.ignore.filter((entry) => typeof entry === "string");
251
+ } catch {
252
+ return [];
253
+ }
254
+ }
255
+ function parseChangesetFrontmatterPackageNames(markdownContent) {
256
+ const frontmatterMatch = /^---\r?\n([\s\S]*?)\r?\n---/.exec(markdownContent);
257
+ if (!frontmatterMatch?.[1]) {
258
+ return [];
259
+ }
260
+ const packages = new Set;
261
+ for (const line of frontmatterMatch[1].split(/\r?\n/)) {
262
+ const trimmed = line.trim();
263
+ const match = /^(["']?)(@[^"':\s]+\/[^"':\s]+)\1\s*:/.exec(trimmed);
264
+ if (match?.[2]) {
265
+ packages.add(match[2]);
266
+ }
267
+ }
268
+ return [...packages].sort();
269
+ }
270
+ function findIgnoredPackageReferences(input) {
271
+ if (input.ignoredPackages.length === 0 || input.changesetFiles.length === 0) {
272
+ return [];
273
+ }
274
+ const ignored = new Set(input.ignoredPackages);
275
+ const results = [];
276
+ for (const file of input.changesetFiles) {
277
+ const content = input.readChangesetFile(file);
278
+ const referencedPackages = parseChangesetFrontmatterPackageNames(content);
279
+ const invalidReferences = referencedPackages.filter((pkg) => ignored.has(pkg));
280
+ if (invalidReferences.length > 0) {
281
+ results.push({ file, packages: invalidReferences.sort() });
282
+ }
283
+ }
284
+ return results.sort((a, b) => a.file.localeCompare(b.file));
285
+ }
286
+ function loadIgnoredPackages(cwd) {
287
+ const configPath = join(cwd, ".changeset", "config.json");
288
+ if (!existsSync(configPath)) {
289
+ return [];
290
+ }
291
+ try {
292
+ return parseIgnoredPackagesFromChangesetConfig(readFileSync(configPath, "utf-8"));
293
+ } catch {
294
+ return [];
295
+ }
296
+ }
297
+ function getIgnoredReferencesForChangedChangesets(cwd, changesetFiles) {
298
+ const ignoredPackages = loadIgnoredPackages(cwd);
299
+ return findIgnoredPackageReferences({
300
+ changesetFiles,
301
+ ignoredPackages,
302
+ readChangesetFile: (filename) => {
303
+ try {
304
+ return readFileSync(join(cwd, ".changeset", filename), "utf-8");
305
+ } catch {
306
+ return "";
307
+ }
308
+ }
309
+ });
310
+ }
239
311
  var COLORS2 = {
240
312
  reset: "\x1B[0m",
241
313
  red: "\x1B[31m",
@@ -275,25 +347,43 @@ async function runCheckChangeset(options = {}) {
275
347
  }
276
348
  const changesetFiles = getChangedChangesetFiles(changedFiles);
277
349
  const check = checkChangesetRequired(changedPackages, changesetFiles);
278
- if (check.ok) {
279
- process.stdout.write(`${COLORS2.green}Changeset found for ${changedPackages.length} changed package(s).${COLORS2.reset}
350
+ if (!check.ok) {
351
+ process.stderr.write(`${COLORS2.yellow}No changeset found.${COLORS2.reset} ` + "Consider adding one with `bun run changeset` for a custom changelog entry.\n\n");
352
+ process.stderr.write(`Packages with source changes:
353
+
354
+ `);
355
+ for (const pkg of check.missingFor) {
356
+ process.stderr.write(` ${COLORS2.yellow}@outfitter/${pkg}${COLORS2.reset}
357
+ `);
358
+ }
359
+ process.stderr.write(`
360
+ Run ${COLORS2.blue}bun run changeset${COLORS2.reset} for a custom changelog entry, ` + `or add ${COLORS2.blue}release:none${COLORS2.reset} to skip.
280
361
  `);
281
- process.exit(0);
282
362
  }
283
- process.stderr.write(`${COLORS2.red}Missing changeset!${COLORS2.reset}
363
+ const ignoredReferences = getIgnoredReferencesForChangedChangesets(cwd, changesetFiles);
364
+ if (ignoredReferences.length > 0) {
365
+ process.stderr.write(`${COLORS2.red}Invalid changeset package reference(s).${COLORS2.reset}
284
366
 
285
367
  `);
286
- process.stderr.write(`The following packages have source changes but no changeset:
368
+ process.stderr.write(`Changesets must not reference packages listed in .changeset/config.json ignore:
287
369
 
288
370
  `);
289
- for (const pkg of check.missingFor) {
290
- process.stderr.write(` ${COLORS2.yellow}@outfitter/${pkg}${COLORS2.reset}
371
+ for (const reference of ignoredReferences) {
372
+ process.stderr.write(` ${COLORS2.yellow}${reference.file}${COLORS2.reset}
291
373
  `);
374
+ for (const pkg of reference.packages) {
375
+ process.stderr.write(` - ${pkg}
376
+ `);
377
+ }
378
+ }
379
+ process.stderr.write(`
380
+ Update the affected changeset files to remove ignored packages before merging.
381
+ `);
382
+ process.exit(1);
292
383
  }
293
- process.stderr.write(`
294
- Run ${COLORS2.blue}bun run changeset${COLORS2.reset} to add a changeset, ` + `or add the ${COLORS2.blue}no-changeset${COLORS2.reset} label to skip.
384
+ process.stdout.write(`${COLORS2.green}Changeset found for ${changedPackages.length} changed package(s).${COLORS2.reset}
295
385
  `);
296
- process.exit(1);
386
+ process.exit(0);
297
387
  }
298
388
 
299
389
  // src/cli/check-clean-tree.ts
@@ -674,8 +764,9 @@ async function runInit(cwd = process.cwd()) {
674
764
  }
675
765
 
676
766
  // src/cli/pre-push.ts
677
- import { existsSync, readFileSync } from "node:fs";
678
- import { join } from "node:path";
767
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
768
+ import { join as join2, resolve as resolve4 } from "node:path";
769
+ import ts from "typescript";
679
770
  var COLORS5 = {
680
771
  reset: "\x1B[0m",
681
772
  red: "\x1B[31m",
@@ -712,6 +803,9 @@ function isRedPhaseBranch(branch) {
712
803
  function isScaffoldBranch(branch) {
713
804
  return branch.endsWith("-scaffold") || branch.endsWith("/scaffold") || branch.endsWith("_scaffold");
714
805
  }
806
+ function isReleaseBranch(branch) {
807
+ return branch.startsWith("changeset-release/");
808
+ }
715
809
  var TEST_PATH_PATTERNS = [
716
810
  /(^|\/)__tests__\//,
717
811
  /(^|\/)__snapshots__\//,
@@ -731,6 +825,32 @@ function areFilesTestOnly(paths) {
731
825
  function canBypassRedPhaseByChangedFiles(changedFiles) {
732
826
  return changedFiles.deterministic && areFilesTestOnly(changedFiles.files);
733
827
  }
828
+ function hasPackageSourceChanges(changedFiles) {
829
+ const packageSrcPattern = /^packages\/[^/]+\/src\//;
830
+ return changedFiles.files.some((f) => packageSrcPattern.test(f));
831
+ }
832
+ async function printTsdocSummary() {
833
+ const glob = new Bun.Glob("packages/*/src/index.ts");
834
+ const cwd = process.cwd();
835
+ const allDeclarations = [];
836
+ for (const entry of glob.scanSync({ cwd })) {
837
+ const filePath = resolve4(cwd, entry);
838
+ const content = await Bun.file(filePath).text();
839
+ const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
840
+ allDeclarations.push(...analyzeSourceFile(sourceFile));
841
+ }
842
+ if (allDeclarations.length === 0)
843
+ return;
844
+ const coverage = calculateCoverage(allDeclarations);
845
+ const parts = [];
846
+ if (coverage.documented > 0)
847
+ parts.push(`${coverage.documented} documented`);
848
+ if (coverage.partial > 0)
849
+ parts.push(`${coverage.partial} partial`);
850
+ if (coverage.undocumented > 0)
851
+ parts.push(`${coverage.undocumented} undocumented`);
852
+ log(`${COLORS5.blue}TSDoc${COLORS5.reset}: ${coverage.percentage}% coverage (${parts.join(", ")} of ${coverage.total} total)`);
853
+ }
734
854
  function resolveBaseRef() {
735
855
  const candidates = [
736
856
  "origin/main",
@@ -868,12 +988,12 @@ function createVerificationPlan(scripts) {
868
988
  };
869
989
  }
870
990
  function readPackageScripts(cwd = process.cwd()) {
871
- const packageJsonPath = join(cwd, "package.json");
872
- if (!existsSync(packageJsonPath)) {
991
+ const packageJsonPath = join2(cwd, "package.json");
992
+ if (!existsSync2(packageJsonPath)) {
873
993
  return {};
874
994
  }
875
995
  try {
876
- const parsed = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
996
+ const parsed = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
877
997
  const scripts = parsed.scripts ?? {};
878
998
  const normalized = {};
879
999
  for (const [name, value] of Object.entries(scripts)) {
@@ -898,6 +1018,11 @@ async function runPrePush(options = {}) {
898
1018
  log(`${COLORS5.blue}Pre-push verify${COLORS5.reset} (TDD-aware)`);
899
1019
  log("");
900
1020
  const branch = getCurrentBranch();
1021
+ if (isReleaseBranch(branch)) {
1022
+ log(`${COLORS5.yellow}Release branch detected${COLORS5.reset}: ${COLORS5.blue}${branch}${COLORS5.reset}`);
1023
+ log(`${COLORS5.yellow}Skipping strict verification${COLORS5.reset} for automated changeset release push`);
1024
+ process.exit(0);
1025
+ }
901
1026
  if (isRedPhaseBranch(branch)) {
902
1027
  if (maybeSkipForRedPhase("branch", branch)) {
903
1028
  process.exit(0);
@@ -943,14 +1068,20 @@ async function runPrePush(options = {}) {
943
1068
  log(" - feature_tests");
944
1069
  process.exit(1);
945
1070
  }
1071
+ const changedFiles = getChangedFilesForPush();
1072
+ if (hasPackageSourceChanges(changedFiles)) {
1073
+ try {
1074
+ await printTsdocSummary();
1075
+ } catch {}
1076
+ }
946
1077
  log("");
947
1078
  log(`${COLORS5.green}Strict verification passed${COLORS5.reset}`);
948
1079
  process.exit(0);
949
1080
  }
950
1081
 
951
1082
  // src/cli/upgrade-bun.ts
952
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync } from "node:fs";
953
- import { join as join2 } from "node:path";
1083
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync } from "node:fs";
1084
+ import { join as join3 } from "node:path";
954
1085
  var COLORS6 = {
955
1086
  reset: "\x1B[0m",
956
1087
  red: "\x1B[31m",
@@ -988,13 +1119,13 @@ function findPackageJsonFiles(dir) {
988
1119
  const glob = new Bun.Glob("**/package.json");
989
1120
  for (const path of glob.scanSync({ cwd: dir })) {
990
1121
  if (!path.includes("node_modules")) {
991
- results.push(join2(dir, path));
1122
+ results.push(join3(dir, path));
992
1123
  }
993
1124
  }
994
1125
  return results;
995
1126
  }
996
1127
  function updateEnginesBun(filePath, version) {
997
- const content = readFileSync2(filePath, "utf-8");
1128
+ const content = readFileSync3(filePath, "utf-8");
998
1129
  const pattern = /"bun":\s*">=[\d.]+"/;
999
1130
  if (!pattern.test(content)) {
1000
1131
  return false;
@@ -1007,7 +1138,7 @@ function updateEnginesBun(filePath, version) {
1007
1138
  return false;
1008
1139
  }
1009
1140
  function updateTypesBun(filePath, version) {
1010
- const content = readFileSync2(filePath, "utf-8");
1141
+ const content = readFileSync3(filePath, "utf-8");
1011
1142
  const pattern = /"@types\/bun":\s*"\^[\d.]+"/;
1012
1143
  if (!pattern.test(content)) {
1013
1144
  return false;
@@ -1021,14 +1152,14 @@ function updateTypesBun(filePath, version) {
1021
1152
  }
1022
1153
  async function runUpgradeBun(targetVersion, options = {}) {
1023
1154
  const cwd = process.cwd();
1024
- const bunVersionFile = join2(cwd, ".bun-version");
1155
+ const bunVersionFile = join3(cwd, ".bun-version");
1025
1156
  let version = targetVersion;
1026
1157
  if (!version) {
1027
1158
  info("Fetching latest Bun version...");
1028
1159
  version = await fetchLatestVersion();
1029
1160
  log2(`Latest version: ${version}`);
1030
1161
  }
1031
- const currentVersion = existsSync2(bunVersionFile) ? readFileSync2(bunVersionFile, "utf-8").trim() : "unknown";
1162
+ const currentVersion = existsSync3(bunVersionFile) ? readFileSync3(bunVersionFile, "utf-8").trim() : "unknown";
1032
1163
  log2(`Current version: ${currentVersion}`);
1033
1164
  if (currentVersion === version) {
1034
1165
  success(`Already on version ${version}`);
@@ -1129,6 +1260,14 @@ register(new Command("check-changeset").description("Validate PRs touching packa
1129
1260
  register(new Command("check-exports").description("Validate package.json exports match source entry points").option("--json", "Output results as JSON").action(async (options) => {
1130
1261
  await runCheckExports(options);
1131
1262
  }));
1263
+ register(new Command("check-tsdoc").description("Check TSDoc coverage on exported declarations").argument("[paths...]", "Specific package paths to check").option("--strict", "Exit non-zero when coverage is below threshold").option("--json", "Output results as JSON").option("--min-coverage <percentage>", "Minimum coverage percentage", "0").action(async (paths, options) => {
1264
+ await runCheckTsdoc({
1265
+ paths: paths.length > 0 ? paths : undefined,
1266
+ strict: options.strict,
1267
+ json: options.json,
1268
+ minCoverage: options.minCoverage ? Number.parseInt(options.minCoverage, 10) : undefined
1269
+ });
1270
+ }));
1132
1271
  register(new Command("check-clean-tree").description("Assert working tree is clean (no modified or untracked files)").option("--paths <paths...>", "Limit check to specific paths").action(async (options) => {
1133
1272
  await runCheckCleanTree(options);
1134
1273
  }));
package/dist/index.d.ts CHANGED
@@ -1,4 +1,79 @@
1
1
  import { ZodType } from "zod";
2
+ /** Coverage classification for a single declaration. */
3
+ type CoverageLevel = "documented" | "partial" | "undocumented";
4
+ /** Result for a single exported declaration. */
5
+ interface DeclarationCoverage {
6
+ readonly name: string;
7
+ readonly kind: string;
8
+ readonly level: CoverageLevel;
9
+ readonly file: string;
10
+ readonly line: number;
11
+ }
12
+ /** Coverage summary statistics. */
13
+ interface CoverageSummary {
14
+ readonly documented: number;
15
+ readonly partial: number;
16
+ readonly undocumented: number;
17
+ readonly total: number;
18
+ readonly percentage: number;
19
+ }
20
+ /** Per-package TSDoc coverage stats. */
21
+ interface PackageCoverage {
22
+ readonly name: string;
23
+ readonly path: string;
24
+ readonly declarations: readonly DeclarationCoverage[];
25
+ readonly documented: number;
26
+ readonly partial: number;
27
+ readonly undocumented: number;
28
+ readonly total: number;
29
+ readonly percentage: number;
30
+ }
31
+ /** Aggregated result across all packages. */
32
+ interface TsDocCheckResult {
33
+ readonly ok: boolean;
34
+ readonly packages: readonly PackageCoverage[];
35
+ readonly summary: CoverageSummary;
36
+ }
37
+ /** Zod schema for {@link CoverageLevel}. */
38
+ declare const coverageLevelSchema: ZodType<CoverageLevel>;
39
+ /** Zod schema for {@link DeclarationCoverage}. */
40
+ declare const declarationCoverageSchema: ZodType<DeclarationCoverage>;
41
+ /** Zod schema for {@link PackageCoverage}. */
42
+ declare const packageCoverageSchema: ZodType<PackageCoverage>;
43
+ /** Zod schema for {@link TsDocCheckResult}. */
44
+ declare const tsDocCheckResultSchema: ZodType<TsDocCheckResult>;
45
+ /** Options for the check-tsdoc command. */
46
+ interface CheckTsDocOptions {
47
+ readonly strict?: boolean | undefined;
48
+ readonly json?: boolean | undefined;
49
+ readonly minCoverage?: number | undefined;
50
+ readonly cwd?: string | undefined;
51
+ readonly paths?: readonly string[] | undefined;
52
+ }
53
+ /**
54
+ * Analyze TSDoc coverage across workspace packages.
55
+ *
56
+ * Pure function that discovers packages, analyzes TSDoc coverage on exported
57
+ * declarations, and returns the aggregated result. Does not print output or
58
+ * call `process.exit()`.
59
+ *
60
+ * @param options - Analysis options (paths, strict mode, coverage threshold)
61
+ * @returns Aggregated coverage result across all packages, or `null` if no packages found
62
+ */
63
+ declare function analyzeCheckTsdoc(options?: CheckTsDocOptions): TsDocCheckResult | null;
64
+ /**
65
+ * Print a TSDoc coverage result in human-readable format.
66
+ *
67
+ * Renders a bar chart per package with summary statistics. Writes to stdout/stderr.
68
+ *
69
+ * @param result - The coverage result to print
70
+ * @param options - Display options (strict mode, coverage threshold for warning)
71
+ */
72
+ declare function printCheckTsdocHuman(result: TsDocCheckResult, options?: {
73
+ strict?: boolean | undefined;
74
+ minCoverage?: number | undefined;
75
+ }): void;
76
+ import { ZodType as ZodType2 } from "zod";
2
77
  /**
3
78
  * File entry in a block.
4
79
  */
@@ -16,7 +91,7 @@ interface FileEntry {
16
91
  * Schema for a file entry in a block.
17
92
  * Represents a file that will be copied to the user's project.
18
93
  */
19
- declare const FileEntrySchema: ZodType<FileEntry>;
94
+ declare const FileEntrySchema: ZodType2<FileEntry>;
20
95
  /**
21
96
  * Block in the registry.
22
97
  */
@@ -38,7 +113,7 @@ interface Block {
38
113
  * Schema for a block in the registry.
39
114
  * A block is a collection of related files that can be added together.
40
115
  */
41
- declare const BlockSchema: ZodType<Block>;
116
+ declare const BlockSchema: ZodType2<Block>;
42
117
  /**
43
118
  * Complete registry structure.
44
119
  */
@@ -52,7 +127,7 @@ interface Registry {
52
127
  * Schema for the complete registry.
53
128
  * Contains all available blocks with their files and metadata.
54
129
  */
55
- declare const RegistrySchema: ZodType<Registry>;
130
+ declare const RegistrySchema: ZodType2<Registry>;
56
131
  /**
57
132
  * Block definition used in the build script.
58
133
  * Specifies how to collect source files into a block.
@@ -108,4 +183,4 @@ interface AddBlockOptions {
108
183
  }
109
184
  /** Package version, read from package.json at load time. */
110
185
  declare const VERSION: string;
111
- export { VERSION, RegistrySchema, RegistryBuildConfig, Registry, FileEntrySchema, FileEntry, BlockSchema, BlockDefinition, Block, AddBlockResult, AddBlockOptions };
186
+ export { tsDocCheckResultSchema, printCheckTsdocHuman, packageCoverageSchema, declarationCoverageSchema, coverageLevelSchema, analyzeCheckTsdoc, VERSION, TsDocCheckResult, RegistrySchema, RegistryBuildConfig, Registry, PackageCoverage, FileEntrySchema, FileEntry, DeclarationCoverage, CoverageLevel, CheckTsDocOptions, BlockSchema, BlockDefinition, Block, AddBlockResult, AddBlockOptions };
package/dist/index.js CHANGED
@@ -1,8 +1,13 @@
1
1
  import {
2
- VERSION
3
- } from "./shared/chunk-8aenrm6f.js";
2
+ VERSION,
3
+ analyzeCheckTsdoc,
4
+ coverageLevelSchema,
5
+ declarationCoverageSchema,
6
+ packageCoverageSchema,
7
+ printCheckTsdocHuman,
8
+ tsDocCheckResultSchema
9
+ } from "./shared/chunk-cmde0fwx.js";
4
10
  import"./shared/chunk-3s189drz.js";
5
-
6
11
  // src/registry/schema.ts
7
12
  import { z } from "zod";
8
13
  var FileEntrySchema = z.object({
@@ -15,15 +20,21 @@ var BlockSchema = z.object({
15
20
  name: z.string().min(1),
16
21
  description: z.string().min(1),
17
22
  files: z.array(FileEntrySchema).optional(),
18
- dependencies: z.record(z.string()).optional(),
19
- devDependencies: z.record(z.string()).optional(),
23
+ dependencies: z.record(z.string(), z.string()).optional(),
24
+ devDependencies: z.record(z.string(), z.string()).optional(),
20
25
  extends: z.array(z.string()).optional()
21
26
  });
22
27
  var RegistrySchema = z.object({
23
28
  version: z.string(),
24
- blocks: z.record(BlockSchema)
29
+ blocks: z.record(z.string(), BlockSchema)
25
30
  });
26
31
  export {
32
+ tsDocCheckResultSchema,
33
+ printCheckTsdocHuman,
34
+ packageCoverageSchema,
35
+ declarationCoverageSchema,
36
+ coverageLevelSchema,
37
+ analyzeCheckTsdoc,
27
38
  VERSION,
28
39
  RegistrySchema,
29
40
  FileEntrySchema,