@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,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI router entry: `directive <namespace> <verb>` → flat dispatcher (#1670 / #11 S3).
|
|
3
|
+
*/
|
|
4
|
+
import { dispatch } from "../dispatch.js";
|
|
5
|
+
import { runInit } from "../init-cli/init.js";
|
|
6
|
+
import { runUpdate } from "../init-cli/update.js";
|
|
7
|
+
import { routeArgv } from "./route-argv.js";
|
|
8
|
+
function defaultIo() {
|
|
9
|
+
return {
|
|
10
|
+
writeOut: (text) => {
|
|
11
|
+
process.stdout.write(text);
|
|
12
|
+
},
|
|
13
|
+
writeErr: (text) => {
|
|
14
|
+
process.stderr.write(text);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export { DEFERRED_TOP_LEVEL_VERBS, PR_VERB_MAP, routeArgv, SCOPE_LIFECYCLE_VERBS, STUBBED_TOP_LEVEL_VERBS, SUBCOMMAND_ROUTES, TOP_LEVEL_UX_VERBS, taskKeyToDispatchArgv, VERIFY_VERB_MAP, } from "./route-argv.js";
|
|
19
|
+
/** Route user argv then dispatch to the existing engine handlers. */
|
|
20
|
+
export async function routeAndDispatch(argv, io) {
|
|
21
|
+
const routed = routeArgv(argv);
|
|
22
|
+
if (routed.kind === "stub") {
|
|
23
|
+
const message = routed.stubMessage ?? "directive: command not available";
|
|
24
|
+
const sink = io ?? defaultIo();
|
|
25
|
+
sink.writeErr(`${message}\n`);
|
|
26
|
+
return 2;
|
|
27
|
+
}
|
|
28
|
+
const [first, ...rest] = routed.argv;
|
|
29
|
+
if (first === "init") {
|
|
30
|
+
return runInit(rest, io ?? defaultIo());
|
|
31
|
+
}
|
|
32
|
+
if (first === "update") {
|
|
33
|
+
return runUpdate(rest, io ?? defaultIo());
|
|
34
|
+
}
|
|
35
|
+
return dispatch(routed.argv, io);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps `directive <namespace> <verb>` argv to flat dispatcher verbs (#1670 / #11 S3).
|
|
3
|
+
* Mirrors the `task <namespace>:<verb>` surface one-to-one.
|
|
4
|
+
*/
|
|
5
|
+
/** Top-level UX verbs promoted above the namespace layer (#1670). */
|
|
6
|
+
export declare const TOP_LEVEL_UX_VERBS: readonly ["init", "update", "bootstrap", "check", "doctor", "version", "feature"];
|
|
7
|
+
/** Stubbed until a later story lands the handler (#1670 / #11). */
|
|
8
|
+
export declare const STUBBED_TOP_LEVEL_VERBS: Set<string>;
|
|
9
|
+
/** Registered but not yet implemented as TS handlers. */
|
|
10
|
+
export declare const DEFERRED_TOP_LEVEL_VERBS: Set<string>;
|
|
11
|
+
/** scope:* lifecycle verbs routed through scope-lifecycle handler. */
|
|
12
|
+
export declare const SCOPE_LIFECYCLE_VERBS: Set<string>;
|
|
13
|
+
/** pr:* task names that do not hyphenate 1:1 to handler stems. */
|
|
14
|
+
export declare const PR_VERB_MAP: Readonly<Record<string, string>>;
|
|
15
|
+
/** verify:* aliases that map to non-verify-* handler stems. */
|
|
16
|
+
export declare const VERIFY_VERB_MAP: Readonly<Record<string, string>>;
|
|
17
|
+
/** Namespace handlers that require a subcommand token after the handler stem. */
|
|
18
|
+
export declare const SUBCOMMAND_ROUTES: Readonly<Record<string, readonly [string, string]>>;
|
|
19
|
+
export type RouteKind = "dispatch" | "stub";
|
|
20
|
+
export interface RoutedArgv {
|
|
21
|
+
kind: RouteKind;
|
|
22
|
+
argv: string[];
|
|
23
|
+
stubMessage?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Transform user-facing argv (`directive <ns> <verb>` or top-level UX) into
|
|
27
|
+
* flat dispatcher argv consumed by `dispatch()`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function routeArgv(argv: readonly string[]): RoutedArgv;
|
|
30
|
+
/** Map `namespace:verb` task key to flat dispatcher argv (test seam). */
|
|
31
|
+
export declare function taskKeyToDispatchArgv(taskKey: string, rest?: readonly string[]): string[] | null;
|
|
32
|
+
//# sourceMappingURL=route-argv.d.ts.map
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps `directive <namespace> <verb>` argv to flat dispatcher verbs (#1670 / #11 S3).
|
|
3
|
+
* Mirrors the `task <namespace>:<verb>` surface one-to-one.
|
|
4
|
+
*/
|
|
5
|
+
import { resolveCanonicalVerb } from "../dispatch.js";
|
|
6
|
+
/** Top-level UX verbs promoted above the namespace layer (#1670). */
|
|
7
|
+
export const TOP_LEVEL_UX_VERBS = [
|
|
8
|
+
"init",
|
|
9
|
+
"update",
|
|
10
|
+
"bootstrap",
|
|
11
|
+
"check",
|
|
12
|
+
"doctor",
|
|
13
|
+
"version",
|
|
14
|
+
"feature",
|
|
15
|
+
];
|
|
16
|
+
/** Stubbed until a later story lands the handler (#1670 / #11). */
|
|
17
|
+
export const STUBBED_TOP_LEVEL_VERBS = new Set([]);
|
|
18
|
+
/** Registered but not yet implemented as TS handlers. */
|
|
19
|
+
export const DEFERRED_TOP_LEVEL_VERBS = new Set(["bootstrap", "feature"]);
|
|
20
|
+
/** scope:* lifecycle verbs routed through scope-lifecycle handler. */
|
|
21
|
+
export const SCOPE_LIFECYCLE_VERBS = new Set([
|
|
22
|
+
"promote",
|
|
23
|
+
"activate",
|
|
24
|
+
"complete",
|
|
25
|
+
"fail",
|
|
26
|
+
"cancel",
|
|
27
|
+
"restore",
|
|
28
|
+
"block",
|
|
29
|
+
"unblock",
|
|
30
|
+
]);
|
|
31
|
+
/** pr:* task names that do not hyphenate 1:1 to handler stems. */
|
|
32
|
+
export const PR_VERB_MAP = {
|
|
33
|
+
"merge-ready": "pr-merge-readiness",
|
|
34
|
+
"check-protected-issues": "pr-protected-issues",
|
|
35
|
+
"check-closing-keywords": "pr-closing-keywords",
|
|
36
|
+
"wait-mergeable-and-merge": "pr-wait-mergeable",
|
|
37
|
+
};
|
|
38
|
+
/** verify:* aliases that map to non-verify-* handler stems. */
|
|
39
|
+
export const VERIFY_VERB_MAP = {
|
|
40
|
+
routing: "swarm-routing-verify",
|
|
41
|
+
"codebase-map-fresh": "codebase-map-fresh",
|
|
42
|
+
"strategy-output": "validate-strategy-output",
|
|
43
|
+
"vbrief-conformance": "vbrief-validate",
|
|
44
|
+
"destructive-gh-verbs": "preflight-gh",
|
|
45
|
+
"cache-fresh": "preflight-cache",
|
|
46
|
+
"pack-drift": "pack-render",
|
|
47
|
+
};
|
|
48
|
+
/** Namespace handlers that require a subcommand token after the handler stem. */
|
|
49
|
+
export const SUBCOMMAND_ROUTES = {
|
|
50
|
+
"triage:accept": ["triage-actions", "accept"],
|
|
51
|
+
"triage:reject": ["triage-actions", "reject"],
|
|
52
|
+
"triage:defer": ["triage-actions", "defer"],
|
|
53
|
+
"triage:needs-ac": ["triage-actions", "needs-ac"],
|
|
54
|
+
"triage:mark-duplicate": ["triage-actions", "mark-duplicate"],
|
|
55
|
+
"triage:status": ["triage-actions", "status"],
|
|
56
|
+
"triage:reset": ["triage-actions", "reset"],
|
|
57
|
+
"triage:history": ["triage-actions", "history"],
|
|
58
|
+
"triage:bulk-accept": ["triage-bulk", "accept"],
|
|
59
|
+
"triage:bulk-reject": ["triage-bulk", "reject"],
|
|
60
|
+
"triage:bulk-defer": ["triage-bulk", "defer"],
|
|
61
|
+
"triage:bulk-needs-ac": ["triage-bulk", "needs-ac"],
|
|
62
|
+
"triage:show": ["triage-queue", "show"],
|
|
63
|
+
"triage:audit": ["triage-queue", "audit"],
|
|
64
|
+
"cache:put": ["cache", "put"],
|
|
65
|
+
"cache:get": ["cache", "get"],
|
|
66
|
+
"cache:invalidate": ["cache", "invalidate"],
|
|
67
|
+
"cache:fetch-all": ["cache", "fetch-all"],
|
|
68
|
+
"cache:prune": ["cache", "prune"],
|
|
69
|
+
"policy:show": ["policy", "show"],
|
|
70
|
+
"policy:enforce-branches": ["policy", "enforce-branches"],
|
|
71
|
+
"policy:allow-direct-commits": ["policy", "allow-direct-commits"],
|
|
72
|
+
"vbrief:reconcile-graph": ["vbrief-reconcile", "graph"],
|
|
73
|
+
"vbrief:reconcile-labels": ["vbrief-reconcile", "labels"],
|
|
74
|
+
"vbrief:reconcile-umbrellas": ["vbrief-reconcile", "umbrellas"],
|
|
75
|
+
"slice:record-existing": ["slice", "record-existing"],
|
|
76
|
+
"slice:list": ["slice", "list"],
|
|
77
|
+
"github-body:issue-create": ["github-body", "issue-create"],
|
|
78
|
+
"github-body:issue-edit": ["github-body", "issue-edit"],
|
|
79
|
+
"github-body:comment-create": ["github-body", "comment-create"],
|
|
80
|
+
"github-body:comment-edit": ["github-body", "comment-edit"],
|
|
81
|
+
"github-body:pr-edit": ["github-body", "pr-edit"],
|
|
82
|
+
};
|
|
83
|
+
function isMetaVerb(token) {
|
|
84
|
+
return token === "--help" || token === "-h" || token === "--version" || token === "-V";
|
|
85
|
+
}
|
|
86
|
+
function routeTopLevel(first, rest) {
|
|
87
|
+
if (first === "version") {
|
|
88
|
+
return { kind: "dispatch", argv: ["--version", ...rest] };
|
|
89
|
+
}
|
|
90
|
+
if (first === "check" || first === "doctor") {
|
|
91
|
+
return { kind: "dispatch", argv: [first, ...rest] };
|
|
92
|
+
}
|
|
93
|
+
if (first === "init" || first === "update") {
|
|
94
|
+
return { kind: "dispatch", argv: [first, ...rest] };
|
|
95
|
+
}
|
|
96
|
+
if (STUBBED_TOP_LEVEL_VERBS.has(first)) {
|
|
97
|
+
return {
|
|
98
|
+
kind: "stub",
|
|
99
|
+
argv: [],
|
|
100
|
+
stubMessage: `directive ${first}: not yet implemented in the TS CLI (#1670 / #11).`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (DEFERRED_TOP_LEVEL_VERBS.has(first)) {
|
|
104
|
+
return {
|
|
105
|
+
kind: "stub",
|
|
106
|
+
argv: [],
|
|
107
|
+
stubMessage: `directive ${first}: not yet implemented in the TS CLI (#1670 / #11).`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
function routeSubcommandKey(ns, verb, rest) {
|
|
113
|
+
const colonKey = `${ns}:${verb}`;
|
|
114
|
+
const mapped = SUBCOMMAND_ROUTES[colonKey];
|
|
115
|
+
if (mapped !== undefined) {
|
|
116
|
+
return { kind: "dispatch", argv: [...mapped, ...rest] };
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
function routeNamespaceVerb(ns, verb, rest) {
|
|
121
|
+
const colonKey = `${ns}:${verb}`;
|
|
122
|
+
const subcommand = routeSubcommandKey(ns, verb, rest);
|
|
123
|
+
if (subcommand !== null)
|
|
124
|
+
return subcommand;
|
|
125
|
+
if (resolveCanonicalVerb(colonKey) !== null) {
|
|
126
|
+
return { kind: "dispatch", argv: [colonKey, ...rest] };
|
|
127
|
+
}
|
|
128
|
+
if (ns === "scope") {
|
|
129
|
+
if (SCOPE_LIFECYCLE_VERBS.has(verb)) {
|
|
130
|
+
return { kind: "dispatch", argv: ["scope-lifecycle", verb, ...rest] };
|
|
131
|
+
}
|
|
132
|
+
if (verb === "demote")
|
|
133
|
+
return { kind: "dispatch", argv: ["scope-demote", ...rest] };
|
|
134
|
+
if (verb === "decompose")
|
|
135
|
+
return { kind: "dispatch", argv: ["scope-decompose", ...rest] };
|
|
136
|
+
if (verb === "undo")
|
|
137
|
+
return { kind: "dispatch", argv: ["scope-undo", ...rest] };
|
|
138
|
+
}
|
|
139
|
+
if (ns === "pr") {
|
|
140
|
+
const prStem = PR_VERB_MAP[verb];
|
|
141
|
+
if (prStem !== undefined) {
|
|
142
|
+
return { kind: "dispatch", argv: [prStem, ...rest] };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (ns === "verify") {
|
|
146
|
+
const verifyStem = VERIFY_VERB_MAP[verb];
|
|
147
|
+
if (verifyStem !== undefined) {
|
|
148
|
+
return { kind: "dispatch", argv: [verifyStem, ...rest] };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (ns === "issue" && verb === "ingest") {
|
|
152
|
+
return { kind: "dispatch", argv: ["issue-ingest", ...rest] };
|
|
153
|
+
}
|
|
154
|
+
if (ns === "issue" && verb === "emit") {
|
|
155
|
+
return { kind: "dispatch", argv: ["issue-emit", ...rest] };
|
|
156
|
+
}
|
|
157
|
+
if (ns === "triage" && verb.startsWith("bulk-")) {
|
|
158
|
+
return { kind: "dispatch", argv: ["triage-bulk", verb.slice("bulk-".length), ...rest] };
|
|
159
|
+
}
|
|
160
|
+
const hyphenStem = `${ns}-${verb}`;
|
|
161
|
+
if (resolveCanonicalVerb(hyphenStem) !== null) {
|
|
162
|
+
return { kind: "dispatch", argv: [hyphenStem, ...rest] };
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
function routeThreeToken(ns, verb, subverb, rest) {
|
|
167
|
+
if (ns === "scm" && verb === "issue") {
|
|
168
|
+
return { kind: "dispatch", argv: ["scm", "issue", subverb, ...rest] };
|
|
169
|
+
}
|
|
170
|
+
if (ns === "vbrief" && verb === "reconcile") {
|
|
171
|
+
return { kind: "dispatch", argv: ["vbrief-reconcile", subverb, ...rest] };
|
|
172
|
+
}
|
|
173
|
+
if (ns === "policy" && verb === "set") {
|
|
174
|
+
return { kind: "dispatch", argv: ["policy-set", subverb, ...rest] };
|
|
175
|
+
}
|
|
176
|
+
const compositeKey = `${ns}:${verb}-${subverb}`;
|
|
177
|
+
const subcommand = SUBCOMMAND_ROUTES[compositeKey];
|
|
178
|
+
if (subcommand !== undefined) {
|
|
179
|
+
return { kind: "dispatch", argv: [...subcommand, ...rest] };
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Transform user-facing argv (`directive <ns> <verb>` or top-level UX) into
|
|
185
|
+
* flat dispatcher argv consumed by `dispatch()`.
|
|
186
|
+
*/
|
|
187
|
+
export function routeArgv(argv) {
|
|
188
|
+
if (argv.length === 0) {
|
|
189
|
+
return { kind: "dispatch", argv: [] };
|
|
190
|
+
}
|
|
191
|
+
const [first, second, third, ...tail] = argv;
|
|
192
|
+
if (first === undefined) {
|
|
193
|
+
return { kind: "dispatch", argv: [] };
|
|
194
|
+
}
|
|
195
|
+
if (isMetaVerb(first) || first === "help") {
|
|
196
|
+
return { kind: "dispatch", argv: [...argv] };
|
|
197
|
+
}
|
|
198
|
+
const topLevel = routeTopLevel(first, argv.slice(1));
|
|
199
|
+
if (topLevel !== null)
|
|
200
|
+
return topLevel;
|
|
201
|
+
if (argv.length === 1 && resolveCanonicalVerb(first) !== null) {
|
|
202
|
+
return { kind: "dispatch", argv: [first] };
|
|
203
|
+
}
|
|
204
|
+
if (second !== undefined) {
|
|
205
|
+
const nsRoute = routeNamespaceVerb(first, second, third !== undefined ? [third, ...tail] : tail);
|
|
206
|
+
if (nsRoute !== null)
|
|
207
|
+
return nsRoute;
|
|
208
|
+
}
|
|
209
|
+
if (second !== undefined && third !== undefined) {
|
|
210
|
+
const threeToken = routeThreeToken(first, second, third, tail);
|
|
211
|
+
if (threeToken !== null)
|
|
212
|
+
return threeToken;
|
|
213
|
+
}
|
|
214
|
+
return { kind: "dispatch", argv: [...argv] };
|
|
215
|
+
}
|
|
216
|
+
/** Map `namespace:verb` task key to flat dispatcher argv (test seam). */
|
|
217
|
+
export function taskKeyToDispatchArgv(taskKey, rest = []) {
|
|
218
|
+
const colon = taskKey.indexOf(":");
|
|
219
|
+
if (colon <= 0)
|
|
220
|
+
return null;
|
|
221
|
+
const ns = taskKey.slice(0, colon);
|
|
222
|
+
const verb = taskKey.slice(colon + 1);
|
|
223
|
+
const routed = routeNamespaceVerb(ns, verb, [...rest]);
|
|
224
|
+
return routed?.kind === "dispatch" ? routed.argv : null;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=route-argv.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runDefaultExtractorCli } from "@deftai/directive-core/codebase";
|
|
3
|
+
const result = runDefaultExtractorCli(process.argv.slice(2));
|
|
4
|
+
if (result.stdout)
|
|
5
|
+
process.stdout.write(result.stdout);
|
|
6
|
+
if (result.stderr)
|
|
7
|
+
process.stderr.write(result.stderr);
|
|
8
|
+
process.exit(result.exitCode);
|
|
9
|
+
//# sourceMappingURL=codebase-default-extractor.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCodebaseMapFreshCli } from "@deftai/directive-core/codebase";
|
|
3
|
+
const result = runCodebaseMapFreshCli(process.argv.slice(2));
|
|
4
|
+
if (result.stdout)
|
|
5
|
+
process.stdout.write(result.stdout);
|
|
6
|
+
if (result.stderr)
|
|
7
|
+
process.stderr.write(result.stderr);
|
|
8
|
+
process.exit(result.exitCode);
|
|
9
|
+
//# sourceMappingURL=codebase-map-fresh.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCodebaseMapCli } from "@deftai/directive-core/codebase";
|
|
3
|
+
const result = runCodebaseMapCli(process.argv.slice(2));
|
|
4
|
+
if (result.stdout)
|
|
5
|
+
process.stdout.write(result.stdout);
|
|
6
|
+
if (result.stderr)
|
|
7
|
+
process.stderr.write(result.stderr);
|
|
8
|
+
process.exit(result.exitCode);
|
|
9
|
+
//# sourceMappingURL=codebase-map.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
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: string;
|
|
10
|
+
readonly argv: string[];
|
|
11
|
+
readonly setup?: (root: string) => void;
|
|
12
|
+
readonly env?: Record<string, string | undefined>;
|
|
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 const PARITY_CASES: readonly ParityCase[];
|
|
27
|
+
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
28
|
+
export declare function runParity(): ParityResult;
|
|
29
|
+
export declare function renderReport(result: ParityResult): string;
|
|
30
|
+
//# sourceMappingURL=codebase-parity.d.ts.map
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Golden-output parity harness (#1786): runs BOTH the frozen Python codebase/capacity
|
|
4
|
+
* modules and the ported TS CLIs over shared fixtures, cache-off.
|
|
5
|
+
*
|
|
6
|
+
* Exit codes: 0 parity / 1 divergence / 2 harness setup error.
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync } from "node:child_process";
|
|
9
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { dirname, join, resolve } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
import { runCodebaseMapCli } from "@deftai/directive-core/codebase";
|
|
14
|
+
function runCapture(cmd, args, cwd, env = {}) {
|
|
15
|
+
const merged = { ...process.env, ...env };
|
|
16
|
+
for (const key of Object.keys(merged)) {
|
|
17
|
+
if (merged[key] === undefined)
|
|
18
|
+
delete merged[key];
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const stdout = execFileSync(cmd, args, {
|
|
22
|
+
cwd,
|
|
23
|
+
encoding: "utf8",
|
|
24
|
+
env: merged,
|
|
25
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
26
|
+
});
|
|
27
|
+
return { status: 0, stdout, stderr: "" };
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const e = err;
|
|
31
|
+
return {
|
|
32
|
+
status: typeof e.status === "number" ? e.status : 2,
|
|
33
|
+
stdout: typeof e.stdout === "string" ? e.stdout : "",
|
|
34
|
+
stderr: typeof e.stderr === "string" ? e.stderr : "",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function resolveDeftRoot() {
|
|
39
|
+
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
40
|
+
return resolve(process.env.DEFT_ROOT);
|
|
41
|
+
}
|
|
42
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
43
|
+
}
|
|
44
|
+
const TS_CLI = {
|
|
45
|
+
codebase_projection_registry: "codebase-projection-registry.js",
|
|
46
|
+
codebase_default_extractor: "codebase-default-extractor.js",
|
|
47
|
+
codebase_provider: "codebase-provider.js",
|
|
48
|
+
codebase_map: "codebase-map.js",
|
|
49
|
+
codebase_map_fresh: "codebase-map-fresh.js",
|
|
50
|
+
capacity_show: "capacity-show.js",
|
|
51
|
+
capacity_backfill: "capacity-backfill.js",
|
|
52
|
+
};
|
|
53
|
+
const NO_PROJECT_ROOT = new Set(["codebase_projection_registry"]);
|
|
54
|
+
function runPython(deftRoot, script, repo, argv) {
|
|
55
|
+
const args = ["run", "python", join(deftRoot, "scripts", `${script}.py`), ...argv];
|
|
56
|
+
if (!NO_PROJECT_ROOT.has(script)) {
|
|
57
|
+
args.push("--project-root", repo);
|
|
58
|
+
}
|
|
59
|
+
const cap = runCapture("uv", args, deftRoot);
|
|
60
|
+
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
61
|
+
}
|
|
62
|
+
function runTs(deftRoot, script, repo, argv) {
|
|
63
|
+
const cli = TS_CLI[script];
|
|
64
|
+
if (cli === undefined) {
|
|
65
|
+
throw new Error(`no TS CLI mapped for ${script}`);
|
|
66
|
+
}
|
|
67
|
+
const args = [join(deftRoot, "packages", "cli", "dist", cli), ...argv];
|
|
68
|
+
if (!NO_PROJECT_ROOT.has(script)) {
|
|
69
|
+
args.push("--project-root", repo);
|
|
70
|
+
}
|
|
71
|
+
const cap = runCapture("node", args, deftRoot);
|
|
72
|
+
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
73
|
+
}
|
|
74
|
+
function writeCapacityProject(root) {
|
|
75
|
+
const vbrief = join(root, "vbrief");
|
|
76
|
+
for (const folder of ["proposed", "pending", "active", "completed", "cancelled"]) {
|
|
77
|
+
mkdirSync(join(vbrief, folder), { recursive: true });
|
|
78
|
+
}
|
|
79
|
+
writeFileSync(join(vbrief, "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
|
|
80
|
+
vBRIEFInfo: { version: "0.6" },
|
|
81
|
+
plan: {
|
|
82
|
+
title: "Capacity parity",
|
|
83
|
+
status: "running",
|
|
84
|
+
items: [],
|
|
85
|
+
policy: {
|
|
86
|
+
capacityAllocation: {
|
|
87
|
+
unit: "vbrief-count",
|
|
88
|
+
window: 30,
|
|
89
|
+
enforcement: "advise",
|
|
90
|
+
minSampleSize: 2,
|
|
91
|
+
defaultBucket: "feature",
|
|
92
|
+
buckets: [
|
|
93
|
+
{ id: "debt", target: 0.4, match: { labels: { "any-of": ["tech-debt"] } } },
|
|
94
|
+
{ id: "feature", target: 0.6, match: { labels: { "any-of": ["feature"] } } },
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
}, null, 2)}\n`, { encoding: "utf8" });
|
|
100
|
+
}
|
|
101
|
+
function writeCodeStructureProject(root) {
|
|
102
|
+
const vbrief = join(root, "vbrief");
|
|
103
|
+
mkdirSync(vbrief, { recursive: true });
|
|
104
|
+
writeFileSync(join(vbrief, "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
|
|
105
|
+
vBRIEFInfo: { version: "0.6" },
|
|
106
|
+
plan: {
|
|
107
|
+
title: "Fixture",
|
|
108
|
+
status: "running",
|
|
109
|
+
architecture: {
|
|
110
|
+
codeStructure: {
|
|
111
|
+
version: "0.1",
|
|
112
|
+
modules: [
|
|
113
|
+
{
|
|
114
|
+
id: "app",
|
|
115
|
+
name: "App",
|
|
116
|
+
purpose: "Application entry points.",
|
|
117
|
+
pathGlobs: ["app/**/*.py"],
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
pathOwnership: [],
|
|
121
|
+
allowedPatterns: [],
|
|
122
|
+
projectionManifest: [],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
}, null, 2)}\n`, { encoding: "utf8" });
|
|
127
|
+
mkdirSync(join(root, "app"), { recursive: true });
|
|
128
|
+
writeFileSync(join(root, "app", "main.py"), "from lib.util import thing\n", { encoding: "utf8" });
|
|
129
|
+
}
|
|
130
|
+
function writeCodeStructureProjectNonAscii(root) {
|
|
131
|
+
const vbrief = join(root, "vbrief");
|
|
132
|
+
mkdirSync(vbrief, { recursive: true });
|
|
133
|
+
writeFileSync(join(vbrief, "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
|
|
134
|
+
vBRIEFInfo: { version: "0.6" },
|
|
135
|
+
plan: {
|
|
136
|
+
title: "Fixture",
|
|
137
|
+
status: "running",
|
|
138
|
+
architecture: {
|
|
139
|
+
codeStructure: {
|
|
140
|
+
version: "0.1",
|
|
141
|
+
modules: [
|
|
142
|
+
{
|
|
143
|
+
id: "app",
|
|
144
|
+
name: "Café App — naïve façade",
|
|
145
|
+
purpose: "Entrée points with non-ASCII glyphs: \u00e9 \u00f1 \u2014 \ud83d\ude80.",
|
|
146
|
+
pathGlobs: ["app/**/*.py"],
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
pathOwnership: [],
|
|
150
|
+
allowedPatterns: [],
|
|
151
|
+
projectionManifest: [],
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
}, null, 2)}\n`, { encoding: "utf8" });
|
|
156
|
+
mkdirSync(join(root, "app"), { recursive: true });
|
|
157
|
+
writeFileSync(join(root, "app", "main.py"), "from lib.util import thing\n", { encoding: "utf8" });
|
|
158
|
+
}
|
|
159
|
+
function writeFreshCodebaseMapProject(root) {
|
|
160
|
+
writeCodeStructureProject(root);
|
|
161
|
+
const result = runCodebaseMapCli(["--project-root", root]);
|
|
162
|
+
if (result.exitCode !== 0) {
|
|
163
|
+
throw new Error(`failed to write MAP fixture: ${result.stderr || result.stdout}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
export const PARITY_CASES = [
|
|
167
|
+
{
|
|
168
|
+
name: "projection-registry-list",
|
|
169
|
+
script: "codebase_projection_registry",
|
|
170
|
+
argv: ["--list"],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "projection-registry-kind",
|
|
174
|
+
script: "codebase_projection_registry",
|
|
175
|
+
argv: ["--kind", "codebase-map"],
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "default-extractor-curated",
|
|
179
|
+
script: "codebase_default_extractor",
|
|
180
|
+
argv: [],
|
|
181
|
+
setup: writeCodeStructureProject,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "provider-default-fallback",
|
|
185
|
+
script: "codebase_provider",
|
|
186
|
+
argv: [],
|
|
187
|
+
setup: writeCodeStructureProject,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "map-stdout",
|
|
191
|
+
script: "codebase_map",
|
|
192
|
+
argv: ["--stdout"],
|
|
193
|
+
setup: writeCodeStructureProject,
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "map-stdout-nonascii",
|
|
197
|
+
script: "codebase_map",
|
|
198
|
+
argv: ["--stdout"],
|
|
199
|
+
setup: writeCodeStructureProjectNonAscii,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
name: "map-fresh-missing",
|
|
203
|
+
script: "codebase_map_fresh",
|
|
204
|
+
argv: [],
|
|
205
|
+
setup: writeCodeStructureProject,
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: "map-fresh-current",
|
|
209
|
+
script: "codebase_map_fresh",
|
|
210
|
+
argv: [],
|
|
211
|
+
setup: writeFreshCodebaseMapProject,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: "capacity-show-advisory",
|
|
215
|
+
script: "capacity_show",
|
|
216
|
+
argv: [],
|
|
217
|
+
setup: writeCapacityProject,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: "capacity-backfill-dry-run",
|
|
221
|
+
script: "capacity_backfill",
|
|
222
|
+
argv: [],
|
|
223
|
+
setup: writeCapacityProject,
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: "capacity-backfill-json",
|
|
227
|
+
script: "capacity_backfill",
|
|
228
|
+
argv: ["--json"],
|
|
229
|
+
setup: writeCapacityProject,
|
|
230
|
+
},
|
|
231
|
+
];
|
|
232
|
+
export function diffCase(python, ts, caseName) {
|
|
233
|
+
return {
|
|
234
|
+
caseName,
|
|
235
|
+
exitMismatch: python.exitCode !== ts.exitCode,
|
|
236
|
+
stdoutMismatch: python.stdout !== ts.stdout,
|
|
237
|
+
stderrMismatch: python.stderr !== ts.stderr,
|
|
238
|
+
pythonExit: python.exitCode,
|
|
239
|
+
tsExit: ts.exitCode,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
export function runParity() {
|
|
243
|
+
const deftRoot = resolveDeftRoot();
|
|
244
|
+
const diffs = [];
|
|
245
|
+
for (const testCase of PARITY_CASES) {
|
|
246
|
+
const repo = mkdtempSync(join(tmpdir(), "deft-codebase-parity-"));
|
|
247
|
+
try {
|
|
248
|
+
testCase.setup?.(repo);
|
|
249
|
+
const argv = testCase.argv.filter((a) => a !== "--project-root");
|
|
250
|
+
const python = runPython(deftRoot, testCase.script, repo, argv);
|
|
251
|
+
const ts = runTs(deftRoot, testCase.script, repo, argv);
|
|
252
|
+
diffs.push(diffCase(python, ts, testCase.name));
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
rmSync(repo, { recursive: true, force: true });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
259
|
+
return { ok, diffs };
|
|
260
|
+
}
|
|
261
|
+
export function renderReport(result) {
|
|
262
|
+
if (result.ok) {
|
|
263
|
+
return `codebase parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
264
|
+
}
|
|
265
|
+
const lines = ["codebase parity: DIVERGENCE"];
|
|
266
|
+
for (const d of result.diffs) {
|
|
267
|
+
if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
|
|
268
|
+
lines.push(` case: ${d.caseName}`);
|
|
269
|
+
if (d.exitMismatch)
|
|
270
|
+
lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
|
|
271
|
+
if (d.stdoutMismatch)
|
|
272
|
+
lines.push(" stdout mismatch");
|
|
273
|
+
if (d.stderrMismatch)
|
|
274
|
+
lines.push(" stderr mismatch");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return lines.join("\n");
|
|
278
|
+
}
|
|
279
|
+
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
280
|
+
try {
|
|
281
|
+
const result = runParity();
|
|
282
|
+
if (result.ok) {
|
|
283
|
+
process.stdout.write(`${renderReport(result)}\n`);
|
|
284
|
+
process.exit(0);
|
|
285
|
+
}
|
|
286
|
+
process.stderr.write(`${renderReport(result)}\n`);
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
process.stderr.write(`codebase parity: harness error -- ${String(err)}\n`);
|
|
291
|
+
process.exit(2);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=codebase-parity.js.map
|