@outfitter/tooling 0.3.3 → 0.3.5

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 (94) hide show
  1. package/.markdownlint-cli2.jsonc +55 -55
  2. package/README.md +33 -24
  3. package/dist/bun-version-compat.d.ts +2 -0
  4. package/dist/bun-version-compat.js +10 -0
  5. package/dist/cli/check-boundary-invocations.d.ts +34 -0
  6. package/dist/cli/check-boundary-invocations.js +14 -0
  7. package/dist/cli/check-bunup-registry.d.ts +36 -0
  8. package/dist/cli/check-bunup-registry.js +12 -0
  9. package/dist/cli/check-changeset.d.ts +82 -0
  10. package/dist/cli/check-changeset.js +24 -0
  11. package/dist/cli/check-clean-tree.d.ts +36 -0
  12. package/dist/cli/check-clean-tree.js +14 -0
  13. package/dist/cli/check-exports.d.ts +3 -0
  14. package/dist/cli/check-exports.js +17 -0
  15. package/dist/cli/check-home-paths.d.ts +31 -0
  16. package/dist/cli/check-home-paths.js +12 -0
  17. package/dist/cli/check-markdown-links.d.ts +42 -0
  18. package/dist/cli/check-markdown-links.js +13 -0
  19. package/dist/cli/check-readme-imports.d.ts +61 -0
  20. package/dist/{shared/chunk-7tdgbqb0.js → cli/check-readme-imports.js} +7 -6
  21. package/dist/cli/check-tsdoc.d.ts +5 -0
  22. package/dist/cli/check-tsdoc.js +42 -0
  23. package/dist/cli/check.d.ts +19 -0
  24. package/dist/cli/check.js +10 -0
  25. package/dist/cli/fix.d.ts +19 -0
  26. package/dist/cli/fix.js +10 -0
  27. package/dist/cli/index.js +61 -1218
  28. package/dist/cli/init.d.ts +31 -0
  29. package/dist/cli/init.js +12 -0
  30. package/dist/cli/internal/exports-analysis.d.ts +2 -0
  31. package/dist/cli/internal/exports-analysis.js +10 -0
  32. package/dist/cli/internal/exports-fs.d.ts +17 -0
  33. package/dist/cli/internal/exports-fs.js +9 -0
  34. package/dist/cli/internal/pre-push-checks.d.ts +2 -0
  35. package/dist/cli/internal/pre-push-checks.js +37 -0
  36. package/dist/cli/internal/tsdoc-analysis.d.ts +3 -0
  37. package/dist/cli/internal/tsdoc-analysis.js +26 -0
  38. package/dist/cli/internal/tsdoc-formatting.d.ts +3 -0
  39. package/dist/cli/internal/tsdoc-formatting.js +10 -0
  40. package/dist/cli/internal/tsdoc-types.d.ts +2 -0
  41. package/dist/cli/internal/tsdoc-types.js +16 -0
  42. package/dist/cli/pre-push.d.ts +7 -0
  43. package/dist/cli/pre-push.js +29 -0
  44. package/dist/cli/upgrade-bun.d.ts +8 -0
  45. package/dist/cli/upgrade-bun.js +9 -0
  46. package/dist/index.d.ts +9 -186
  47. package/dist/index.js +4 -42
  48. package/dist/registry/build.d.ts +4 -0
  49. package/dist/registry/build.js +279 -0
  50. package/dist/registry/index.d.ts +3 -0
  51. package/dist/registry/index.js +1 -0
  52. package/dist/registry/schema.d.ts +2 -0
  53. package/dist/registry/schema.js +28 -0
  54. package/dist/shared/@outfitter/tooling-0zjz8eg9.js +106 -0
  55. package/dist/shared/@outfitter/tooling-1hez6j9d.js +21 -0
  56. package/dist/shared/@outfitter/tooling-2vv5y3s4.js +145 -0
  57. package/dist/shared/{chunk-cmde0fwx.js → @outfitter/tooling-5xxctk9b.js} +12 -138
  58. package/dist/shared/@outfitter/tooling-5ynz680q.js +59 -0
  59. package/dist/shared/@outfitter/tooling-7437rmy6.js +39 -0
  60. package/dist/shared/@outfitter/tooling-8qcwr06t.d.ts +74 -0
  61. package/dist/shared/@outfitter/tooling-9ram55dd.js +69 -0
  62. package/dist/shared/@outfitter/tooling-9vs606gq.d.ts +3 -0
  63. package/dist/shared/@outfitter/tooling-a4bfx4be.js +21 -0
  64. package/dist/shared/@outfitter/tooling-a59br34g.js +32 -0
  65. package/dist/shared/@outfitter/tooling-a6q3zh7t.js +86 -0
  66. package/dist/shared/@outfitter/tooling-amrbp7cm.js +102 -0
  67. package/dist/shared/@outfitter/tooling-ayps7c4x.js +58 -0
  68. package/dist/shared/@outfitter/tooling-c8q6mj8z.js +228 -0
  69. package/dist/shared/@outfitter/tooling-cb0b8wsx.d.ts +57 -0
  70. package/dist/shared/@outfitter/tooling-ctmgnap5.js +19 -0
  71. package/dist/shared/@outfitter/tooling-f8q38e9z.d.ts +16 -0
  72. package/dist/shared/@outfitter/tooling-gcdvsqqp.js +73 -0
  73. package/dist/shared/@outfitter/tooling-h5dnevjw.js +139 -0
  74. package/dist/shared/@outfitter/tooling-j8d1h2zd.d.ts +10 -0
  75. package/dist/shared/@outfitter/tooling-ja1zg5yc.js +214 -0
  76. package/dist/shared/@outfitter/tooling-jnrs9rqd.js +4 -0
  77. package/dist/shared/@outfitter/tooling-mkynjra9.js +23 -0
  78. package/dist/shared/@outfitter/tooling-mq2xvz96.js +285 -0
  79. package/dist/shared/@outfitter/tooling-pq47jv6t.js +213 -0
  80. package/dist/shared/@outfitter/tooling-sjm8nebx.d.ts +109 -0
  81. package/dist/shared/@outfitter/tooling-stgnc2zx.d.ts +85 -0
  82. package/dist/shared/@outfitter/tooling-tj9p41vj.d.ts +55 -0
  83. package/dist/shared/@outfitter/tooling-vjmhvpjq.d.ts +29 -0
  84. package/dist/shared/@outfitter/tooling-wwm97f47.js +81 -0
  85. package/dist/shared/@outfitter/tooling-y43b117h.d.ts +13 -0
  86. package/dist/version.d.ts +2 -0
  87. package/dist/version.js +8 -0
  88. package/lefthook.yml +5 -1
  89. package/package.json +140 -131
  90. package/registry/registry.json +19 -12
  91. package/tsconfig.preset.bun.json +5 -5
  92. package/tsconfig.preset.json +33 -33
  93. package/biome.json +0 -81
  94. package/dist/shared/chunk-3s189drz.js +0 -4
@@ -1,45 +1,11 @@
1
+ // @bun
1
2
  import {
2
3
  __require
3
- } from "./chunk-3s189drz.js";
4
+ } from "./tooling-jnrs9rqd.js";
4
5
 
5
- // src/cli/check-tsdoc.ts
6
- import { resolve } from "node:path";
6
+ // packages/tooling/src/cli/internal/tsdoc-analysis.ts
7
+ import { resolve } from "path";
7
8
  import ts from "typescript";
8
- import { z } from "zod";
9
- var coverageLevelSchema = z.enum([
10
- "documented",
11
- "partial",
12
- "undocumented"
13
- ]);
14
- var declarationCoverageSchema = z.object({
15
- name: z.string(),
16
- kind: z.string(),
17
- level: coverageLevelSchema,
18
- file: z.string(),
19
- line: z.number()
20
- });
21
- var coverageSummarySchema = z.object({
22
- documented: z.number(),
23
- partial: z.number(),
24
- undocumented: z.number(),
25
- total: z.number(),
26
- percentage: z.number()
27
- });
28
- var packageCoverageSchema = z.object({
29
- name: z.string(),
30
- path: z.string(),
31
- declarations: z.array(declarationCoverageSchema),
32
- documented: z.number(),
33
- partial: z.number(),
34
- undocumented: z.number(),
35
- total: z.number(),
36
- percentage: z.number()
37
- });
38
- var tsDocCheckResultSchema = z.object({
39
- ok: z.boolean(),
40
- packages: z.array(packageCoverageSchema),
41
- summary: coverageSummarySchema
42
- });
43
9
  function isExportedDeclaration(node) {
44
10
  if (ts.isExportDeclaration(node))
45
11
  return false;
@@ -158,24 +124,6 @@ function calculateCoverage(declarations) {
158
124
  const percentage = Math.round(score / total * 100);
159
125
  return { documented, partial, undocumented, total, percentage };
160
126
  }
161
- var COLORS = {
162
- reset: "\x1B[0m",
163
- red: "\x1B[31m",
164
- green: "\x1B[32m",
165
- yellow: "\x1B[33m",
166
- blue: "\x1B[34m",
167
- dim: "\x1B[2m",
168
- bold: "\x1B[1m"
169
- };
170
- function resolveJsonMode(options = {}) {
171
- return options.json ?? process.env["OUTFITTER_JSON"] === "1";
172
- }
173
- function bar(percentage, width = 20) {
174
- const filled = Math.round(percentage / 100 * width);
175
- const empty = width - filled;
176
- const color = percentage >= 80 ? COLORS.green : percentage >= 50 ? COLORS.yellow : COLORS.red;
177
- return `${color}${"█".repeat(filled)}${COLORS.dim}${"░".repeat(empty)}${COLORS.reset}`;
178
- }
179
127
  function discoverPackages(cwd) {
180
128
  const packages = [];
181
129
  const seenEntryPoints = new Set;
@@ -195,7 +143,7 @@ function discoverPackages(cwd) {
195
143
  const pkgRoot = resolve(cwd, rootDir, pkgDir);
196
144
  let pkgName = pkgDir;
197
145
  try {
198
- const pkgJson = JSON.parse(__require("node:fs").readFileSync(resolve(pkgRoot, "package.json"), "utf-8"));
146
+ const pkgJson = JSON.parse(__require("fs").readFileSync(resolve(pkgRoot, "package.json"), "utf-8"));
199
147
  if (pkgJson.name)
200
148
  pkgName = pkgJson.name;
201
149
  } catch {}
@@ -209,10 +157,10 @@ function discoverPackages(cwd) {
209
157
  if (packages.length === 0) {
210
158
  const entryPoint = resolve(cwd, "src/index.ts");
211
159
  try {
212
- __require("node:fs").accessSync(entryPoint);
160
+ __require("fs").accessSync(entryPoint);
213
161
  let pkgName = "root";
214
162
  try {
215
- const pkgJson = JSON.parse(__require("node:fs").readFileSync(resolve(cwd, "package.json"), "utf-8"));
163
+ const pkgJson = JSON.parse(__require("fs").readFileSync(resolve(cwd, "package.json"), "utf-8"));
216
164
  if (pkgJson.name)
217
165
  pkgName = pkgJson.name;
218
166
  } catch {}
@@ -224,7 +172,7 @@ function discoverPackages(cwd) {
224
172
  seenEntryPoints.add(entryPoint);
225
173
  } catch {}
226
174
  }
227
- return packages.sort((a, b) => a.name.localeCompare(b.name));
175
+ return packages.toSorted((a, b) => a.name.localeCompare(b.name));
228
176
  }
229
177
  function collectReExportedSourceFiles(sourceFile, program, pkgPath) {
230
178
  const result = [];
@@ -256,7 +204,7 @@ function collectReExportedSourceFiles(sourceFile, program, pkgPath) {
256
204
  }
257
205
  function analyzePackage(pkg, workspaceCwd) {
258
206
  try {
259
- __require("node:fs").accessSync(pkg.entryPoint);
207
+ __require("fs").accessSync(pkg.entryPoint);
260
208
  } catch {
261
209
  return {
262
210
  name: pkg.name,
@@ -271,7 +219,7 @@ function analyzePackage(pkg, workspaceCwd) {
271
219
  }
272
220
  let tsconfigPath = resolve(pkg.path, "tsconfig.json");
273
221
  try {
274
- __require("node:fs").accessSync(tsconfigPath);
222
+ __require("fs").accessSync(tsconfigPath);
275
223
  } catch {
276
224
  tsconfigPath = resolve(workspaceCwd, "tsconfig.json");
277
225
  }
@@ -318,7 +266,7 @@ function analyzeCheckTsdoc(options = {}) {
318
266
  const entryPoint = resolve(absPath, "src/index.ts");
319
267
  let name = p;
320
268
  try {
321
- const pkgJson = JSON.parse(__require("node:fs").readFileSync(resolve(absPath, "package.json"), "utf-8"));
269
+ const pkgJson = JSON.parse(__require("fs").readFileSync(resolve(absPath, "package.json"), "utf-8"));
322
270
  if (pkgJson.name)
323
271
  name = pkgJson.name;
324
272
  } catch {}
@@ -343,79 +291,5 @@ function analyzeCheckTsdoc(options = {}) {
343
291
  summary
344
292
  };
345
293
  }
346
- function printCheckTsdocHuman(result, options) {
347
- process.stdout.write(`
348
- ${COLORS.bold}TSDoc Coverage Report${COLORS.reset}
349
-
350
- `);
351
- for (const pkg of result.packages) {
352
- const color = pkg.percentage >= 80 ? COLORS.green : pkg.percentage >= 50 ? COLORS.yellow : COLORS.red;
353
- process.stdout.write(` ${color}${pkg.percentage.toString().padStart(3)}%${COLORS.reset} ${bar(pkg.percentage)} ${pkg.name}
354
- `);
355
- if (pkg.total > 0) {
356
- const parts = [];
357
- if (pkg.documented > 0)
358
- parts.push(`${COLORS.green}${pkg.documented} documented${COLORS.reset}`);
359
- if (pkg.partial > 0)
360
- parts.push(`${COLORS.yellow}${pkg.partial} partial${COLORS.reset}`);
361
- if (pkg.undocumented > 0)
362
- parts.push(`${COLORS.red}${pkg.undocumented} undocumented${COLORS.reset}`);
363
- process.stdout.write(` ${COLORS.dim}${pkg.total} declarations:${COLORS.reset} ${parts.join(", ")}
364
- `);
365
- } else {
366
- process.stdout.write(` ${COLORS.dim}no exported declarations${COLORS.reset}
367
- `);
368
- }
369
- }
370
- const { summary } = result;
371
- process.stdout.write(`
372
- ${COLORS.bold}Summary:${COLORS.reset} ${summary.percentage}% coverage (${summary.documented} documented, ${summary.partial} partial, ${summary.undocumented} undocumented of ${summary.total} total)
373
- `);
374
- const minCoverage = options?.minCoverage ?? 0;
375
- if (options?.strict && summary.percentage < minCoverage) {
376
- process.stderr.write(`
377
- ${COLORS.red}Coverage ${summary.percentage}% is below minimum threshold of ${minCoverage}%${COLORS.reset}
378
- `);
379
- }
380
- process.stdout.write(`
381
- `);
382
- }
383
- async function runCheckTsdoc(options = {}) {
384
- const result = analyzeCheckTsdoc(options);
385
- if (!result) {
386
- process.stderr.write(`No packages found with src/index.ts entry points.
387
- ` + `Searched: packages/*/src/index.ts, apps/*/src/index.ts, src/index.ts
388
- ` + `Use --package <path> to specify a package path explicitly.
389
- `);
390
- process.exit(1);
391
- }
392
- if (resolveJsonMode(options)) {
393
- process.stdout.write(`${JSON.stringify(result, null, 2)}
394
- `);
395
- } else {
396
- printCheckTsdocHuman(result, {
397
- strict: options.strict,
398
- minCoverage: options.minCoverage
399
- });
400
- }
401
- process.exit(result.ok ? 0 : 1);
402
- }
403
-
404
- // src/version.ts
405
- import { readFileSync } from "node:fs";
406
- import { createRequire } from "node:module";
407
- var DEFAULT_VERSION = "0.0.0";
408
- function readPackageVersion() {
409
- try {
410
- const require2 = createRequire(import.meta.url);
411
- const pkgPath = require2.resolve("@outfitter/tooling/package.json");
412
- const packageJson = JSON.parse(readFileSync(pkgPath, "utf8"));
413
- if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
414
- return packageJson.version;
415
- }
416
- } catch {}
417
- return DEFAULT_VERSION;
418
- }
419
- var VERSION = readPackageVersion();
420
294
 
421
- export { coverageLevelSchema, declarationCoverageSchema, packageCoverageSchema, tsDocCheckResultSchema, analyzeSourceFile, calculateCoverage, analyzeCheckTsdoc, printCheckTsdocHuman, runCheckTsdoc, VERSION };
295
+ export { isExportedDeclaration, getDeclarationName, getDeclarationKind, classifyDeclaration, analyzeSourceFile, calculateCoverage, discoverPackages, collectReExportedSourceFiles, analyzePackage, analyzeCheckTsdoc };
@@ -0,0 +1,59 @@
1
+ // @bun
2
+ // packages/tooling/src/cli/internal/tsdoc-formatting.ts
3
+ var COLORS = {
4
+ reset: "\x1B[0m",
5
+ red: "\x1B[31m",
6
+ green: "\x1B[32m",
7
+ yellow: "\x1B[33m",
8
+ blue: "\x1B[34m",
9
+ dim: "\x1B[2m",
10
+ bold: "\x1B[1m"
11
+ };
12
+ function resolveJsonMode(options = {}) {
13
+ return options.json ?? process.env["OUTFITTER_JSON"] === "1";
14
+ }
15
+ function bar(percentage, width = 20) {
16
+ const filled = Math.round(percentage / 100 * width);
17
+ const empty = width - filled;
18
+ const color = percentage >= 80 ? COLORS.green : percentage >= 50 ? COLORS.yellow : COLORS.red;
19
+ return `${color}${"\u2588".repeat(filled)}${COLORS.dim}${"\u2591".repeat(empty)}${COLORS.reset}`;
20
+ }
21
+ function printCheckTsdocHuman(result, options) {
22
+ process.stdout.write(`
23
+ ${COLORS.bold}TSDoc Coverage Report${COLORS.reset}
24
+
25
+ `);
26
+ for (const pkg of result.packages) {
27
+ const color = pkg.percentage >= 80 ? COLORS.green : pkg.percentage >= 50 ? COLORS.yellow : COLORS.red;
28
+ process.stdout.write(` ${color}${pkg.percentage.toString().padStart(3)}%${COLORS.reset} ${bar(pkg.percentage)} ${pkg.name}
29
+ `);
30
+ if (pkg.total > 0) {
31
+ const parts = [];
32
+ if (pkg.documented > 0)
33
+ parts.push(`${COLORS.green}${pkg.documented} documented${COLORS.reset}`);
34
+ if (pkg.partial > 0)
35
+ parts.push(`${COLORS.yellow}${pkg.partial} partial${COLORS.reset}`);
36
+ if (pkg.undocumented > 0)
37
+ parts.push(`${COLORS.red}${pkg.undocumented} undocumented${COLORS.reset}`);
38
+ process.stdout.write(` ${COLORS.dim}${pkg.total} declarations:${COLORS.reset} ${parts.join(", ")}
39
+ `);
40
+ } else {
41
+ process.stdout.write(` ${COLORS.dim}no exported declarations${COLORS.reset}
42
+ `);
43
+ }
44
+ }
45
+ const { summary } = result;
46
+ process.stdout.write(`
47
+ ${COLORS.bold}Summary:${COLORS.reset} ${summary.percentage}% coverage (${summary.documented} documented, ${summary.partial} partial, ${summary.undocumented} undocumented of ${summary.total} total)
48
+ `);
49
+ const minCoverage = options?.minCoverage ?? 0;
50
+ if (options?.strict && summary.percentage < minCoverage) {
51
+ process.stderr.write(`
52
+ ${COLORS.red}Coverage ${summary.percentage}% is below minimum threshold of ${minCoverage}%${COLORS.reset}
53
+ `);
54
+ }
55
+ process.stdout.write(`
56
+ `);
57
+ }
58
+
59
+ export { resolveJsonMode, printCheckTsdocHuman };
@@ -0,0 +1,39 @@
1
+ // @bun
2
+ // packages/tooling/src/cli/internal/tsdoc-types.ts
3
+ import { z } from "zod";
4
+ var coverageLevelSchema = z.enum([
5
+ "documented",
6
+ "partial",
7
+ "undocumented"
8
+ ]);
9
+ var declarationCoverageSchema = z.object({
10
+ name: z.string(),
11
+ kind: z.string(),
12
+ level: coverageLevelSchema,
13
+ file: z.string(),
14
+ line: z.number()
15
+ });
16
+ var coverageSummarySchema = z.object({
17
+ documented: z.number(),
18
+ partial: z.number(),
19
+ undocumented: z.number(),
20
+ total: z.number(),
21
+ percentage: z.number()
22
+ });
23
+ var packageCoverageSchema = z.object({
24
+ name: z.string(),
25
+ path: z.string(),
26
+ declarations: z.array(declarationCoverageSchema),
27
+ documented: z.number(),
28
+ partial: z.number(),
29
+ undocumented: z.number(),
30
+ total: z.number(),
31
+ percentage: z.number()
32
+ });
33
+ var tsDocCheckResultSchema = z.object({
34
+ ok: z.boolean(),
35
+ packages: z.array(packageCoverageSchema),
36
+ summary: coverageSummarySchema
37
+ });
38
+
39
+ export { coverageLevelSchema, declarationCoverageSchema, coverageSummarySchema, packageCoverageSchema, tsDocCheckResultSchema };
@@ -0,0 +1,74 @@
1
+ /** Get current git branch name */
2
+ declare function getCurrentBranch(): string;
3
+ declare function runGit(args: readonly string[]): {
4
+ readonly ok: boolean;
5
+ readonly lines: readonly string[];
6
+ };
7
+ /** Check if branch is a TDD RED phase branch */
8
+ declare function isRedPhaseBranch(branch: string): boolean;
9
+ /** Check if branch is a scaffold branch */
10
+ declare function isScaffoldBranch(branch: string): boolean;
11
+ /** Check if branch is a changeset release branch */
12
+ declare function isReleaseBranch(branch: string): boolean;
13
+ /** Determine if a file path is test-related */
14
+ declare function isTestOnlyPath(path: string): boolean;
15
+ /** Check if all paths in the list are test-related */
16
+ declare function areFilesTestOnly(paths: readonly string[]): boolean;
17
+ interface PushChangedFiles {
18
+ readonly files: readonly string[];
19
+ readonly deterministic: boolean;
20
+ readonly source: "upstream" | "baseRef" | "undetermined";
21
+ }
22
+ /** Check if bypass is safe: deterministic range with test-only changes */
23
+ declare function canBypassRedPhaseByChangedFiles(changedFiles: PushChangedFiles): boolean;
24
+ /**
25
+ * Check whether any changed files are package source files.
26
+ *
27
+ * Matches files under "packages/PKGNAME/src/" (any depth).
28
+ */
29
+ declare function hasPackageSourceChanges(changedFiles: PushChangedFiles): boolean;
30
+ /** Determine which files have changed for the current push */
31
+ declare function getChangedFilesForPush(): PushChangedFiles;
32
+ /** Check if any branch in context is a RED phase branch */
33
+ declare function hasRedPhaseBranchInContext(currentBranch: string): boolean;
34
+ type ScriptMap = Readonly<Record<string, string | undefined>>;
35
+ type VerificationPlan = {
36
+ readonly ok: true;
37
+ readonly scripts: readonly string[];
38
+ readonly source: "verify:push" | "verify:ci" | "fallback";
39
+ } | {
40
+ readonly ok: false;
41
+ readonly error: string;
42
+ };
43
+ /**
44
+ * Derive strict pre-push verification from package scripts.
45
+ *
46
+ * Priority:
47
+ * 1) `verify:push`
48
+ * 2) `verify:ci`
49
+ * 3) fallback sequence: `typecheck`, `check|lint`, `build`, `test`
50
+ */
51
+ declare function createVerificationPlan(scripts: ScriptMap): VerificationPlan;
52
+ /** Read and normalize scripts from package.json */
53
+ declare function readPackageScripts(cwd?: string): ScriptMap;
54
+ interface BunVersionCheckResult {
55
+ readonly matches: boolean;
56
+ readonly expected?: string;
57
+ readonly actual?: string;
58
+ }
59
+ /**
60
+ * Check that the local Bun version matches the pinned version in ".bun-version".
61
+ *
62
+ * @param projectRoot - Directory containing ".bun-version" (defaults to cwd)
63
+ * @returns Result indicating whether versions match
64
+ */
65
+ declare function checkBunVersion(projectRoot?: string): BunVersionCheckResult;
66
+ /**
67
+ * Print a one-line TSDoc coverage summary across all workspace packages.
68
+ *
69
+ * Discovers package entry points ("packages/STAR/src/index.ts"), analyzes
70
+ * TSDoc coverage, and outputs a single summary line. This is advisory
71
+ * only -- the result does not affect the exit code.
72
+ */
73
+ declare function printTsdocSummary(log: (msg: string) => void): Promise<void>;
74
+ export { getCurrentBranch, runGit, isRedPhaseBranch, isScaffoldBranch, isReleaseBranch, isTestOnlyPath, areFilesTestOnly, PushChangedFiles, canBypassRedPhaseByChangedFiles, hasPackageSourceChanges, getChangedFilesForPush, hasRedPhaseBranchInContext, VerificationPlan, createVerificationPlan, readPackageScripts, BunVersionCheckResult, checkBunVersion, printTsdocSummary };
@@ -0,0 +1,69 @@
1
+ // @bun
2
+ // packages/tooling/src/cli/init.ts
3
+ var FRAMEWORK_DETECTORS = {
4
+ react: ["react", "react-dom"],
5
+ next: ["next"],
6
+ vue: ["vue"],
7
+ nuxt: ["nuxt"],
8
+ svelte: ["svelte"],
9
+ angular: ["@angular/core"],
10
+ solid: ["solid-js"],
11
+ astro: ["astro"],
12
+ remix: ["@remix-run/react"],
13
+ qwik: ["@builder.io/qwik"]
14
+ };
15
+ function detectFrameworks(pkg) {
16
+ const allDeps = {
17
+ ...pkg.dependencies,
18
+ ...pkg.devDependencies
19
+ };
20
+ const detected = [];
21
+ for (const [framework, packages] of Object.entries(FRAMEWORK_DETECTORS)) {
22
+ if (packages.some((p) => (p in allDeps))) {
23
+ detected.push(framework);
24
+ }
25
+ }
26
+ if (detected.length === 0) {
27
+ return [];
28
+ }
29
+ return ["--frameworks", ...detected];
30
+ }
31
+ function buildUltraciteCommand(options) {
32
+ const cmd = [
33
+ "ultracite",
34
+ "init",
35
+ "--linter",
36
+ "oxlint",
37
+ "--pm",
38
+ "bun",
39
+ "--quiet"
40
+ ];
41
+ if (options.frameworks && options.frameworks.length > 0) {
42
+ cmd.push("--frameworks", ...options.frameworks);
43
+ }
44
+ return cmd;
45
+ }
46
+ async function runInit(cwd = process.cwd()) {
47
+ const pkgPath = `${cwd}/package.json`;
48
+ const pkgFile = Bun.file(pkgPath);
49
+ if (!await pkgFile.exists()) {
50
+ process.stderr.write(`No package.json found in current directory
51
+ `);
52
+ process.exitCode = 1;
53
+ return;
54
+ }
55
+ const pkg = await pkgFile.json();
56
+ const frameworkFlags = detectFrameworks(pkg);
57
+ const frameworks = frameworkFlags.length > 0 ? frameworkFlags.slice(1) : [];
58
+ const cmd = buildUltraciteCommand({ frameworks });
59
+ process.stdout.write(`Running: bun x ${cmd.join(" ")}
60
+ `);
61
+ const proc = Bun.spawn(["bun", "x", ...cmd], {
62
+ cwd,
63
+ stdio: ["inherit", "inherit", "inherit"]
64
+ });
65
+ const exitCode = await proc.exited;
66
+ process.exitCode = exitCode;
67
+ }
68
+
69
+ export { detectFrameworks, buildUltraciteCommand, runInit };
@@ -0,0 +1,3 @@
1
+ /** Package version, read from package.json at load time. */
2
+ declare const VERSION: string;
3
+ export { VERSION };
@@ -0,0 +1,21 @@
1
+ // @bun
2
+ // packages/tooling/src/cli/check.ts
3
+ function buildCheckCommand(options) {
4
+ const cmd = ["ultracite", "check"];
5
+ if (options.paths && options.paths.length > 0) {
6
+ cmd.push(...options.paths);
7
+ }
8
+ return cmd;
9
+ }
10
+ async function runCheck(paths = []) {
11
+ const cmd = buildCheckCommand({ paths });
12
+ process.stdout.write(`Running: bun x ${cmd.join(" ")}
13
+ `);
14
+ const proc = Bun.spawn(["bun", "x", ...cmd], {
15
+ stdio: ["inherit", "inherit", "inherit"]
16
+ });
17
+ const exitCode = await proc.exited;
18
+ process.exitCode = exitCode;
19
+ }
20
+
21
+ export { buildCheckCommand, runCheck };
@@ -0,0 +1,32 @@
1
+ // @bun
2
+ import {
3
+ printCheckTsdocHuman,
4
+ resolveJsonMode
5
+ } from "./tooling-5ynz680q.js";
6
+ import {
7
+ analyzeCheckTsdoc
8
+ } from "./tooling-5xxctk9b.js";
9
+ // packages/tooling/src/cli/check-tsdoc.ts
10
+ async function runCheckTsdoc(options = {}) {
11
+ const result = analyzeCheckTsdoc(options);
12
+ if (!result) {
13
+ process.stderr.write(`No packages found with src/index.ts entry points.
14
+ ` + `Searched: packages/*/src/index.ts, apps/*/src/index.ts, src/index.ts
15
+ ` + `Use --package <path> to specify a package path explicitly.
16
+ `);
17
+ process.exitCode = 1;
18
+ return;
19
+ }
20
+ if (resolveJsonMode(options)) {
21
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
22
+ `);
23
+ } else {
24
+ printCheckTsdocHuman(result, {
25
+ strict: options.strict,
26
+ minCoverage: options.minCoverage
27
+ });
28
+ }
29
+ process.exitCode = result.ok ? 0 : 1;
30
+ }
31
+
32
+ export { runCheckTsdoc };
@@ -0,0 +1,86 @@
1
+ // @bun
2
+ import {
3
+ entryToSubpath
4
+ } from "./tooling-ayps7c4x.js";
5
+
6
+ // packages/tooling/src/cli/internal/exports-fs.ts
7
+ function matchesExclude(subpath, excludes) {
8
+ return excludes.some((pattern) => new Bun.Glob(pattern).match(subpath));
9
+ }
10
+ var CLI_EXCLUSION_PATTERNS = [
11
+ "**/cli.ts",
12
+ "**/cli/index.ts",
13
+ "**/bin.ts",
14
+ "**/bin/index.ts"
15
+ ];
16
+ function isCliEntrypoint(entry) {
17
+ return CLI_EXCLUSION_PATTERNS.some((pattern) => new Bun.Glob(pattern).match(entry));
18
+ }
19
+ function buildExportValue(entry) {
20
+ const distPath = entry.replace(/^src\//, "").replace(/\.[cm]?[jt]sx?$/, "");
21
+ return {
22
+ import: {
23
+ types: `./dist/${distPath}.d.ts`,
24
+ default: `./dist/${distPath}.js`
25
+ }
26
+ };
27
+ }
28
+ function discoverEntries(packageRoot) {
29
+ const glob = new Bun.Glob("src/**/*.ts");
30
+ const entries = [];
31
+ for (const match of glob.scanSync({ cwd: packageRoot, dot: false })) {
32
+ if (match.includes("__tests__") || match.endsWith(".test.ts")) {
33
+ continue;
34
+ }
35
+ entries.push(match);
36
+ }
37
+ return entries.toSorted();
38
+ }
39
+ function addConfigFileExports(expected, pkg) {
40
+ const CONFIG_RE = /\.(json|jsonc|yml|yaml|toml)$/;
41
+ const configFiles = (pkg.files ?? []).filter((file) => CONFIG_RE.test(file) && file !== "package.json");
42
+ for (const file of configFiles) {
43
+ expected[`./${file}`] = `./${file}`;
44
+ let base = file.replace(CONFIG_RE, "");
45
+ const match = base.match(/^(.+)\.preset(?:\.(.+))?$/);
46
+ if (match?.[1]) {
47
+ base = match[2] ? `${match[1]}-${match[2]}` : match[1];
48
+ }
49
+ if (base !== file) {
50
+ expected[`./${base}`] = `./${file}`;
51
+ }
52
+ }
53
+ }
54
+ function computeExpectedExports(packageRoot, workspace, pkg) {
55
+ const entries = discoverEntries(packageRoot);
56
+ const exportsConfig = typeof workspace.config?.exports === "object" ? workspace.config.exports : undefined;
57
+ const excludes = exportsConfig?.exclude ?? [];
58
+ const customExports = exportsConfig?.customExports ?? {};
59
+ const expected = {};
60
+ const subpathEntries = new Map;
61
+ for (const entry of entries) {
62
+ if (isCliEntrypoint(entry))
63
+ continue;
64
+ const subpath = entryToSubpath(entry);
65
+ if (matchesExclude(subpath, excludes))
66
+ continue;
67
+ const existing = subpathEntries.get(subpath);
68
+ if (existing) {
69
+ if (!existing.endsWith("/index.ts") && entry.endsWith("/index.ts")) {
70
+ continue;
71
+ }
72
+ }
73
+ subpathEntries.set(subpath, entry);
74
+ }
75
+ for (const [subpath, entry] of subpathEntries) {
76
+ expected[subpath] = buildExportValue(entry);
77
+ }
78
+ for (const [key, value] of Object.entries(customExports)) {
79
+ expected[`./${key.replace(/^\.\//, "")}`] = value;
80
+ }
81
+ addConfigFileExports(expected, pkg);
82
+ expected["./package.json"] = "./package.json";
83
+ return expected;
84
+ }
85
+
86
+ export { computeExpectedExports };