@deftai/directive 0.55.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/bin.d.ts +3 -0
- package/dist/bin.js +5 -0
- package/dist/branch-parity.d.ts +47 -0
- package/dist/branch-parity.js +263 -0
- package/dist/cache-parity.d.ts +36 -0
- package/dist/cache-parity.js +165 -0
- package/dist/cache.d.ts +4 -0
- package/dist/cache.js +10 -0
- package/dist/capacity-backfill.d.ts +3 -0
- package/dist/capacity-backfill.js +9 -0
- package/dist/capacity-show.d.ts +3 -0
- package/dist/capacity-show.js +9 -0
- package/dist/check.d.ts +10 -0
- package/dist/check.js +60 -0
- package/dist/cli-router/index.d.ts +8 -0
- package/dist/cli-router/index.js +37 -0
- package/dist/cli-router/route-argv.d.ts +32 -0
- package/dist/cli-router/route-argv.js +226 -0
- package/dist/codebase-default-extractor.d.ts +3 -0
- package/dist/codebase-default-extractor.js +9 -0
- package/dist/codebase-map-fresh.d.ts +3 -0
- package/dist/codebase-map-fresh.js +9 -0
- package/dist/codebase-map.d.ts +3 -0
- package/dist/codebase-map.js +9 -0
- package/dist/codebase-parity.d.ts +30 -0
- package/dist/codebase-parity.js +294 -0
- package/dist/codebase-projection-registry.d.ts +3 -0
- package/dist/codebase-projection-registry.js +9 -0
- package/dist/codebase-provider.d.ts +3 -0
- package/dist/codebase-provider.js +9 -0
- package/dist/content-validate-cli/validate-links.d.ts +11 -0
- package/dist/content-validate-cli/validate-links.js +37 -0
- package/dist/content-validate-cli/validate-strategy-output.d.ts +13 -0
- package/dist/content-validate-cli/validate-strategy-output.js +56 -0
- package/dist/content-validate-cli/verify-capacity.d.ts +12 -0
- package/dist/content-validate-cli/verify-capacity.js +54 -0
- package/dist/dispatch.d.ts +26 -0
- package/dist/dispatch.js +569 -0
- package/dist/doctor-parity.d.ts +38 -0
- package/dist/doctor-parity.js +151 -0
- package/dist/doctor.d.ts +3 -0
- package/dist/doctor.js +10 -0
- package/dist/gates-cli/_helpers.d.ts +18 -0
- package/dist/gates-cli/_helpers.js +71 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +15 -0
- package/dist/init-cli/constants.d.ts +5 -0
- package/dist/init-cli/constants.js +5 -0
- package/dist/init-cli/init.d.ts +3 -0
- package/dist/init-cli/init.js +11 -0
- package/dist/init-cli/resolve-binary.d.ts +34 -0
- package/dist/init-cli/resolve-binary.js +78 -0
- package/dist/init-cli/run-deft-install.d.ts +23 -0
- package/dist/init-cli/run-deft-install.js +71 -0
- package/dist/init-cli/update.d.ts +3 -0
- package/dist/init-cli/update.js +11 -0
- package/dist/install-cli/coverage-map.d.ts +14 -0
- package/dist/install-cli/coverage-map.js +111 -0
- package/dist/intake-parity.d.ts +30 -0
- package/dist/intake-parity.js +203 -0
- package/dist/lifecycle-cli/coverage-map.d.ts +16 -0
- package/dist/lifecycle-cli/coverage-map.js +254 -0
- package/dist/lifecycle-cli/helpers.d.ts +8 -0
- package/dist/lifecycle-cli/helpers.js +20 -0
- package/dist/lifecycle-packs-parity.d.ts +30 -0
- package/dist/lifecycle-packs-parity.js +377 -0
- package/dist/orchestration-cli/coverage-map.d.ts +21 -0
- package/dist/orchestration-cli/coverage-map.js +225 -0
- package/dist/orchestration-cli/helpers.d.ts +11 -0
- package/dist/orchestration-cli/helpers.js +35 -0
- package/dist/orchestration-parity.d.ts +38 -0
- package/dist/orchestration-parity.js +364 -0
- package/dist/parity.d.ts +36 -0
- package/dist/parity.js +176 -0
- package/dist/platform-parity.d.ts +26 -0
- package/dist/platform-parity.js +309 -0
- package/dist/policy-parity.d.ts +35 -0
- package/dist/policy-parity.js +214 -0
- package/dist/policy.d.ts +27 -0
- package/dist/policy.js +316 -0
- package/dist/pr-closing-keywords-parity.d.ts +45 -0
- package/dist/pr-closing-keywords-parity.js +259 -0
- package/dist/pr-closing-keywords.d.ts +3 -0
- package/dist/pr-closing-keywords.js +10 -0
- package/dist/pr-merge-readiness-parity.d.ts +44 -0
- package/dist/pr-merge-readiness-parity.js +296 -0
- package/dist/pr-merge-readiness.d.ts +3 -0
- package/dist/pr-merge-readiness.js +10 -0
- package/dist/pr-monitor-parity.d.ts +44 -0
- package/dist/pr-monitor-parity.js +283 -0
- package/dist/pr-monitor.d.ts +3 -0
- package/dist/pr-monitor.js +10 -0
- package/dist/pr-protected-issues-parity.d.ts +41 -0
- package/dist/pr-protected-issues-parity.js +220 -0
- package/dist/pr-protected-issues.d.ts +3 -0
- package/dist/pr-protected-issues.js +10 -0
- package/dist/pr-wait-mergeable-parity.d.ts +45 -0
- package/dist/pr-wait-mergeable-parity.js +340 -0
- package/dist/pr-wait-mergeable.d.ts +3 -0
- package/dist/pr-wait-mergeable.js +10 -0
- package/dist/preflight-cache.d.ts +16 -0
- package/dist/preflight-cache.js +106 -0
- package/dist/preflight-gh.d.ts +12 -0
- package/dist/preflight-gh.js +188 -0
- package/dist/probe-session.d.ts +3 -0
- package/dist/probe-session.js +10 -0
- package/dist/release-e2e-parity.d.ts +31 -0
- package/dist/release-e2e-parity.js +114 -0
- package/dist/release-e2e.d.ts +3 -0
- package/dist/release-e2e.js +10 -0
- package/dist/release-parity.d.ts +40 -0
- package/dist/release-parity.js +223 -0
- package/dist/release-publish-parity.d.ts +36 -0
- package/dist/release-publish-parity.js +138 -0
- package/dist/release-publish.d.ts +3 -0
- package/dist/release-publish.js +10 -0
- package/dist/release-rollback-parity.d.ts +37 -0
- package/dist/release-rollback-parity.js +161 -0
- package/dist/release-rollback.d.ts +3 -0
- package/dist/release-rollback.js +10 -0
- package/dist/release.d.ts +3 -0
- package/dist/release.js +10 -0
- package/dist/render-cli/deft-ts-runner.d.ts +20 -0
- package/dist/render-cli/deft-ts-runner.js +35 -0
- package/dist/render-cli/prd-render-cli.d.ts +2 -0
- package/dist/render-cli/prd-render-cli.js +7 -0
- package/dist/render-cli/project-render-cli.d.ts +2 -0
- package/dist/render-cli/project-render-cli.js +6 -0
- package/dist/render-cli/spec-render-cli.d.ts +2 -0
- package/dist/render-cli/spec-render-cli.js +6 -0
- package/dist/render-cli/spec-validate-cli.d.ts +2 -0
- package/dist/render-cli/spec-validate-cli.js +6 -0
- package/dist/render-parity.d.ts +35 -0
- package/dist/render-parity.js +383 -0
- package/dist/scm-parity.d.ts +39 -0
- package/dist/scm-parity.js +181 -0
- package/dist/scope-lifecycle-parity.d.ts +35 -0
- package/dist/scope-lifecycle-parity.js +177 -0
- package/dist/scope-lifecycle.d.ts +4 -0
- package/dist/scope-lifecycle.js +29 -0
- package/dist/session-parity.d.ts +39 -0
- package/dist/session-parity.js +260 -0
- package/dist/slice-parity.d.ts +36 -0
- package/dist/slice-parity.js +304 -0
- package/dist/slice.d.ts +4 -0
- package/dist/slice.js +29 -0
- package/dist/story-ready-parity.d.ts +49 -0
- package/dist/story-ready-parity.js +254 -0
- package/dist/subagent-monitor.d.ts +3 -0
- package/dist/subagent-monitor.js +10 -0
- package/dist/swarm-parity.d.ts +28 -0
- package/dist/swarm-parity.js +326 -0
- package/dist/toolchain-check.d.ts +3 -0
- package/dist/toolchain-check.js +14 -0
- package/dist/triage-actions-parity.d.ts +33 -0
- package/dist/triage-actions-parity.js +201 -0
- package/dist/triage-actions.d.ts +17 -0
- package/dist/triage-actions.js +144 -0
- package/dist/triage-aux-a-parity.d.ts +35 -0
- package/dist/triage-aux-a-parity.js +172 -0
- package/dist/triage-aux-b-parity.d.ts +32 -0
- package/dist/triage-aux-b-parity.js +308 -0
- package/dist/triage-bootstrap-parity.d.ts +44 -0
- package/dist/triage-bootstrap-parity.js +226 -0
- package/dist/triage-bootstrap.d.ts +24 -0
- package/dist/triage-bootstrap.js +172 -0
- package/dist/triage-bulk.d.ts +17 -0
- package/dist/triage-bulk.js +154 -0
- package/dist/triage-classify-parity.d.ts +40 -0
- package/dist/triage-classify-parity.js +227 -0
- package/dist/triage-classify.d.ts +13 -0
- package/dist/triage-classify.js +76 -0
- package/dist/triage-help.d.ts +3 -0
- package/dist/triage-help.js +10 -0
- package/dist/triage-queue-parity.d.ts +59 -0
- package/dist/triage-queue-parity.js +363 -0
- package/dist/triage-queue.d.ts +17 -0
- package/dist/triage-queue.js +174 -0
- package/dist/triage-reconcile.d.ts +11 -0
- package/dist/triage-reconcile.js +76 -0
- package/dist/triage-refresh.d.ts +7 -0
- package/dist/triage-refresh.js +37 -0
- package/dist/triage-scope-drift.d.ts +12 -0
- package/dist/triage-scope-drift.js +117 -0
- package/dist/triage-scope-parity.d.ts +34 -0
- package/dist/triage-scope-parity.js +218 -0
- package/dist/triage-scope.d.ts +4 -0
- package/dist/triage-scope.js +29 -0
- package/dist/triage-smoketest.d.ts +3 -0
- package/dist/triage-smoketest.js +43 -0
- package/dist/triage-subscribe.d.ts +15 -0
- package/dist/triage-subscribe.js +157 -0
- package/dist/triage-summary-parity.d.ts +50 -0
- package/dist/triage-summary-parity.js +306 -0
- package/dist/triage-summary.d.ts +14 -0
- package/dist/triage-summary.js +77 -0
- package/dist/triage-welcome.d.ts +12 -0
- package/dist/triage-welcome.js +78 -0
- package/dist/ts-check-lane.d.ts +9 -0
- package/dist/ts-check-lane.js +49 -0
- package/dist/validate-content-parity.d.ts +33 -0
- package/dist/validate-content-parity.js +356 -0
- package/dist/vbrief-activate-parity.d.ts +39 -0
- package/dist/vbrief-activate-parity.js +216 -0
- package/dist/vbrief-activate.d.ts +3 -0
- package/dist/vbrief-activate.js +7 -0
- package/dist/vbrief-build-parity.d.ts +28 -0
- package/dist/vbrief-build-parity.js +399 -0
- package/dist/vbrief-build.d.ts +3 -0
- package/dist/vbrief-build.js +8 -0
- package/dist/vbrief-preflight-parity.d.ts +34 -0
- package/dist/vbrief-preflight-parity.js +163 -0
- package/dist/vbrief-preflight.d.ts +12 -0
- package/dist/vbrief-preflight.js +58 -0
- package/dist/vbrief-reconcile-parity.d.ts +22 -0
- package/dist/vbrief-reconcile-parity.js +600 -0
- package/dist/vbrief-reconcile.d.ts +3 -0
- package/dist/vbrief-reconcile.js +7 -0
- package/dist/vbrief-validate-parity.d.ts +27 -0
- package/dist/vbrief-validate-parity.js +122 -0
- package/dist/vbrief-validate.d.ts +3 -0
- package/dist/vbrief-validate.js +8 -0
- package/dist/vbrief-validation-parity.d.ts +28 -0
- package/dist/vbrief-validation-parity.js +645 -0
- package/dist/vbrief-validation.d.ts +3 -0
- package/dist/vbrief-validation.js +8 -0
- package/dist/verify-branch.d.ts +14 -0
- package/dist/verify-branch.js +81 -0
- package/dist/verify-encoding.d.ts +15 -0
- package/dist/verify-encoding.js +86 -0
- package/dist/verify-env-parity.d.ts +28 -0
- package/dist/verify-env-parity.js +272 -0
- package/dist/verify-hooks-installed.d.ts +10 -0
- package/dist/verify-hooks-installed.js +48 -0
- package/dist/verify-investigation.d.ts +3 -0
- package/dist/verify-investigation.js +10 -0
- package/dist/verify-judgment-gates.d.ts +3 -0
- package/dist/verify-judgment-gates.js +10 -0
- package/dist/verify-no-task-runtime.d.ts +3 -0
- package/dist/verify-no-task-runtime.js +16 -0
- package/dist/verify-session-ritual.d.ts +13 -0
- package/dist/verify-session-ritual.js +78 -0
- package/dist/verify-source-cli/rule-ownership-lint.d.ts +12 -0
- package/dist/verify-source-cli/rule-ownership-lint.js +61 -0
- package/dist/verify-source-cli/verify-content-manifest.d.ts +12 -0
- package/dist/verify-source-cli/verify-content-manifest.js +61 -0
- package/dist/verify-source-cli/verify-scm-boundary.d.ts +13 -0
- package/dist/verify-source-cli/verify-scm-boundary.js +66 -0
- package/dist/verify-source-cli/verify-stubs.d.ts +11 -0
- package/dist/verify-source-cli/verify-stubs.js +27 -0
- package/dist/verify-source-parity.d.ts +26 -0
- package/dist/verify-source-parity.js +178 -0
- package/dist/verify-story-ready.d.ts +16 -0
- package/dist/verify-story-ready.js +138 -0
- package/dist/verify-tools.d.ts +13 -0
- package/dist/verify-tools.js +67 -0
- package/dist/verify-wip-cap.d.ts +13 -0
- package/dist/verify-wip-cap.js +62 -0
- package/dist/wip-cap-parity.d.ts +39 -0
- package/dist/wip-cap-parity.js +209 -0
- package/package.json +50 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Golden-output parity harness (#1725): runs BOTH the Python oracle
|
|
4
|
+
* (`scripts/triage_actions.py`) and the ported TS triage-actions CLI with
|
|
5
|
+
* isolated fixture roots, then diffs exit codes and normalised stdout/stderr.
|
|
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";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { dirname, join, resolve } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
/** Strip volatile UUIDs and timestamps before compare. */
|
|
15
|
+
export function normalizeOutput(text) {
|
|
16
|
+
return text
|
|
17
|
+
.replace(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g, "<UUID>")
|
|
18
|
+
.replace(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/g, "<TS>")
|
|
19
|
+
.replace(/Using CPython[^\n]*\n/g, "")
|
|
20
|
+
.replace(/Creating virtual environment[^\n]*\n/g, "")
|
|
21
|
+
.replace(/Installed \d+ packages[^\n]*\n/g, "");
|
|
22
|
+
}
|
|
23
|
+
function runCapture(cmd, args, cwd, env = {}) {
|
|
24
|
+
const merged = { ...process.env, ...env };
|
|
25
|
+
for (const key of Object.keys(merged)) {
|
|
26
|
+
if (merged[key] === undefined)
|
|
27
|
+
delete merged[key];
|
|
28
|
+
}
|
|
29
|
+
const result = spawnSync(cmd, args, {
|
|
30
|
+
cwd,
|
|
31
|
+
encoding: "utf8",
|
|
32
|
+
env: merged,
|
|
33
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
status: result.status ?? 2,
|
|
37
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
38
|
+
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** Build a throwaway project root with an empty audit-log parent directory. */
|
|
42
|
+
export function buildFixtureRepo() {
|
|
43
|
+
const root = mkdtempSync(join(tmpdir(), "deft-triage-actions-parity-"));
|
|
44
|
+
mkdirSync(join(root, "vbrief", ".eval"), { recursive: true });
|
|
45
|
+
return root;
|
|
46
|
+
}
|
|
47
|
+
function resolveDeftRoot() {
|
|
48
|
+
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
49
|
+
return resolve(process.env.DEFT_ROOT);
|
|
50
|
+
}
|
|
51
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
52
|
+
}
|
|
53
|
+
function pythonWrapperScript(deftRoot, fixtureRoot) {
|
|
54
|
+
return [
|
|
55
|
+
"import os, sys",
|
|
56
|
+
"from pathlib import Path",
|
|
57
|
+
`fixture = Path(${JSON.stringify(fixtureRoot)})`,
|
|
58
|
+
`deft_root = Path(${JSON.stringify(deftRoot)})`,
|
|
59
|
+
"sys.path.insert(0, str(deft_root / 'scripts'))",
|
|
60
|
+
"import candidates_log as cl",
|
|
61
|
+
"cl.DEFAULT_LOG_PATH = fixture / 'vbrief/.eval/candidates.jsonl'",
|
|
62
|
+
"import triage_actions",
|
|
63
|
+
"triage_actions.candidates_log = cl",
|
|
64
|
+
"raise SystemExit(triage_actions.main(sys.argv[1:]))",
|
|
65
|
+
].join("\n");
|
|
66
|
+
}
|
|
67
|
+
function runPythonTriageAction(deftRoot, fixtureRoot, argv) {
|
|
68
|
+
const cap = runCapture("uv", ["run", "python", "-c", pythonWrapperScript(deftRoot, fixtureRoot), ...argv], deftRoot, { TRIAGE_PARITY_FIXTURE: fixtureRoot });
|
|
69
|
+
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
70
|
+
}
|
|
71
|
+
function runTsTriageAction(deftRoot, fixtureRoot, argv) {
|
|
72
|
+
const cap = runCapture("node", [
|
|
73
|
+
join(deftRoot, "packages", "cli", "dist", "triage-actions.js"),
|
|
74
|
+
...argv,
|
|
75
|
+
"--project-root",
|
|
76
|
+
fixtureRoot,
|
|
77
|
+
], deftRoot);
|
|
78
|
+
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
79
|
+
}
|
|
80
|
+
/** Diff one parity case between Python oracle and TS CLI. */
|
|
81
|
+
export function diffCase(python, ts, caseName) {
|
|
82
|
+
const pyOut = normalizeOutput(python.stdout);
|
|
83
|
+
const tsOut = normalizeOutput(ts.stdout);
|
|
84
|
+
const pyErr = normalizeOutput(python.stderr);
|
|
85
|
+
const tsErr = normalizeOutput(ts.stderr);
|
|
86
|
+
return {
|
|
87
|
+
caseName,
|
|
88
|
+
exitMismatch: python.exitCode !== ts.exitCode,
|
|
89
|
+
stdoutMismatch: pyOut !== tsOut,
|
|
90
|
+
stderrMismatch: pyErr !== tsErr,
|
|
91
|
+
pythonExit: python.exitCode,
|
|
92
|
+
tsExit: ts.exitCode,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export const PARITY_CASES = [
|
|
96
|
+
{
|
|
97
|
+
name: "defer-invalid-resume-on",
|
|
98
|
+
argv: [
|
|
99
|
+
"defer",
|
|
100
|
+
"--issue",
|
|
101
|
+
"7",
|
|
102
|
+
"--repo",
|
|
103
|
+
"deftai/directive",
|
|
104
|
+
"--reason",
|
|
105
|
+
"later",
|
|
106
|
+
"--resume-on",
|
|
107
|
+
"not-valid",
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "defer-success",
|
|
112
|
+
argv: ["defer", "--issue", "7", "--repo", "deftai/directive", "--reason", "later"],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "defer-with-resume-on",
|
|
116
|
+
argv: [
|
|
117
|
+
"defer",
|
|
118
|
+
"--issue",
|
|
119
|
+
"8",
|
|
120
|
+
"--repo",
|
|
121
|
+
"deftai/directive",
|
|
122
|
+
"--reason",
|
|
123
|
+
"blocked",
|
|
124
|
+
"--resume-on",
|
|
125
|
+
"ref:closed:#99",
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "accept-idempotent",
|
|
130
|
+
argv: ["accept", "--issue", "9", "--repo", "deftai/directive", "--actor", "agent:test"],
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
function seedAcceptFixture(fixtureRoot) {
|
|
134
|
+
const entry = {
|
|
135
|
+
actor: "agent:test",
|
|
136
|
+
decision: "accept",
|
|
137
|
+
decision_id: "prior-id-0000-0000-0000-000000000001",
|
|
138
|
+
issue_number: 9,
|
|
139
|
+
repo: "deftai/directive",
|
|
140
|
+
timestamp: "2026-06-18T12:00:00Z",
|
|
141
|
+
};
|
|
142
|
+
writeFileSync(join(fixtureRoot, "vbrief/.eval/candidates.jsonl"), `${JSON.stringify(entry, Object.keys(entry).sort())}\n`, "utf8");
|
|
143
|
+
}
|
|
144
|
+
/** Run all parity cases; returns aggregate result. */
|
|
145
|
+
export function runParity() {
|
|
146
|
+
const deftRoot = resolveDeftRoot();
|
|
147
|
+
const diffs = [];
|
|
148
|
+
for (const testCase of PARITY_CASES) {
|
|
149
|
+
const pyFixture = buildFixtureRepo();
|
|
150
|
+
const tsFixture = buildFixtureRepo();
|
|
151
|
+
if (testCase.name === "accept-idempotent") {
|
|
152
|
+
seedAcceptFixture(pyFixture);
|
|
153
|
+
seedAcceptFixture(tsFixture);
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const python = runPythonTriageAction(deftRoot, pyFixture, testCase.argv);
|
|
157
|
+
const ts = runTsTriageAction(deftRoot, tsFixture, testCase.argv);
|
|
158
|
+
diffs.push(diffCase(python, ts, testCase.name));
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
rmSync(pyFixture, { recursive: true, force: true });
|
|
162
|
+
rmSync(tsFixture, { recursive: true, force: true });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
166
|
+
return { ok, diffs };
|
|
167
|
+
}
|
|
168
|
+
export function renderReport(result) {
|
|
169
|
+
if (result.ok) {
|
|
170
|
+
return `triage-actions parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
171
|
+
}
|
|
172
|
+
const lines = ["triage-actions parity: DIVERGENCE"];
|
|
173
|
+
for (const d of result.diffs) {
|
|
174
|
+
if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
|
|
175
|
+
lines.push(` case: ${d.caseName}`);
|
|
176
|
+
if (d.exitMismatch)
|
|
177
|
+
lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
|
|
178
|
+
if (d.stdoutMismatch)
|
|
179
|
+
lines.push(" stdout mismatch");
|
|
180
|
+
if (d.stderrMismatch)
|
|
181
|
+
lines.push(" stderr mismatch");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return lines.join("\n");
|
|
185
|
+
}
|
|
186
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
187
|
+
try {
|
|
188
|
+
const result = runParity();
|
|
189
|
+
if (result.ok) {
|
|
190
|
+
process.stdout.write(`${renderReport(result)}\n`);
|
|
191
|
+
process.exit(0);
|
|
192
|
+
}
|
|
193
|
+
process.stderr.write(`${renderReport(result)}\n`);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
process.stderr.write(`triage-actions parity: harness error -- ${String(err)}\n`);
|
|
198
|
+
process.exit(2);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=triage-actions-parity.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface ParsedArgs {
|
|
3
|
+
cmd?: string;
|
|
4
|
+
issue?: number;
|
|
5
|
+
repo?: string;
|
|
6
|
+
reason?: string;
|
|
7
|
+
resumeOn?: string;
|
|
8
|
+
actor?: string;
|
|
9
|
+
projectRoot: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Parse triage-actions CLI argv mirroring ``triage_actions.py`` argparse. */
|
|
13
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
14
|
+
/** Run triage-actions CLI and return exit code. */
|
|
15
|
+
export declare function run(argv: string[]): number;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=triage-actions.d.ts.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { accept, createDefaultDeps, deferAction, reject, TriageError, UpstreamCloseError, } from "../../core/dist/triage/actions/index.js";
|
|
5
|
+
/** Parse triage-actions CLI argv mirroring ``triage_actions.py`` argparse. */
|
|
6
|
+
export function parseArgs(argv) {
|
|
7
|
+
const parsed = { projectRoot: process.cwd() };
|
|
8
|
+
if (argv.length === 0) {
|
|
9
|
+
return { ...parsed, error: "missing subcommand" };
|
|
10
|
+
}
|
|
11
|
+
parsed.cmd = argv[0];
|
|
12
|
+
for (let i = 1; i < argv.length; i += 1) {
|
|
13
|
+
const arg = argv[i];
|
|
14
|
+
if (arg === "--issue") {
|
|
15
|
+
const value = argv[i + 1];
|
|
16
|
+
if (value === undefined)
|
|
17
|
+
return { ...parsed, error: "argument --issue: expected one argument" };
|
|
18
|
+
parsed.issue = Number.parseInt(value, 10);
|
|
19
|
+
i += 1;
|
|
20
|
+
}
|
|
21
|
+
else if (arg?.startsWith("--issue=")) {
|
|
22
|
+
parsed.issue = Number.parseInt(arg.slice("--issue=".length), 10);
|
|
23
|
+
}
|
|
24
|
+
else if (arg === "--repo") {
|
|
25
|
+
const value = argv[i + 1];
|
|
26
|
+
if (value === undefined)
|
|
27
|
+
return { ...parsed, error: "argument --repo: expected one argument" };
|
|
28
|
+
parsed.repo = value;
|
|
29
|
+
i += 1;
|
|
30
|
+
}
|
|
31
|
+
else if (arg?.startsWith("--repo=")) {
|
|
32
|
+
parsed.repo = arg.slice("--repo=".length);
|
|
33
|
+
}
|
|
34
|
+
else if (arg === "--reason") {
|
|
35
|
+
const value = argv[i + 1];
|
|
36
|
+
if (value === undefined)
|
|
37
|
+
return { ...parsed, error: "argument --reason: expected one argument" };
|
|
38
|
+
parsed.reason = value;
|
|
39
|
+
i += 1;
|
|
40
|
+
}
|
|
41
|
+
else if (arg?.startsWith("--reason=")) {
|
|
42
|
+
parsed.reason = arg.slice("--reason=".length);
|
|
43
|
+
}
|
|
44
|
+
else if (arg === "--resume-on") {
|
|
45
|
+
const value = argv[i + 1];
|
|
46
|
+
if (value === undefined)
|
|
47
|
+
return { ...parsed, error: "argument --resume-on: expected one argument" };
|
|
48
|
+
parsed.resumeOn = value;
|
|
49
|
+
i += 1;
|
|
50
|
+
}
|
|
51
|
+
else if (arg?.startsWith("--resume-on=")) {
|
|
52
|
+
parsed.resumeOn = arg.slice("--resume-on=".length);
|
|
53
|
+
}
|
|
54
|
+
else if (arg === "--actor") {
|
|
55
|
+
const value = argv[i + 1];
|
|
56
|
+
if (value === undefined)
|
|
57
|
+
return { ...parsed, error: "argument --actor: expected one argument" };
|
|
58
|
+
parsed.actor = value;
|
|
59
|
+
i += 1;
|
|
60
|
+
}
|
|
61
|
+
else if (arg?.startsWith("--actor=")) {
|
|
62
|
+
parsed.actor = arg.slice("--actor=".length);
|
|
63
|
+
}
|
|
64
|
+
else if (arg === "--project-root") {
|
|
65
|
+
const value = argv[i + 1];
|
|
66
|
+
if (value === undefined)
|
|
67
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
68
|
+
parsed.projectRoot = value;
|
|
69
|
+
i += 1;
|
|
70
|
+
}
|
|
71
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
72
|
+
parsed.projectRoot = arg.slice("--project-root=".length);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return parsed;
|
|
79
|
+
}
|
|
80
|
+
/** Run triage-actions CLI and return exit code. */
|
|
81
|
+
export function run(argv) {
|
|
82
|
+
const args = parseArgs(argv);
|
|
83
|
+
if (args.error !== undefined) {
|
|
84
|
+
process.stderr.write(`triage_actions: ${args.error}\n`);
|
|
85
|
+
return 2;
|
|
86
|
+
}
|
|
87
|
+
if (args.cmd !== "accept" && args.cmd !== "reject" && args.cmd !== "defer") {
|
|
88
|
+
process.stderr.write(`triage_actions: unknown subcommand ${args.cmd ?? ""}\n`);
|
|
89
|
+
return 2;
|
|
90
|
+
}
|
|
91
|
+
if (args.issue === undefined || Number.isNaN(args.issue)) {
|
|
92
|
+
process.stderr.write("triage_actions: argument --issue: expected one argument\n");
|
|
93
|
+
return 2;
|
|
94
|
+
}
|
|
95
|
+
if (args.repo === undefined) {
|
|
96
|
+
process.stderr.write("triage_actions: argument --repo: expected one argument\n");
|
|
97
|
+
return 2;
|
|
98
|
+
}
|
|
99
|
+
if (args.cmd === "reject" && args.reason === undefined) {
|
|
100
|
+
process.stderr.write("triage_actions: argument --reason: expected one argument\n");
|
|
101
|
+
return 2;
|
|
102
|
+
}
|
|
103
|
+
if (args.cmd === "defer" && args.reason === undefined) {
|
|
104
|
+
process.stderr.write("triage_actions: argument --reason: expected one argument\n");
|
|
105
|
+
return 2;
|
|
106
|
+
}
|
|
107
|
+
const projectRoot = resolve(args.projectRoot);
|
|
108
|
+
const deps = createDefaultDeps(projectRoot);
|
|
109
|
+
const n = args.issue;
|
|
110
|
+
const repo = args.repo;
|
|
111
|
+
try {
|
|
112
|
+
if (args.cmd === "accept") {
|
|
113
|
+
const decisionId = accept(n, repo, deps, { actor: args.actor, projectRoot });
|
|
114
|
+
process.stdout.write(`accept #${n} (${repo}) -> ${decisionId}\n`);
|
|
115
|
+
}
|
|
116
|
+
else if (args.cmd === "reject") {
|
|
117
|
+
const decisionId = reject(n, repo, args.reason ?? "", deps, {
|
|
118
|
+
actor: args.actor,
|
|
119
|
+
projectRoot,
|
|
120
|
+
});
|
|
121
|
+
process.stdout.write(`reject #${n} (${repo}) -> ${decisionId}\n`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const decisionId = deferAction(n, repo, args.reason, deps, {
|
|
125
|
+
actor: args.actor,
|
|
126
|
+
resumeOn: args.resumeOn,
|
|
127
|
+
projectRoot,
|
|
128
|
+
});
|
|
129
|
+
process.stdout.write(`defer #${n} (${repo}) -> ${decisionId}\n`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
if (err instanceof TriageError || err instanceof UpstreamCloseError) {
|
|
134
|
+
process.stderr.write(`triage_actions: ${err.message}\n`);
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
142
|
+
process.exit(run(process.argv.slice(2)));
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=triage-actions.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export interface CommandCapture {
|
|
3
|
+
readonly exitCode: number;
|
|
4
|
+
readonly stdout: string;
|
|
5
|
+
readonly stderr: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ParityCase {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly script: "triage_welcome.py" | "triage_reconcile.py" | "triage_scope_drift.py" | "triage_refresh.py";
|
|
10
|
+
readonly tsCli: "triage-welcome.js" | "triage-reconcile.js" | "triage-scope-drift.js" | "triage-refresh.js";
|
|
11
|
+
readonly argv: readonly string[];
|
|
12
|
+
readonly setup?: (root: string) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface ParityDiff {
|
|
15
|
+
readonly caseName: string;
|
|
16
|
+
readonly exitMismatch: boolean;
|
|
17
|
+
readonly stdoutMismatch: boolean;
|
|
18
|
+
readonly stderrMismatch: boolean;
|
|
19
|
+
readonly pythonExit: number;
|
|
20
|
+
readonly tsExit: number;
|
|
21
|
+
}
|
|
22
|
+
export interface ParityResult {
|
|
23
|
+
readonly ok: boolean;
|
|
24
|
+
readonly diffs: ParityDiff[];
|
|
25
|
+
}
|
|
26
|
+
/** Strip volatile absolute paths before compare. */
|
|
27
|
+
export declare function normalizeOutput(text: string): string;
|
|
28
|
+
declare function resolveDeftRoot(): string;
|
|
29
|
+
export { resolveDeftRoot };
|
|
30
|
+
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
31
|
+
export declare const PARITY_CASES: readonly ParityCase[];
|
|
32
|
+
export declare function buildFixtureRepo(setup?: (root: string) => void): string;
|
|
33
|
+
export declare function runParity(): ParityResult;
|
|
34
|
+
export declare function renderReport(result: ParityResult): string;
|
|
35
|
+
//# sourceMappingURL=triage-aux-a-parity.d.ts.map
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Golden-output parity harness (#1725): runs BOTH the Python oracle and the
|
|
4
|
+
* ported TS triage aux-A CLIs with identical argv on throwaway fixtures,
|
|
5
|
+
* then 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";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import { dirname, join, resolve } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
/** Strip volatile absolute paths before compare. */
|
|
15
|
+
export function normalizeOutput(text) {
|
|
16
|
+
return text
|
|
17
|
+
.replace(/project_root=[^\s)"]+/g, "project_root=<ROOT>")
|
|
18
|
+
.replace(/"project_root": "[^"]+"/g, '"project_root": "<ROOT>"')
|
|
19
|
+
.replace(/\/tmp\/[^\s"']+/g, "<TMP>");
|
|
20
|
+
}
|
|
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
|
+
status: result.status ?? 2,
|
|
30
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
31
|
+
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function resolveDeftRoot() {
|
|
35
|
+
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
36
|
+
return resolve(process.env.DEFT_ROOT);
|
|
37
|
+
}
|
|
38
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
39
|
+
}
|
|
40
|
+
export { resolveDeftRoot };
|
|
41
|
+
function runPython(deftRoot, script, repo, argv) {
|
|
42
|
+
const cap = runCapture("python3", [join(deftRoot, "scripts", script), ...argv, "--project-root", repo], deftRoot);
|
|
43
|
+
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
44
|
+
}
|
|
45
|
+
function runTs(deftRoot, cli, repo, argv) {
|
|
46
|
+
const cap = runCapture("node", [join(deftRoot, "packages", "cli", "dist", cli), ...argv, "--project-root", repo], deftRoot);
|
|
47
|
+
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
48
|
+
}
|
|
49
|
+
export function diffCase(python, ts, caseName) {
|
|
50
|
+
const pyOut = normalizeOutput(python.stdout);
|
|
51
|
+
const tsOut = normalizeOutput(ts.stdout);
|
|
52
|
+
const pyErr = normalizeOutput(python.stderr);
|
|
53
|
+
const tsErr = normalizeOutput(ts.stderr);
|
|
54
|
+
return {
|
|
55
|
+
caseName,
|
|
56
|
+
exitMismatch: python.exitCode !== ts.exitCode,
|
|
57
|
+
stdoutMismatch: pyOut !== tsOut,
|
|
58
|
+
stderrMismatch: pyErr !== tsErr,
|
|
59
|
+
pythonExit: python.exitCode,
|
|
60
|
+
tsExit: ts.exitCode,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function writeProjectDefinition(root, policy = {}) {
|
|
64
|
+
mkdirSync(join(root, "vbrief"), { recursive: true });
|
|
65
|
+
writeFileSync(join(root, "vbrief", "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({ vBRIEFInfo: { version: "0.6" }, plan: { policy } }, null, 2)}\n`, "utf8");
|
|
66
|
+
}
|
|
67
|
+
export const PARITY_CASES = [
|
|
68
|
+
{
|
|
69
|
+
name: "welcome-default-empty",
|
|
70
|
+
script: "triage_welcome.py",
|
|
71
|
+
tsCli: "triage-welcome.js",
|
|
72
|
+
argv: ["--no-history"],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "reconcile-dry-run-json-empty",
|
|
76
|
+
script: "triage_reconcile.py",
|
|
77
|
+
tsCli: "triage-reconcile.js",
|
|
78
|
+
argv: ["--dry-run", "--json"],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "reconcile-text-empty",
|
|
82
|
+
script: "triage_reconcile.py",
|
|
83
|
+
tsCli: "triage-reconcile.js",
|
|
84
|
+
argv: [],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "scope-drift-empty-cache",
|
|
88
|
+
script: "triage_scope_drift.py",
|
|
89
|
+
tsCli: "triage-scope-drift.js",
|
|
90
|
+
argv: [],
|
|
91
|
+
setup: (root) => writeProjectDefinition(root),
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "refresh-empty-active",
|
|
95
|
+
script: "triage_refresh.py",
|
|
96
|
+
tsCli: "triage-refresh.js",
|
|
97
|
+
argv: [],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "welcome-bad-root",
|
|
101
|
+
script: "triage_welcome.py",
|
|
102
|
+
tsCli: "triage-welcome.js",
|
|
103
|
+
argv: [],
|
|
104
|
+
setup: () => { },
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
export function buildFixtureRepo(setup) {
|
|
108
|
+
const root = mkdtempSync(join(tmpdir(), "deft-triage-aux-a-parity-"));
|
|
109
|
+
mkdirSync(join(root, "vbrief"), { recursive: true });
|
|
110
|
+
setup?.(root);
|
|
111
|
+
return root;
|
|
112
|
+
}
|
|
113
|
+
export function runParity() {
|
|
114
|
+
const deftRoot = resolveDeftRoot();
|
|
115
|
+
const diffs = [];
|
|
116
|
+
for (const testCase of PARITY_CASES) {
|
|
117
|
+
if (testCase.name === "welcome-bad-root") {
|
|
118
|
+
const badRoot = join(tmpdir(), "deft-triage-missing-dir-never-created");
|
|
119
|
+
const python = runPython(deftRoot, testCase.script, badRoot, testCase.argv);
|
|
120
|
+
const ts = runTs(deftRoot, testCase.tsCli, badRoot, testCase.argv);
|
|
121
|
+
diffs.push(diffCase(python, ts, testCase.name));
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const pyRepo = buildFixtureRepo(testCase.setup);
|
|
125
|
+
const tsRepo = buildFixtureRepo(testCase.setup);
|
|
126
|
+
try {
|
|
127
|
+
const python = runPython(deftRoot, testCase.script, pyRepo, testCase.argv);
|
|
128
|
+
const ts = runTs(deftRoot, testCase.tsCli, tsRepo, testCase.argv);
|
|
129
|
+
diffs.push(diffCase(python, ts, testCase.name));
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
rmSync(pyRepo, { recursive: true, force: true });
|
|
133
|
+
rmSync(tsRepo, { recursive: true, force: true });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
137
|
+
return { ok, diffs };
|
|
138
|
+
}
|
|
139
|
+
export function renderReport(result) {
|
|
140
|
+
if (result.ok) {
|
|
141
|
+
return `triage-aux-a parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
142
|
+
}
|
|
143
|
+
const lines = ["triage-aux-a parity: DIVERGENCE"];
|
|
144
|
+
for (const d of result.diffs) {
|
|
145
|
+
if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
|
|
146
|
+
lines.push(` case: ${d.caseName}`);
|
|
147
|
+
if (d.exitMismatch)
|
|
148
|
+
lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
|
|
149
|
+
if (d.stdoutMismatch)
|
|
150
|
+
lines.push(" stdout mismatch");
|
|
151
|
+
if (d.stderrMismatch)
|
|
152
|
+
lines.push(" stderr mismatch");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return lines.join("\n");
|
|
156
|
+
}
|
|
157
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
158
|
+
try {
|
|
159
|
+
const result = runParity();
|
|
160
|
+
if (result.ok) {
|
|
161
|
+
process.stdout.write(`${renderReport(result)}\n`);
|
|
162
|
+
process.exit(0);
|
|
163
|
+
}
|
|
164
|
+
process.stderr.write(`${renderReport(result)}\n`);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
process.stderr.write(`triage-aux-a parity: harness error -- ${String(err)}\n`);
|
|
169
|
+
process.exit(2);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=triage-aux-a-parity.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export interface CommandCapture {
|
|
3
|
+
readonly exitCode: number;
|
|
4
|
+
readonly stdout: string;
|
|
5
|
+
readonly stderr: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ParityCase {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly verb: "help" | "subscribe" | "bulk" | "smoketest";
|
|
10
|
+
readonly argv: readonly string[];
|
|
11
|
+
readonly fixtureRoot?: string;
|
|
12
|
+
readonly env?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export interface ParityDiff {
|
|
15
|
+
readonly caseName: string;
|
|
16
|
+
readonly exitMismatch: boolean;
|
|
17
|
+
readonly stdoutMismatch: boolean;
|
|
18
|
+
readonly stderrMismatch: boolean;
|
|
19
|
+
readonly pythonExit: number;
|
|
20
|
+
readonly tsExit: number;
|
|
21
|
+
}
|
|
22
|
+
export interface ParityResult {
|
|
23
|
+
readonly ok: boolean;
|
|
24
|
+
readonly diffs: ParityDiff[];
|
|
25
|
+
}
|
|
26
|
+
export declare function normalizeOutput(text: string): string;
|
|
27
|
+
export declare function buildFixtureRepo(kind: "subscribe" | "bulk-empty" | "bulk-filter"): string;
|
|
28
|
+
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
29
|
+
export declare const PARITY_CASES: readonly ParityCase[];
|
|
30
|
+
export declare function runParity(): ParityResult;
|
|
31
|
+
export declare function renderReport(result: ParityResult): string;
|
|
32
|
+
//# sourceMappingURL=triage-aux-b-parity.d.ts.map
|