@deftai/directive 0.61.2 → 0.63.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/dist/{branch-parity.d.ts → branch-fixtures.d.ts} +1 -3
- package/dist/{branch-parity.js → branch-fixtures.js} +3 -110
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +4 -1
- package/dist/framework-check-updates.d.ts +10 -0
- package/dist/framework-check-updates.js +68 -0
- package/dist/install-cli/coverage-map.js +3 -2
- package/dist/orchestration-cli/coverage-map.js +1 -1
- package/dist/{policy-parity.d.ts → policy-fixtures.d.ts} +1 -3
- package/dist/{policy-parity.js → policy-fixtures.js} +4 -100
- package/dist/{release-e2e-parity.d.ts → release-e2e-fixtures.d.ts} +1 -3
- package/dist/release-e2e-fixtures.js +38 -0
- package/dist/{story-ready-parity.d.ts → story-ready-fixtures.d.ts} +1 -3
- package/dist/{story-ready-parity.js → story-ready-fixtures.js} +4 -121
- package/dist/{triage-aux-a-parity.d.ts → triage-aux-a-fixtures.d.ts} +1 -3
- package/dist/{triage-aux-a-parity.js → triage-aux-a-fixtures.js} +3 -73
- package/dist/{triage-aux-b-parity.d.ts → triage-aux-b-fixtures.d.ts} +1 -3
- package/dist/triage-aux-b-fixtures.js +167 -0
- package/dist/{triage-bootstrap-parity.d.ts → triage-bootstrap-fixtures.d.ts} +1 -3
- package/dist/{triage-bootstrap-parity.js → triage-bootstrap-fixtures.js} +4 -91
- package/dist/{triage-classify-parity.d.ts → triage-classify-fixtures.d.ts} +1 -3
- package/dist/{triage-classify-parity.js → triage-classify-fixtures.js} +4 -94
- package/dist/{triage-queue-parity.d.ts → triage-queue-fixtures.d.ts} +1 -3
- package/dist/{triage-queue-parity.js → triage-queue-fixtures.js} +4 -86
- package/dist/{triage-scope-parity.d.ts → triage-scope-fixtures.d.ts} +1 -3
- package/dist/{triage-scope-parity.js → triage-scope-fixtures.js} +4 -91
- package/dist/umbrella-current-shape.d.ts +9 -0
- package/dist/umbrella-current-shape.js +56 -0
- package/dist/{vbrief-preflight-parity.d.ts → vbrief-preflight-fixtures.d.ts} +1 -3
- package/dist/vbrief-preflight-fixtures.js +79 -0
- package/dist/{wip-cap-parity.d.ts → wip-cap-fixtures.d.ts} +1 -3
- package/dist/{wip-cap-parity.js → wip-cap-fixtures.js} +4 -91
- package/package.json +4 -15
- package/dist/cache-parity.d.ts +0 -36
- package/dist/cache-parity.js +0 -165
- package/dist/codebase-parity.d.ts +0 -31
- package/dist/codebase-parity.js +0 -303
- package/dist/doc-cli-parity.d.ts +0 -29
- package/dist/doc-cli-parity.js +0 -159
- package/dist/doctor-parity.d.ts +0 -42
- package/dist/doctor-parity.js +0 -157
- package/dist/intake-parity.d.ts +0 -30
- package/dist/intake-parity.js +0 -203
- package/dist/lifecycle-packs-parity.d.ts +0 -30
- package/dist/lifecycle-packs-parity.js +0 -377
- package/dist/orchestration-parity.d.ts +0 -38
- package/dist/orchestration-parity.js +0 -364
- package/dist/parity.d.ts +0 -36
- package/dist/parity.js +0 -176
- package/dist/platform-parity.d.ts +0 -26
- package/dist/platform-parity.js +0 -309
- package/dist/pr-closing-keywords-parity.d.ts +0 -45
- package/dist/pr-closing-keywords-parity.js +0 -259
- package/dist/pr-merge-readiness-parity.d.ts +0 -44
- package/dist/pr-merge-readiness-parity.js +0 -296
- package/dist/pr-monitor-parity.d.ts +0 -44
- package/dist/pr-monitor-parity.js +0 -283
- package/dist/pr-protected-issues-parity.d.ts +0 -41
- package/dist/pr-protected-issues-parity.js +0 -220
- package/dist/pr-wait-mergeable-parity.d.ts +0 -45
- package/dist/pr-wait-mergeable-parity.js +0 -340
- package/dist/release-e2e-parity.js +0 -114
- package/dist/release-parity.d.ts +0 -40
- package/dist/release-parity.js +0 -226
- package/dist/release-publish-parity.d.ts +0 -36
- package/dist/release-publish-parity.js +0 -138
- package/dist/release-rollback-parity.d.ts +0 -37
- package/dist/release-rollback-parity.js +0 -161
- package/dist/render-parity.d.ts +0 -36
- package/dist/render-parity.js +0 -385
- package/dist/scm-parity.d.ts +0 -39
- package/dist/scm-parity.js +0 -181
- package/dist/scope-lifecycle-parity.d.ts +0 -35
- package/dist/scope-lifecycle-parity.js +0 -177
- package/dist/session-parity.d.ts +0 -39
- package/dist/session-parity.js +0 -262
- package/dist/slice-parity.d.ts +0 -36
- package/dist/slice-parity.js +0 -304
- package/dist/swarm-parity.d.ts +0 -28
- package/dist/swarm-parity.js +0 -327
- package/dist/triage-actions-parity.d.ts +0 -36
- package/dist/triage-actions-parity.js +0 -357
- package/dist/triage-aux-b-parity.js +0 -308
- package/dist/triage-summary-parity.d.ts +0 -50
- package/dist/triage-summary-parity.js +0 -306
- package/dist/validate-content-parity.d.ts +0 -33
- package/dist/validate-content-parity.js +0 -356
- package/dist/vbrief-activate-parity.d.ts +0 -39
- package/dist/vbrief-activate-parity.js +0 -216
- package/dist/vbrief-build-parity.d.ts +0 -28
- package/dist/vbrief-build-parity.js +0 -399
- package/dist/vbrief-preflight-parity.js +0 -163
- package/dist/vbrief-reconcile-parity.d.ts +0 -23
- package/dist/vbrief-reconcile-parity.js +0 -609
- package/dist/vbrief-validate-parity.d.ts +0 -27
- package/dist/vbrief-validate-parity.js +0 -122
- package/dist/vbrief-validation-parity.d.ts +0 -28
- package/dist/vbrief-validation-parity.js +0 -645
- package/dist/verify-env-parity.d.ts +0 -28
- package/dist/verify-env-parity.js +0 -272
- package/dist/verify-source-parity.d.ts +0 -26
- package/dist/verify-source-parity.js +0 -178
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Golden-output parity harness (#1725): builds throwaway fixture repos, runs
|
|
4
|
-
* BOTH the Python oracle (`scripts/triage_queue.py queue`) and the ported TS
|
|
5
|
-
* triage:queue CLI, and diffs exit codes + stdout/stderr (cache-off).
|
|
6
|
-
*
|
|
7
|
-
* Exit codes: 0 parity / 1 divergence / 2 harness setup error.
|
|
8
|
-
*/
|
|
9
|
-
import { spawnSync } from "node:child_process";
|
|
10
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
11
3
|
import { tmpdir } from "node:os";
|
|
12
|
-
import {
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { join } from "node:path";
|
|
14
5
|
const DEFAULT_REPO = "owner/repo";
|
|
15
6
|
/** Strip volatile absolute paths before compare. */
|
|
16
7
|
export function normalizeOutput(text) {
|
|
@@ -18,25 +9,6 @@ export function normalizeOutput(text) {
|
|
|
18
9
|
.replace(/^WARN [^\n]*\n/gm, "")
|
|
19
10
|
.replace(/project_root=[^\s)]+/g, "project_root=<ROOT>");
|
|
20
11
|
}
|
|
21
|
-
function runCapture(cmd, args, cwd, env = {}) {
|
|
22
|
-
const merged = { ...process.env, ...env };
|
|
23
|
-
for (const key of Object.keys(merged)) {
|
|
24
|
-
if (merged[key] === undefined) {
|
|
25
|
-
delete merged[key];
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const result = spawnSync(cmd, args, {
|
|
29
|
-
cwd,
|
|
30
|
-
encoding: "utf8",
|
|
31
|
-
env: merged,
|
|
32
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
33
|
-
});
|
|
34
|
-
return {
|
|
35
|
-
status: result.status ?? 2,
|
|
36
|
-
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
37
|
-
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
12
|
function writeCachedIssue(root, repo, issue) {
|
|
41
13
|
const parts = repo.split("/", 2);
|
|
42
14
|
const owner = parts[0];
|
|
@@ -142,20 +114,6 @@ export function buildFixtureRepo(options = {}) {
|
|
|
142
114
|
}
|
|
143
115
|
return root;
|
|
144
116
|
}
|
|
145
|
-
function resolveDeftRoot() {
|
|
146
|
-
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
147
|
-
return resolve(process.env.DEFT_ROOT);
|
|
148
|
-
}
|
|
149
|
-
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
150
|
-
}
|
|
151
|
-
function runPythonQueue(deftRoot, _repo, argv) {
|
|
152
|
-
const cap = runCapture("uv", ["run", "python", join(deftRoot, "scripts", "triage_queue.py"), "queue", ...argv], deftRoot, { DEFT_TRIAGE_REPO: undefined, PYTHONUTF8: "1" });
|
|
153
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
154
|
-
}
|
|
155
|
-
function runTsQueue(deftRoot, _repo, argv) {
|
|
156
|
-
const cap = runCapture("node", [join(deftRoot, "packages", "cli", "dist", "triage-queue.js"), "queue", ...argv], deftRoot, { DEFT_TRIAGE_REPO: undefined });
|
|
157
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
158
|
-
}
|
|
159
117
|
/** Diff one parity case between Python oracle and TS CLI. */
|
|
160
118
|
export function diffCase(python, ts, caseName) {
|
|
161
119
|
const pyOut = normalizeOutput(python.stdout);
|
|
@@ -301,31 +259,6 @@ export function augmentParityArgv(testCase, root) {
|
|
|
301
259
|
return [...argv, ...extras];
|
|
302
260
|
}
|
|
303
261
|
/** Run all parity cases; returns aggregate result. */
|
|
304
|
-
export function runParity() {
|
|
305
|
-
const deftRoot = resolveDeftRoot();
|
|
306
|
-
const diffs = [];
|
|
307
|
-
for (const testCase of PARITY_CASES) {
|
|
308
|
-
const pyRepo = testCase.skipFixture
|
|
309
|
-
? mkdtempSync(join(tmpdir(), "deft-triage-queue-parity-"))
|
|
310
|
-
: buildFixtureRepo(testCase.fixture);
|
|
311
|
-
const tsRepo = testCase.skipFixture
|
|
312
|
-
? mkdtempSync(join(tmpdir(), "deft-triage-queue-parity-"))
|
|
313
|
-
: buildFixtureRepo(testCase.fixture);
|
|
314
|
-
const pyArgv = augmentParityArgv(testCase, pyRepo);
|
|
315
|
-
const tsArgv = augmentParityArgv(testCase, tsRepo);
|
|
316
|
-
try {
|
|
317
|
-
const python = runPythonQueue(deftRoot, pyRepo, pyArgv);
|
|
318
|
-
const ts = runTsQueue(deftRoot, tsRepo, tsArgv);
|
|
319
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
320
|
-
}
|
|
321
|
-
finally {
|
|
322
|
-
rmSync(pyRepo, { recursive: true, force: true });
|
|
323
|
-
rmSync(tsRepo, { recursive: true, force: true });
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
const ok = diffs.every((diff) => !diff.exitMismatch && !diff.stdoutMismatch && !diff.stderrMismatch);
|
|
327
|
-
return { ok, diffs };
|
|
328
|
-
}
|
|
329
262
|
export function renderReport(result) {
|
|
330
263
|
if (result.ok) {
|
|
331
264
|
return `triage:queue parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
@@ -347,19 +280,4 @@ export function renderReport(result) {
|
|
|
347
280
|
}
|
|
348
281
|
return lines.join("\n");
|
|
349
282
|
}
|
|
350
|
-
|
|
351
|
-
try {
|
|
352
|
-
const result = runParity();
|
|
353
|
-
if (result.ok) {
|
|
354
|
-
process.stdout.write(`${renderReport(result)}\n`);
|
|
355
|
-
process.exit(0);
|
|
356
|
-
}
|
|
357
|
-
process.stderr.write(`${renderReport(result)}\n`);
|
|
358
|
-
process.exit(1);
|
|
359
|
-
}
|
|
360
|
-
catch (err) {
|
|
361
|
-
process.stderr.write(`triage:queue parity: harness error -- ${String(err)}\n`);
|
|
362
|
-
process.exit(2);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
//# sourceMappingURL=triage-queue-parity.js.map
|
|
283
|
+
//# sourceMappingURL=triage-queue-fixtures.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
export interface CommandCapture {
|
|
3
2
|
readonly exitCode: number;
|
|
4
3
|
readonly stdout: string;
|
|
@@ -29,6 +28,5 @@ export declare function normalizeOutput(text: string): string;
|
|
|
29
28
|
export declare function buildFixtureRepo(options?: ScopeFixtureOptions): string;
|
|
30
29
|
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
31
30
|
export declare const PARITY_CASES: readonly ParityCase[];
|
|
32
|
-
export declare function runParity(): ParityResult;
|
|
33
31
|
export declare function renderReport(result: ParityResult): string;
|
|
34
|
-
//# sourceMappingURL=triage-scope-
|
|
32
|
+
//# sourceMappingURL=triage-scope-fixtures.d.ts.map
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Golden-output parity harness (#1725): runs BOTH the Python oracle
|
|
4
|
-
* (`scripts/triage_scope.py`) and the ported TS triage:scope CLI, then
|
|
5
|
-
* diffs exit codes and normalised stdout/stderr (cache-off).
|
|
6
|
-
*
|
|
7
|
-
* Exit codes: 0 parity / 1 divergence / 2 harness setup error.
|
|
8
|
-
*/
|
|
9
|
-
import { spawnSync } from "node:child_process";
|
|
10
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
11
3
|
import { tmpdir } from "node:os";
|
|
12
|
-
import {
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { join } from "node:path";
|
|
14
5
|
/** Strip volatile absolute paths before compare. */
|
|
15
6
|
export function normalizeOutput(text) {
|
|
16
7
|
return text
|
|
@@ -18,19 +9,6 @@ export function normalizeOutput(text) {
|
|
|
18
9
|
.replace(/--cache-root [^\s]+/g, "--cache-root <ROOT>")
|
|
19
10
|
.replace(/path=[^\s\n]+coverage\.json/g, "path=<ROOT>/coverage.json");
|
|
20
11
|
}
|
|
21
|
-
function runCapture(cmd, args, cwd) {
|
|
22
|
-
const result = spawnSync(cmd, args, {
|
|
23
|
-
cwd,
|
|
24
|
-
encoding: "utf8",
|
|
25
|
-
env: process.env,
|
|
26
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
27
|
-
});
|
|
28
|
-
return {
|
|
29
|
-
exitCode: result.status ?? 2,
|
|
30
|
-
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
31
|
-
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
12
|
function writeProjectDefinition(root, policy = {}) {
|
|
35
13
|
const dir = join(root, "vbrief");
|
|
36
14
|
mkdirSync(dir, { recursive: true });
|
|
@@ -45,25 +23,6 @@ export function buildFixtureRepo(options = {}) {
|
|
|
45
23
|
writeProjectDefinition(root, options.policy ?? {});
|
|
46
24
|
return root;
|
|
47
25
|
}
|
|
48
|
-
function resolveDeftRoot() {
|
|
49
|
-
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
50
|
-
return resolve(process.env.DEFT_ROOT);
|
|
51
|
-
}
|
|
52
|
-
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
53
|
-
}
|
|
54
|
-
function runPythonScope(deftRoot, repo, argv) {
|
|
55
|
-
return runCapture("uv", [
|
|
56
|
-
"run",
|
|
57
|
-
"python",
|
|
58
|
-
join(deftRoot, "scripts", "triage_scope.py"),
|
|
59
|
-
...argv,
|
|
60
|
-
"--project-root",
|
|
61
|
-
repo,
|
|
62
|
-
], deftRoot);
|
|
63
|
-
}
|
|
64
|
-
function runTsScope(deftRoot, repo, argv) {
|
|
65
|
-
return runCapture("node", [join(deftRoot, "packages", "cli", "dist", "triage-scope.js"), ...argv, "--project-root", repo], deftRoot);
|
|
66
|
-
}
|
|
67
26
|
export function diffCase(python, ts, caseName) {
|
|
68
27
|
const pyOut = normalizeOutput(python.stdout);
|
|
69
28
|
const tsOut = normalizeOutput(ts.stdout);
|
|
@@ -151,37 +110,6 @@ export const PARITY_CASES = [
|
|
|
151
110
|
},
|
|
152
111
|
},
|
|
153
112
|
];
|
|
154
|
-
export function runParity() {
|
|
155
|
-
const deftRoot = resolveDeftRoot();
|
|
156
|
-
const diffs = [];
|
|
157
|
-
for (const testCase of PARITY_CASES) {
|
|
158
|
-
if (testCase.name === "invalid-project-root") {
|
|
159
|
-
const missing = join(tmpdir(), `deft-missing-${Date.now()}`);
|
|
160
|
-
const python = runPythonScope(deftRoot, missing, testCase.argv);
|
|
161
|
-
const ts = runTsScope(deftRoot, missing, testCase.argv);
|
|
162
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
const pyRepo = buildFixtureRepo(testCase.fixture);
|
|
166
|
-
const tsRepo = buildFixtureRepo(testCase.fixture);
|
|
167
|
-
try {
|
|
168
|
-
const extraArgv = [...testCase.argv];
|
|
169
|
-
if (testCase.name === "refresh-denominator-success") {
|
|
170
|
-
const cacheRoot = mkdtempSync(join(tmpdir(), "deft-scope-cache-"));
|
|
171
|
-
extraArgv.push("--cache-root", cacheRoot);
|
|
172
|
-
}
|
|
173
|
-
const python = runPythonScope(deftRoot, pyRepo, extraArgv);
|
|
174
|
-
const ts = runTsScope(deftRoot, tsRepo, extraArgv);
|
|
175
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
176
|
-
}
|
|
177
|
-
finally {
|
|
178
|
-
rmSync(pyRepo, { recursive: true, force: true });
|
|
179
|
-
rmSync(tsRepo, { recursive: true, force: true });
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
183
|
-
return { ok, diffs };
|
|
184
|
-
}
|
|
185
113
|
export function renderReport(result) {
|
|
186
114
|
if (result.ok) {
|
|
187
115
|
return `triage:scope parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
@@ -200,19 +128,4 @@ export function renderReport(result) {
|
|
|
200
128
|
}
|
|
201
129
|
return lines.join("\n");
|
|
202
130
|
}
|
|
203
|
-
|
|
204
|
-
try {
|
|
205
|
-
const result = runParity();
|
|
206
|
-
if (result.ok) {
|
|
207
|
-
process.stdout.write(`${renderReport(result)}\n`);
|
|
208
|
-
process.exit(0);
|
|
209
|
-
}
|
|
210
|
-
process.stderr.write(`${renderReport(result)}\n`);
|
|
211
|
-
process.exit(1);
|
|
212
|
-
}
|
|
213
|
-
catch (err) {
|
|
214
|
-
process.stderr.write(`triage:scope parity: harness error -- ${String(err)}\n`);
|
|
215
|
-
process.exit(2);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
//# sourceMappingURL=triage-scope-parity.js.map
|
|
131
|
+
//# sourceMappingURL=triage-scope-fixtures.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export interface ParsedUmbrellaCurrentShapeArgs {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
passthrough: string[];
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseArgs(argv: readonly string[]): ParsedUmbrellaCurrentShapeArgs;
|
|
8
|
+
export declare function run(argv: readonly string[]): number;
|
|
9
|
+
//# sourceMappingURL=umbrella-current-shape.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { parseCurrentShapeArgv, runCurrentShape, } from "@deftai/directive-core/umbrella-current-shape";
|
|
4
|
+
export function parseArgs(argv) {
|
|
5
|
+
let projectRoot = process.cwd();
|
|
6
|
+
const passthrough = [];
|
|
7
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
8
|
+
const arg = argv[i] ?? "";
|
|
9
|
+
if (arg === "--project-root") {
|
|
10
|
+
const value = argv[i + 1];
|
|
11
|
+
if (value === undefined) {
|
|
12
|
+
return {
|
|
13
|
+
projectRoot,
|
|
14
|
+
passthrough,
|
|
15
|
+
error: "argument --project-root: expected one argument",
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
projectRoot = value;
|
|
19
|
+
i += 1;
|
|
20
|
+
}
|
|
21
|
+
else if (arg.startsWith("--project-root=")) {
|
|
22
|
+
projectRoot = arg.slice("--project-root=".length);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
passthrough.push(arg);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return { projectRoot, passthrough };
|
|
29
|
+
}
|
|
30
|
+
export function run(argv) {
|
|
31
|
+
const args = parseArgs(argv);
|
|
32
|
+
if (args.error !== undefined) {
|
|
33
|
+
process.stderr.write(`umbrella:current-shape: ${args.error}\n`);
|
|
34
|
+
return 2;
|
|
35
|
+
}
|
|
36
|
+
const parsed = parseCurrentShapeArgv(args.passthrough);
|
|
37
|
+
if (parsed.passthroughError !== undefined) {
|
|
38
|
+
process.stderr.write(`umbrella:current-shape: ${parsed.passthroughError}\n`);
|
|
39
|
+
return 2;
|
|
40
|
+
}
|
|
41
|
+
if (parsed.issueNumber === null) {
|
|
42
|
+
process.stderr.write("umbrella:current-shape: issue number required\n");
|
|
43
|
+
return 2;
|
|
44
|
+
}
|
|
45
|
+
return runCurrentShape({
|
|
46
|
+
issueNumber: parsed.issueNumber,
|
|
47
|
+
projectRoot: args.projectRoot,
|
|
48
|
+
repo: parsed.repo,
|
|
49
|
+
jsonMode: parsed.jsonMode,
|
|
50
|
+
strict: parsed.strict,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
54
|
+
process.exit(run(process.argv.slice(2)));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=umbrella-current-shape.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
export interface JsonGateOutput {
|
|
3
2
|
readonly exitCode: number;
|
|
4
3
|
readonly ready: boolean;
|
|
@@ -28,7 +27,6 @@ export declare function diffOutputs(name: string, python: JsonGateOutput, ts: Js
|
|
|
28
27
|
/** Build temp fixture files; returns map of label -> absolute path. */
|
|
29
28
|
export declare function buildFixtures(root: string): Map<string, string>;
|
|
30
29
|
/** Run both gates against all fixtures and diff them. */
|
|
31
|
-
export declare function runParity(): ParityResult;
|
|
32
30
|
/** Render a human-readable parity report (exported for unit tests). */
|
|
33
31
|
export declare function renderReport(result: ParityResult): string;
|
|
34
|
-
//# sourceMappingURL=vbrief-preflight-
|
|
32
|
+
//# sourceMappingURL=vbrief-preflight-fixtures.d.ts.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
/** Fixture corpus: [label, folder, file content]. */
|
|
5
|
+
export const PARITY_FIXTURES = [
|
|
6
|
+
["active_running", "active", JSON.stringify({ plan: { status: "running" } })],
|
|
7
|
+
["pending", "pending", JSON.stringify({ plan: { status: "running" } })],
|
|
8
|
+
["proposed", "proposed", JSON.stringify({ plan: { status: "running" } })],
|
|
9
|
+
["malformed_json", "active", "{bad json"],
|
|
10
|
+
["wrong_status", "active", JSON.stringify({ plan: { status: "pending" } })],
|
|
11
|
+
["missing_plan_status", "active", JSON.stringify({ plan: {} })],
|
|
12
|
+
];
|
|
13
|
+
/** Parse the structured `--json` stdout payload. */
|
|
14
|
+
export function parseJsonOutput(stdout, exitCode) {
|
|
15
|
+
const trimmed = stdout.trim();
|
|
16
|
+
let payload;
|
|
17
|
+
try {
|
|
18
|
+
payload = JSON.parse(trimmed);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new Error(`Expected JSON output but got: ${trimmed.length > 0 ? trimmed : "(empty)"}`);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
exitCode,
|
|
25
|
+
ready: payload.ready,
|
|
26
|
+
vbriefPath: payload.vbrief_path,
|
|
27
|
+
message: payload.message,
|
|
28
|
+
rawJson: trimmed,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Diff two gate JSON outputs for one fixture case. */
|
|
32
|
+
export function diffOutputs(name, python, ts) {
|
|
33
|
+
const exitMismatch = python.exitCode !== ts.exitCode;
|
|
34
|
+
const readyMismatch = python.ready !== ts.ready;
|
|
35
|
+
const messageMismatch = python.message !== ts.message;
|
|
36
|
+
return {
|
|
37
|
+
name,
|
|
38
|
+
ok: !exitMismatch && !readyMismatch && !messageMismatch,
|
|
39
|
+
pythonExit: python.exitCode,
|
|
40
|
+
tsExit: ts.exitCode,
|
|
41
|
+
exitMismatch,
|
|
42
|
+
readyMismatch,
|
|
43
|
+
messageMismatch,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Build temp fixture files; returns map of label -> absolute path. */
|
|
47
|
+
export function buildFixtures(root) {
|
|
48
|
+
const paths = new Map();
|
|
49
|
+
for (const [label, folder, content] of PARITY_FIXTURES) {
|
|
50
|
+
const dir = join(root, folder);
|
|
51
|
+
mkdirSync(dir, { recursive: true });
|
|
52
|
+
const file = join(dir, `${label}.vbrief.json`);
|
|
53
|
+
writeFileSync(file, content, { encoding: "utf8" });
|
|
54
|
+
paths.set(label, file);
|
|
55
|
+
}
|
|
56
|
+
return paths;
|
|
57
|
+
}
|
|
58
|
+
/** Run both gates against all fixtures and diff them. */
|
|
59
|
+
/** Render a human-readable parity report (exported for unit tests). */
|
|
60
|
+
export function renderReport(result) {
|
|
61
|
+
if (result.ok) {
|
|
62
|
+
return `vbrief_preflight parity: CLEAN -- Python and TS agree on ${result.cases.length} fixture(s).`;
|
|
63
|
+
}
|
|
64
|
+
const lines = ["vbrief_preflight parity: DIVERGENCE"];
|
|
65
|
+
for (const c of result.cases.filter((x) => !x.ok)) {
|
|
66
|
+
lines.push(` case ${c.name}:`);
|
|
67
|
+
if (c.exitMismatch) {
|
|
68
|
+
lines.push(` exit mismatch: python=${c.pythonExit} ts=${c.tsExit}`);
|
|
69
|
+
}
|
|
70
|
+
if (c.readyMismatch) {
|
|
71
|
+
lines.push(" ready mismatch");
|
|
72
|
+
}
|
|
73
|
+
if (c.messageMismatch) {
|
|
74
|
+
lines.push(" message mismatch");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return lines.join("\n");
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=vbrief-preflight-fixtures.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
export interface CommandCapture {
|
|
3
2
|
readonly exitCode: number;
|
|
4
3
|
readonly stdout: string;
|
|
@@ -34,6 +33,5 @@ export declare function buildFixtureRepo(options?: WipFixtureOptions): string;
|
|
|
34
33
|
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
35
34
|
export declare const PARITY_CASES: readonly ParityCase[];
|
|
36
35
|
/** Run all parity cases; returns aggregate result. */
|
|
37
|
-
export declare function runParity(): ParityResult;
|
|
38
36
|
export declare function renderReport(result: ParityResult): string;
|
|
39
|
-
//# sourceMappingURL=wip-cap-
|
|
37
|
+
//# sourceMappingURL=wip-cap-fixtures.d.ts.map
|
|
@@ -1,38 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Golden-output parity harness (#1723): builds throwaway fixture repos, runs
|
|
4
|
-
* BOTH the Python oracle (`scripts/preflight_wip_cap.py`) and the ported TS
|
|
5
|
-
* verify:wip-cap gate, and diffs exit codes + stdout/stderr (cache-off).
|
|
6
|
-
*
|
|
7
|
-
* Exit codes: 0 parity / 1 divergence / 2 harness setup error.
|
|
8
|
-
*/
|
|
9
|
-
import { spawnSync } from "node:child_process";
|
|
10
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
11
3
|
import { tmpdir } from "node:os";
|
|
12
|
-
import {
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { join } from "node:path";
|
|
14
5
|
/** Strip volatile absolute paths before compare. */
|
|
15
6
|
export function normalizeOutput(text) {
|
|
16
7
|
return text.replace(/project_root=[^\s)]+/g, "project_root=<ROOT>");
|
|
17
8
|
}
|
|
18
|
-
function runCapture(cmd, args, cwd, env = {}) {
|
|
19
|
-
const merged = { ...process.env, ...env };
|
|
20
|
-
for (const key of Object.keys(merged)) {
|
|
21
|
-
if (merged[key] === undefined)
|
|
22
|
-
delete merged[key];
|
|
23
|
-
}
|
|
24
|
-
const result = spawnSync(cmd, args, {
|
|
25
|
-
cwd,
|
|
26
|
-
encoding: "utf8",
|
|
27
|
-
env: merged,
|
|
28
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
29
|
-
});
|
|
30
|
-
return {
|
|
31
|
-
status: result.status ?? 2,
|
|
32
|
-
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
33
|
-
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
9
|
function writeProjectDefinition(root, plan) {
|
|
37
10
|
const dir = join(root, "vbrief");
|
|
38
11
|
mkdirSync(dir, { recursive: true });
|
|
@@ -61,32 +34,6 @@ export function buildFixtureRepo(options = {}) {
|
|
|
61
34
|
}
|
|
62
35
|
return root;
|
|
63
36
|
}
|
|
64
|
-
function resolveDeftRoot() {
|
|
65
|
-
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
66
|
-
return resolve(process.env.DEFT_ROOT);
|
|
67
|
-
}
|
|
68
|
-
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
69
|
-
}
|
|
70
|
-
function runPythonWipCap(deftRoot, repo, argv) {
|
|
71
|
-
const cap = runCapture("uv", [
|
|
72
|
-
"run",
|
|
73
|
-
"python",
|
|
74
|
-
join(deftRoot, "scripts", "preflight_wip_cap.py"),
|
|
75
|
-
...argv,
|
|
76
|
-
"--project-root",
|
|
77
|
-
repo,
|
|
78
|
-
], deftRoot);
|
|
79
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
80
|
-
}
|
|
81
|
-
function runTsWipCap(deftRoot, repo, argv) {
|
|
82
|
-
const cap = runCapture("node", [
|
|
83
|
-
join(deftRoot, "packages", "cli", "dist", "verify-wip-cap.js"),
|
|
84
|
-
...argv,
|
|
85
|
-
"--project-root",
|
|
86
|
-
repo,
|
|
87
|
-
], deftRoot);
|
|
88
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
89
|
-
}
|
|
90
37
|
/** Diff one parity case between Python oracle and TS CLI. */
|
|
91
38
|
export function diffCase(python, ts, caseName) {
|
|
92
39
|
const pyOut = normalizeOutput(python.stdout);
|
|
@@ -154,25 +101,6 @@ export const PARITY_CASES = [
|
|
|
154
101
|
},
|
|
155
102
|
];
|
|
156
103
|
/** Run all parity cases; returns aggregate result. */
|
|
157
|
-
export function runParity() {
|
|
158
|
-
const deftRoot = resolveDeftRoot();
|
|
159
|
-
const diffs = [];
|
|
160
|
-
for (const testCase of PARITY_CASES) {
|
|
161
|
-
const pyRepo = buildFixtureRepo(testCase.fixture);
|
|
162
|
-
const tsRepo = buildFixtureRepo(testCase.fixture);
|
|
163
|
-
try {
|
|
164
|
-
const python = runPythonWipCap(deftRoot, pyRepo, testCase.argv);
|
|
165
|
-
const ts = runTsWipCap(deftRoot, tsRepo, testCase.argv);
|
|
166
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
167
|
-
}
|
|
168
|
-
finally {
|
|
169
|
-
rmSync(pyRepo, { recursive: true, force: true });
|
|
170
|
-
rmSync(tsRepo, { recursive: true, force: true });
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
174
|
-
return { ok, diffs };
|
|
175
|
-
}
|
|
176
104
|
export function renderReport(result) {
|
|
177
105
|
if (result.ok) {
|
|
178
106
|
return `verify:wip-cap parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
@@ -191,19 +119,4 @@ export function renderReport(result) {
|
|
|
191
119
|
}
|
|
192
120
|
return lines.join("\n");
|
|
193
121
|
}
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
const result = runParity();
|
|
197
|
-
if (result.ok) {
|
|
198
|
-
process.stdout.write(`${renderReport(result)}\n`);
|
|
199
|
-
process.exit(0);
|
|
200
|
-
}
|
|
201
|
-
process.stderr.write(`${renderReport(result)}\n`);
|
|
202
|
-
process.exit(1);
|
|
203
|
-
}
|
|
204
|
-
catch (err) {
|
|
205
|
-
process.stderr.write(`verify:wip-cap parity: harness error -- ${String(err)}\n`);
|
|
206
|
-
process.exit(2);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
//# sourceMappingURL=wip-cap-parity.js.map
|
|
122
|
+
//# sourceMappingURL=wip-cap-fixtures.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"description": "Directive CLI — npm install path for the Deft Directive framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -9,18 +9,7 @@
|
|
|
9
9
|
"directive": "./dist/bin.js",
|
|
10
10
|
"deft": "./dist/bin.js",
|
|
11
11
|
"deft-ts": "./dist/bin.js",
|
|
12
|
-
"deft-verify-encoding": "./dist/verify-encoding.js"
|
|
13
|
-
"deft-encoding-parity": "./dist/parity.js",
|
|
14
|
-
"deft-policy": "./dist/policy.js",
|
|
15
|
-
"deft-policy-parity": "./dist/policy-parity.js",
|
|
16
|
-
"deft-vbrief-preflight": "./dist/vbrief-preflight.js",
|
|
17
|
-
"deft-vbrief-preflight-parity": "./dist/vbrief-preflight-parity.js",
|
|
18
|
-
"deft-verify-story-ready": "./dist/verify-story-ready.js",
|
|
19
|
-
"deft-story-ready-parity": "./dist/story-ready-parity.js",
|
|
20
|
-
"deft-verify-branch": "./dist/verify-branch.js",
|
|
21
|
-
"deft-branch-parity": "./dist/branch-parity.js",
|
|
22
|
-
"deft-verify-wip-cap": "./dist/verify-wip-cap.js",
|
|
23
|
-
"deft-wip-cap-parity": "./dist/wip-cap-parity.js"
|
|
12
|
+
"deft-verify-encoding": "./dist/verify-encoding.js"
|
|
24
13
|
},
|
|
25
14
|
"exports": {
|
|
26
15
|
".": {
|
|
@@ -42,8 +31,8 @@
|
|
|
42
31
|
"provenance": true
|
|
43
32
|
},
|
|
44
33
|
"dependencies": {
|
|
45
|
-
"@deftai/directive-core": "^0.
|
|
46
|
-
"@deftai/directive-content": "^0.
|
|
34
|
+
"@deftai/directive-core": "^0.63.0",
|
|
35
|
+
"@deftai/directive-content": "^0.63.0"
|
|
47
36
|
},
|
|
48
37
|
"scripts": {
|
|
49
38
|
"build": "tsc -b"
|
package/dist/cache-parity.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
export interface ScenarioResult {
|
|
3
|
-
readonly name: string;
|
|
4
|
-
readonly exitCode: number;
|
|
5
|
-
readonly stdout: string;
|
|
6
|
-
readonly stderr: string;
|
|
7
|
-
}
|
|
8
|
-
export interface ParityScenario {
|
|
9
|
-
readonly name: string;
|
|
10
|
-
readonly argv: readonly string[];
|
|
11
|
-
}
|
|
12
|
-
export interface ParityResult {
|
|
13
|
-
readonly ok: boolean;
|
|
14
|
-
readonly scenarios: Array<{
|
|
15
|
-
readonly name: string;
|
|
16
|
-
readonly exitMismatch: boolean;
|
|
17
|
-
readonly pythonExit: number;
|
|
18
|
-
readonly tsExit: number;
|
|
19
|
-
readonly messageMismatch: boolean;
|
|
20
|
-
readonly pythonMessage: string;
|
|
21
|
-
readonly tsMessage: string;
|
|
22
|
-
}>;
|
|
23
|
-
}
|
|
24
|
-
/** Validation-only scenarios (no live gh network). */
|
|
25
|
-
export declare const PARITY_SCENARIOS: readonly ParityScenario[];
|
|
26
|
-
/** Normalise gate output for comparison. */
|
|
27
|
-
export declare function normaliseMessage(stdout: string, stderr: string, exitCode: number): string;
|
|
28
|
-
export declare function diffParity(python: ScenarioResult, ts: ScenarioResult): {
|
|
29
|
-
exitMismatch: boolean;
|
|
30
|
-
messageMismatch: boolean;
|
|
31
|
-
pythonMessage: string;
|
|
32
|
-
tsMessage: string;
|
|
33
|
-
};
|
|
34
|
-
export declare function runParity(): ParityResult;
|
|
35
|
-
export declare function renderReport(result: ParityResult): string;
|
|
36
|
-
//# sourceMappingURL=cache-parity.d.ts.map
|