@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.
Files changed (102) 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 +4 -1
  5. package/dist/framework-check-updates.d.ts +10 -0
  6. package/dist/framework-check-updates.js +68 -0
  7. package/dist/install-cli/coverage-map.js +3 -2
  8. package/dist/orchestration-cli/coverage-map.js +1 -1
  9. package/dist/{policy-parity.d.ts → policy-fixtures.d.ts} +1 -3
  10. package/dist/{policy-parity.js → policy-fixtures.js} +4 -100
  11. package/dist/{release-e2e-parity.d.ts → release-e2e-fixtures.d.ts} +1 -3
  12. package/dist/release-e2e-fixtures.js +38 -0
  13. package/dist/{story-ready-parity.d.ts → story-ready-fixtures.d.ts} +1 -3
  14. package/dist/{story-ready-parity.js → story-ready-fixtures.js} +4 -121
  15. package/dist/{triage-aux-a-parity.d.ts → triage-aux-a-fixtures.d.ts} +1 -3
  16. package/dist/{triage-aux-a-parity.js → triage-aux-a-fixtures.js} +3 -73
  17. package/dist/{triage-aux-b-parity.d.ts → triage-aux-b-fixtures.d.ts} +1 -3
  18. package/dist/triage-aux-b-fixtures.js +167 -0
  19. package/dist/{triage-bootstrap-parity.d.ts → triage-bootstrap-fixtures.d.ts} +1 -3
  20. package/dist/{triage-bootstrap-parity.js → triage-bootstrap-fixtures.js} +4 -91
  21. package/dist/{triage-classify-parity.d.ts → triage-classify-fixtures.d.ts} +1 -3
  22. package/dist/{triage-classify-parity.js → triage-classify-fixtures.js} +4 -94
  23. package/dist/{triage-queue-parity.d.ts → triage-queue-fixtures.d.ts} +1 -3
  24. package/dist/{triage-queue-parity.js → triage-queue-fixtures.js} +4 -86
  25. package/dist/{triage-scope-parity.d.ts → triage-scope-fixtures.d.ts} +1 -3
  26. package/dist/{triage-scope-parity.js → triage-scope-fixtures.js} +4 -91
  27. package/dist/umbrella-current-shape.d.ts +9 -0
  28. package/dist/umbrella-current-shape.js +56 -0
  29. package/dist/{vbrief-preflight-parity.d.ts → vbrief-preflight-fixtures.d.ts} +1 -3
  30. package/dist/vbrief-preflight-fixtures.js +79 -0
  31. package/dist/{wip-cap-parity.d.ts → wip-cap-fixtures.d.ts} +1 -3
  32. package/dist/{wip-cap-parity.js → wip-cap-fixtures.js} +4 -91
  33. package/package.json +4 -15
  34. package/dist/cache-parity.d.ts +0 -36
  35. package/dist/cache-parity.js +0 -165
  36. package/dist/codebase-parity.d.ts +0 -31
  37. package/dist/codebase-parity.js +0 -303
  38. package/dist/doc-cli-parity.d.ts +0 -29
  39. package/dist/doc-cli-parity.js +0 -159
  40. package/dist/doctor-parity.d.ts +0 -42
  41. package/dist/doctor-parity.js +0 -157
  42. package/dist/intake-parity.d.ts +0 -30
  43. package/dist/intake-parity.js +0 -203
  44. package/dist/lifecycle-packs-parity.d.ts +0 -30
  45. package/dist/lifecycle-packs-parity.js +0 -377
  46. package/dist/orchestration-parity.d.ts +0 -38
  47. package/dist/orchestration-parity.js +0 -364
  48. package/dist/parity.d.ts +0 -36
  49. package/dist/parity.js +0 -176
  50. package/dist/platform-parity.d.ts +0 -26
  51. package/dist/platform-parity.js +0 -309
  52. package/dist/pr-closing-keywords-parity.d.ts +0 -45
  53. package/dist/pr-closing-keywords-parity.js +0 -259
  54. package/dist/pr-merge-readiness-parity.d.ts +0 -44
  55. package/dist/pr-merge-readiness-parity.js +0 -296
  56. package/dist/pr-monitor-parity.d.ts +0 -44
  57. package/dist/pr-monitor-parity.js +0 -283
  58. package/dist/pr-protected-issues-parity.d.ts +0 -41
  59. package/dist/pr-protected-issues-parity.js +0 -220
  60. package/dist/pr-wait-mergeable-parity.d.ts +0 -45
  61. package/dist/pr-wait-mergeable-parity.js +0 -340
  62. package/dist/release-e2e-parity.js +0 -114
  63. package/dist/release-parity.d.ts +0 -40
  64. package/dist/release-parity.js +0 -226
  65. package/dist/release-publish-parity.d.ts +0 -36
  66. package/dist/release-publish-parity.js +0 -138
  67. package/dist/release-rollback-parity.d.ts +0 -37
  68. package/dist/release-rollback-parity.js +0 -161
  69. package/dist/render-parity.d.ts +0 -36
  70. package/dist/render-parity.js +0 -385
  71. package/dist/scm-parity.d.ts +0 -39
  72. package/dist/scm-parity.js +0 -181
  73. package/dist/scope-lifecycle-parity.d.ts +0 -35
  74. package/dist/scope-lifecycle-parity.js +0 -177
  75. package/dist/session-parity.d.ts +0 -39
  76. package/dist/session-parity.js +0 -262
  77. package/dist/slice-parity.d.ts +0 -36
  78. package/dist/slice-parity.js +0 -304
  79. package/dist/swarm-parity.d.ts +0 -28
  80. package/dist/swarm-parity.js +0 -327
  81. package/dist/triage-actions-parity.d.ts +0 -36
  82. package/dist/triage-actions-parity.js +0 -357
  83. package/dist/triage-aux-b-parity.js +0 -308
  84. package/dist/triage-summary-parity.d.ts +0 -50
  85. package/dist/triage-summary-parity.js +0 -306
  86. package/dist/validate-content-parity.d.ts +0 -33
  87. package/dist/validate-content-parity.js +0 -356
  88. package/dist/vbrief-activate-parity.d.ts +0 -39
  89. package/dist/vbrief-activate-parity.js +0 -216
  90. package/dist/vbrief-build-parity.d.ts +0 -28
  91. package/dist/vbrief-build-parity.js +0 -399
  92. package/dist/vbrief-preflight-parity.js +0 -163
  93. package/dist/vbrief-reconcile-parity.d.ts +0 -23
  94. package/dist/vbrief-reconcile-parity.js +0 -609
  95. package/dist/vbrief-validate-parity.d.ts +0 -27
  96. package/dist/vbrief-validate-parity.js +0 -122
  97. package/dist/vbrief-validation-parity.d.ts +0 -28
  98. package/dist/vbrief-validation-parity.js +0 -645
  99. package/dist/verify-env-parity.d.ts +0 -28
  100. package/dist/verify-env-parity.js +0 -272
  101. package/dist/verify-source-parity.d.ts +0 -26
  102. 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