@williamthorsen/nmr 0.34.0 → 0.36.0

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 (65) hide show
  1. package/.meta/changelog.json +1416 -0
  2. package/.readyup/kits/default.js +174 -19
  3. package/.readyup/manifest.json +11 -8
  4. package/CHANGELOG.md +894 -0
  5. package/README.md +91 -18
  6. package/agents/guidance/rulebooks/nmr.md +1 -1
  7. package/dist/esm/UserError.d.ts +6 -0
  8. package/dist/esm/check-cache.d.ts +145 -0
  9. package/dist/esm/commands/build-output.d.ts +64 -0
  10. package/dist/esm/commands/build.d.ts +29 -1
  11. package/dist/esm/commands/build.js +26 -6
  12. package/dist/esm/commands/clean.d.ts +15 -0
  13. package/dist/esm/commands/ensure-prepublish-hooks.d.ts +11 -0
  14. package/dist/esm/commands/fmt.d.ts +32 -0
  15. package/dist/esm/commands/report-catalog.d.ts +10 -0
  16. package/dist/esm/commands/report-overrides.d.ts +6 -0
  17. package/dist/esm/commands/taze.d.ts +18 -0
  18. package/dist/esm/config.d.ts +19 -2
  19. package/dist/esm/config.js +66 -9
  20. package/dist/esm/context.d.ts +11 -0
  21. package/dist/esm/default-scripts.d.ts +15 -0
  22. package/dist/esm/defineConfig.d.ts +9 -0
  23. package/dist/esm/help.d.ts +13 -0
  24. package/dist/esm/helpers/clampToBytes.d.ts +12 -0
  25. package/dist/esm/helpers/config-path.d.ts +8 -0
  26. package/dist/esm/helpers/config-path.js +7 -0
  27. package/dist/esm/helpers/createBoundedBuffer.d.ts +7 -0
  28. package/dist/esm/helpers/deriveExcerpt.d.ts +10 -0
  29. package/dist/esm/helpers/duration.d.ts +15 -0
  30. package/dist/esm/helpers/findClosestName.d.ts +7 -0
  31. package/dist/esm/helpers/findClosestName.js +38 -0
  32. package/dist/esm/helpers/hook-name.d.ts +8 -0
  33. package/dist/esm/helpers/package-json.d.ts +25 -0
  34. package/dist/esm/helpers/package-json.js +1 -1
  35. package/dist/esm/helpers/readStringValues.d.ts +7 -0
  36. package/dist/esm/helpers/reportClosing.d.ts +15 -0
  37. package/dist/esm/helpers/transcript.d.ts +25 -0
  38. package/dist/esm/helpers/type-guards.d.ts +1 -0
  39. package/dist/esm/helpers/workspace-patterns.d.ts +7 -0
  40. package/dist/esm/prettier.d.ts +8 -0
  41. package/dist/esm/recording.d.ts +39 -1
  42. package/dist/esm/replay-assembly.d.ts +18 -2
  43. package/dist/esm/report-format.d.ts +33 -0
  44. package/dist/esm/reportCliFailure.d.ts +8 -0
  45. package/dist/esm/resolve-scripts.d.ts +10 -1
  46. package/dist/esm/resolver.d.ts +67 -2
  47. package/dist/esm/resolver.js +1 -1
  48. package/dist/esm/runCli.d.ts +17 -0
  49. package/dist/esm/runCli.js +2 -2
  50. package/dist/esm/runner.d.ts +52 -0
  51. package/dist/esm/scripts.d.ts +1 -0
  52. package/dist/esm/steps.d.ts +71 -0
  53. package/dist/esm/taze.d.ts +16 -0
  54. package/dist/esm/tests.d.ts +40 -0
  55. package/dist/esm/tests.js +25 -0
  56. package/dist/esm/tiers.d.ts +56 -1
  57. package/dist/esm/tiers.js +22 -9
  58. package/dist/esm/types.d.ts +28 -0
  59. package/dist/esm/verbosity.d.ts +37 -0
  60. package/dist/esm/verdict.d.ts +45 -0
  61. package/dist/esm/vitest-git-isolation.js +6 -0
  62. package/dist/esm/vitest.d.ts +72 -2
  63. package/dist/esm/vitest.js +17 -9
  64. package/dist/esm/workspace.d.ts +18 -0
  65. package/package.json +20 -10
@@ -1,19 +1,40 @@
1
- /** @noformat — @generated. Do not edit. Compiled by rdy. */
1
+ /** @noformat -- @generated. Do not edit. Compiled by rdy. */
2
2
  /* eslint-disable */
3
- export const __readyupVersion = "0.32.0";
3
+ export const __readyupVersion = "0.35.0";
4
4
 
5
5
 
6
6
  // .readyup/kits/default.ts
7
7
  import { existsSync, globSync, readdirSync as readdirSync2 } from "node:fs";
8
- import { basename, join, sep } from "node:path";
8
+ import { basename, dirname, join, posix, sep } from "node:path";
9
+
10
+ // ../../node_modules/.pnpm/@williamthorsen+toolbelt.errors@0.7.0/node_modules/@williamthorsen/toolbelt.errors/dist/esm/4-release/isError.js
11
+ function isError(error) {
12
+ return error instanceof Error || Object.prototype.toString.call(error) === "[object Error]";
13
+ }
14
+
15
+ // ../../node_modules/.pnpm/@williamthorsen+toolbelt.errors@0.7.0/node_modules/@williamthorsen/toolbelt.errors/dist/esm/4-release/describeError.js
16
+ function describeError(error) {
17
+ try {
18
+ if (isError(error) && typeof error.message === "string" && error.message !== "") {
19
+ return error.message;
20
+ }
21
+ return String(error);
22
+ } catch {
23
+ return "[unstringifiable value]";
24
+ }
25
+ }
26
+
27
+ // .readyup/kits/default.ts
9
28
  import { defineRdyKit } from "readyup";
10
29
  import {
30
+ discoverWorkspaces,
11
31
  fileContains,
12
32
  fileExists,
13
33
  hasDevDependency,
14
34
  hasMinDevDependencyVersion,
15
35
  hasPackageJsonField,
16
36
  isRecord,
37
+ listTrackedFiles,
17
38
  readFile,
18
39
  readPackageJson
19
40
  } from "readyup/check-utils";
@@ -108,10 +129,8 @@ var TEST_EXTENSIONS = "{ts,tsx}";
108
129
  var TEST_GLOB_PREFIX = `**/${TEST_DIR}/**`;
109
130
  var TEST_FILE_PATTERN = /\.test\.tsx?$/;
110
131
  var ALL_TEST_PATTERNS = [`${TEST_GLOB_PREFIX}/*.test.${TEST_EXTENSIONS}`];
111
- function findTestFiles(rootDir) {
112
- const found = [];
113
- collectTestFiles(rootDir, "", false, found);
114
- return found.toSorted();
132
+ function findTestFiles(rootDir, options = {}) {
133
+ return walkTestFiles(rootDir, options, false);
115
134
  }
116
135
  function hasTierInfix(filePath) {
117
136
  const tiers = TIER_NAMES;
@@ -119,18 +138,27 @@ function hasTierInfix(filePath) {
119
138
  }
120
139
  var TEST_COLLECTION_EXCLUDE = [".git", "coverage", "dist", "node_modules"];
121
140
  var TIER_NAMES = ["unit", "tool", "localhost", "remote"];
122
- function collectTestFiles(dir, relativeDir, inTestDir, found) {
141
+ function collectTestFiles(dir, relativeDir, inTestDir, context) {
123
142
  const entries = readdirSync(dir, { withFileTypes: true });
124
143
  for (const entry of entries) {
125
144
  const relativePath = relativeDir === "" ? entry.name : `${relativeDir}/${entry.name}`;
126
145
  if (entry.isDirectory()) {
127
- if (TEST_COLLECTION_EXCLUDE.includes(entry.name)) continue;
128
- collectTestFiles(path.join(dir, entry.name), relativePath, inTestDir || entry.name === TEST_DIR, found);
129
- } else if (inTestDir && TEST_FILE_PATTERN.test(entry.name)) {
130
- found.push(relativePath);
146
+ if (context.pruned.has(entry.name)) continue;
147
+ collectTestFiles(path.join(dir, entry.name), relativePath, inTestDir || entry.name === TEST_DIR, context);
148
+ } else if (inTestDir !== context.misplaced && TEST_FILE_PATTERN.test(entry.name)) {
149
+ context.found.push(relativePath);
131
150
  }
132
151
  }
133
152
  }
153
+ function walkTestFiles(rootDir, { exclude = [] }, misplaced) {
154
+ const context = {
155
+ found: [],
156
+ misplaced,
157
+ pruned: /* @__PURE__ */ new Set([...TEST_COLLECTION_EXCLUDE, ...exclude])
158
+ };
159
+ collectTestFiles(rootDir, "", false, context);
160
+ return context.found.toSorted();
161
+ }
134
162
 
135
163
  // .readyup/kits/default.ts
136
164
  var default_default = defineRdyKit({
@@ -231,6 +259,19 @@ var default_default = defineRdyKit({
231
259
  check: allWorkspacePackagesCanBuild,
232
260
  fix: `Add "build": ":" to packages that don't need a build, or ensure packages that use the default nmr build have a tsconfig.json and a src/ directory`
233
261
  },
262
+ // -- Bin targets ---------------------------------------------------------
263
+ {
264
+ name: "every bin target is a committed wrapper",
265
+ severity: "error",
266
+ check: () => everyBinTargetIsACommittedWrapper(),
267
+ fix: `Point each listed entry at a committed wrapper under bin/ that loads the build output at runtime. pnpm links a workspace package's bins during the install's link phase, which runs before anything is built, so a target that is not committed does not exist when pnpm reaches for it \u2014 and pnpm never retries, leaving the link missing for the life of the node_modules tree`
268
+ },
269
+ {
270
+ name: "every bin wrapper's build-output target is covered by files",
271
+ severity: "warn",
272
+ check: () => everyBinWrapperTargetIsCoveredByFiles(),
273
+ fix: "Add the build output directory to `files` in each listed package. npm and pnpm publish the bin target itself whatever `files` says, so the wrapper ships pointing at build output missing from the tarball"
274
+ },
234
275
  // -- Vitest projects -----------------------------------------------------
235
276
  {
236
277
  name: "no retired Vitest config variants",
@@ -240,10 +281,10 @@ var default_default = defineRdyKit({
240
281
  fix: "Delete every vitest.standalone.config.* and vitest.integration.config.*. nmr's test scripts select Vitest projects instead of naming config files"
241
282
  },
242
283
  {
243
- name: "vitest.config.ts builds on @williamthorsen/nmr/vitest",
284
+ name: "every vitest.config builds on @williamthorsen/nmr/vitest",
244
285
  severity: "error",
245
286
  check: () => vitestConfigBuildsOnSharedConfig(),
246
- fix: "Replace vitest.config.ts with: import { defineVitestConfig } from '@williamthorsen/nmr/vitest'; export default defineVitestConfig();"
287
+ fix: "Replace each listed config with: import { defineVitestConfig } from '@williamthorsen/nmr/vitest'; export default defineVitestConfig(); -- a config that does not call the factory declares no projects, so every tier-selecting test command fails against it. Pass your own settings to the factory as layers to keep them"
247
288
  },
248
289
  {
249
290
  name: "vitest.root.config.ts builds on @williamthorsen/nmr/vitest",
@@ -251,6 +292,12 @@ var default_default = defineRdyKit({
251
292
  check: () => vitestRootConfigBuildsOnSharedConfig(),
252
293
  fix: "Replace vitest.root.config.ts with: import { defineRootVitestConfig } from '@williamthorsen/nmr/vitest'; export default defineRootVitestConfig({ monorepoRoot: import.meta.dirname });"
253
294
  },
295
+ {
296
+ name: "every workspace with a Vite config has a Vitest config",
297
+ severity: "error",
298
+ check: () => everyViteConfigHasVitestConfig(),
299
+ fix: "Add a vitest.config.ts calling defineVitestConfig() from @williamthorsen/nmr/vitest beside each listed vite.config -- Vitest stops its config search at the first directory holding either name, so the Vite config otherwise wins and the projects model is never reached"
300
+ },
254
301
  {
255
302
  name: "every test file names its isolation tier",
256
303
  severity: "error",
@@ -312,7 +359,11 @@ var default_default = defineRdyKit({
312
359
  ]
313
360
  });
314
361
  var SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([".git", "coverage", "dist", "node_modules"]);
362
+ var BUILD_OUTPUT_DIR = "dist";
363
+ var WRAPPER_TARGET_PATTERN = /['"](\.\.?\/[^'"]+)['"]/;
315
364
  var CONFIG_EXTENSIONS = "{ts,mts,cts,js,mjs,cjs}";
365
+ var VITE_CONFIG_PATTERN = `vite.config.${CONFIG_EXTENSIONS}`;
366
+ var VITEST_CONFIG_PATTERN = `vitest.config.${CONFIG_EXTENSIONS}`;
316
367
  var SHARED_VITEST_MODULE = "@williamthorsen/nmr/vitest";
317
368
  var SHARED_PRETTIER_MODULE = "@williamthorsen/nmr/prettier";
318
369
  var INERT_PRETTIER_CONFIGS = [".prettierrc", ".prettierrc.{json,json5,yaml,yml,toml}"];
@@ -403,20 +454,105 @@ function hasPrettierConfigKey(cwd) {
403
454
  return false;
404
455
  }
405
456
  }
457
+ function discoverMemberWorkspaces() {
458
+ try {
459
+ return { ok: true, workspaces: discoverWorkspaces({ filter: (workspace) => !workspace.isRoot }) };
460
+ } catch (error) {
461
+ return { ok: false, detail: `cannot enumerate workspaces: ${describeError(error)}` };
462
+ }
463
+ }
464
+ async function everyBinTargetIsACommittedWrapper() {
465
+ const discovery = discoverMemberWorkspaces();
466
+ if (!discovery.ok) return discovery;
467
+ const tracked = await listTrackedFiles();
468
+ const trackedPaths = tracked === void 0 ? void 0 : new Set(tracked);
469
+ const offenders = discovery.workspaces.flatMap(
470
+ (workspace) => readBinEntries(workspace).flatMap((entry) => {
471
+ const defect = describeBinTargetDefect(workspace, entry, trackedPaths);
472
+ return defect === void 0 ? [] : [`${describeBinEntry(workspace, entry)} (${defect})`];
473
+ })
474
+ );
475
+ if (offenders.length === 0) return true;
476
+ return { ok: false, detail: formatPaths(offenders) };
477
+ }
478
+ function everyBinWrapperTargetIsCoveredByFiles() {
479
+ const discovery = discoverMemberWorkspaces();
480
+ if (!discovery.ok) return discovery;
481
+ const cwd = process.cwd();
482
+ const offenders = discovery.workspaces.flatMap((workspace) => {
483
+ const files = workspace.packageJson["files"];
484
+ if (!Array.isArray(files)) return [];
485
+ const published = new Set(files.flatMap((entry) => typeof entry === "string" ? [readFirstSegment(entry)] : []));
486
+ return readBinEntries(workspace).flatMap((entry) => {
487
+ const target = readWrapperTarget(cwd, workspace, entry);
488
+ if (target === void 0 || published.has(readFirstSegment(target))) return [];
489
+ return [`${describeBinEntry(workspace, entry)} -> ${target}`];
490
+ });
491
+ });
492
+ if (offenders.length === 0) return true;
493
+ return { ok: false, detail: formatPaths(offenders) };
494
+ }
495
+ function describeBinEntry(workspace, entry) {
496
+ return `${workspace.name ?? workspace.dir}:${entry.command} -> ${entry.target}`;
497
+ }
498
+ function describeBinTargetDefect(workspace, entry, trackedPaths) {
499
+ if (readFirstSegment(entry.target) === BUILD_OUTPUT_DIR) return `names a path under ${BUILD_OUTPUT_DIR}/`;
500
+ if (trackedPaths === void 0) return void 0;
501
+ return trackedPaths.has(`${workspace.dir}/${entry.target}`) ? void 0 : "untracked";
502
+ }
503
+ function normalizeBinTarget(target) {
504
+ return target.replace(/^\.\//, "");
505
+ }
506
+ function readBinEntries(workspace) {
507
+ const bin = workspace.packageJson["bin"];
508
+ if (typeof bin === "string") {
509
+ const command = workspace.name?.split("/").at(-1) ?? basename(workspace.dir);
510
+ return [{ command, target: normalizeBinTarget(bin) }];
511
+ }
512
+ if (!isRecord(bin)) return [];
513
+ return Object.entries(bin).flatMap(
514
+ ([command, target]) => typeof target === "string" ? [{ command, target: normalizeBinTarget(target) }] : []
515
+ );
516
+ }
517
+ function readFirstSegment(entry) {
518
+ return normalizeBinTarget(entry).split("/", 1).at(0) ?? "";
519
+ }
520
+ function readWrapperTarget(cwd, workspace, entry) {
521
+ if (readFirstSegment(entry.target) === BUILD_OUTPUT_DIR) return void 0;
522
+ const content = readFileIn(cwd, `${workspace.dir}/${entry.target}`);
523
+ if (content === void 0) return void 0;
524
+ const specifier = WRAPPER_TARGET_PATTERN.exec(content)?.[1];
525
+ if (specifier === void 0) return void 0;
526
+ return posix.normalize(posix.join(posix.dirname(entry.target), specifier));
527
+ }
406
528
  function everyTestFileNamesItsTier(cwd = process.cwd()) {
407
529
  const untiered = findTestFiles(cwd).filter((path2) => !hasTierInfix(path2));
408
530
  if (untiered.length === 0) return true;
409
531
  return { ok: false, detail: formatPaths(untiered) };
410
532
  }
533
+ function everyViteConfigHasVitestConfig() {
534
+ const discovery = discoverMemberWorkspaces();
535
+ if (!discovery.ok) return discovery;
536
+ const unpaired = discovery.workspaces.flatMap((workspace) => {
537
+ const viteConfigs = findWorkspaceConfigs(workspace, VITE_CONFIG_PATTERN);
538
+ if (viteConfigs.length === 0) return [];
539
+ return findWorkspaceConfigs(workspace, VITEST_CONFIG_PATTERN).length > 0 ? [] : viteConfigs;
540
+ });
541
+ if (unpaired.length === 0) return true;
542
+ return { ok: false, detail: formatPaths(unpaired) };
543
+ }
411
544
  function findFiles(patterns, cwd) {
412
545
  return globSync(patterns, { cwd, exclude: (path2) => SCAN_EXCLUDE_DIRS.has(basename(path2)) }).map((path2) => path2.split(sep).join("/")).toSorted();
413
546
  }
547
+ function findWorkspaceConfigs(workspace, pattern) {
548
+ return findFiles([pattern], workspace.absolutePath).map((name) => `${workspace.dir}/${name}`);
549
+ }
414
550
  function formatPaths(paths) {
415
551
  return `${paths.length} found:
416
552
  ${paths.map((path2) => ` ${path2}`).join("\n")}`;
417
553
  }
418
554
  function getMinVersion() {
419
- const picked = { "version": "0.34.0" };
555
+ const picked = { "version": "0.36.0" };
420
556
  if (typeof picked["version"] !== "string") {
421
557
  throw new TypeError("nmr/package.json: 'version' must be a string");
422
558
  }
@@ -432,11 +568,17 @@ function hasSupportedStrictLintVersion() {
432
568
  exempt: resolvesVersionViaWorkspace
433
569
  });
434
570
  }
571
+ function hasViteConfigBeside(cwd, relativePath) {
572
+ return findFiles([VITE_CONFIG_PATTERN], join(cwd, dirname(relativePath))).length > 0;
573
+ }
435
574
  function importsSharedExport(content, exportName, moduleSpecifier) {
436
575
  if (content === void 0) return false;
437
576
  const pattern = new RegExp(String.raw`import\s*\{[^}]*\b${exportName}\b[^}]*\}\s*from\s*['"]${moduleSpecifier}['"]`);
438
577
  return pattern.test(content);
439
578
  }
579
+ function isOwnedByReExportCheck(cwd, relativePath) {
580
+ return isReExportOnly(readFileIn(cwd, relativePath)) && !hasViteConfigBeside(cwd, relativePath);
581
+ }
440
582
  function isReExportOnly(content) {
441
583
  if (content === void 0) return false;
442
584
  const statements = content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "").split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
@@ -452,8 +594,8 @@ function noPnpmFieldInPackageJson(cwd = process.cwd()) {
452
594
  return { ok: false, detail: formatPaths(declaring) };
453
595
  }
454
596
  function noReExportOnlyVitestConfigs(cwd = process.cwd()) {
455
- const nonRootConfigs = findFiles([`**/vitest.config.${CONFIG_EXTENSIONS}`], cwd).filter((path2) => path2.includes("/"));
456
- const reExports = nonRootConfigs.filter((path2) => isReExportOnly(readFileIn(cwd, path2)));
597
+ const nonRootConfigs = findFiles([`**/${VITEST_CONFIG_PATTERN}`], cwd).filter((path2) => path2.includes("/"));
598
+ const reExports = nonRootConfigs.filter((path2) => isOwnedByReExportCheck(cwd, path2));
457
599
  if (reExports.length === 0) return true;
458
600
  return { ok: false, detail: formatPaths(reExports) };
459
601
  }
@@ -546,15 +688,28 @@ function toolVersionsHasNoPnpm() {
546
688
  if (content === void 0) return true;
547
689
  return !/^pnpm\s/m.test(content);
548
690
  }
549
- function vitestConfigBuildsOnSharedConfig(cwd = process.cwd()) {
550
- return checkRootVitestConfig("vitest.config", "defineVitestConfig", cwd);
691
+ function vitestConfigBuildsOnSharedConfig() {
692
+ const cwd = process.cwd();
693
+ const rootConfigs = findFiles([VITEST_CONFIG_PATTERN], cwd);
694
+ if (rootConfigs.length === 0) return { ok: false, detail: "vitest.config.ts is missing" };
695
+ const discovery = discoverMemberWorkspaces();
696
+ if (!discovery.ok) return discovery;
697
+ const workspaceConfigs = discovery.workspaces.flatMap((workspace) => findWorkspaceConfigs(workspace, VITEST_CONFIG_PATTERN)).filter((relativePath) => !isOwnedByReExportCheck(cwd, relativePath));
698
+ const stale = [...rootConfigs, ...workspaceConfigs].filter(
699
+ (relativePath) => !importsSharedExport(readFileIn(cwd, relativePath), "defineVitestConfig", SHARED_VITEST_MODULE)
700
+ );
701
+ if (stale.length === 0) return true;
702
+ return { ok: false, detail: formatPaths(stale) };
551
703
  }
552
704
  function vitestRootConfigBuildsOnSharedConfig(cwd = process.cwd()) {
553
705
  return checkRootVitestConfig("vitest.root.config", "defineRootVitestConfig", cwd);
554
706
  }
555
707
  export {
556
708
  default_default as default,
709
+ everyBinTargetIsACommittedWrapper,
710
+ everyBinWrapperTargetIsCoveredByFiles,
557
711
  everyTestFileNamesItsTier,
712
+ everyViteConfigHasVitestConfig,
558
713
  hasSupportedEslintVersion,
559
714
  hasSupportedStrictLintVersion,
560
715
  noPnpmFieldInPackageJson,
@@ -2,18 +2,21 @@
2
2
  "version": 1,
3
3
  "kits": [
4
4
  {
5
+ "bundledDependencies": {
6
+ "@williamthorsen/toolbelt.errors": "0.7.0"
7
+ },
5
8
  "checklists": [
6
9
  "nmr"
7
10
  ],
8
- "esbuildVersion": "0.28.1",
11
+ "esbuildVersion": "0.28.2",
9
12
  "inputs": [
10
13
  {
11
- "hash": "f58e8934",
14
+ "hash": "5c3cbdb9",
12
15
  "kind": "module",
13
16
  "path": "kits/default.ts"
14
17
  },
15
18
  {
16
- "hash": "cbbd2a2c",
19
+ "hash": "6f709fcd",
17
20
  "kind": "inline",
18
21
  "path": "../package.json",
19
22
  "paths": [
@@ -26,22 +29,22 @@
26
29
  "path": "../src/default-scripts.ts"
27
30
  },
28
31
  {
29
- "hash": "b42c7523",
32
+ "hash": "c53d0c51",
30
33
  "kind": "module",
31
34
  "path": "../src/resolve-scripts.ts"
32
35
  },
33
36
  {
34
- "hash": "c2d21075",
37
+ "hash": "2dfde614",
35
38
  "kind": "module",
36
39
  "path": "../src/tiers.ts"
37
40
  }
38
41
  ],
39
42
  "name": "default",
40
43
  "path": "kits/default.js",
41
- "readyupVersion": "0.32.0",
44
+ "readyupVersion": "0.35.0",
42
45
  "source": "kits/default.ts",
43
- "sourceHash": "f58e8934",
44
- "targetHash": "debdcb6e"
46
+ "sourceHash": "5c3cbdb9",
47
+ "targetHash": "c24a46ec"
45
48
  }
46
49
  ]
47
50
  }