@williamthorsen/nmr 0.38.0 → 0.40.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 (112) hide show
  1. package/.meta/changelog.json +212 -4
  2. package/.readyup/kits/default.js +124 -104
  3. package/.readyup/manifest.json +12 -7
  4. package/CHANGELOG.md +108 -0
  5. package/README.md +41 -47
  6. package/agents/README.md +8 -8
  7. package/agents/guidance/rulebooks/nmr.md +8 -8
  8. package/bin/ensure-prepublish-hooks.js +1 -1
  9. package/bin/nmr-clean.js +1 -1
  10. package/bin/nmr-compile.js +1 -1
  11. package/bin/nmr-fmt.js +1 -1
  12. package/bin/nmr-report-catalog.js +1 -1
  13. package/bin/nmr-report-overrides.js +1 -1
  14. package/bin/nmr-taze.js +1 -1
  15. package/bin/nmr.js +1 -1
  16. package/dist/esm/UserError.d.ts +1 -2
  17. package/dist/esm/check-cache.d.ts +61 -63
  18. package/dist/esm/check-cache.js +24 -24
  19. package/dist/esm/cli-ensure-prepublish-hooks.js +4 -4
  20. package/dist/esm/commands/build-output.d.ts +37 -38
  21. package/dist/esm/commands/build-output.js +9 -9
  22. package/dist/esm/commands/build.d.ts +13 -14
  23. package/dist/esm/commands/build.js +67 -65
  24. package/dist/esm/commands/clean.d.ts +6 -6
  25. package/dist/esm/commands/clean.js +11 -11
  26. package/dist/esm/commands/ensure-prepublish-hooks.d.ts +7 -7
  27. package/dist/esm/commands/ensure-prepublish-hooks.js +41 -41
  28. package/dist/esm/commands/fmt.d.ts +8 -8
  29. package/dist/esm/commands/fmt.js +33 -33
  30. package/dist/esm/commands/report-catalog.d.ts +5 -7
  31. package/dist/esm/commands/report-catalog.js +10 -8
  32. package/dist/esm/commands/report-overrides.d.ts +0 -2
  33. package/dist/esm/commands/report-overrides.js +8 -8
  34. package/dist/esm/commands/taze.d.ts +9 -8
  35. package/dist/esm/config.d.ts +5 -5
  36. package/dist/esm/config.js +27 -27
  37. package/dist/esm/context.d.ts +1 -2
  38. package/dist/esm/context.js +8 -8
  39. package/dist/esm/default-scripts.d.ts +5 -6
  40. package/dist/esm/defineConfig.d.ts +1 -1
  41. package/dist/esm/git-ignored-paths.d.ts +9 -0
  42. package/dist/esm/git-ignored-paths.js +10 -0
  43. package/dist/esm/glyphs.d.ts +3 -3
  44. package/dist/esm/help.d.ts +4 -4
  45. package/dist/esm/help.js +21 -21
  46. package/dist/esm/helpers/clampToBytes.d.ts +4 -5
  47. package/dist/esm/helpers/clampToBytes.js +3 -3
  48. package/dist/esm/helpers/config-path.d.ts +0 -2
  49. package/dist/esm/helpers/createBoundedBuffer.d.ts +3 -3
  50. package/dist/esm/helpers/createBoundedBuffer.js +2 -2
  51. package/dist/esm/helpers/deriveExcerpt.d.ts +4 -5
  52. package/dist/esm/helpers/duration.d.ts +10 -11
  53. package/dist/esm/helpers/duration.js +7 -7
  54. package/dist/esm/helpers/filter-selection.d.ts +19 -19
  55. package/dist/esm/helpers/filter-selection.js +12 -12
  56. package/dist/esm/helpers/findClosestName.d.ts +1 -1
  57. package/dist/esm/helpers/findClosestName.js +15 -15
  58. package/dist/esm/helpers/hook-name.d.ts +2 -5
  59. package/dist/esm/helpers/package-json.d.ts +11 -10
  60. package/dist/esm/helpers/package-json.js +26 -25
  61. package/dist/esm/helpers/readStringValues.d.ts +2 -3
  62. package/dist/esm/helpers/reportClosing.d.ts +8 -9
  63. package/dist/esm/helpers/transcript.d.ts +15 -15
  64. package/dist/esm/helpers/transcript.js +14 -14
  65. package/dist/esm/helpers/type-guards.d.ts +1 -0
  66. package/dist/esm/output-style.d.ts +12 -13
  67. package/dist/esm/prettier.d.ts +2 -2
  68. package/dist/esm/prettier.js +5 -5
  69. package/dist/esm/recording.d.ts +25 -20
  70. package/dist/esm/recording.js +28 -21
  71. package/dist/esm/replay-assembly.d.ts +10 -10
  72. package/dist/esm/report-format.d.ts +15 -20
  73. package/dist/esm/report-format.js +7 -7
  74. package/dist/esm/reportCliFailure.d.ts +2 -3
  75. package/dist/esm/resolve-scripts.d.ts +4 -5
  76. package/dist/esm/resolveBinStyles.d.ts +4 -5
  77. package/dist/esm/resolveBinStyles.js +3 -3
  78. package/dist/esm/resolver.d.ts +16 -20
  79. package/dist/esm/resolver.js +15 -15
  80. package/dist/esm/runCli.d.ts +6 -6
  81. package/dist/esm/runCli.js +261 -195
  82. package/dist/esm/runner.d.ts +20 -20
  83. package/dist/esm/runner.js +18 -18
  84. package/dist/esm/steps.d.ts +51 -38
  85. package/dist/esm/steps.js +32 -27
  86. package/dist/esm/taze.d.ts +1 -1
  87. package/dist/esm/tests.d.ts +23 -18
  88. package/dist/esm/tests.js +21 -9
  89. package/dist/esm/tiers.d.ts +28 -24
  90. package/dist/esm/tiers.js +13 -9
  91. package/dist/esm/types.d.ts +5 -5
  92. package/dist/esm/verbosity.d.ts +23 -21
  93. package/dist/esm/verbosity.js +7 -7
  94. package/dist/esm/verdict.d.ts +39 -32
  95. package/dist/esm/verdict.js +63 -50
  96. package/dist/esm/vitest-source-resolution.d.ts +11 -11
  97. package/dist/esm/vitest-source-resolution.js +49 -47
  98. package/dist/esm/vitest.d.ts +27 -26
  99. package/dist/esm/vitest.js +90 -33
  100. package/dist/esm/workspace.d.ts +6 -22
  101. package/dist/esm/workspace.js +9 -67
  102. package/docs/check-cache.md +57 -57
  103. package/docs/prettier.md +10 -10
  104. package/docs/reporting.md +48 -44
  105. package/docs/scripts.md +29 -29
  106. package/docs/upgrades.md +18 -18
  107. package/docs/utilities.md +13 -13
  108. package/docs/vitest.md +68 -66
  109. package/docs/workspace.md +27 -4
  110. package/package.json +6 -6
  111. package/dist/esm/helpers/workspace-patterns.d.ts +0 -8
  112. package/dist/esm/helpers/workspace-patterns.js +0 -29
@@ -2,22 +2,22 @@ import { type ScriptRegistry, type ScriptValue } from './resolve-scripts.js';
2
2
  import { type Step } from './steps.js';
3
3
  import type { NmrConfig } from './types.js';
4
4
  /**
5
- * Replace the first token of a command with a `devBin` substitute.
5
+ * Replaces the first token of a command with a `devBin` substitute.
6
6
  * Relative paths in the replacement are resolved from `monorepoRoot`.
7
7
  */
8
8
  export declare function applyDevBin(command: string, devBin: Record<string, string> | undefined, monorepoRoot: string): string;
9
9
  /**
10
10
  * Applies a `devBin` substitution to each opaque step, leaving nmr's own compositions alone.
11
11
  *
12
- * A structural step names a command nmr resolves for itself, so substituting its first token would replace the
13
- * `nmr` that carries the composite rather than the leaf tool `devBin` documents replacing.
12
+ * A structural step names a command that nmr resolves for itself, so substituting its first token would replace
13
+ * the `nmr` that runs the composite rather than the leaf tool that `devBin` documents replacing.
14
14
  */
15
15
  export declare function applyDevBinToSteps(steps: readonly Step[], devBin: Record<string, string> | undefined, monorepoRoot: string): readonly Step[];
16
16
  /**
17
17
  * Where a resolved script was read from.
18
18
  *
19
19
  * `registry` covers the built-in defaults and the repo-wide config together, which resolution cannot tell
20
- * apart: it receives the two already merged. A caller holding the config refines the two.
20
+ * apart: It receives the two already merged. A caller that has the config refines the two.
21
21
  */
22
22
  export type ScriptOrigin = {
23
23
  tier: 'registry';
@@ -32,13 +32,13 @@ export interface ResolvedScript {
32
32
  steps: readonly Step[];
33
33
  }
34
34
  /**
35
- * Expands a script value into the ordered steps it runs as: a string is one opaque step, and an array is one
35
+ * Expands a script value into the ordered steps that it runs as: a string is one opaque step, and an array is one
36
36
  * structural step per element.
37
37
  *
38
38
  * A bare string element and the `{ run }` spec compose the same step. The spec's only addition is the
39
- * declaration of what the step does with the invocation's trailing arguments, which position cannot carry.
39
+ * declaration of what the step does with the invocation's trailing arguments, which position cannot express.
40
40
  */
41
- export declare function expandScript(script: ScriptValue, workspaceRoot: boolean): readonly Step[];
41
+ export declare function expandScript(script: ScriptValue, isWorkspaceRoot: boolean): readonly Step[];
42
42
  /**
43
43
  * Returns a description of a script for help output.
44
44
  */
@@ -47,8 +47,7 @@ export declare function describeScript(script: ScriptValue): string;
47
47
  * Reads a package.json's `scripts`, rejecting any value that is not a string.
48
48
  *
49
49
  * npm and pnpm read a script as a string too, so a value of any other type is malformed however it got there.
50
- * Dropping one silently would run the registry's entry in its place, which is what an array written here after
51
- * being told a step list resolves a shelled-nmr crossing would otherwise do.
50
+ * Dropping one silently would run the registry's entry in its place.
52
51
  */
53
52
  export declare function readPackageJsonScripts(packageDir: string): Record<string, string> | undefined;
54
53
  /**
@@ -62,20 +61,17 @@ export declare function buildWorkspaceRegistry(config: NmrConfig): ScriptRegistr
62
61
  */
63
62
  export declare function buildRootRegistry(config: NmrConfig): ScriptRegistry;
64
63
  /**
65
- * Returns a `package.json` entry that re-invokes the command it is declared under alongside other steps, or
66
- * `undefined` where the entry declares no such thing.
64
+ * Returns a `package.json` entry that re-invokes the command under which it is declared alongside other steps,
65
+ * or `undefined` when the entry does not.
67
66
  *
68
- * Resolution discards a self-referential entry however it reads, so an entry that chains loses the steps it
67
+ * Resolution discards a self-referential entry however it reads, so an entry that chains loses the steps that it
69
68
  * chained. This is what an invocation rejects on, read where the command runs rather than raised from
70
- * resolution: the same scripts are resolved speculatively, for packages nobody named.
69
+ * resolution: The same scripts are resolved speculatively, for packages that nobody named.
71
70
  */
72
71
  export declare function findChainedSelfReference(packageDir: string | undefined, commandName: string): string | undefined;
73
72
  /**
74
- * Reports whether a `package.json` entry re-invokes the command it is declared under, wherever the
75
- * re-invocation stands in it, e.g. `"build": "nmr build"` or `"build": "rdy compile && nmr build"`.
76
- *
77
- * Honouring one spawns a shell that runs the same command in the same directory, reaching the same entry
78
- * again without bound, so resolution discards it.
73
+ * Reports whether a `package.json` entry re-invokes the command under which it is declared, wherever the
74
+ * re-invocation appears in it, e.g. `"build": "nmr build"` or `"build": "rdy compile && nmr build"`.
79
75
  */
80
76
  export declare function isSelfReferential(script: string, commandName: string, packageDir: string): boolean;
81
77
  /**
@@ -85,6 +81,6 @@ export declare function isSelfReferential(script: string, commandName: string, p
85
81
  * 3. Per-package overrides (package.json scripts)
86
82
  *
87
83
  * Returns undefined if the command is not found in the registry. A package.json override of `""` (indicating
88
- * skip) resolves to a single opaque step carrying it, which renders back to the empty string.
84
+ * skip) resolves to a single opaque step containing it, which renders back to the empty string.
89
85
  */
90
- export declare function resolveScript(commandName: string, registry: ScriptRegistry, packageDir: string | undefined, workspaceRoot: boolean): ResolvedScript | undefined;
86
+ export declare function resolveScript(commandName: string, registry: ScriptRegistry, packageDir: string | undefined, isWorkspaceRoot: boolean): ResolvedScript | undefined;
@@ -12,13 +12,13 @@ export function applyDevBin(command, devBin, monorepoRoot) {
12
12
  }
13
13
  const spaceIndex = command.indexOf(' ');
14
14
  const firstToken = spaceIndex === -1 ? command : command.slice(0, spaceIndex);
15
- const rest = spaceIndex === -1 ? '' : command.slice(spaceIndex);
15
+ const restOfCommand = spaceIndex === -1 ? '' : command.slice(spaceIndex);
16
16
  const replacement = devBin[firstToken];
17
17
  if (replacement === undefined) {
18
18
  return command;
19
19
  }
20
20
  const resolvedReplacement = resolveReplacementPaths(replacement, monorepoRoot);
21
- return resolvedReplacement + rest;
21
+ return resolvedReplacement + restOfCommand;
22
22
  }
23
23
  export function applyDevBinToSteps(steps, devBin, monorepoRoot) {
24
24
  if (!devBin) {
@@ -40,13 +40,13 @@ function resolveReplacementPaths(replacement, monorepoRoot) {
40
40
  })
41
41
  .join(' ');
42
42
  }
43
- export function expandScript(script, workspaceRoot) {
43
+ export function expandScript(script, isWorkspaceRoot) {
44
44
  if (typeof script === 'string') {
45
45
  return [{ kind: 'opaque', command: script }];
46
46
  }
47
47
  return script.map((element) => typeof element === 'string'
48
- ? composeNmrStep(element, workspaceRoot)
49
- : composeNmrStep(element.run, workspaceRoot, element.shouldDeclineArguments));
48
+ ? composeNmrStep(element, isWorkspaceRoot)
49
+ : composeNmrStep(element.run, isWorkspaceRoot, element.shouldDeclineArguments));
50
50
  }
51
51
  export function describeScript(script) {
52
52
  return typeof script === 'string' ? script : `[${script.map(describeElement).join(', ')}]`;
@@ -59,9 +59,9 @@ function describeElement(element) {
59
59
  }
60
60
  export function readPackageJsonScripts(packageDir) {
61
61
  const file = resolvePackageJsonPath(packageDir);
62
- let raw;
62
+ let rawText;
63
63
  try {
64
- raw = readFileSync(file, 'utf8');
64
+ rawText = readFileSync(file, 'utf8');
65
65
  }
66
66
  catch (error) {
67
67
  if (hasErrnoCode(error, 'ENOENT')) {
@@ -69,10 +69,10 @@ export function readPackageJsonScripts(packageDir) {
69
69
  }
70
70
  throw error;
71
71
  }
72
- const parsed = parsePackageJson(raw, file);
73
- if (!isObject(parsed))
72
+ const parsedManifest = parsePackageJson(rawText, file);
73
+ if (!isObject(parsedManifest))
74
74
  return undefined;
75
- const scripts = parsed['scripts'];
75
+ const scripts = parsedManifest['scripts'];
76
76
  if (!isObject(scripts))
77
77
  return undefined;
78
78
  return readScriptRecord(packageDir, scripts);
@@ -108,15 +108,15 @@ export function findChainedSelfReference(packageDir, commandName) {
108
108
  export function isSelfReferential(script, commandName, packageDir) {
109
109
  return readSelfReference({ anchoredAtRoot: isMonorepoRoot(packageDir), commandName, script }) !== undefined;
110
110
  }
111
- export function resolveScript(commandName, registry, packageDir, workspaceRoot) {
111
+ export function resolveScript(commandName, registry, packageDir, isWorkspaceRoot) {
112
112
  if (packageDir) {
113
113
  const pkgScripts = readPackageJsonScripts(packageDir);
114
114
  if (pkgScripts && Object.hasOwn(pkgScripts, commandName)) {
115
- const override = pkgScripts[commandName];
116
- if (override !== undefined && !isSelfReferential(override, commandName, packageDir)) {
115
+ const overrideCommand = pkgScripts[commandName];
116
+ if (overrideCommand !== undefined && !isSelfReferential(overrideCommand, commandName, packageDir)) {
117
117
  return {
118
118
  origin: { tier: 'package', file: resolvePackageJsonPath(packageDir), key: commandName },
119
- steps: [{ kind: 'opaque', command: override }],
119
+ steps: [{ kind: 'opaque', command: overrideCommand }],
120
120
  };
121
121
  }
122
122
  }
@@ -128,5 +128,5 @@ export function resolveScript(commandName, registry, packageDir, workspaceRoot)
128
128
  if (registryEntry === undefined) {
129
129
  return undefined;
130
130
  }
131
- return { origin: { tier: 'registry', key: commandName }, steps: expandScript(registryEntry, workspaceRoot) };
131
+ return { origin: { tier: 'registry', key: commandName }, steps: expandScript(registryEntry, isWorkspaceRoot) };
132
132
  }
@@ -1,7 +1,7 @@
1
1
  import type { Writable } from 'node:stream';
2
2
  /**
3
- * Marks a run made on a delegating caller's behalf, where a command the registry does not define exits 0
4
- * rather than failing.
3
+ * Marks a run made on a delegating caller's behalf, in which a command that the registry does not define, and a
4
+ * `--log` with nothing to show, exit 0 rather than failing.
5
5
  */
6
6
  export declare const RUN_IF_PRESENT_ENV_VAR = "NMR_RUN_IF_PRESENT";
7
7
  /** @internal */
@@ -10,11 +10,11 @@ export interface RunCliOptions {
10
10
  args: string[];
11
11
  /** Working directory used to resolve the nmr execution context. */
12
12
  cwd: string;
13
- /** Environment for `runCli` (used for `NMR_RUN_IF_PRESENT` reads and `-R` writes). */
13
+ /** Environment from which `runCli` reads its settings, and the base of the one that its children inherit. */
14
14
  env: NodeJS.ProcessEnv;
15
- /** Stream for normal output (help text, override messages). */
15
+ /** Stream for normal output: help, version, verdicts, recordings, and override notices. */
16
16
  stdout: Writable;
17
- /** Stream for error output (unknown command, parse errors). */
17
+ /** Stream for errors, warnings, and debug notes. */
18
18
  stderr: Writable;
19
19
  }
20
20
  /** @internal */
@@ -23,7 +23,7 @@ export interface RunCliResult {
23
23
  }
24
24
  /**
25
25
  * Executes the nmr CLI flow in-process and returns the resulting exit code.
26
- * Holds no global state, reads no `process.*` globals, never calls `process.exit`.
26
+ * Does not hold global state, does not read `process.*` globals, and never calls `process.exit`.
27
27
  *
28
28
  * @internal
29
29
  */