@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
@@ -0,0 +1,421 @@
1
+ import {
2
+ __require
3
+ } from "./chunk-3s189drz.js";
4
+
5
+ // src/cli/check-tsdoc.ts
6
+ import { resolve } from "node:path";
7
+ 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
+ function isExportedDeclaration(node) {
44
+ if (ts.isExportDeclaration(node))
45
+ return false;
46
+ if (ts.isExportAssignment(node))
47
+ return false;
48
+ const isDeclaration = ts.isFunctionDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isClassDeclaration(node) || ts.isEnumDeclaration(node) || ts.isVariableStatement(node);
49
+ if (!isDeclaration)
50
+ return false;
51
+ const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
52
+ if (!modifiers)
53
+ return false;
54
+ return modifiers.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword);
55
+ }
56
+ function getDeclarationName(node) {
57
+ if (ts.isVariableStatement(node)) {
58
+ const decl = node.declarationList.declarations[0];
59
+ if (decl && ts.isIdentifier(decl.name)) {
60
+ return decl.name.text;
61
+ }
62
+ return;
63
+ }
64
+ if (ts.isFunctionDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isClassDeclaration(node) || ts.isEnumDeclaration(node)) {
65
+ return node.name?.text;
66
+ }
67
+ return;
68
+ }
69
+ function getDeclarationKind(node) {
70
+ if (ts.isFunctionDeclaration(node))
71
+ return "function";
72
+ if (ts.isInterfaceDeclaration(node))
73
+ return "interface";
74
+ if (ts.isTypeAliasDeclaration(node))
75
+ return "type";
76
+ if (ts.isClassDeclaration(node))
77
+ return "class";
78
+ if (ts.isEnumDeclaration(node))
79
+ return "enum";
80
+ if (ts.isVariableStatement(node))
81
+ return "variable";
82
+ return "unknown";
83
+ }
84
+ function hasJSDocComment(node, sourceFile) {
85
+ const sourceText = sourceFile.getFullText();
86
+ const ranges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
87
+ if (!ranges)
88
+ return false;
89
+ return ranges.some((range) => {
90
+ if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia)
91
+ return false;
92
+ const text = sourceText.slice(range.pos, range.end);
93
+ return text.startsWith("/**");
94
+ });
95
+ }
96
+ function memberHasJSDoc(member, sourceFile) {
97
+ const sourceText = sourceFile.getFullText();
98
+ const ranges = ts.getLeadingCommentRanges(sourceText, member.getFullStart());
99
+ if (!ranges)
100
+ return false;
101
+ return ranges.some((range) => {
102
+ if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia)
103
+ return false;
104
+ const text = sourceText.slice(range.pos, range.end);
105
+ return text.startsWith("/**");
106
+ });
107
+ }
108
+ function classifyDeclaration(node, sourceFile) {
109
+ const hasDoc = hasJSDocComment(node, sourceFile);
110
+ if (!hasDoc)
111
+ return "undocumented";
112
+ if (ts.isInterfaceDeclaration(node) || ts.isClassDeclaration(node)) {
113
+ const members = node.members;
114
+ if (members.length > 0) {
115
+ const allMembersDocumented = members.every((member) => memberHasJSDoc(member, sourceFile));
116
+ if (!allMembersDocumented)
117
+ return "partial";
118
+ }
119
+ }
120
+ return "documented";
121
+ }
122
+ function analyzeSourceFile(sourceFile) {
123
+ const results = [];
124
+ for (const statement of sourceFile.statements) {
125
+ if (!isExportedDeclaration(statement))
126
+ continue;
127
+ const name = getDeclarationName(statement);
128
+ if (!name)
129
+ continue;
130
+ const kind = getDeclarationKind(statement);
131
+ const level = classifyDeclaration(statement, sourceFile);
132
+ const { line } = sourceFile.getLineAndCharacterOfPosition(statement.getStart(sourceFile));
133
+ results.push({
134
+ name,
135
+ kind,
136
+ level,
137
+ file: sourceFile.fileName,
138
+ line: line + 1
139
+ });
140
+ }
141
+ return results;
142
+ }
143
+ function calculateCoverage(declarations) {
144
+ const total = declarations.length;
145
+ if (total === 0) {
146
+ return {
147
+ documented: 0,
148
+ partial: 0,
149
+ undocumented: 0,
150
+ total: 0,
151
+ percentage: 100
152
+ };
153
+ }
154
+ const documented = declarations.filter((d) => d.level === "documented").length;
155
+ const partial = declarations.filter((d) => d.level === "partial").length;
156
+ const undocumented = declarations.filter((d) => d.level === "undocumented").length;
157
+ const score = documented + partial * 0.5;
158
+ const percentage = Math.round(score / total * 100);
159
+ return { documented, partial, undocumented, total, percentage };
160
+ }
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
+ function discoverPackages(cwd) {
180
+ const packages = [];
181
+ const seenEntryPoints = new Set;
182
+ for (const pattern of ["packages/*/src/index.ts", "apps/*/src/index.ts"]) {
183
+ const glob = new Bun.Glob(pattern);
184
+ for (const match of glob.scanSync({ cwd, dot: false })) {
185
+ const parts = match.split("/");
186
+ const rootDir = parts[0];
187
+ const pkgDir = parts[1];
188
+ if (!rootDir || !pkgDir)
189
+ continue;
190
+ const entryPoint = resolve(cwd, match);
191
+ if (seenEntryPoints.has(entryPoint)) {
192
+ continue;
193
+ }
194
+ seenEntryPoints.add(entryPoint);
195
+ const pkgRoot = resolve(cwd, rootDir, pkgDir);
196
+ let pkgName = pkgDir;
197
+ try {
198
+ const pkgJson = JSON.parse(__require("node:fs").readFileSync(resolve(pkgRoot, "package.json"), "utf-8"));
199
+ if (pkgJson.name)
200
+ pkgName = pkgJson.name;
201
+ } catch {}
202
+ packages.push({
203
+ name: pkgName,
204
+ path: pkgRoot,
205
+ entryPoint
206
+ });
207
+ }
208
+ }
209
+ if (packages.length === 0) {
210
+ const entryPoint = resolve(cwd, "src/index.ts");
211
+ try {
212
+ __require("node:fs").accessSync(entryPoint);
213
+ let pkgName = "root";
214
+ try {
215
+ const pkgJson = JSON.parse(__require("node:fs").readFileSync(resolve(cwd, "package.json"), "utf-8"));
216
+ if (pkgJson.name)
217
+ pkgName = pkgJson.name;
218
+ } catch {}
219
+ packages.push({
220
+ name: pkgName,
221
+ path: cwd,
222
+ entryPoint
223
+ });
224
+ seenEntryPoints.add(entryPoint);
225
+ } catch {}
226
+ }
227
+ return packages.sort((a, b) => a.name.localeCompare(b.name));
228
+ }
229
+ function collectReExportedSourceFiles(sourceFile, program, pkgPath) {
230
+ const result = [];
231
+ const seen = new Set;
232
+ for (const statement of sourceFile.statements) {
233
+ if (!ts.isExportDeclaration(statement))
234
+ continue;
235
+ if (!statement.moduleSpecifier)
236
+ continue;
237
+ if (!ts.isStringLiteral(statement.moduleSpecifier))
238
+ continue;
239
+ const specifier = statement.moduleSpecifier.text;
240
+ if (!specifier.startsWith("."))
241
+ continue;
242
+ const resolvedModule = ts.resolveModuleName(specifier, sourceFile.fileName, program.getCompilerOptions(), ts.sys);
243
+ const resolvedFileName = resolvedModule.resolvedModule?.resolvedFileName;
244
+ if (!resolvedFileName)
245
+ continue;
246
+ if (!resolvedFileName.startsWith(pkgPath))
247
+ continue;
248
+ if (seen.has(resolvedFileName))
249
+ continue;
250
+ seen.add(resolvedFileName);
251
+ const sf = program.getSourceFile(resolvedFileName);
252
+ if (sf)
253
+ result.push(sf);
254
+ }
255
+ return result;
256
+ }
257
+ function analyzePackage(pkg, workspaceCwd) {
258
+ try {
259
+ __require("node:fs").accessSync(pkg.entryPoint);
260
+ } catch {
261
+ return {
262
+ name: pkg.name,
263
+ path: pkg.path,
264
+ declarations: [],
265
+ documented: 0,
266
+ partial: 0,
267
+ undocumented: 0,
268
+ total: 0,
269
+ percentage: 0
270
+ };
271
+ }
272
+ let tsconfigPath = resolve(pkg.path, "tsconfig.json");
273
+ try {
274
+ __require("node:fs").accessSync(tsconfigPath);
275
+ } catch {
276
+ tsconfigPath = resolve(workspaceCwd, "tsconfig.json");
277
+ }
278
+ const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
279
+ const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, pkg.path);
280
+ const program = ts.createProgram({
281
+ rootNames: [pkg.entryPoint],
282
+ options: parsedConfig.options,
283
+ host: ts.createCompilerHost(parsedConfig.options)
284
+ });
285
+ const sourceFile = program.getSourceFile(pkg.entryPoint);
286
+ if (!sourceFile) {
287
+ return {
288
+ name: pkg.name,
289
+ path: pkg.path,
290
+ declarations: [],
291
+ documented: 0,
292
+ partial: 0,
293
+ undocumented: 0,
294
+ total: 0,
295
+ percentage: 0
296
+ };
297
+ }
298
+ const declarations = analyzeSourceFile(sourceFile);
299
+ const reExportedFiles = collectReExportedSourceFiles(sourceFile, program, pkg.path);
300
+ for (const sf of reExportedFiles) {
301
+ declarations.push(...analyzeSourceFile(sf));
302
+ }
303
+ const stats = calculateCoverage(declarations);
304
+ return {
305
+ name: pkg.name,
306
+ path: pkg.path,
307
+ declarations,
308
+ ...stats
309
+ };
310
+ }
311
+ function analyzeCheckTsdoc(options = {}) {
312
+ const cwd = options.cwd ? resolve(options.cwd) : process.cwd();
313
+ const minCoverage = options.minCoverage ?? 0;
314
+ let packages;
315
+ if (options.paths && options.paths.length > 0) {
316
+ packages = options.paths.map((p) => {
317
+ const absPath = resolve(cwd, p);
318
+ const entryPoint = resolve(absPath, "src/index.ts");
319
+ let name = p;
320
+ try {
321
+ const pkgJson = JSON.parse(__require("node:fs").readFileSync(resolve(absPath, "package.json"), "utf-8"));
322
+ if (pkgJson.name)
323
+ name = pkgJson.name;
324
+ } catch {}
325
+ return { name, path: absPath, entryPoint };
326
+ });
327
+ } else {
328
+ packages = discoverPackages(cwd);
329
+ }
330
+ if (packages.length === 0) {
331
+ return null;
332
+ }
333
+ const packageResults = [];
334
+ for (const pkg of packages) {
335
+ packageResults.push(analyzePackage(pkg, cwd));
336
+ }
337
+ const allDeclarations = packageResults.flatMap((p) => p.declarations);
338
+ const summary = calculateCoverage(allDeclarations);
339
+ const ok = !options.strict || summary.percentage >= minCoverage;
340
+ return {
341
+ ok,
342
+ packages: packageResults,
343
+ summary
344
+ };
345
+ }
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
+
421
+ export { coverageLevelSchema, declarationCoverageSchema, packageCoverageSchema, tsDocCheckResultSchema, analyzeSourceFile, calculateCoverage, analyzeCheckTsdoc, printCheckTsdocHuman, runCheckTsdoc, VERSION };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@outfitter/tooling",
3
3
  "description": "Dev tooling configuration presets for Outfitter projects (biome, typescript, lefthook, markdownlint)",
4
- "version": "0.2.4",
4
+ "version": "0.3.3",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -31,6 +31,12 @@
31
31
  "default": "./dist/cli/check.js"
32
32
  }
33
33
  },
34
+ "./cli/check-tsdoc": {
35
+ "import": {
36
+ "types": "./dist/cli/check-tsdoc.d.ts",
37
+ "default": "./dist/cli/check-tsdoc.js"
38
+ }
39
+ },
34
40
  "./cli/fix": {
35
41
  "import": {
36
42
  "types": "./dist/cli/fix.d.ts",
@@ -70,19 +76,20 @@
70
76
  "prepack": "bun run sync:exports",
71
77
  "lint": "biome lint ./src",
72
78
  "lint:fix": "biome lint --write ./src",
73
- "test": "bun test",
79
+ "test": "bun run build:registry && bun test",
74
80
  "typecheck": "tsc --noEmit",
75
81
  "clean": "rm -rf dist registry",
76
82
  "prepublishOnly": "bun ../../scripts/check-publish-manifest.ts"
77
83
  },
78
84
  "dependencies": {
79
- "@outfitter/cli": "0.5.1",
85
+ "@outfitter/cli": "0.5.2",
80
86
  "commander": "^14.0.2",
81
- "zod": "^3.25.17"
87
+ "typescript": "^5.9.3",
88
+ "zod": "^4.3.5"
82
89
  },
83
90
  "devDependencies": {
84
- "@types/bun": "^1.3.7",
85
- "typescript": "^5.9.3",
91
+ "@outfitter/presets": "0.2.0",
92
+ "@types/bun": "^1.3.9",
86
93
  "yaml": "^2.8.2"
87
94
  },
88
95
  "peerDependencies": {
@@ -102,7 +109,7 @@
102
109
  }
103
110
  },
104
111
  "engines": {
105
- "bun": ">=1.3.7"
112
+ "bun": ">=1.3.9"
106
113
  },
107
114
  "keywords": [
108
115
  "outfitter",
@@ -22,11 +22,11 @@
22
22
  "files": [
23
23
  {
24
24
  "path": "biome.json",
25
- "content": "{\n\t\"$schema\": \"https://biomejs.dev/schemas/2.3.12/schema.json\",\n\t\"root\": false,\n\t\"javascript\": {\n\t\t\"globals\": [\"Bun\"]\n\t},\n\t\"linter\": {\n\t\t\"rules\": {\n\t\t\t\"complexity\": {\n\t\t\t\t\"useLiteralKeys\": \"off\",\n\t\t\t\t\"noVoid\": \"off\",\n\t\t\t\t\"noExcessiveCognitiveComplexity\": \"off\"\n\t\t\t},\n\t\t\t\"performance\": {\n\t\t\t\t\"useTopLevelRegex\": \"off\"\n\t\t\t},\n\t\t\t\"style\": {\n\t\t\t\t\"useBlockStatements\": \"off\"\n\t\t\t},\n\t\t\t\"suspicious\": {\n\t\t\t\t\"noConsole\": \"error\"\n\t\t\t}\n\t\t}\n\t},\n\t\"vcs\": {\n\t\t\"enabled\": true,\n\t\t\"clientKind\": \"git\",\n\t\t\"useIgnoreFile\": true\n\t},\n\t\"files\": {\n\t\t\"ignoreUnknown\": true,\n\t\t\"includes\": [\n\t\t\t\"**\",\n\t\t\t\"!**/node_modules\",\n\t\t\t\"!**/dist\",\n\t\t\t\"!**/.turbo\",\n\t\t\t\"!**/*.gen.ts\",\n\t\t\t\"!registry/registry.json\"\n\t\t]\n\t},\n\t\"overrides\": [\n\t\t{\n\t\t\t\"includes\": [\n\t\t\t\t\"packages/*/src/index.ts\",\n\t\t\t\t\"apps/*/src/index.ts\",\n\t\t\t\t\"**/index.ts\"\n\t\t\t],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"performance\": {\n\t\t\t\t\t\t\"noBarrelFile\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"includes\": [\"**/*.test.ts\", \"**/__tests__/**/*\"],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"suspicious\": {\n\t\t\t\t\t\t\"useAwait\": \"off\",\n\t\t\t\t\t\t\"noConsole\": \"off\"\n\t\t\t\t\t},\n\t\t\t\t\t\"performance\": {\n\t\t\t\t\t\t\"noDelete\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"includes\": [\"apps/**/*.ts\", \"scripts/**/*.ts\", \"**/scripts/**/*.ts\"],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"suspicious\": {\n\t\t\t\t\t\t\"noConsole\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n"
25
+ "content": "{\n\t\"$schema\": \"https://biomejs.dev/schemas/2.4.4/schema.json\",\n\t\"root\": false,\n\t\"javascript\": {\n\t\t\"globals\": [\"Bun\"]\n\t},\n\t\"linter\": {\n\t\t\"rules\": {\n\t\t\t\"complexity\": {\n\t\t\t\t\"useLiteralKeys\": \"off\",\n\t\t\t\t\"noVoid\": \"off\",\n\t\t\t\t\"noExcessiveCognitiveComplexity\": \"off\"\n\t\t\t},\n\t\t\t\"performance\": {\n\t\t\t\t\"useTopLevelRegex\": \"off\"\n\t\t\t},\n\t\t\t\"style\": {\n\t\t\t\t\"useBlockStatements\": \"off\"\n\t\t\t},\n\t\t\t\"suspicious\": {\n\t\t\t\t\"noConsole\": \"error\"\n\t\t\t}\n\t\t}\n\t},\n\t\"vcs\": {\n\t\t\"enabled\": true,\n\t\t\"clientKind\": \"git\",\n\t\t\"useIgnoreFile\": true\n\t},\n\t\"files\": {\n\t\t\"ignoreUnknown\": true,\n\t\t\"includes\": [\n\t\t\t\"**\",\n\t\t\t\"!**/node_modules\",\n\t\t\t\"!**/dist\",\n\t\t\t\"!**/.turbo\",\n\t\t\t\"!**/*.gen.ts\",\n\t\t\t\"!registry/registry.json\"\n\t\t]\n\t},\n\t\"overrides\": [\n\t\t{\n\t\t\t\"includes\": [\n\t\t\t\t\"packages/*/src/index.ts\",\n\t\t\t\t\"apps/*/src/index.ts\",\n\t\t\t\t\"**/index.ts\"\n\t\t\t],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"performance\": {\n\t\t\t\t\t\t\"noBarrelFile\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"includes\": [\"**/*.test.ts\", \"**/__tests__/**/*\"],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"suspicious\": {\n\t\t\t\t\t\t\"useAwait\": \"off\",\n\t\t\t\t\t\t\"noConsole\": \"off\"\n\t\t\t\t\t},\n\t\t\t\t\t\"performance\": {\n\t\t\t\t\t\t\"noDelete\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"includes\": [\"apps/**/*.ts\", \"scripts/**/*.ts\", \"**/scripts/**/*.ts\"],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"suspicious\": {\n\t\t\t\t\t\t\"noConsole\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n}\n"
26
26
  }
27
27
  ],
28
28
  "devDependencies": {
29
- "ultracite": "^7.1.1"
29
+ "ultracite": "7.2.3"
30
30
  }
31
31
  },
32
32
  "lefthook": {
@@ -39,9 +39,9 @@
39
39
  }
40
40
  ],
41
41
  "devDependencies": {
42
- "@outfitter/tooling": "^0.2.1",
43
- "lefthook": "^2.0.16",
44
- "ultracite": "^7.1.1"
42
+ "@outfitter/tooling": "^0.3.3",
43
+ "lefthook": "^2.1.1",
44
+ "ultracite": "7.2.3"
45
45
  }
46
46
  },
47
47
  "markdownlint": {
@@ -60,7 +60,7 @@
60
60
  "files": [
61
61
  {
62
62
  "path": "scripts/bootstrap.sh",
63
- "content": "#!/usr/bin/env bash\n#\n# bootstrap.sh — Get this repo from clone to runnable\n#\n# Usage: ./scripts/bootstrap.sh [--force]\n#\n# By default, exits immediately if all tools and deps are present.\n# Use --force to run full bootstrap regardless.\n#\n\nset -euo pipefail\n\n# -----------------------------------------------------------------------------\n# Fast path — exit immediately if all tools and deps are present\n# -----------------------------------------------------------------------------\nif [[ \"${1:-}\" != \"--force\" ]]; then\n all_present=true\n command -v bun &>/dev/null || all_present=false\n command -v gh &>/dev/null || all_present=false\n command -v gt &>/dev/null || all_present=false\n command -v markdownlint-cli2 &>/dev/null || all_present=false\n [[ -d \"node_modules\" ]] || all_present=false\n\n if $all_present; then\n exit 0 # All good, nothing to do\n fi\nfi\n\n# Strip --force if present\n[[ \"${1:-}\" == \"--force\" ]] && shift\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[0;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m' # No Color\n\ninfo() { echo -e \"${BLUE}▸${NC} $1\"; }\nsuccess() { echo -e \"${GREEN}✓${NC} $1\"; }\nwarn() { echo -e \"${YELLOW}!${NC} $1\"; }\nerror() { echo -e \"${RED}✗${NC} $1\" >&2; }\n\n# Check if command exists\nhas() { command -v \"$1\" &>/dev/null; }\n\n# Detect OS\nOS=\"$(uname -s)\"\ncase \"$OS\" in\n Darwin) IS_MACOS=true ;;\n Linux) IS_MACOS=false ;;\n *) error \"Unsupported OS: $OS\"; exit 1 ;;\nesac\n\n# -----------------------------------------------------------------------------\n# Homebrew (macOS only)\n# -----------------------------------------------------------------------------\ninstall_homebrew() {\n if $IS_MACOS && ! has brew; then\n info \"Installing Homebrew...\"\n /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n success \"Homebrew installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Bun\n# -----------------------------------------------------------------------------\ninstall_bun() {\n if has bun; then\n success \"Bun already installed ($(bun --version))\"\n else\n info \"Installing Bun...\"\n curl -fsSL https://bun.sh/install | bash\n # Source the updated profile\n export BUN_INSTALL=\"$HOME/.bun\"\n export PATH=\"$BUN_INSTALL/bin:$PATH\"\n success \"Bun installed ($(bun --version))\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# GitHub CLI (gh)\n# -----------------------------------------------------------------------------\ninstall_gh() {\n if has gh; then\n success \"GitHub CLI already installed ($(gh --version | head -1))\"\n else\n info \"Installing GitHub CLI...\"\n if $IS_MACOS; then\n brew install gh\n else\n # Linux: use official apt repo\n curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg\n echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null\n sudo apt update && sudo apt install gh -y\n fi\n success \"GitHub CLI installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Graphite CLI (gt)\n# -----------------------------------------------------------------------------\ninstall_graphite() {\n if has gt; then\n success \"Graphite CLI already installed ($(gt --version 2>/dev/null || echo 'unknown'))\"\n else\n info \"Installing Graphite CLI...\"\n if $IS_MACOS && has brew; then\n brew install withgraphite/tap/graphite\n else\n bun install -g @withgraphite/graphite-cli\n fi\n success \"Graphite CLI installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# markdownlint-cli2\n# -----------------------------------------------------------------------------\ninstall_markdownlint() {\n if has markdownlint-cli2; then\n success \"markdownlint-cli2 already installed\"\n else\n info \"Installing markdownlint-cli2...\"\n bun install -g markdownlint-cli2\n success \"markdownlint-cli2 installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Auth checks\n# -----------------------------------------------------------------------------\ncheck_auth() {\n echo \"\"\n info \"Checking authentication...\"\n\n # GitHub CLI\n if [[ -n \"${GH_TOKEN:-}\" ]] || [[ -n \"${GITHUB_TOKEN:-}\" ]]; then\n success \"GitHub CLI token found in environment\"\n elif gh auth status &>/dev/null; then\n success \"GitHub CLI already authenticated\"\n else\n echo \" GitHub CLI not authenticated. Run 'gh auth login' or set GH_TOKEN\"\n fi\n\n # Graphite CLI\n if [[ -n \"${GT_AUTH_TOKEN:-}\" ]]; then\n info \"Authenticating Graphite CLI...\"\n gt auth --token \"$GT_AUTH_TOKEN\"\n success \"Graphite CLI authenticated\"\n elif gt auth status &>/dev/null 2>&1; then\n success \"Graphite CLI already authenticated\"\n else\n echo \" Graphite CLI not authenticated. Run 'gt auth' or set GT_AUTH_TOKEN\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Project dependencies\n# -----------------------------------------------------------------------------\ninstall_deps() {\n info \"Installing project dependencies...\"\n bun install\n success \"Dependencies installed\"\n}\n\n# -----------------------------------------------------------------------------\n# Main\n# -----------------------------------------------------------------------------\nmain() {\n echo \"\"\n echo -e \"${BLUE}Outfitter Kit Bootstrap${NC}\"\n echo \"────────────────────────\"\n echo \"\"\n\n # Prerequisites\n if $IS_MACOS; then\n install_homebrew\n fi\n\n # Core tools\n install_bun\n install_gh\n install_graphite\n install_markdownlint\n\n # Auth status\n check_auth\n\n echo \"\"\n\n # Project setup\n install_deps\n\n echo \"\"\n echo -e \"${GREEN}Bootstrap complete!${NC}\"\n echo \"\"\n echo \"Next steps:\"\n echo \" bun run build # Build all packages\"\n echo \" bun run test # Run tests\"\n echo \"\"\n}\n\nmain \"$@\"\n",
63
+ "content": "#!/usr/bin/env bash\n#\n# bootstrap.sh — Get this repo from clone to runnable\n#\n# Usage: ./scripts/bootstrap.sh [--force]\n#\n# By default, exits immediately if all tools and deps are present.\n# Use --force to run full bootstrap regardless.\n#\n# This is the generic template distributed via `outfitter add bootstrap`.\n# It does NOT include project-specific tools like Graphite.\n# Add project-specific tools by extending this script or using the\n# TS bootstrap API's `extend` callback.\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]}\")\" && pwd)\"\nREPO_ROOT=\"$(cd -- \"$SCRIPT_DIR/..\" && pwd)\"\nBUN_VERSION_FILE=\"$REPO_ROOT/.bun-version\"\nPINNED_BUN_VERSION=\"\"\n\nif [[ -f \"$BUN_VERSION_FILE\" ]]; then\n PINNED_BUN_VERSION=\"$(tr -d '[:space:]' < \"$BUN_VERSION_FILE\")\"\n if [[ -z \"$PINNED_BUN_VERSION\" ]]; then\n echo \"Warning: .bun-version is empty; falling back to latest Bun install\" >&2\n fi\nfi\n\n# -----------------------------------------------------------------------------\n# Fast path — exit immediately if all tools and deps are present\n# -----------------------------------------------------------------------------\nif [[ \"${1:-}\" != \"--force\" ]]; then\n all_present=true\n\n if command -v bun &>/dev/null; then\n installed_bun_version=\"$(bun --version)\"\n if [[ -n \"$PINNED_BUN_VERSION\" ]]; then\n [[ \"$installed_bun_version\" == \"$PINNED_BUN_VERSION\" ]] || all_present=false\n fi\n else\n all_present=false\n fi\n\n command -v gh &>/dev/null || all_present=false\n command -v markdownlint-cli2 &>/dev/null || all_present=false\n [[ -d \"$REPO_ROOT/node_modules\" ]] || all_present=false\n\n if $all_present; then\n exit 0 # All good, nothing to do\n fi\nfi\n\n# Strip --force if present\n[[ \"${1:-}\" == \"--force\" ]] && shift\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[0;33m'\nBLUE='\\033[0;34m'\nNC='\\033[0m' # No Color\n\ninfo() { echo -e \"${BLUE}▸${NC} $1\"; }\nsuccess() { echo -e \"${GREEN}✓${NC} $1\"; }\nwarn() { echo -e \"${YELLOW}!${NC} $1\"; }\nerror() { echo -e \"${RED}✗${NC} $1\" >&2; }\n\n# Check if command exists\nhas() { command -v \"$1\" &>/dev/null; }\n\n# Detect OS\nOS=\"$(uname -s)\"\ncase \"$OS\" in\n Darwin) IS_MACOS=true ;;\n Linux) IS_MACOS=false ;;\n *) error \"Unsupported OS: $OS\"; exit 1 ;;\nesac\n\n# -----------------------------------------------------------------------------\n# Homebrew (macOS only)\n# -----------------------------------------------------------------------------\ninstall_homebrew() {\n if $IS_MACOS && ! has brew; then\n info \"Installing Homebrew...\"\n /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n success \"Homebrew installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Bun\n# -----------------------------------------------------------------------------\ninstall_bun() {\n local installed_bun_version=\"\"\n\n if has bun; then\n installed_bun_version=\"$(bun --version)\"\n fi\n\n if [[ -n \"$installed_bun_version\" ]]; then\n if [[ -n \"$PINNED_BUN_VERSION\" && \"$installed_bun_version\" == \"$PINNED_BUN_VERSION\" ]]; then\n success \"Bun already installed ($installed_bun_version)\"\n return\n fi\n if [[ -z \"$PINNED_BUN_VERSION\" ]]; then\n success \"Bun already installed ($installed_bun_version)\"\n return\n fi\n fi\n\n if [[ -n \"$PINNED_BUN_VERSION\" && -n \"$installed_bun_version\" ]]; then\n info \"Updating Bun from $installed_bun_version to $PINNED_BUN_VERSION...\"\n elif [[ -n \"$PINNED_BUN_VERSION\" ]]; then\n info \"Installing Bun $PINNED_BUN_VERSION...\"\n else\n info \"Installing Bun (latest stable)...\"\n fi\n\n if [[ -n \"$PINNED_BUN_VERSION\" ]]; then\n curl -fsSL https://bun.sh/install | bash -s -- \"bun-v$PINNED_BUN_VERSION\"\n else\n curl -fsSL https://bun.sh/install | bash\n fi\n\n # Source the updated profile\n export BUN_INSTALL=\"$HOME/.bun\"\n export PATH=\"$BUN_INSTALL/bin:$PATH\"\n hash -r\n\n local resolved_bun_version\n resolved_bun_version=\"$(bun --version)\"\n\n if [[ -n \"$PINNED_BUN_VERSION\" && \"$resolved_bun_version\" != \"$PINNED_BUN_VERSION\" ]]; then\n error \"Expected Bun $PINNED_BUN_VERSION but found $resolved_bun_version after install\"\n exit 1\n fi\n\n success \"Bun ready ($resolved_bun_version)\"\n}\n\n# -----------------------------------------------------------------------------\n# GitHub CLI (gh)\n# -----------------------------------------------------------------------------\ninstall_gh() {\n if has gh; then\n success \"GitHub CLI already installed ($(gh --version | head -1))\"\n else\n info \"Installing GitHub CLI...\"\n if $IS_MACOS; then\n brew install gh\n else\n # Linux: use official apt repo\n curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg\n echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null\n sudo apt update && sudo apt install gh -y\n fi\n success \"GitHub CLI installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# markdownlint-cli2\n# -----------------------------------------------------------------------------\ninstall_markdownlint() {\n if has markdownlint-cli2; then\n success \"markdownlint-cli2 already installed\"\n else\n info \"Installing markdownlint-cli2...\"\n bun install -g markdownlint-cli2\n success \"markdownlint-cli2 installed\"\n fi\n}\n\n# -----------------------------------------------------------------------------\n# Auth checks\n# -----------------------------------------------------------------------------\ncheck_auth() {\n echo \"\"\n info \"Checking authentication...\"\n\n # GitHub CLI\n if [[ -n \"${GH_TOKEN:-}\" ]] || [[ -n \"${GITHUB_TOKEN:-}\" ]]; then\n success \"GitHub CLI token found in environment\"\n elif gh auth status &>/dev/null; then\n success \"GitHub CLI already authenticated\"\n else\n echo \" GitHub CLI not authenticated. Run 'gh auth login' or set GH_TOKEN\"\n fi\n\n # Add project-specific auth checks (e.g., Graphite) below\n}\n\n# -----------------------------------------------------------------------------\n# Project dependencies\n# -----------------------------------------------------------------------------\ninstall_deps() {\n info \"Installing project dependencies...\"\n (\n cd \"$REPO_ROOT\"\n bun install\n )\n success \"Dependencies installed\"\n}\n\n# -----------------------------------------------------------------------------\n# Main\n# -----------------------------------------------------------------------------\nmain() {\n echo \"\"\n echo -e \"${BLUE}Outfitter Bootstrap${NC}\"\n echo \"────────────────────────\"\n echo \"\"\n\n # Prerequisites\n if $IS_MACOS; then\n install_homebrew\n fi\n\n # Core tools\n install_bun\n install_gh\n install_markdownlint\n # Add project-specific tools (e.g., Graphite) below\n\n # Auth status\n check_auth\n\n echo \"\"\n\n # Project setup\n install_deps\n\n echo \"\"\n echo -e \"${GREEN}Bootstrap complete!${NC}\"\n echo \"\"\n echo \"Next steps:\"\n echo \" bun run build # Build all packages\"\n echo \" bun run test # Run tests\"\n echo \"\"\n}\n\nmain \"$@\"\n",
64
64
  "executable": true
65
65
  }
66
66
  ]
@@ -1,34 +0,0 @@
1
- interface ScriptLocation {
2
- readonly file: string;
3
- readonly scriptName: string;
4
- readonly command: string;
5
- }
6
- interface BoundaryViolation extends ScriptLocation {
7
- readonly rule: "root-runs-package-src" | "cd-package-then-runs-src";
8
- }
9
- interface ReadScriptEntriesOptions {
10
- readonly appManifestRelativePaths?: readonly string[];
11
- readonly readPackageJson?: (filePath: string) => Promise<{
12
- scripts?: Record<string, string>;
13
- }>;
14
- }
15
- /**
16
- * Detect whether a single script command violates boundary invocation rules.
17
- */
18
- declare function detectBoundaryViolation(location: ScriptLocation): BoundaryViolation | null;
19
- /**
20
- * Find all boundary violations across package/app script maps.
21
- */
22
- declare function findBoundaryViolations(entries: readonly {
23
- file: string;
24
- scripts: Readonly<Record<string, string>>;
25
- }[]): BoundaryViolation[];
26
- declare function readScriptEntries(cwd: string, options?: ReadScriptEntriesOptions): Promise<{
27
- file: string;
28
- scripts: Record<string, string>;
29
- }[]>;
30
- /**
31
- * Run boundary invocation checks against root/apps package scripts.
32
- */
33
- declare function runCheckBoundaryInvocations(): Promise<void>;
34
- export { runCheckBoundaryInvocations, readScriptEntries, findBoundaryViolations, detectBoundaryViolation, ScriptLocation, BoundaryViolation };
@@ -1,14 +0,0 @@
1
- // @bun
2
- import {
3
- detectBoundaryViolation,
4
- findBoundaryViolations,
5
- readScriptEntries,
6
- runCheckBoundaryInvocations
7
- } from "../shared/@outfitter/tooling-r9976n43.js";
8
- import"../shared/@outfitter/tooling-dvwh9qve.js";
9
- export {
10
- runCheckBoundaryInvocations,
11
- readScriptEntries,
12
- findBoundaryViolations,
13
- detectBoundaryViolation
14
- };
@@ -1,36 +0,0 @@
1
- /** Result of checking bunup workspace registration */
2
- interface RegistryCheckResult {
3
- readonly ok: boolean;
4
- readonly missing: string[];
5
- }
6
- /**
7
- * Extract the package name from a build script containing `bunup --filter`.
8
- *
9
- * @example
10
- * extractBunupFilterName("bunup --filter @outfitter/logging")
11
- * // => "@outfitter/logging"
12
- *
13
- * extractBunupFilterName("cd ../.. && bunup --filter @outfitter/types")
14
- * // => "@outfitter/types"
15
- *
16
- * extractBunupFilterName("tsc --noEmit")
17
- * // => null
18
- */
19
- declare function extractBunupFilterName(script: string): string | null;
20
- /**
21
- * Find packages that have `bunup --filter` build scripts but are not
22
- * registered in the bunup workspace config.
23
- *
24
- * @param packagesWithFilter - Package names that have `bunup --filter` in their build script
25
- * @param registeredNames - Package names registered in bunup.config.ts
26
- * @returns Result with sorted list of missing packages
27
- */
28
- declare function findUnregisteredPackages(packagesWithFilter: string[], registeredNames: string[]): RegistryCheckResult;
29
- /**
30
- * Run bunup registry check across all workspace packages.
31
- *
32
- * Scans packages/&#42;/package.json for build scripts containing `bunup --filter`,
33
- * then verifies each is registered in bunup.config.ts.
34
- */
35
- declare function runCheckBunupRegistry(): Promise<void>;
36
- export { runCheckBunupRegistry, findUnregisteredPackages, extractBunupFilterName, RegistryCheckResult };
@@ -1,12 +0,0 @@
1
- // @bun
2
- import {
3
- extractBunupFilterName,
4
- findUnregisteredPackages,
5
- runCheckBunupRegistry
6
- } from "../shared/@outfitter/tooling-t17gnh9b.js";
7
- import"../shared/@outfitter/tooling-dvwh9qve.js";
8
- export {
9
- runCheckBunupRegistry,
10
- findUnregisteredPackages,
11
- extractBunupFilterName
12
- };