@deftai/directive 0.62.0 → 0.64.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 (99) hide show
  1. package/dist/{branch-parity.d.ts → branch-fixtures.d.ts} +1 -3
  2. package/dist/{branch-parity.js → branch-fixtures.js} +3 -110
  3. package/dist/dispatch.d.ts +1 -1
  4. package/dist/dispatch.js +3 -1
  5. package/dist/orchestration-cli/coverage-map.js +1 -1
  6. package/dist/{policy-parity.d.ts → policy-fixtures.d.ts} +1 -3
  7. package/dist/{policy-parity.js → policy-fixtures.js} +4 -100
  8. package/dist/{release-e2e-parity.d.ts → release-e2e-fixtures.d.ts} +1 -3
  9. package/dist/release-e2e-fixtures.js +38 -0
  10. package/dist/{story-ready-parity.d.ts → story-ready-fixtures.d.ts} +1 -3
  11. package/dist/{story-ready-parity.js → story-ready-fixtures.js} +4 -121
  12. package/dist/{triage-aux-a-parity.d.ts → triage-aux-a-fixtures.d.ts} +1 -3
  13. package/dist/{triage-aux-a-parity.js → triage-aux-a-fixtures.js} +3 -73
  14. package/dist/{triage-aux-b-parity.d.ts → triage-aux-b-fixtures.d.ts} +1 -3
  15. package/dist/triage-aux-b-fixtures.js +167 -0
  16. package/dist/{triage-bootstrap-parity.d.ts → triage-bootstrap-fixtures.d.ts} +1 -3
  17. package/dist/{triage-bootstrap-parity.js → triage-bootstrap-fixtures.js} +4 -91
  18. package/dist/{triage-classify-parity.d.ts → triage-classify-fixtures.d.ts} +1 -3
  19. package/dist/{triage-classify-parity.js → triage-classify-fixtures.js} +4 -94
  20. package/dist/{triage-queue-parity.d.ts → triage-queue-fixtures.d.ts} +1 -3
  21. package/dist/{triage-queue-parity.js → triage-queue-fixtures.js} +4 -86
  22. package/dist/{triage-scope-parity.d.ts → triage-scope-fixtures.d.ts} +1 -3
  23. package/dist/{triage-scope-parity.js → triage-scope-fixtures.js} +4 -91
  24. package/dist/{vbrief-preflight-parity.d.ts → vbrief-preflight-fixtures.d.ts} +1 -3
  25. package/dist/vbrief-preflight-fixtures.js +79 -0
  26. package/dist/verify-source-cli/verify-cursor-tier1.d.ts +12 -0
  27. package/dist/verify-source-cli/verify-cursor-tier1.js +51 -0
  28. package/dist/{wip-cap-parity.d.ts → wip-cap-fixtures.d.ts} +1 -3
  29. package/dist/{wip-cap-parity.js → wip-cap-fixtures.js} +4 -91
  30. package/package.json +4 -15
  31. package/dist/cache-parity.d.ts +0 -36
  32. package/dist/cache-parity.js +0 -165
  33. package/dist/codebase-parity.d.ts +0 -31
  34. package/dist/codebase-parity.js +0 -303
  35. package/dist/doc-cli-parity.d.ts +0 -29
  36. package/dist/doc-cli-parity.js +0 -159
  37. package/dist/doctor-parity.d.ts +0 -42
  38. package/dist/doctor-parity.js +0 -157
  39. package/dist/intake-parity.d.ts +0 -30
  40. package/dist/intake-parity.js +0 -203
  41. package/dist/lifecycle-packs-parity.d.ts +0 -30
  42. package/dist/lifecycle-packs-parity.js +0 -377
  43. package/dist/orchestration-parity.d.ts +0 -38
  44. package/dist/orchestration-parity.js +0 -364
  45. package/dist/parity.d.ts +0 -36
  46. package/dist/parity.js +0 -176
  47. package/dist/platform-parity.d.ts +0 -26
  48. package/dist/platform-parity.js +0 -309
  49. package/dist/pr-closing-keywords-parity.d.ts +0 -45
  50. package/dist/pr-closing-keywords-parity.js +0 -259
  51. package/dist/pr-merge-readiness-parity.d.ts +0 -44
  52. package/dist/pr-merge-readiness-parity.js +0 -296
  53. package/dist/pr-monitor-parity.d.ts +0 -44
  54. package/dist/pr-monitor-parity.js +0 -283
  55. package/dist/pr-protected-issues-parity.d.ts +0 -41
  56. package/dist/pr-protected-issues-parity.js +0 -220
  57. package/dist/pr-wait-mergeable-parity.d.ts +0 -45
  58. package/dist/pr-wait-mergeable-parity.js +0 -340
  59. package/dist/release-e2e-parity.js +0 -114
  60. package/dist/release-parity.d.ts +0 -40
  61. package/dist/release-parity.js +0 -226
  62. package/dist/release-publish-parity.d.ts +0 -36
  63. package/dist/release-publish-parity.js +0 -138
  64. package/dist/release-rollback-parity.d.ts +0 -37
  65. package/dist/release-rollback-parity.js +0 -161
  66. package/dist/render-parity.d.ts +0 -36
  67. package/dist/render-parity.js +0 -385
  68. package/dist/scm-parity.d.ts +0 -39
  69. package/dist/scm-parity.js +0 -181
  70. package/dist/scope-lifecycle-parity.d.ts +0 -35
  71. package/dist/scope-lifecycle-parity.js +0 -177
  72. package/dist/session-parity.d.ts +0 -39
  73. package/dist/session-parity.js +0 -262
  74. package/dist/slice-parity.d.ts +0 -36
  75. package/dist/slice-parity.js +0 -304
  76. package/dist/swarm-parity.d.ts +0 -28
  77. package/dist/swarm-parity.js +0 -327
  78. package/dist/triage-actions-parity.d.ts +0 -36
  79. package/dist/triage-actions-parity.js +0 -357
  80. package/dist/triage-aux-b-parity.js +0 -308
  81. package/dist/triage-summary-parity.d.ts +0 -50
  82. package/dist/triage-summary-parity.js +0 -306
  83. package/dist/validate-content-parity.d.ts +0 -33
  84. package/dist/validate-content-parity.js +0 -356
  85. package/dist/vbrief-activate-parity.d.ts +0 -39
  86. package/dist/vbrief-activate-parity.js +0 -216
  87. package/dist/vbrief-build-parity.d.ts +0 -28
  88. package/dist/vbrief-build-parity.js +0 -399
  89. package/dist/vbrief-preflight-parity.js +0 -163
  90. package/dist/vbrief-reconcile-parity.d.ts +0 -23
  91. package/dist/vbrief-reconcile-parity.js +0 -609
  92. package/dist/vbrief-validate-parity.d.ts +0 -27
  93. package/dist/vbrief-validate-parity.js +0 -122
  94. package/dist/vbrief-validation-parity.d.ts +0 -28
  95. package/dist/vbrief-validation-parity.js +0 -645
  96. package/dist/verify-env-parity.d.ts +0 -28
  97. package/dist/verify-env-parity.js +0 -272
  98. package/dist/verify-source-parity.d.ts +0 -26
  99. package/dist/verify-source-parity.js +0 -178
@@ -1,114 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Golden-output parity harness (#1729): runs BOTH the Python oracle
4
- * (`scripts/release_e2e.py`) and the ported TS release:e2e CLI with
5
- * identical argv, then diffs exit codes and normalised stderr/stdout.
6
- */
7
- import { spawnSync } from "node:child_process";
8
- import { dirname, join, resolve } from "node:path";
9
- import { fileURLToPath } from "node:url";
10
- export const PARITY_SCENARIOS = [
11
- { name: "help", argv: ["--help"], compareStdout: true },
12
- { name: "dry-run", argv: ["--dry-run"] },
13
- { name: "dry-run-keep-repo", argv: ["--dry-run", "--keep-repo"] },
14
- {
15
- name: "dry-run-project-root",
16
- argv: ["--dry-run", "--owner", "deftai", "--project-root", "/tmp/deft-e2e-parity-root"],
17
- },
18
- ];
19
- /** Normalise volatile repo slugs and ISO dates in stderr while preserving semantics. */
20
- export function normaliseStderr(text) {
21
- return text
22
- .replace(/deftai-release-test-\d{14}-[0-9a-f]{6}/g, "deftai-release-test-YYYYMMDDHHMMSS-uuid6")
23
- .replace(/\d{4}-\d{2}-\d{2}/g, "YYYY-MM-DD");
24
- }
25
- function runCapture(cmd, args, cwd) {
26
- const result = spawnSync(cmd, args, {
27
- cwd,
28
- encoding: "utf8",
29
- env: {
30
- ...process.env,
31
- DEFT_CACHE_DISABLE: "1",
32
- PYTHONUTF8: "1",
33
- },
34
- stdio: ["ignore", "pipe", "pipe"],
35
- });
36
- return {
37
- exitCode: result.status ?? 2,
38
- stdout: typeof result.stdout === "string" ? result.stdout : "",
39
- stderr: typeof result.stderr === "string" ? result.stderr : "",
40
- };
41
- }
42
- function resolveDeftRoot() {
43
- if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
44
- return resolve(process.env.DEFT_ROOT);
45
- }
46
- return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
47
- }
48
- function runScenario(deftRoot, scenario) {
49
- const argv = [...scenario.argv];
50
- const py = runCapture("uv", ["run", "python", join(deftRoot, "scripts", "release_e2e.py"), ...argv], deftRoot);
51
- const ts = runCapture("node", [join(deftRoot, "packages", "cli", "dist", "release-e2e.js"), ...argv], deftRoot);
52
- const stream = scenario.compareStdout ? "stdout" : "stderr";
53
- let pythonOutput = stream === "stdout" ? py.stdout : py.stderr;
54
- let tsOutput = stream === "stdout" ? ts.stdout : ts.stderr;
55
- if (stream === "stderr") {
56
- pythonOutput = normaliseStderr(pythonOutput);
57
- tsOutput = normaliseStderr(tsOutput);
58
- }
59
- return {
60
- name: scenario.name,
61
- exitMismatch: py.exitCode !== ts.exitCode,
62
- outputMismatch: pythonOutput !== tsOutput,
63
- pythonExit: py.exitCode,
64
- tsExit: ts.exitCode,
65
- pythonOutput,
66
- tsOutput,
67
- stream,
68
- };
69
- }
70
- export function runParity() {
71
- const deftRoot = resolveDeftRoot();
72
- const diffs = PARITY_SCENARIOS.map((scenario) => runScenario(deftRoot, scenario));
73
- const ok = diffs.every((d) => !d.exitMismatch && !d.outputMismatch);
74
- return { ok, diffs };
75
- }
76
- export function renderReport(result) {
77
- if (result.ok) {
78
- return `release-e2e parity: CLEAN -- Python and TS agree on ${result.diffs.length} scenario(s).`;
79
- }
80
- const lines = ["release-e2e parity: DIVERGENCE"];
81
- for (const d of result.diffs) {
82
- if (d.exitMismatch || d.outputMismatch) {
83
- lines.push(` scenario: ${d.name}`);
84
- if (d.exitMismatch) {
85
- lines.push(` exit mismatch: python=${d.pythonExit} ts=${d.tsExit}`);
86
- }
87
- if (d.outputMismatch) {
88
- lines.push(` stream: ${d.stream}`);
89
- lines.push(` python (${d.pythonOutput.length} bytes):`);
90
- lines.push(d.pythonOutput);
91
- lines.push(` ts (${d.tsOutput.length} bytes):`);
92
- lines.push(d.tsOutput);
93
- }
94
- }
95
- }
96
- return lines.join("\n");
97
- }
98
- if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
99
- try {
100
- const result = runParity();
101
- if (result.ok) {
102
- process.stdout.write(`${renderReport(result)}\n`);
103
- process.exit(0);
104
- }
105
- process.stderr.write(`${renderReport(result)}\n`);
106
- process.exit(1);
107
- }
108
- catch (err) {
109
- const msg = String(err).replace(/\r?\n/g, " ");
110
- process.stderr.write(`release-e2e parity: harness error -- ${msg}\n`);
111
- process.exit(2);
112
- }
113
- }
114
- //# sourceMappingURL=release-e2e-parity.js.map
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env node
2
- export declare const SAMPLE_CHANGELOG = " Changelog\n\nAll notable changes to the project.\n\n## [Unreleased]\n\n### Added\n- New release automation (#74)\n\n### Changed\n- Refactored module X\n\n### Fixed\n- Bug Y\n\n## [0.20.2] - 2026-04-24\n\n### Added\n- Prior change\n\n## [0.20.0] - 2026-04-23\n\n### Added\n- Older change\n\n[Unreleased]: https://github.com/deftai/directive/compare/v0.20.2...HEAD\n[0.20.2]: https://github.com/deftai/directive/compare/v0.20.0...v0.20.2\n[0.20.0]: https://github.com/deftai/directive/compare/v0.19.0...v0.20.0\n";
3
- export interface ScenarioResult {
4
- readonly name: string;
5
- readonly exitCode: number;
6
- readonly stdout: string;
7
- readonly stderr: string;
8
- }
9
- export interface ParityScenario {
10
- readonly name: string;
11
- readonly argv: readonly string[];
12
- readonly setup?: (root: string) => void;
13
- readonly compareStdout?: boolean;
14
- }
15
- export interface ParityResult {
16
- readonly ok: boolean;
17
- readonly scenarios: Array<{
18
- readonly name: string;
19
- readonly exitMismatch: boolean;
20
- readonly pythonExit: number;
21
- readonly tsExit: number;
22
- readonly outputMismatch: boolean;
23
- readonly pythonOutput: string;
24
- readonly tsOutput: string;
25
- readonly stream: "stdout" | "stderr";
26
- }>;
27
- }
28
- export declare const PARITY_SCENARIOS: readonly ParityScenario[];
29
- /** Normalise volatile ISO dates in stderr while preserving semantics. */
30
- export declare function normaliseStderr(text: string): string;
31
- export declare function pickOutput(result: ScenarioResult, stream: "stdout" | "stderr"): string;
32
- export declare function diffParity(python: ScenarioResult, ts: ScenarioResult, stream: "stdout" | "stderr"): {
33
- exitMismatch: boolean;
34
- outputMismatch: boolean;
35
- pythonOutput: string;
36
- tsOutput: string;
37
- };
38
- export declare function runParity(): ParityResult;
39
- export declare function renderReport(result: ParityResult): string;
40
- //# sourceMappingURL=release-parity.d.ts.map
@@ -1,226 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Golden-output parity harness (#1729): runs BOTH the Python oracle
4
- * (`scripts/release.py`) and the ported TS release CLI with identical argv,
5
- * then diffs exit codes and normalised stderr/stdout. Exit 0 only on
6
- * byte-identical results (volatile ISO dates normalised in stderr).
7
- *
8
- * Exit codes: 0 parity / 1 divergence / 2 harness setup error.
9
- */
10
- import { execFileSync, spawnSync } from "node:child_process";
11
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
12
- import { tmpdir } from "node:os";
13
- import { dirname, join, resolve } from "node:path";
14
- import { fileURLToPath } from "node:url";
15
- export const SAMPLE_CHANGELOG = ` Changelog
16
-
17
- All notable changes to the project.
18
-
19
- ## [Unreleased]
20
-
21
- ### Added
22
- - New release automation (#74)
23
-
24
- ### Changed
25
- - Refactored module X
26
-
27
- ### Fixed
28
- - Bug Y
29
-
30
- ## [0.20.2] - 2026-04-24
31
-
32
- ### Added
33
- - Prior change
34
-
35
- ## [0.20.0] - 2026-04-23
36
-
37
- ### Added
38
- - Older change
39
-
40
- [Unreleased]: https://github.com/deftai/directive/compare/v0.20.2...HEAD
41
- [0.20.2]: https://github.com/deftai/directive/compare/v0.20.0...v0.20.2
42
- [0.20.0]: https://github.com/deftai/directive/compare/v0.19.0...v0.20.0
43
- `;
44
- export const PARITY_SCENARIOS = [
45
- { name: "invalid-version", argv: ["not-a-version"] },
46
- {
47
- name: "dry-run-fixture",
48
- argv: [
49
- "0.21.0",
50
- "--dry-run",
51
- "--skip-tag",
52
- "--skip-release",
53
- "--repo",
54
- "deftai/directive",
55
- "--allow-vbrief-drift",
56
- "--skip-ci",
57
- ],
58
- setup(root) {
59
- writeFileSync(join(root, "CHANGELOG.md"), SAMPLE_CHANGELOG, "utf8");
60
- execFileSync("git", ["init", "-q", "-b", "master", root]);
61
- execFileSync("git", ["config", "user.email", "parity@test.local"], { cwd: root });
62
- execFileSync("git", ["config", "user.name", "deft-parity"], { cwd: root });
63
- execFileSync("git", ["add", "CHANGELOG.md"], { cwd: root });
64
- execFileSync("git", ["commit", "-q", "-m", "init"], {
65
- cwd: root,
66
- env: {
67
- ...process.env,
68
- GIT_AUTHOR_NAME: "deft-parity",
69
- GIT_AUTHOR_EMAIL: "parity@test.local",
70
- GIT_COMMITTER_NAME: "deft-parity",
71
- GIT_COMMITTER_EMAIL: "parity@test.local",
72
- },
73
- });
74
- },
75
- },
76
- { name: "help", argv: ["--help"], compareStdout: true },
77
- ];
78
- function runCapture(cmd, args, cwd, env = {}) {
79
- const merged = {
80
- ...process.env,
81
- ...env,
82
- DEFT_CACHE_DISABLE: "1",
83
- PYTHONUTF8: "1",
84
- };
85
- for (const key of Object.keys(merged)) {
86
- if (merged[key] === undefined)
87
- delete merged[key];
88
- }
89
- try {
90
- const result = spawnSync(cmd, args, {
91
- cwd,
92
- encoding: "utf8",
93
- env: merged,
94
- stdio: ["ignore", "pipe", "pipe"],
95
- });
96
- return {
97
- status: result.status ?? 2,
98
- stdout: typeof result.stdout === "string" ? result.stdout : "",
99
- stderr: typeof result.stderr === "string" ? result.stderr : "",
100
- };
101
- }
102
- catch (err) {
103
- const e = err;
104
- return {
105
- status: typeof e.status === "number" ? e.status : 2,
106
- stdout: typeof e.stdout === "string" ? e.stdout : "",
107
- stderr: typeof e.stderr === "string" ? e.stderr : "",
108
- };
109
- }
110
- }
111
- function resolveDeftRoot() {
112
- if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
113
- return resolve(process.env.DEFT_ROOT);
114
- }
115
- return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
116
- }
117
- /** Normalise volatile ISO dates in stderr while preserving semantics. */
118
- export function normaliseStderr(text) {
119
- return text
120
- .replace(/\d{4}-\d{2}-\d{2}/g, "YYYY-MM-DD")
121
- .replace(/(?:\/private)?\/var\/folders\/[^\s)]+\/deft-release-parity-[^\s)]+/g, "<TMP>")
122
- .replace(/\/tmp\/deft-release-parity-[^\s)]+/g, "<TMP>");
123
- }
124
- export function pickOutput(result, stream) {
125
- return stream === "stdout" ? result.stdout : result.stderr;
126
- }
127
- function runScenario(deftRoot, scenario) {
128
- let cwd = deftRoot;
129
- let tempRoot;
130
- let projectRoot;
131
- const argv = [...scenario.argv];
132
- if (scenario.setup) {
133
- tempRoot = mkdtempSync(join(tmpdir(), "deft-release-parity-"));
134
- projectRoot = tempRoot;
135
- scenario.setup(tempRoot);
136
- const idx = argv.indexOf("--project-root");
137
- if (idx === -1) {
138
- argv.push("--project-root", tempRoot);
139
- }
140
- cwd = deftRoot;
141
- }
142
- try {
143
- const pyArgs = ["run", "python", join(deftRoot, "scripts", "release.py"), ...argv];
144
- const tsArgs = [join(deftRoot, "packages", "cli", "dist", "release.js"), ...argv];
145
- const py = runCapture("uv", pyArgs, cwd);
146
- const ts = runCapture("node", tsArgs, cwd);
147
- return {
148
- python: { name: scenario.name, exitCode: py.status, stdout: py.stdout, stderr: py.stderr },
149
- ts: { name: scenario.name, exitCode: ts.status, stdout: ts.stdout, stderr: ts.stderr },
150
- projectRoot,
151
- };
152
- }
153
- finally {
154
- if (tempRoot) {
155
- rmSync(tempRoot, { recursive: true, force: true });
156
- }
157
- }
158
- }
159
- export function diffParity(python, ts, stream) {
160
- let pythonOutput = pickOutput(python, stream);
161
- let tsOutput = pickOutput(ts, stream);
162
- if (stream === "stderr") {
163
- pythonOutput = normaliseStderr(pythonOutput);
164
- tsOutput = normaliseStderr(tsOutput);
165
- }
166
- return {
167
- exitMismatch: python.exitCode !== ts.exitCode,
168
- outputMismatch: pythonOutput !== tsOutput,
169
- pythonOutput,
170
- tsOutput,
171
- };
172
- }
173
- export function runParity() {
174
- const deftRoot = resolveDeftRoot();
175
- const scenarios = [];
176
- for (const scenario of PARITY_SCENARIOS) {
177
- const ran = runScenario(deftRoot, scenario);
178
- const stream = scenario.compareStdout ? "stdout" : "stderr";
179
- scenarios.push({
180
- name: scenario.name,
181
- pythonExit: ran.python.exitCode,
182
- tsExit: ran.ts.exitCode,
183
- stream,
184
- ...diffParity(ran.python, ran.ts, stream),
185
- });
186
- }
187
- const ok = scenarios.every((s) => !s.exitMismatch && !s.outputMismatch);
188
- return { ok, scenarios };
189
- }
190
- export function renderReport(result) {
191
- if (result.ok) {
192
- return `release parity: CLEAN -- Python and TS agree on ${result.scenarios.length} scenario(s).`;
193
- }
194
- const lines = ["release parity: DIVERGENCE"];
195
- for (const s of result.scenarios) {
196
- if (s.exitMismatch || s.outputMismatch) {
197
- lines.push(` scenario: ${s.name}`);
198
- if (s.exitMismatch) {
199
- lines.push(` exit mismatch: python=${s.pythonExit} ts=${s.tsExit}`);
200
- }
201
- if (s.outputMismatch) {
202
- lines.push(` stream: ${s.stream}`);
203
- lines.push(` python (${s.pythonOutput.length} bytes)`);
204
- lines.push(` ts (${s.tsOutput.length} bytes)`);
205
- }
206
- }
207
- }
208
- return lines.join("\n");
209
- }
210
- if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
211
- try {
212
- const result = runParity();
213
- if (result.ok) {
214
- process.stdout.write(`${renderReport(result)}\n`);
215
- process.exit(0);
216
- }
217
- process.stderr.write(`${renderReport(result)}\n`);
218
- process.exit(1);
219
- }
220
- catch (err) {
221
- const msg = String(err).replace(/\r?\n/g, " ");
222
- process.stderr.write(`release parity: harness error -- ${msg}\n`);
223
- process.exit(2);
224
- }
225
- }
226
- //# sourceMappingURL=release-parity.js.map
@@ -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
- readonly compareStdout?: boolean;
12
- }
13
- export interface ParityResult {
14
- readonly ok: boolean;
15
- readonly scenarios: Array<{
16
- readonly name: string;
17
- readonly exitMismatch: boolean;
18
- readonly pythonExit: number;
19
- readonly tsExit: number;
20
- readonly outputMismatch: boolean;
21
- readonly pythonOutput: string;
22
- readonly tsOutput: string;
23
- readonly stream: "stdout" | "stderr";
24
- }>;
25
- }
26
- export declare const PARITY_SCENARIOS: readonly ParityScenario[];
27
- export declare function pickOutput(result: ScenarioResult, stream: "stdout" | "stderr"): string;
28
- export declare function diffParity(python: ScenarioResult, ts: ScenarioResult, stream: "stdout" | "stderr"): {
29
- exitMismatch: boolean;
30
- outputMismatch: boolean;
31
- pythonOutput: string;
32
- tsOutput: string;
33
- };
34
- export declare function runParity(): ParityResult;
35
- export declare function renderReport(result: ParityResult): string;
36
- //# sourceMappingURL=release-publish-parity.d.ts.map
@@ -1,138 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Golden-output parity harness (#1729): runs BOTH the Python oracle
4
- * (`scripts/release_publish.py`) and the ported TS release:publish CLI
5
- * with identical argv, then diffs exit codes and normalised stderr/stdout.
6
- * Exit 0 only on byte-identical results (cache off).
7
- *
8
- * Exit codes: 0 parity / 1 divergence / 2 harness setup error.
9
- */
10
- import { spawnSync } from "node:child_process";
11
- import { dirname, join, resolve } from "node:path";
12
- import { fileURLToPath } from "node:url";
13
- export const PARITY_SCENARIOS = [
14
- { name: "invalid-version", argv: ["not-a-version"] },
15
- { name: "missing-version", argv: [] },
16
- {
17
- name: "dry-run",
18
- argv: ["0.21.0", "--dry-run", "--repo", "deftai/directive"],
19
- },
20
- { name: "help", argv: ["--help"], compareStdout: true },
21
- ];
22
- function runCapture(cmd, args, cwd, env = {}) {
23
- const merged = {
24
- ...process.env,
25
- ...env,
26
- DEFT_CACHE_DISABLE: "1",
27
- PYTHONUTF8: "1",
28
- };
29
- for (const key of Object.keys(merged)) {
30
- if (merged[key] === undefined)
31
- delete merged[key];
32
- }
33
- try {
34
- const result = spawnSync(cmd, args, {
35
- cwd,
36
- encoding: "utf8",
37
- env: merged,
38
- stdio: ["ignore", "pipe", "pipe"],
39
- });
40
- return {
41
- status: result.status ?? 2,
42
- stdout: typeof result.stdout === "string" ? result.stdout : "",
43
- stderr: typeof result.stderr === "string" ? result.stderr : "",
44
- };
45
- }
46
- catch (err) {
47
- const e = err;
48
- return {
49
- status: typeof e.status === "number" ? e.status : 2,
50
- stdout: typeof e.stdout === "string" ? e.stdout : "",
51
- stderr: typeof e.stderr === "string" ? e.stderr : "",
52
- };
53
- }
54
- }
55
- function resolveDeftRoot() {
56
- if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
57
- return resolve(process.env.DEFT_ROOT);
58
- }
59
- return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
60
- }
61
- export function pickOutput(result, stream) {
62
- return stream === "stdout" ? result.stdout : result.stderr;
63
- }
64
- function runScenario(deftRoot, scenario) {
65
- const argv = [...scenario.argv];
66
- const pyArgs = ["run", "python", join(deftRoot, "scripts", "release_publish.py"), ...argv];
67
- const tsArgs = [join(deftRoot, "packages", "cli", "dist", "release-publish.js"), ...argv];
68
- const py = runCapture("uv", pyArgs, deftRoot);
69
- const ts = runCapture("node", tsArgs, deftRoot);
70
- return {
71
- python: { name: scenario.name, exitCode: py.status, stdout: py.stdout, stderr: py.stderr },
72
- ts: { name: scenario.name, exitCode: ts.status, stdout: ts.stdout, stderr: ts.stderr },
73
- };
74
- }
75
- export function diffParity(python, ts, stream) {
76
- const pythonOutput = pickOutput(python, stream);
77
- const tsOutput = pickOutput(ts, stream);
78
- return {
79
- exitMismatch: python.exitCode !== ts.exitCode,
80
- outputMismatch: pythonOutput !== tsOutput,
81
- pythonOutput,
82
- tsOutput,
83
- };
84
- }
85
- export function runParity() {
86
- const deftRoot = resolveDeftRoot();
87
- const scenarios = [];
88
- for (const scenario of PARITY_SCENARIOS) {
89
- const ran = runScenario(deftRoot, scenario);
90
- const stream = scenario.compareStdout ? "stdout" : "stderr";
91
- scenarios.push({
92
- name: scenario.name,
93
- pythonExit: ran.python.exitCode,
94
- tsExit: ran.ts.exitCode,
95
- stream,
96
- ...diffParity(ran.python, ran.ts, stream),
97
- });
98
- }
99
- const ok = scenarios.every((s) => !s.exitMismatch && !s.outputMismatch);
100
- return { ok, scenarios };
101
- }
102
- export function renderReport(result) {
103
- if (result.ok) {
104
- return `release-publish parity: CLEAN -- Python and TS agree on ${result.scenarios.length} scenario(s).`;
105
- }
106
- const lines = ["release-publish parity: DIVERGENCE"];
107
- for (const s of result.scenarios) {
108
- if (s.exitMismatch || s.outputMismatch) {
109
- lines.push(` scenario: ${s.name}`);
110
- if (s.exitMismatch) {
111
- lines.push(` exit mismatch: python=${s.pythonExit} ts=${s.tsExit}`);
112
- }
113
- if (s.outputMismatch) {
114
- lines.push(` stream: ${s.stream}`);
115
- lines.push(` python (${s.pythonOutput.length} bytes)`);
116
- lines.push(` ts (${s.tsOutput.length} bytes)`);
117
- }
118
- }
119
- }
120
- return lines.join("\n");
121
- }
122
- if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
123
- try {
124
- const result = runParity();
125
- if (result.ok) {
126
- process.stdout.write(`${renderReport(result)}\n`);
127
- process.exit(0);
128
- }
129
- process.stderr.write(`${renderReport(result)}\n`);
130
- process.exit(1);
131
- }
132
- catch (err) {
133
- const msg = String(err).replace(/\r?\n/g, " ");
134
- process.stderr.write(`release-publish parity: harness error -- ${msg}\n`);
135
- process.exit(2);
136
- }
137
- }
138
- //# sourceMappingURL=release-publish-parity.js.map
@@ -1,37 +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
- readonly compareStdout?: boolean;
12
- }
13
- export interface ParityResult {
14
- readonly ok: boolean;
15
- readonly scenarios: Array<{
16
- readonly name: string;
17
- readonly exitMismatch: boolean;
18
- readonly pythonExit: number;
19
- readonly tsExit: number;
20
- readonly outputMismatch: boolean;
21
- readonly pythonOutput: string;
22
- readonly tsOutput: string;
23
- readonly stream: "stdout" | "stderr";
24
- }>;
25
- }
26
- export declare const PARITY_SCENARIOS: readonly ParityScenario[];
27
- export declare function normaliseStderr(text: string): string;
28
- export declare function pickOutput(result: ScenarioResult, stream: "stdout" | "stderr"): string;
29
- export declare function diffParity(python: ScenarioResult, ts: ScenarioResult, stream: "stdout" | "stderr"): {
30
- exitMismatch: boolean;
31
- outputMismatch: boolean;
32
- pythonOutput: string;
33
- tsOutput: string;
34
- };
35
- export declare function runParity(): ParityResult;
36
- export declare function renderReport(result: ParityResult): string;
37
- //# sourceMappingURL=release-rollback-parity.d.ts.map