@ultimat3/cli 22.2.2 → 22.3.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.
package/src/verify-run.ts CHANGED
@@ -17,16 +17,18 @@ import type { StepOutcome, VerifyContext, VerifyStep } from './verify-step';
17
17
  * Run every step, never bailing early: an agent fixing three things at once needs all
18
18
  * three findings from one run, not one per round-trip.
19
19
  *
20
- * `ctx.only` narrows the list to one step. The narrowing lives HERE rather than in `cmd-verify.ts`
21
- * so that every caller of the runner — the command, `x build`, the MCP host — gets the banner and
22
- * the `--json` flag with it, instead of one of them filtering a list quietly.
20
+ * `ctx.only` narrows the list to the steps it names, kept in declared order. The narrowing lives
21
+ * HERE rather than in `cmd-verify.ts` so that every caller of the runner — the command, `x build`,
22
+ * the MCP host — gets the banner and the `--json` flag with it, instead of one of them filtering a
23
+ * list quietly.
23
24
  */
24
25
  export async function runVerify(
25
26
  steps: readonly VerifyStep[],
26
27
  ctx: VerifyContext,
27
28
  ): Promise<CommandResult> {
28
29
  const floor = await readVerifyFloor(ctx.root);
29
- const selected = ctx.only === undefined ? steps : steps.filter((step) => step.name === ctx.only);
30
+ const only = onlyList(ctx.only);
31
+ const selected = only === undefined ? steps : steps.filter((step) => only.includes(step.name));
30
32
  const byName = new Map<string, StepResult>();
31
33
  const began = performance.now();
32
34
  // The static steps wait for the serial suites and then run BESIDE them — only when `live` is in
@@ -75,7 +77,7 @@ export async function runVerify(
75
77
  // Rendered through the catalog like every other summary this file emits; the machine marker
76
78
  // is `data.notAGateRun` below. It was a bare `NOT A GATE RUN` constant, which put one
77
79
  // user-facing string outside `messages.ts` for a fact `--json` was already carrying twice.
78
- summary: ctx.only === undefined ? summary : msg('cli.verify.notAGateRun', { summary }),
80
+ summary: only === undefined ? summary : msg('cli.verify.notAGateRun', { summary }),
79
81
  steps: results,
80
82
  // `skipped` is a list beside `failed` and not a count, because the two answer the same kind of
81
83
  // question — *which* steps, not how many — and a caller ratcheting on coverage needs the names.
@@ -85,13 +87,18 @@ export async function runVerify(
85
87
  durationMs: totalMs,
86
88
  // A BOOLEAN beside the banner, so a reader of `--json` never has to substring-match a
87
89
  // summary line to learn that this run checked one thing.
88
- ...(ctx.only === undefined ? {} : { notAGateRun: true, only: ctx.only }),
90
+ // `only` is always the LIST, in declared order — one name is a list of one.
91
+ ...(only === undefined ? {} : { notAGateRun: true, only: [...only] }),
89
92
  },
90
93
  // The step's own status: one step, so `failedSteps` is that step and nothing else.
91
94
  exitCode: failedSteps.length === 0 ? 0 : 1,
92
95
  };
93
96
  }
94
97
 
98
+ /** One name or several, as one list — the context accepts both, every reader here wants a list. */
99
+ const onlyList = (only: VerifyContext['only']): readonly string[] | undefined =>
100
+ only === undefined ? undefined : typeof only === 'string' ? [only] : only;
101
+
95
102
  /**
96
103
  * What the counts are allowed to claim. A step that does not apply is recorded green so the run
97
104
  * continues, and the summary counted it among the "all 17 steps passed" — so a repo whose `job`
@@ -79,15 +79,18 @@ export interface VerifyContext {
79
79
  */
80
80
  readonly workers?: number;
81
81
  /**
82
- * ONE step, by name — an iteration loop, and the one thing here that IS a narrowing. The
82
+ * Some steps, by name — an iteration loop, and the one thing here that IS a narrowing. The
83
83
  * whole gate costs minutes (3m19s at the framework root on 12 cores, `As of 2026-09-23`), which
84
- * is the cost of asking a question about one step. It does not weaken axiom 5, and the two rules that keep it honest are
85
- * mechanical rather than remembered: a run with this set prints `NOT A GATE RUN` in the summary
86
- * AND carries `notAGateRun` in `--json` (`verify-run.ts`), so no reader of either can mistake it
87
- * for the gate; and nothing writes `x.verify.json`, so the suite floor cannot be lowered by a
88
- * run that never executed the suites. Green still means the no-flag run, unchanged.
84
+ * is the cost of asking a question about one step. A list (`x verify --only typecheck,lint`) runs
85
+ * in ONE process, so an app's scoped runner stops paying a CLI boot and an app load per step.
86
+ * It does not weaken axiom 5, and the two rules that keep it honest are mechanical rather than
87
+ * remembered: a run with this set prints `NOT A GATE RUN` in the summary AND carries `notAGateRun`
88
+ * in `--json` (`verify-run.ts`), so no reader of either can mistake it for the gate; and nothing
89
+ * writes `x.verify.json`, so the suite floor cannot be lowered by a run that never executed the
90
+ * suites — even a list naming every step. Green still means the no-flag run, unchanged. A single
91
+ * name is accepted for the callers that narrow to one (`scripts/verify.ts`).
89
92
  */
90
- readonly only?: VerifyStepName;
93
+ readonly only?: VerifyStepName | readonly VerifyStepName[];
91
94
  }
92
95
 
93
96
  export interface StepOutcome {