ccqa 1.56.0 → 1.57.1
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/dist/bin/ccqa.mjs +102 -106
- package/dist/hub-client/index.d.cts +2 -2
- package/dist/hub-client/index.d.mts +2 -2
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/bin/ccqa.mjs
CHANGED
|
@@ -8200,52 +8200,15 @@ function exportedNames(source) {
|
|
|
8200
8200
|
function reviewEmittedFiles(input) {
|
|
8201
8201
|
const locators = collectLocators(input.files);
|
|
8202
8202
|
const said = input.caseText.join("\n");
|
|
8203
|
-
return [
|
|
8204
|
-
...
|
|
8205
|
-
...
|
|
8206
|
-
...
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
...weakerTwin(file, source),
|
|
8213
|
-
...unreached(file, source, input)
|
|
8214
|
-
])
|
|
8215
|
-
];
|
|
8216
|
-
}
|
|
8217
|
-
/**
|
|
8218
|
-
* A path with a placeholder segment in it — `/orders/{orderId}`. Writing one
|
|
8219
|
-
* in prose is a statement about the address, not about the page's contents:
|
|
8220
|
-
* there is no other reason to name the part that changes per run.
|
|
8221
|
-
*/
|
|
8222
|
-
const PLACEHOLDER_PATH = /\/[A-Za-z0-9_\-]+(?:\/[A-Za-z0-9_\-]+)*\/\{[A-Za-z0-9_]+\}/;
|
|
8223
|
-
/**
|
|
8224
|
-
* A case that says where the run must end up, and a test that never looks at
|
|
8225
|
-
* the address.
|
|
8226
|
-
*
|
|
8227
|
-
* The row being on screen is not the same claim as being on the screen that
|
|
8228
|
-
* shows it — a product that rendered the row without navigating passes, and
|
|
8229
|
-
* that is the failure the expectation was written to catch. Scoped to
|
|
8230
|
-
* placeholder paths because those are unambiguous; a path mentioned as scenery
|
|
8231
|
-
* ("on /settings, the button is shown") is not a claim about the address.
|
|
8232
|
-
*
|
|
8233
|
-
* Calibrated against a small set of hand-written case definitions: a few
|
|
8234
|
-
* name a placeholder path in their expectations, most of those already
|
|
8235
|
-
* assert on the URL, and the one that does not is the defect this was
|
|
8236
|
-
* written for.
|
|
8237
|
-
*/
|
|
8238
|
-
function unassertedPath(input) {
|
|
8239
|
-
const source = input.files.get(input.testPath);
|
|
8240
|
-
if (source === void 0) return [];
|
|
8241
|
-
const stated = input.caseText.find((text) => PLACEHOLDER_PATH.test(text));
|
|
8242
|
-
if (stated === void 0 || /\btoHaveURL\b/.test(source)) return [];
|
|
8243
|
-
return [{
|
|
8244
|
-
file: input.testPath,
|
|
8245
|
-
line: 1,
|
|
8246
|
-
rule: "unasserted-path",
|
|
8247
|
-
message: `the case says where the run ends up — "${PLACEHOLDER_PATH.exec(stated)?.[0]}" — and nothing here looks at the address. What the screen shows can be right while the screen is wrong. Assert the URL where the case says it changes`
|
|
8248
|
-
}];
|
|
8203
|
+
return [...decidesNothing(input), ...[...input.files].flatMap(([file, source]) => [
|
|
8204
|
+
...toolIdentifiers(file, source),
|
|
8205
|
+
...containerOfPageText(file, source),
|
|
8206
|
+
...unjustifiedFirst(file, source),
|
|
8207
|
+
...describeEcho(file, source),
|
|
8208
|
+
...unaskedAssertions(file, source, locators, said),
|
|
8209
|
+
...weakerTwin(file, source),
|
|
8210
|
+
...unreached(file, source, input)
|
|
8211
|
+
])];
|
|
8249
8212
|
}
|
|
8250
8213
|
/** `readonly name =`, `name(...): Locator {`, and `export … name`. */
|
|
8251
8214
|
const DECLARED = /(?:readonly\s+([A-Za-z0-9_]+)\s*=|\b([A-Za-z0-9_]+)\([^)]*\)\s*:\s*Locator\b|export\s+(?:async\s+)?(?:const|let|function|class)\s+([A-Za-z0-9_]+))/g;
|
|
@@ -28084,7 +28047,7 @@ async function checkSpec(target, opts) {
|
|
|
28084
28047
|
locators,
|
|
28085
28048
|
systemPrompt,
|
|
28086
28049
|
userPrompt
|
|
28087
|
-
}).
|
|
28050
|
+
}).catch((err) => warn(`${name}: could not write the audit inputs (${err.message})`));
|
|
28088
28051
|
const MAX_ATTEMPTS = 2;
|
|
28089
28052
|
let lastError = "";
|
|
28090
28053
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
@@ -28155,12 +28118,12 @@ async function checkSpec(target, opts) {
|
|
|
28155
28118
|
//#endregion
|
|
28156
28119
|
//#region src/drift/format.ts
|
|
28157
28120
|
/**
|
|
28158
|
-
* Render drift results
|
|
28159
|
-
*
|
|
28160
|
-
*
|
|
28121
|
+
* Render drift results for a terminal. `json` is not one of these: it prints
|
|
28122
|
+
* the same payload the report file holds, which is assembled asynchronously
|
|
28123
|
+
* and so is built once by the caller rather than rendered from results here
|
|
28124
|
+
* (`buildAuditReport`).
|
|
28161
28125
|
*/
|
|
28162
28126
|
function renderDrift(results, format, cwd) {
|
|
28163
|
-
if (format === "json") return renderJson(results);
|
|
28164
28127
|
if (format === "github") return renderGithub(results, cwd);
|
|
28165
28128
|
return renderText$1(results);
|
|
28166
28129
|
}
|
|
@@ -28195,16 +28158,6 @@ function renderText$1(results) {
|
|
|
28195
28158
|
out.push("");
|
|
28196
28159
|
return out.join("\n");
|
|
28197
28160
|
}
|
|
28198
|
-
function renderJson(results) {
|
|
28199
|
-
const payload = { specs: results.map((r) => ({
|
|
28200
|
-
feature: r.target.featureName,
|
|
28201
|
-
spec: r.target.specName,
|
|
28202
|
-
ok: r.ok,
|
|
28203
|
-
...r.error ? { error: r.error } : {},
|
|
28204
|
-
drift: r.drift
|
|
28205
|
-
})) };
|
|
28206
|
-
return `${JSON.stringify(payload, null, 2)}\n`;
|
|
28207
|
-
}
|
|
28208
28161
|
function renderGithub(results, cwd) {
|
|
28209
28162
|
const repoRoot = process.env["GITHUB_WORKSPACE"] ?? process.cwd();
|
|
28210
28163
|
const lines = [];
|
|
@@ -28335,41 +28288,49 @@ function driftResultsToReport(results, meta) {
|
|
|
28335
28288
|
};
|
|
28336
28289
|
}
|
|
28337
28290
|
//#endregion
|
|
28338
|
-
//#region src/drift/
|
|
28291
|
+
//#region src/drift/audit-report.ts
|
|
28339
28292
|
/**
|
|
28340
|
-
*
|
|
28341
|
-
*
|
|
28293
|
+
* What `ccqa audit` leaves behind for a machine.
|
|
28294
|
+
*
|
|
28295
|
+
* The audit has three audiences: the person reading the terminal, the hub's
|
|
28296
|
+
* ledger, and whatever repairs the test. This is the third, and it is one
|
|
28297
|
+
* payload — written to `<report-dir>/audit.json` by every completed sweep and
|
|
28298
|
+
* printed verbatim by `--report-format json` (ADR-0036).
|
|
28342
28299
|
*/
|
|
28343
|
-
|
|
28344
|
-
|
|
28345
|
-
|
|
28346
|
-
|
|
28347
|
-
|
|
28348
|
-
|
|
28349
|
-
|
|
28350
|
-
|
|
28351
|
-
await mkdir(dirname(path), { recursive: true });
|
|
28352
|
-
await writeFile(path, `${JSON.stringify(brief, null, 2)}\n`, "utf8");
|
|
28353
|
-
return path;
|
|
28354
|
-
}));
|
|
28300
|
+
/** The file the report is written as, inside the report directory. */
|
|
28301
|
+
const AUDIT_REPORT_FILE = "audit.json";
|
|
28302
|
+
/**
|
|
28303
|
+
* The payload, for both the file and `--report-format json`. Each row's reads
|
|
28304
|
+
* are independent, so they resolve together rather than one case at a time.
|
|
28305
|
+
*/
|
|
28306
|
+
async function buildAuditReport(results, cwd, ctx) {
|
|
28307
|
+
return { specs: await Promise.all(results.map((r) => buildRow(r, cwd, ctx))) };
|
|
28355
28308
|
}
|
|
28356
|
-
|
|
28309
|
+
/** Write the report as `<dirAbs>/audit.json`, creating the directory. Returns its path. */
|
|
28310
|
+
async function writeAuditReport(report, dirAbs) {
|
|
28311
|
+
await mkdir(dirAbs, { recursive: true });
|
|
28312
|
+
const path = join(dirAbs, AUDIT_REPORT_FILE);
|
|
28313
|
+
await writeFile(path, `${JSON.stringify(report, null, 2)}\n`, "utf8");
|
|
28314
|
+
return path;
|
|
28315
|
+
}
|
|
28316
|
+
async function buildRow(result, cwd, ctx) {
|
|
28357
28317
|
const drift = result.drift;
|
|
28358
|
-
const
|
|
28318
|
+
const row = {
|
|
28319
|
+
feature: result.target.featureName,
|
|
28320
|
+
spec: result.target.specName,
|
|
28321
|
+
case: caseIdOf(result.target),
|
|
28322
|
+
ok: result.ok,
|
|
28323
|
+
...result.error ? { error: result.error } : {},
|
|
28324
|
+
drift
|
|
28325
|
+
};
|
|
28326
|
+
if (drift === null) return row;
|
|
28359
28327
|
const test = result.live ? null : await caseTestPath(result.target, ctx);
|
|
28360
28328
|
const rewrite = drift.label === "TEST_DRIFT" ? (result.renames ?? []).filter((r) => r.inDocument).map(({ from, to }) => ({
|
|
28361
28329
|
from,
|
|
28362
28330
|
to
|
|
28363
28331
|
})) : [];
|
|
28364
28332
|
return {
|
|
28365
|
-
|
|
28366
|
-
kind: drift.label,
|
|
28367
|
-
surface: drift.surface,
|
|
28368
|
-
confidence: drift.confidence,
|
|
28369
|
-
headline: drift.headline,
|
|
28370
|
-
recommendation: drift.recommendation,
|
|
28371
|
-
reasoning: drift.reasoning,
|
|
28372
|
-
evidence: drift.evidence,
|
|
28333
|
+
...row,
|
|
28373
28334
|
test,
|
|
28374
28335
|
document: documentOf(result, cwd),
|
|
28375
28336
|
repair: await buildRepair(result, test, rewrite, cwd, ctx)
|
|
@@ -28637,7 +28598,7 @@ function selectSpecsNeedingAudit(targets, report, stillDrifted = /* @__PURE__ */
|
|
|
28637
28598
|
//#endregion
|
|
28638
28599
|
//#region src/cli/audit.ts
|
|
28639
28600
|
const DEFAULT_CONCURRENCY = 3;
|
|
28640
|
-
const auditCommand = addProfileOption(addLanguageOption(new Command("audit").argument("[feature/spec]", "Optional spec id. If omitted, every spec under .ccqa/features/ is checked.").description("Read each spec against the code it describes and report where the two have drifted. Static: no browser is run, so this is the cheap check to put in front of `ccqa run`.").optionsGroup("Which specs to audit:").option("--only-affected-by <ref>", "Only specs `ccqa select-specs` decides the diff against <ref> reaches (e.g. origin/main), by intersecting it with each spec's measured coverage from the hub. In pull_request CI, pass $GITHUB_BASE_REF. Specs without a measurement are audited rather than skipped.").option("--only-hub-audit-needed", "Only specs the hub says a deploy has landed on since the audit last read them. A spec that was never audited is always included, one the hub cannot answer for is audited rather than skipped, and one whose drift entry is still open is always re-audited — a merged fix changes only the spec tree, which no deploy answer covers. No git diff involved. Requires a hub connection and --hub-profile.").optionsGroup("How to run it:").option("--concurrency <n>", `Parallel spec checks (default: ${DEFAULT_CONCURRENCY})`).option("-m, --model <name>", "Claude model alias ('sonnet'|'opus'|'haiku') or full ID. Overrides CCQA_MODEL.").optionsGroup("What to do with the results:").option("--report-format <fmt>", "
|
|
28601
|
+
const auditCommand = addProfileOption(addLanguageOption(new Command("audit").argument("[feature/spec]", "Optional spec id. If omitted, every spec under .ccqa/features/ is checked.").description("Read each spec against the code it describes and report where the two have drifted. Static: no browser is run, so this is the cheap check to put in front of `ccqa run`.").optionsGroup("Which specs to audit:").option("--only-affected-by <ref>", "Only specs `ccqa select-specs` decides the diff against <ref> reaches (e.g. origin/main), by intersecting it with each spec's measured coverage from the hub. In pull_request CI, pass $GITHUB_BASE_REF. Specs without a measurement are audited rather than skipped.").option("--only-hub-audit-needed", "Only specs the hub says a deploy has landed on since the audit last read them. A spec that was never audited is always included, one the hub cannot answer for is audited rather than skipped, and one whose drift entry is still open is always re-audited — a merged fix changes only the spec tree, which no deploy answer covers. No git diff involved. Requires a hub connection and --hub-profile.").optionsGroup("How to run it:").option("--concurrency <n>", `Parallel spec checks (default: ${DEFAULT_CONCURRENCY})`).option("-m, --model <name>", "Claude model alias ('sonnet'|'opus'|'haiku') or full ID. Overrides CCQA_MODEL.").optionsGroup("What to do with the results:").option("--report-dir <dir>", `Directory for the structured audit results (audit.json), which are always written. Default: ${DEFAULT_REPORT_DIR}/.`).option("--report-format <fmt>", "Terminal output format: text | json | github. 'json' prints the same payload audit.json holds, and nothing else.", "text").option("--report-to-hub", "Push the result to a ccqa hub as a run (kind: drift), which is what updates the drift ledger. A spec it finds drifted answers `needsRepair` to `ccqa run --only-hub-rerun-needed`, and is not run until a person repairs it.").option("--exit-on <level>", "Exit non-zero on this severity or higher: warn | error", "error").option("--dump-inputs <dir>", "Also write what each case's audit was given — its document, every file it was handed and the import that reached it, the source roots, and the prompt — as one markdown file per case under <dir>. For telling 'this never reached the audit' apart from 'it did, and nothing was reported'.").optionsGroup("Environment and connection:").option("--cwd <path>", "Working directory used as both the .ccqa root and the codebase Claude reads. Useful for monorepos. Defaults to process.cwd().").option("--project <name>", "Logical project name for the pushed run. Defaults to the current directory's name.").option(...hubUrlOption).option(...hubTokenOption).option(...hubHeaderOption))).action(withUsageErrors(async (specPath, opts) => {
|
|
28641
28602
|
await withCostReporting("audit", () => runAudit(specPath, opts));
|
|
28642
28603
|
}));
|
|
28643
28604
|
async function runAudit(specPath, opts) {
|
|
@@ -28645,6 +28606,11 @@ async function runAudit(specPath, opts) {
|
|
|
28645
28606
|
const threshold = parseSeverity(opts.exitOn);
|
|
28646
28607
|
const concurrency = parseConcurrency(opts.concurrency);
|
|
28647
28608
|
const cwd = resolveCwd(opts.cwd);
|
|
28609
|
+
const reportDir = resolve(cwd, opts.reportDir ?? "ccqa-report");
|
|
28610
|
+
await rm(join(reportDir, AUDIT_REPORT_FILE), {
|
|
28611
|
+
force: true,
|
|
28612
|
+
recursive: true
|
|
28613
|
+
}).catch(() => {});
|
|
28648
28614
|
await ensureCcqaDir(cwd);
|
|
28649
28615
|
if (opts.onlyAffectedBy && specPath) {
|
|
28650
28616
|
error("--only-affected-by and an explicit spec id cannot be combined; it only applies to a full sweep");
|
|
@@ -28678,11 +28644,18 @@ async function runAudit(specPath, opts) {
|
|
|
28678
28644
|
const intent = artifactsContext.reader.target;
|
|
28679
28645
|
const sourceRoots = await resolveSourceRoots(cwd, config.sourceRoots);
|
|
28680
28646
|
let targets = await collectTargets(specPath, cwd, artifactsContext.reader);
|
|
28681
|
-
if (targets.length === 0)
|
|
28647
|
+
if (targets.length === 0) {
|
|
28648
|
+
const where = intent ? intent.module : ".ccqa/features/";
|
|
28649
|
+
await exitWithNoSpecs({
|
|
28650
|
+
format,
|
|
28651
|
+
reportDir
|
|
28652
|
+
}, "noSpecsFound", `no test cases found under ${where}`);
|
|
28653
|
+
}
|
|
28682
28654
|
if (format === "text") {
|
|
28683
28655
|
header("audit", specPath ?? `${targets.length} case${targets.length > 1 ? "s" : ""}`);
|
|
28684
28656
|
if (opts.cwd) meta("cwd", cwd);
|
|
28685
28657
|
for (const root of sourceRoots) meta("source", root.abs);
|
|
28658
|
+
if (opts.dumpInputs) meta("inputs", resolve(cwd, opts.dumpInputs));
|
|
28686
28659
|
}
|
|
28687
28660
|
if (opts.onlyHubAuditNeeded) {
|
|
28688
28661
|
const total = targets.length;
|
|
@@ -28697,12 +28670,18 @@ async function runAudit(specPath, opts) {
|
|
|
28697
28670
|
meta("hub", selection.summary);
|
|
28698
28671
|
meta("scoped", `${targets.length} of ${total} spec${total > 1 ? "s" : ""}`);
|
|
28699
28672
|
}
|
|
28700
|
-
if (targets.length === 0) exitWithNoSpecs(
|
|
28673
|
+
if (targets.length === 0) await exitWithNoSpecs({
|
|
28674
|
+
format,
|
|
28675
|
+
reportDir
|
|
28676
|
+
}, "allCurrent", "every spec has been audited since the last deploy that reached it");
|
|
28701
28677
|
holder = randomUUID();
|
|
28702
28678
|
const claimed = await claimSpecs(hub, hubProject, opts.hubProfile, targets, holder);
|
|
28703
28679
|
if (claimed.length < targets.length && format === "text") meta("held-elsewhere", `${targets.length - claimed.length} spec(s) another job is auditing`);
|
|
28704
28680
|
targets = claimed;
|
|
28705
|
-
if (targets.length === 0) exitWithNoSpecs(
|
|
28681
|
+
if (targets.length === 0) await exitWithNoSpecs({
|
|
28682
|
+
format,
|
|
28683
|
+
reportDir
|
|
28684
|
+
}, "allHeld", "every spec that needs auditing is already being audited by another job");
|
|
28706
28685
|
}
|
|
28707
28686
|
let baseRef = null;
|
|
28708
28687
|
if (opts.onlyAffectedBy) {
|
|
@@ -28716,7 +28695,10 @@ async function runAudit(specPath, opts) {
|
|
|
28716
28695
|
targets = selection.specs;
|
|
28717
28696
|
baseRef = selection.base.ref;
|
|
28718
28697
|
if (format === "text") meta("scoped", `${targets.length} of ${total} spec${total > 1 ? "s" : ""}`);
|
|
28719
|
-
if (targets.length === 0) exitWithNoSpecs(
|
|
28698
|
+
if (targets.length === 0) await exitWithNoSpecs({
|
|
28699
|
+
format,
|
|
28700
|
+
reportDir
|
|
28701
|
+
}, "noDiffIntersection", "no specs intersect the changed file set; nothing to check");
|
|
28720
28702
|
}
|
|
28721
28703
|
const blocks = await loadAvailableBlocks(cwd);
|
|
28722
28704
|
let pushConn = null;
|
|
@@ -28757,7 +28739,10 @@ async function runAudit(specPath, opts) {
|
|
|
28757
28739
|
} finally {
|
|
28758
28740
|
if (holder) await releaseSpecs(hub, hubProject, opts.hubProfile, holder);
|
|
28759
28741
|
}
|
|
28760
|
-
|
|
28742
|
+
const report = await buildAuditReport(results, cwd, artifactsContext);
|
|
28743
|
+
if (format === "json") process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
28744
|
+
else process.stdout.write(renderDrift(results, format, cwd));
|
|
28745
|
+
const written = await tryWriteReport(report, reportDir, format);
|
|
28761
28746
|
if (push) await sealDriftPush(push, {
|
|
28762
28747
|
results,
|
|
28763
28748
|
threshold,
|
|
@@ -28766,18 +28751,22 @@ async function runAudit(specPath, opts) {
|
|
|
28766
28751
|
baseRef,
|
|
28767
28752
|
promptCtx
|
|
28768
28753
|
});
|
|
28769
|
-
|
|
28770
|
-
|
|
28771
|
-
|
|
28772
|
-
|
|
28773
|
-
|
|
28774
|
-
|
|
28775
|
-
|
|
28776
|
-
|
|
28754
|
+
process.exit(written ? determineExitCode(results, threshold) : 2);
|
|
28755
|
+
}
|
|
28756
|
+
/**
|
|
28757
|
+
* Write the report, saying whether it landed. A sweep whose results never
|
|
28758
|
+
* landed has to fail: the next reader of `audit.json` would otherwise act on
|
|
28759
|
+
* the previous invocation's findings with nothing saying so.
|
|
28760
|
+
*/
|
|
28761
|
+
async function tryWriteReport(report, dirAbs, format) {
|
|
28762
|
+
try {
|
|
28763
|
+
const path = await writeAuditReport(report, dirAbs);
|
|
28764
|
+
if (format === "text") meta("report", path);
|
|
28765
|
+
return true;
|
|
28777
28766
|
} catch (e) {
|
|
28778
|
-
error(`could not write
|
|
28767
|
+
error(`could not write the audit report to ${dirAbs}: ${errMessage(e)}`);
|
|
28768
|
+
return false;
|
|
28779
28769
|
}
|
|
28780
|
-
process.exit(determineExitCode(results, threshold));
|
|
28781
28770
|
}
|
|
28782
28771
|
/** Longer than the audit's own timeout, so a sweep cannot outlive its claim. */
|
|
28783
28772
|
const AUDIT_LOCK_TTL_SECONDS = 5400;
|
|
@@ -28903,14 +28892,21 @@ async function resolveAuditPromptContext(opts, cwd, resolveCtx = resolveAuditHub
|
|
|
28903
28892
|
function asHubReadError(err) {
|
|
28904
28893
|
throw new RunUsageError(`could not read from the hub: ${errMessage(err)}`);
|
|
28905
28894
|
}
|
|
28906
|
-
|
|
28907
|
-
|
|
28895
|
+
/**
|
|
28896
|
+
* Nothing to audit — still a result, and still written. A reader that found
|
|
28897
|
+
* yesterday's `audit.json` where this sweep left none would act on findings
|
|
28898
|
+
* nothing had re-checked.
|
|
28899
|
+
*/
|
|
28900
|
+
async function exitWithNoSpecs(ctx, reason, message) {
|
|
28901
|
+
const { format, reportDir } = ctx;
|
|
28902
|
+
const report = {
|
|
28908
28903
|
specs: [],
|
|
28909
28904
|
skipped: reason
|
|
28910
|
-
}
|
|
28905
|
+
};
|
|
28906
|
+
if (format === "json") process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
28911
28907
|
else if (format === "text") info(message);
|
|
28912
28908
|
else if (format === "github" && reason === "noSpecsFound") process.stdout.write(`::warning::${message}\n`);
|
|
28913
|
-
process.exit(0);
|
|
28909
|
+
process.exit(await tryWriteReport(report, reportDir, format) ? 0 : 2);
|
|
28914
28910
|
}
|
|
28915
28911
|
/**
|
|
28916
28912
|
* The cases this sweep audits.
|
|
@@ -35,9 +35,9 @@ declare const RunSchema: z.ZodObject<{
|
|
|
35
35
|
running: "running";
|
|
36
36
|
}>;
|
|
37
37
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
38
|
-
record: "record";
|
|
39
38
|
run: "run";
|
|
40
39
|
drift: "drift";
|
|
40
|
+
record: "record";
|
|
41
41
|
}>>;
|
|
42
42
|
drift: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
43
43
|
specs: z.ZodNumber;
|
|
@@ -831,9 +831,9 @@ type ReportSpecResult = z.infer<typeof ReportSpecResultSchema>;
|
|
|
831
831
|
declare const RunReportDataSchema: z.ZodObject<{
|
|
832
832
|
schemaVersion: z.ZodLiteral<1>;
|
|
833
833
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
834
|
-
record: "record";
|
|
835
834
|
run: "run";
|
|
836
835
|
drift: "drift";
|
|
836
|
+
record: "record";
|
|
837
837
|
}>>;
|
|
838
838
|
createdAt: z.ZodString;
|
|
839
839
|
runId: z.ZodNullable<z.ZodString>;
|
|
@@ -35,9 +35,9 @@ declare const RunSchema: z.ZodObject<{
|
|
|
35
35
|
running: "running";
|
|
36
36
|
}>;
|
|
37
37
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
38
|
-
record: "record";
|
|
39
38
|
run: "run";
|
|
40
39
|
drift: "drift";
|
|
40
|
+
record: "record";
|
|
41
41
|
}>>;
|
|
42
42
|
drift: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
43
43
|
specs: z.ZodNumber;
|
|
@@ -831,9 +831,9 @@ type ReportSpecResult = z.infer<typeof ReportSpecResultSchema>;
|
|
|
831
831
|
declare const RunReportDataSchema: z.ZodObject<{
|
|
832
832
|
schemaVersion: z.ZodLiteral<1>;
|
|
833
833
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
834
|
-
record: "record";
|
|
835
834
|
run: "run";
|
|
836
835
|
drift: "drift";
|
|
836
|
+
record: "record";
|
|
837
837
|
}>>;
|
|
838
838
|
createdAt: z.ZodString;
|
|
839
839
|
runId: z.ZodNullable<z.ZodString>;
|
package/dist/package.json
CHANGED