@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.
Files changed (261) hide show
  1. package/dist/bin.d.ts +3 -0
  2. package/dist/bin.js +5 -0
  3. package/dist/branch-parity.d.ts +47 -0
  4. package/dist/branch-parity.js +263 -0
  5. package/dist/cache-parity.d.ts +36 -0
  6. package/dist/cache-parity.js +165 -0
  7. package/dist/cache.d.ts +4 -0
  8. package/dist/cache.js +10 -0
  9. package/dist/capacity-backfill.d.ts +3 -0
  10. package/dist/capacity-backfill.js +9 -0
  11. package/dist/capacity-show.d.ts +3 -0
  12. package/dist/capacity-show.js +9 -0
  13. package/dist/check.d.ts +10 -0
  14. package/dist/check.js +60 -0
  15. package/dist/cli-router/index.d.ts +8 -0
  16. package/dist/cli-router/index.js +37 -0
  17. package/dist/cli-router/route-argv.d.ts +32 -0
  18. package/dist/cli-router/route-argv.js +226 -0
  19. package/dist/codebase-default-extractor.d.ts +3 -0
  20. package/dist/codebase-default-extractor.js +9 -0
  21. package/dist/codebase-map-fresh.d.ts +3 -0
  22. package/dist/codebase-map-fresh.js +9 -0
  23. package/dist/codebase-map.d.ts +3 -0
  24. package/dist/codebase-map.js +9 -0
  25. package/dist/codebase-parity.d.ts +30 -0
  26. package/dist/codebase-parity.js +294 -0
  27. package/dist/codebase-projection-registry.d.ts +3 -0
  28. package/dist/codebase-projection-registry.js +9 -0
  29. package/dist/codebase-provider.d.ts +3 -0
  30. package/dist/codebase-provider.js +9 -0
  31. package/dist/content-validate-cli/validate-links.d.ts +11 -0
  32. package/dist/content-validate-cli/validate-links.js +37 -0
  33. package/dist/content-validate-cli/validate-strategy-output.d.ts +13 -0
  34. package/dist/content-validate-cli/validate-strategy-output.js +56 -0
  35. package/dist/content-validate-cli/verify-capacity.d.ts +12 -0
  36. package/dist/content-validate-cli/verify-capacity.js +54 -0
  37. package/dist/dispatch.d.ts +26 -0
  38. package/dist/dispatch.js +569 -0
  39. package/dist/doctor-parity.d.ts +38 -0
  40. package/dist/doctor-parity.js +151 -0
  41. package/dist/doctor.d.ts +3 -0
  42. package/dist/doctor.js +10 -0
  43. package/dist/gates-cli/_helpers.d.ts +18 -0
  44. package/dist/gates-cli/_helpers.js +71 -0
  45. package/dist/index.d.ts +11 -0
  46. package/dist/index.js +15 -0
  47. package/dist/init-cli/constants.d.ts +5 -0
  48. package/dist/init-cli/constants.js +5 -0
  49. package/dist/init-cli/init.d.ts +3 -0
  50. package/dist/init-cli/init.js +11 -0
  51. package/dist/init-cli/resolve-binary.d.ts +34 -0
  52. package/dist/init-cli/resolve-binary.js +78 -0
  53. package/dist/init-cli/run-deft-install.d.ts +23 -0
  54. package/dist/init-cli/run-deft-install.js +71 -0
  55. package/dist/init-cli/update.d.ts +3 -0
  56. package/dist/init-cli/update.js +11 -0
  57. package/dist/install-cli/coverage-map.d.ts +14 -0
  58. package/dist/install-cli/coverage-map.js +111 -0
  59. package/dist/intake-parity.d.ts +30 -0
  60. package/dist/intake-parity.js +203 -0
  61. package/dist/lifecycle-cli/coverage-map.d.ts +16 -0
  62. package/dist/lifecycle-cli/coverage-map.js +254 -0
  63. package/dist/lifecycle-cli/helpers.d.ts +8 -0
  64. package/dist/lifecycle-cli/helpers.js +20 -0
  65. package/dist/lifecycle-packs-parity.d.ts +30 -0
  66. package/dist/lifecycle-packs-parity.js +377 -0
  67. package/dist/orchestration-cli/coverage-map.d.ts +21 -0
  68. package/dist/orchestration-cli/coverage-map.js +225 -0
  69. package/dist/orchestration-cli/helpers.d.ts +11 -0
  70. package/dist/orchestration-cli/helpers.js +35 -0
  71. package/dist/orchestration-parity.d.ts +38 -0
  72. package/dist/orchestration-parity.js +364 -0
  73. package/dist/parity.d.ts +36 -0
  74. package/dist/parity.js +176 -0
  75. package/dist/platform-parity.d.ts +26 -0
  76. package/dist/platform-parity.js +309 -0
  77. package/dist/policy-parity.d.ts +35 -0
  78. package/dist/policy-parity.js +214 -0
  79. package/dist/policy.d.ts +27 -0
  80. package/dist/policy.js +316 -0
  81. package/dist/pr-closing-keywords-parity.d.ts +45 -0
  82. package/dist/pr-closing-keywords-parity.js +259 -0
  83. package/dist/pr-closing-keywords.d.ts +3 -0
  84. package/dist/pr-closing-keywords.js +10 -0
  85. package/dist/pr-merge-readiness-parity.d.ts +44 -0
  86. package/dist/pr-merge-readiness-parity.js +296 -0
  87. package/dist/pr-merge-readiness.d.ts +3 -0
  88. package/dist/pr-merge-readiness.js +10 -0
  89. package/dist/pr-monitor-parity.d.ts +44 -0
  90. package/dist/pr-monitor-parity.js +283 -0
  91. package/dist/pr-monitor.d.ts +3 -0
  92. package/dist/pr-monitor.js +10 -0
  93. package/dist/pr-protected-issues-parity.d.ts +41 -0
  94. package/dist/pr-protected-issues-parity.js +220 -0
  95. package/dist/pr-protected-issues.d.ts +3 -0
  96. package/dist/pr-protected-issues.js +10 -0
  97. package/dist/pr-wait-mergeable-parity.d.ts +45 -0
  98. package/dist/pr-wait-mergeable-parity.js +340 -0
  99. package/dist/pr-wait-mergeable.d.ts +3 -0
  100. package/dist/pr-wait-mergeable.js +10 -0
  101. package/dist/preflight-cache.d.ts +16 -0
  102. package/dist/preflight-cache.js +106 -0
  103. package/dist/preflight-gh.d.ts +12 -0
  104. package/dist/preflight-gh.js +188 -0
  105. package/dist/probe-session.d.ts +3 -0
  106. package/dist/probe-session.js +10 -0
  107. package/dist/release-e2e-parity.d.ts +31 -0
  108. package/dist/release-e2e-parity.js +114 -0
  109. package/dist/release-e2e.d.ts +3 -0
  110. package/dist/release-e2e.js +10 -0
  111. package/dist/release-parity.d.ts +40 -0
  112. package/dist/release-parity.js +223 -0
  113. package/dist/release-publish-parity.d.ts +36 -0
  114. package/dist/release-publish-parity.js +138 -0
  115. package/dist/release-publish.d.ts +3 -0
  116. package/dist/release-publish.js +10 -0
  117. package/dist/release-rollback-parity.d.ts +37 -0
  118. package/dist/release-rollback-parity.js +161 -0
  119. package/dist/release-rollback.d.ts +3 -0
  120. package/dist/release-rollback.js +10 -0
  121. package/dist/release.d.ts +3 -0
  122. package/dist/release.js +10 -0
  123. package/dist/render-cli/deft-ts-runner.d.ts +20 -0
  124. package/dist/render-cli/deft-ts-runner.js +35 -0
  125. package/dist/render-cli/prd-render-cli.d.ts +2 -0
  126. package/dist/render-cli/prd-render-cli.js +7 -0
  127. package/dist/render-cli/project-render-cli.d.ts +2 -0
  128. package/dist/render-cli/project-render-cli.js +6 -0
  129. package/dist/render-cli/spec-render-cli.d.ts +2 -0
  130. package/dist/render-cli/spec-render-cli.js +6 -0
  131. package/dist/render-cli/spec-validate-cli.d.ts +2 -0
  132. package/dist/render-cli/spec-validate-cli.js +6 -0
  133. package/dist/render-parity.d.ts +35 -0
  134. package/dist/render-parity.js +383 -0
  135. package/dist/scm-parity.d.ts +39 -0
  136. package/dist/scm-parity.js +181 -0
  137. package/dist/scope-lifecycle-parity.d.ts +35 -0
  138. package/dist/scope-lifecycle-parity.js +177 -0
  139. package/dist/scope-lifecycle.d.ts +4 -0
  140. package/dist/scope-lifecycle.js +29 -0
  141. package/dist/session-parity.d.ts +39 -0
  142. package/dist/session-parity.js +260 -0
  143. package/dist/slice-parity.d.ts +36 -0
  144. package/dist/slice-parity.js +304 -0
  145. package/dist/slice.d.ts +4 -0
  146. package/dist/slice.js +29 -0
  147. package/dist/story-ready-parity.d.ts +49 -0
  148. package/dist/story-ready-parity.js +254 -0
  149. package/dist/subagent-monitor.d.ts +3 -0
  150. package/dist/subagent-monitor.js +10 -0
  151. package/dist/swarm-parity.d.ts +28 -0
  152. package/dist/swarm-parity.js +326 -0
  153. package/dist/toolchain-check.d.ts +3 -0
  154. package/dist/toolchain-check.js +14 -0
  155. package/dist/triage-actions-parity.d.ts +33 -0
  156. package/dist/triage-actions-parity.js +201 -0
  157. package/dist/triage-actions.d.ts +17 -0
  158. package/dist/triage-actions.js +144 -0
  159. package/dist/triage-aux-a-parity.d.ts +35 -0
  160. package/dist/triage-aux-a-parity.js +172 -0
  161. package/dist/triage-aux-b-parity.d.ts +32 -0
  162. package/dist/triage-aux-b-parity.js +308 -0
  163. package/dist/triage-bootstrap-parity.d.ts +44 -0
  164. package/dist/triage-bootstrap-parity.js +226 -0
  165. package/dist/triage-bootstrap.d.ts +24 -0
  166. package/dist/triage-bootstrap.js +172 -0
  167. package/dist/triage-bulk.d.ts +17 -0
  168. package/dist/triage-bulk.js +154 -0
  169. package/dist/triage-classify-parity.d.ts +40 -0
  170. package/dist/triage-classify-parity.js +227 -0
  171. package/dist/triage-classify.d.ts +13 -0
  172. package/dist/triage-classify.js +76 -0
  173. package/dist/triage-help.d.ts +3 -0
  174. package/dist/triage-help.js +10 -0
  175. package/dist/triage-queue-parity.d.ts +59 -0
  176. package/dist/triage-queue-parity.js +363 -0
  177. package/dist/triage-queue.d.ts +17 -0
  178. package/dist/triage-queue.js +174 -0
  179. package/dist/triage-reconcile.d.ts +11 -0
  180. package/dist/triage-reconcile.js +76 -0
  181. package/dist/triage-refresh.d.ts +7 -0
  182. package/dist/triage-refresh.js +37 -0
  183. package/dist/triage-scope-drift.d.ts +12 -0
  184. package/dist/triage-scope-drift.js +117 -0
  185. package/dist/triage-scope-parity.d.ts +34 -0
  186. package/dist/triage-scope-parity.js +218 -0
  187. package/dist/triage-scope.d.ts +4 -0
  188. package/dist/triage-scope.js +29 -0
  189. package/dist/triage-smoketest.d.ts +3 -0
  190. package/dist/triage-smoketest.js +43 -0
  191. package/dist/triage-subscribe.d.ts +15 -0
  192. package/dist/triage-subscribe.js +157 -0
  193. package/dist/triage-summary-parity.d.ts +50 -0
  194. package/dist/triage-summary-parity.js +306 -0
  195. package/dist/triage-summary.d.ts +14 -0
  196. package/dist/triage-summary.js +77 -0
  197. package/dist/triage-welcome.d.ts +12 -0
  198. package/dist/triage-welcome.js +78 -0
  199. package/dist/ts-check-lane.d.ts +9 -0
  200. package/dist/ts-check-lane.js +49 -0
  201. package/dist/validate-content-parity.d.ts +33 -0
  202. package/dist/validate-content-parity.js +356 -0
  203. package/dist/vbrief-activate-parity.d.ts +39 -0
  204. package/dist/vbrief-activate-parity.js +216 -0
  205. package/dist/vbrief-activate.d.ts +3 -0
  206. package/dist/vbrief-activate.js +7 -0
  207. package/dist/vbrief-build-parity.d.ts +28 -0
  208. package/dist/vbrief-build-parity.js +399 -0
  209. package/dist/vbrief-build.d.ts +3 -0
  210. package/dist/vbrief-build.js +8 -0
  211. package/dist/vbrief-preflight-parity.d.ts +34 -0
  212. package/dist/vbrief-preflight-parity.js +163 -0
  213. package/dist/vbrief-preflight.d.ts +12 -0
  214. package/dist/vbrief-preflight.js +58 -0
  215. package/dist/vbrief-reconcile-parity.d.ts +22 -0
  216. package/dist/vbrief-reconcile-parity.js +600 -0
  217. package/dist/vbrief-reconcile.d.ts +3 -0
  218. package/dist/vbrief-reconcile.js +7 -0
  219. package/dist/vbrief-validate-parity.d.ts +27 -0
  220. package/dist/vbrief-validate-parity.js +122 -0
  221. package/dist/vbrief-validate.d.ts +3 -0
  222. package/dist/vbrief-validate.js +8 -0
  223. package/dist/vbrief-validation-parity.d.ts +28 -0
  224. package/dist/vbrief-validation-parity.js +645 -0
  225. package/dist/vbrief-validation.d.ts +3 -0
  226. package/dist/vbrief-validation.js +8 -0
  227. package/dist/verify-branch.d.ts +14 -0
  228. package/dist/verify-branch.js +81 -0
  229. package/dist/verify-encoding.d.ts +15 -0
  230. package/dist/verify-encoding.js +86 -0
  231. package/dist/verify-env-parity.d.ts +28 -0
  232. package/dist/verify-env-parity.js +272 -0
  233. package/dist/verify-hooks-installed.d.ts +10 -0
  234. package/dist/verify-hooks-installed.js +48 -0
  235. package/dist/verify-investigation.d.ts +3 -0
  236. package/dist/verify-investigation.js +10 -0
  237. package/dist/verify-judgment-gates.d.ts +3 -0
  238. package/dist/verify-judgment-gates.js +10 -0
  239. package/dist/verify-no-task-runtime.d.ts +3 -0
  240. package/dist/verify-no-task-runtime.js +16 -0
  241. package/dist/verify-session-ritual.d.ts +13 -0
  242. package/dist/verify-session-ritual.js +78 -0
  243. package/dist/verify-source-cli/rule-ownership-lint.d.ts +12 -0
  244. package/dist/verify-source-cli/rule-ownership-lint.js +61 -0
  245. package/dist/verify-source-cli/verify-content-manifest.d.ts +12 -0
  246. package/dist/verify-source-cli/verify-content-manifest.js +61 -0
  247. package/dist/verify-source-cli/verify-scm-boundary.d.ts +13 -0
  248. package/dist/verify-source-cli/verify-scm-boundary.js +66 -0
  249. package/dist/verify-source-cli/verify-stubs.d.ts +11 -0
  250. package/dist/verify-source-cli/verify-stubs.js +27 -0
  251. package/dist/verify-source-parity.d.ts +26 -0
  252. package/dist/verify-source-parity.js +178 -0
  253. package/dist/verify-story-ready.d.ts +16 -0
  254. package/dist/verify-story-ready.js +138 -0
  255. package/dist/verify-tools.d.ts +13 -0
  256. package/dist/verify-tools.js +67 -0
  257. package/dist/verify-wip-cap.d.ts +13 -0
  258. package/dist/verify-wip-cap.js +62 -0
  259. package/dist/wip-cap-parity.d.ts +39 -0
  260. package/dist/wip-cap-parity.js +209 -0
  261. package/package.json +50 -0
package/dist/bin.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
package/dist/bin.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { routeAndDispatch } from "./cli-router/index.js";
3
+ const code = await routeAndDispatch(process.argv.slice(2));
4
+ process.exit(code);
5
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1,47 @@
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 branch: "default" | "feature" | "detached";
11
+ readonly defaultBranchName?: string;
12
+ readonly plan?: Record<string, unknown> | null;
13
+ readonly allowMissingProjectDefinition?: boolean;
14
+ readonly env?: Record<string, string | undefined>;
15
+ }
16
+ export interface ParityResult {
17
+ readonly ok: boolean;
18
+ readonly scenarios: Array<{
19
+ readonly name: string;
20
+ readonly exitMismatch: boolean;
21
+ readonly pythonExit: number;
22
+ readonly tsExit: number;
23
+ readonly messageMismatch: boolean;
24
+ readonly pythonMessage: string;
25
+ readonly tsMessage: string;
26
+ }>;
27
+ }
28
+ /** Scenarios exercised by the parity harness (mirrors Python contract cases). */
29
+ export declare const PARITY_SCENARIOS: readonly ParityScenario[];
30
+ /** Normalise gate message for comparison (trim, collapse whitespace). */
31
+ export declare function normaliseMessage(stdout: string, stderr: string, exitCode: number): string;
32
+ /** Build a fixture git repo for one scenario. */
33
+ export declare function buildScenarioRepo(scenario: ParityScenario): {
34
+ root: string;
35
+ };
36
+ /** Diff python vs TS gate outputs for one scenario. */
37
+ export declare function diffParity(python: ScenarioResult, ts: ScenarioResult): {
38
+ exitMismatch: boolean;
39
+ messageMismatch: boolean;
40
+ pythonMessage: string;
41
+ tsMessage: string;
42
+ };
43
+ /** Run all parity scenarios and return a structured result. */
44
+ export declare function runParity(): ParityResult;
45
+ /** Render a human-readable parity report (exported for unit tests). */
46
+ export declare function renderReport(result: ParityResult): string;
47
+ //# sourceMappingURL=branch-parity.d.ts.map
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Golden-output parity harness (#1719): builds throwaway git fixture repos for
4
+ * branch-protection scenarios, runs BOTH the Python oracle
5
+ * (`scripts/preflight_branch.py`) and the ported TS gate, and diffs exit
6
+ * codes + normalised messages. Exit 0 only on identical results.
7
+ *
8
+ * Exit codes: 0 parity / 1 divergence / 2 harness setup error.
9
+ */
10
+ import { execFileSync } from "node:child_process";
11
+ import { mkdirSync, 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
+ function gitCommit(cwd, message) {
16
+ execFileSync("git", ["commit", "-q", "-m", message], {
17
+ cwd,
18
+ env: {
19
+ ...process.env,
20
+ GIT_AUTHOR_NAME: "deft-parity",
21
+ GIT_AUTHOR_EMAIL: "parity@test.local",
22
+ GIT_COMMITTER_NAME: "deft-parity",
23
+ GIT_COMMITTER_EMAIL: "parity@test.local",
24
+ },
25
+ });
26
+ }
27
+ function writeProjectDef(root, plan) {
28
+ const dir = join(root, "vbrief");
29
+ mkdirSync(dir, { recursive: true });
30
+ writeFileSync(join(dir, "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
31
+ vBRIEFInfo: { version: "0.6" },
32
+ plan: { title: "T", status: "running", items: [], ...plan },
33
+ }, null, 2)}\n`, { encoding: "utf8" });
34
+ }
35
+ /** Scenarios exercised by the parity harness (mirrors Python contract cases). */
36
+ export const PARITY_SCENARIOS = [
37
+ {
38
+ name: "setup-exemption",
39
+ branch: "default",
40
+ plan: null,
41
+ env: { DEFT_SETUP_INTERVIEW: "1", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
42
+ },
43
+ {
44
+ name: "feature-branch",
45
+ branch: "feature",
46
+ plan: { policy: { allowDirectCommitsToMaster: false } },
47
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
48
+ },
49
+ {
50
+ name: "detached-head",
51
+ branch: "detached",
52
+ plan: { policy: { allowDirectCommitsToMaster: false } },
53
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
54
+ },
55
+ {
56
+ name: "master-blocked",
57
+ branch: "default",
58
+ defaultBranchName: "master",
59
+ plan: { policy: { allowDirectCommitsToMaster: false } },
60
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
61
+ },
62
+ {
63
+ name: "master-opt-out-typed",
64
+ branch: "default",
65
+ defaultBranchName: "master",
66
+ plan: { policy: { allowDirectCommitsToMaster: true } },
67
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
68
+ },
69
+ {
70
+ name: "env-bypass",
71
+ branch: "default",
72
+ defaultBranchName: "master",
73
+ plan: { policy: { allowDirectCommitsToMaster: false } },
74
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "1" },
75
+ },
76
+ {
77
+ name: "missing-pd-config-error",
78
+ branch: "default",
79
+ defaultBranchName: "master",
80
+ plan: undefined,
81
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
82
+ },
83
+ {
84
+ name: "missing-pd-bootstrap",
85
+ branch: "default",
86
+ defaultBranchName: "master",
87
+ plan: undefined,
88
+ allowMissingProjectDefinition: true,
89
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
90
+ },
91
+ {
92
+ name: "malformed-typed-field",
93
+ branch: "default",
94
+ defaultBranchName: "master",
95
+ plan: { policy: { allowDirectCommitsToMaster: "yes" } },
96
+ env: { DEFT_SETUP_INTERVIEW: "", DEFT_ALLOW_DEFAULT_BRANCH_COMMIT: "" },
97
+ },
98
+ ];
99
+ function runCapture(cmd, args, cwd, env = {}) {
100
+ const merged = { ...process.env, ...env };
101
+ for (const key of Object.keys(merged)) {
102
+ if (merged[key] === undefined)
103
+ delete merged[key];
104
+ }
105
+ try {
106
+ const stdout = execFileSync(cmd, args, {
107
+ cwd,
108
+ encoding: "utf8",
109
+ env: merged,
110
+ stdio: ["ignore", "pipe", "pipe"],
111
+ });
112
+ return { status: 0, stdout, stderr: "" };
113
+ }
114
+ catch (err) {
115
+ const e = err;
116
+ return {
117
+ status: typeof e.status === "number" ? e.status : 2,
118
+ stdout: typeof e.stdout === "string" ? e.stdout : "",
119
+ stderr: typeof e.stderr === "string" ? e.stderr : "",
120
+ };
121
+ }
122
+ }
123
+ /** Normalise gate message for comparison (trim, collapse whitespace). */
124
+ export function normaliseMessage(stdout, stderr, exitCode) {
125
+ const raw = exitCode === 0 ? stdout : stderr;
126
+ return raw
127
+ .trim()
128
+ .replace(/\s+/g, " ")
129
+ .replace(/PROJECT-DEFINITION not found at [^\s)]+/g, "PROJECT-DEFINITION not found at <ROOT>");
130
+ }
131
+ /** Build a fixture git repo for one scenario. */
132
+ export function buildScenarioRepo(scenario) {
133
+ const root = mkdtempSync(join(tmpdir(), "deft-branch-parity-"));
134
+ const defaultBranch = scenario.defaultBranchName ?? "master";
135
+ try {
136
+ writeFileSync(join(root, "README.md"), "# parity\n", "utf8");
137
+ if (scenario.plan !== null && scenario.plan !== undefined) {
138
+ writeProjectDef(root, scenario.plan);
139
+ }
140
+ execFileSync("git", ["init", "-q"], { cwd: root });
141
+ execFileSync("git", ["branch", "-M", defaultBranch], { cwd: root });
142
+ execFileSync("git", ["add", "-A"], { cwd: root });
143
+ gitCommit(root, "init");
144
+ if (scenario.branch === "feature") {
145
+ execFileSync("git", ["checkout", "-q", "-b", "feat/parity"], { cwd: root });
146
+ }
147
+ else if (scenario.branch === "detached") {
148
+ execFileSync("git", ["checkout", "-q", "--detach"], { cwd: root });
149
+ }
150
+ }
151
+ catch (err) {
152
+ rmSync(root, { recursive: true, force: true });
153
+ throw err;
154
+ }
155
+ return { root };
156
+ }
157
+ function resolveDeftRoot() {
158
+ if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
159
+ return resolve(process.env.DEFT_ROOT);
160
+ }
161
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
162
+ }
163
+ function runScenario(deftRoot, scenario) {
164
+ const { root } = buildScenarioRepo(scenario);
165
+ const env = scenario.env ?? {};
166
+ const sharedArgs = ["--project-root", root];
167
+ if (scenario.allowMissingProjectDefinition) {
168
+ sharedArgs.push("--allow-missing-project-definition");
169
+ }
170
+ const pyArgs = ["run", "python", join(deftRoot, "scripts", "preflight_branch.py"), ...sharedArgs];
171
+ const tsArgs = [join(deftRoot, "packages", "cli", "dist", "verify-branch.js"), ...sharedArgs];
172
+ const py = runCapture("uv", pyArgs, deftRoot, env);
173
+ const ts = runCapture("node", tsArgs, deftRoot, env);
174
+ return {
175
+ root,
176
+ python: {
177
+ name: scenario.name,
178
+ exitCode: py.status,
179
+ stdout: py.stdout,
180
+ stderr: py.stderr,
181
+ },
182
+ ts: {
183
+ name: scenario.name,
184
+ exitCode: ts.status,
185
+ stdout: ts.stdout,
186
+ stderr: ts.stderr,
187
+ },
188
+ };
189
+ }
190
+ /** Diff python vs TS gate outputs for one scenario. */
191
+ export function diffParity(python, ts) {
192
+ const pythonMessage = normaliseMessage(python.stdout, python.stderr, python.exitCode);
193
+ const tsMessage = normaliseMessage(ts.stdout, ts.stderr, ts.exitCode);
194
+ return {
195
+ exitMismatch: python.exitCode !== ts.exitCode,
196
+ messageMismatch: pythonMessage !== tsMessage,
197
+ pythonMessage,
198
+ tsMessage,
199
+ };
200
+ }
201
+ /** Run all parity scenarios and return a structured result. */
202
+ export function runParity() {
203
+ const deftRoot = resolveDeftRoot();
204
+ const scenarios = [];
205
+ for (const scenario of PARITY_SCENARIOS) {
206
+ let root;
207
+ try {
208
+ const ran = runScenario(deftRoot, scenario);
209
+ root = ran.root;
210
+ const diff = diffParity(ran.python, ran.ts);
211
+ scenarios.push({
212
+ name: scenario.name,
213
+ pythonExit: ran.python.exitCode,
214
+ tsExit: ran.ts.exitCode,
215
+ ...diff,
216
+ });
217
+ }
218
+ finally {
219
+ if (root !== undefined) {
220
+ rmSync(root, { recursive: true, force: true });
221
+ }
222
+ }
223
+ }
224
+ const ok = scenarios.every((s) => !s.exitMismatch && !s.messageMismatch);
225
+ return { ok, scenarios };
226
+ }
227
+ /** Render a human-readable parity report (exported for unit tests). */
228
+ export function renderReport(result) {
229
+ if (result.ok) {
230
+ return `verify_branch parity: CLEAN -- Python and TS agree on ${result.scenarios.length} scenario(s).`;
231
+ }
232
+ const lines = ["verify_branch parity: DIVERGENCE"];
233
+ for (const s of result.scenarios) {
234
+ if (s.exitMismatch || s.messageMismatch) {
235
+ lines.push(` scenario: ${s.name}`);
236
+ if (s.exitMismatch) {
237
+ lines.push(` exit mismatch: python=${s.pythonExit} ts=${s.tsExit}`);
238
+ }
239
+ if (s.messageMismatch) {
240
+ lines.push(` python: ${s.pythonMessage}`);
241
+ lines.push(` ts: ${s.tsMessage}`);
242
+ }
243
+ }
244
+ }
245
+ return lines.join("\n");
246
+ }
247
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
248
+ try {
249
+ const result = runParity();
250
+ if (result.ok) {
251
+ process.stdout.write(`${renderReport(result)}\n`);
252
+ process.exit(0);
253
+ }
254
+ process.stderr.write(`${renderReport(result)}\n`);
255
+ process.exit(1);
256
+ }
257
+ catch (err) {
258
+ const msg = String(err).replace(/\r?\n/g, " ");
259
+ process.stderr.write(`verify_branch parity: harness error -- ${msg}\n`);
260
+ process.exit(2);
261
+ }
262
+ }
263
+ //# sourceMappingURL=branch-parity.js.map
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ export interface ScenarioResult {
3
+ readonly name: string;
4
+ readonly exitCode: number;
5
+ readonly stdout: string;
6
+ readonly stderr: string;
7
+ }
8
+ export interface ParityScenario {
9
+ readonly name: string;
10
+ readonly argv: readonly string[];
11
+ }
12
+ export interface ParityResult {
13
+ readonly ok: boolean;
14
+ readonly scenarios: Array<{
15
+ readonly name: string;
16
+ readonly exitMismatch: boolean;
17
+ readonly pythonExit: number;
18
+ readonly tsExit: number;
19
+ readonly messageMismatch: boolean;
20
+ readonly pythonMessage: string;
21
+ readonly tsMessage: string;
22
+ }>;
23
+ }
24
+ /** Validation-only scenarios (no live gh network). */
25
+ export declare const PARITY_SCENARIOS: readonly ParityScenario[];
26
+ /** Normalise gate output for comparison. */
27
+ export declare function normaliseMessage(stdout: string, stderr: string, exitCode: number): string;
28
+ export declare function diffParity(python: ScenarioResult, ts: ScenarioResult): {
29
+ exitMismatch: boolean;
30
+ messageMismatch: boolean;
31
+ pythonMessage: string;
32
+ tsMessage: string;
33
+ };
34
+ export declare function runParity(): ParityResult;
35
+ export declare function renderReport(result: ParityResult): string;
36
+ //# sourceMappingURL=cache-parity.d.ts.map
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Golden-output parity harness (#1728): runs BOTH the Python oracle
4
+ * (`scripts/cache.py`) and the ported TS cache CLI with identical argv,
5
+ * then diffs exit codes and normalised stdout/stderr. Exit 0 only on
6
+ * identical results. Each scenario uses an isolated temp cwd (cache-off).
7
+ *
8
+ * Exit codes: 0 parity / 1 divergence / 2 harness setup error.
9
+ */
10
+ import { spawnSync } from "node:child_process";
11
+ import { mkdtempSync, rmSync } from "node:fs";
12
+ import { tmpdir } from "node:os";
13
+ import { dirname, join, resolve } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ /** Validation-only scenarios (no live gh network). */
16
+ export const PARITY_SCENARIOS = [
17
+ { name: "usage-no-cmd", argv: [] },
18
+ { name: "put-missing-args", argv: ["put"] },
19
+ { name: "get-invalid-key", argv: ["get", "github-issue", "bad/key"] },
20
+ {
21
+ name: "put-missing-raw-file",
22
+ argv: ["put", "github-issue", "deftai/directive/1", "--raw-file", "/nonexistent"],
23
+ },
24
+ { name: "get-miss", argv: ["get", "github-issue", "deftai/directive/999"] },
25
+ {
26
+ name: "invalidate-missing",
27
+ argv: ["invalidate", "github-issue", "deftai/directive/999"],
28
+ },
29
+ { name: "prune-dry-run-empty", argv: ["prune", "--dry-run"] },
30
+ {
31
+ name: "fetch-all-invalid-repo",
32
+ argv: ["fetch-all", "--source", "github-issue", "--repo", "bad"],
33
+ },
34
+ {
35
+ name: "fetch-all-batch-size-zero",
36
+ argv: [
37
+ "fetch-all",
38
+ "--source",
39
+ "github-issue",
40
+ "--repo",
41
+ "deftai/directive",
42
+ "--batch-size",
43
+ "0",
44
+ ],
45
+ },
46
+ {
47
+ name: "fetch-all-delay-negative",
48
+ argv: [
49
+ "fetch-all",
50
+ "--source",
51
+ "github-issue",
52
+ "--repo",
53
+ "deftai/directive",
54
+ "--delay-ms",
55
+ "-1",
56
+ ],
57
+ },
58
+ { name: "prune-to-cap-dry-run", argv: ["prune", "--to-cap", "--dry-run"] },
59
+ ];
60
+ function runCapture(cmd, args, cwd) {
61
+ const result = spawnSync(cmd, args, {
62
+ cwd,
63
+ encoding: "utf8",
64
+ stdio: ["ignore", "pipe", "pipe"],
65
+ });
66
+ return {
67
+ status: result.status ?? 2,
68
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
69
+ stderr: typeof result.stderr === "string" ? result.stderr : "",
70
+ };
71
+ }
72
+ /** Normalise gate output for comparison. */
73
+ export function normaliseMessage(stdout, stderr, exitCode) {
74
+ const raw = exitCode === 0 ? stdout : stderr;
75
+ return raw
76
+ .split("\n")
77
+ .filter((line) => !line.startsWith("Using CPython") &&
78
+ !line.startsWith("Creating virtual environment") &&
79
+ !line.startsWith("Installed "))
80
+ .join("\n")
81
+ .trim()
82
+ .replace(/\s+/g, " ");
83
+ }
84
+ function resolveDeftRoot() {
85
+ if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
86
+ return resolve(process.env.DEFT_ROOT);
87
+ }
88
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
89
+ }
90
+ function runScenario(deftRoot, scenario) {
91
+ const cwd = mkdtempSync(join(tmpdir(), "deft-cache-parity-"));
92
+ try {
93
+ const pyArgs = ["run", "python", join(deftRoot, "scripts", "cache.py"), ...scenario.argv];
94
+ const tsArgs = [join(deftRoot, "packages", "cli", "dist", "cache.js"), ...scenario.argv];
95
+ const py = runCapture("uv", pyArgs, cwd);
96
+ const ts = runCapture("node", tsArgs, cwd);
97
+ return {
98
+ python: { name: scenario.name, exitCode: py.status, stdout: py.stdout, stderr: py.stderr },
99
+ ts: { name: scenario.name, exitCode: ts.status, stdout: ts.stdout, stderr: ts.stderr },
100
+ };
101
+ }
102
+ finally {
103
+ rmSync(cwd, { recursive: true, force: true });
104
+ }
105
+ }
106
+ export function diffParity(python, ts) {
107
+ const pythonMessage = normaliseMessage(python.stdout, python.stderr, python.exitCode);
108
+ const tsMessage = normaliseMessage(ts.stdout, ts.stderr, ts.exitCode);
109
+ return {
110
+ exitMismatch: python.exitCode !== ts.exitCode,
111
+ messageMismatch: pythonMessage !== tsMessage,
112
+ pythonMessage,
113
+ tsMessage,
114
+ };
115
+ }
116
+ export function runParity() {
117
+ const deftRoot = resolveDeftRoot();
118
+ const scenarios = [];
119
+ for (const scenario of PARITY_SCENARIOS) {
120
+ const ran = runScenario(deftRoot, scenario);
121
+ scenarios.push({
122
+ name: scenario.name,
123
+ pythonExit: ran.python.exitCode,
124
+ tsExit: ran.ts.exitCode,
125
+ ...diffParity(ran.python, ran.ts),
126
+ });
127
+ }
128
+ const ok = scenarios.every((s) => !s.exitMismatch && !s.messageMismatch);
129
+ return { ok, scenarios };
130
+ }
131
+ export function renderReport(result) {
132
+ if (result.ok) {
133
+ return `cache parity: CLEAN -- Python and TS agree on ${result.scenarios.length} scenario(s).`;
134
+ }
135
+ const lines = ["cache parity: DIVERGENCE"];
136
+ for (const s of result.scenarios) {
137
+ if (s.exitMismatch || s.messageMismatch) {
138
+ lines.push(` scenario: ${s.name}`);
139
+ if (s.exitMismatch)
140
+ lines.push(` exit mismatch: python=${s.pythonExit} ts=${s.tsExit}`);
141
+ if (s.messageMismatch) {
142
+ lines.push(` python: ${s.pythonMessage}`);
143
+ lines.push(` ts: ${s.tsMessage}`);
144
+ }
145
+ }
146
+ }
147
+ return lines.join("\n");
148
+ }
149
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
150
+ try {
151
+ const result = runParity();
152
+ if (result.ok) {
153
+ process.stdout.write(`${renderReport(result)}\n`);
154
+ process.exit(0);
155
+ }
156
+ process.stderr.write(`${renderReport(result)}\n`);
157
+ process.exit(1);
158
+ }
159
+ catch (err) {
160
+ const msg = String(err).replace(/\r?\n/g, " ");
161
+ process.stderr.write(`cache parity: harness error -- ${msg}\n`);
162
+ process.exit(2);
163
+ }
164
+ }
165
+ //# sourceMappingURL=cache-parity.js.map
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "../../core/dist/cache/main.js";
3
+ export { main };
4
+ //# sourceMappingURL=cache.d.ts.map
package/dist/cache.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { fileURLToPath } from "node:url";
3
+ import { main } from "../../core/dist/cache/main.js";
4
+ /* v8 ignore start -- entry guard; behaviour covered via main() unit tests */
5
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
6
+ process.exit(main(process.argv.slice(2)));
7
+ }
8
+ /* v8 ignore stop */
9
+ export { main };
10
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=capacity-backfill.d.ts.map
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { runCapacityBackfillCli } from "@deftai/directive-core/capacity";
3
+ const result = await runCapacityBackfillCli(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=capacity-backfill.js.map
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=capacity-show.d.ts.map
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { runCapacityShowCli } from "@deftai/directive-core/capacity";
3
+ const result = runCapacityShowCli(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=capacity-show.js.map
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ frameworkRoot?: string;
4
+ projectRoot?: string;
5
+ error?: string;
6
+ }
7
+ export declare function parseArgs(argv: string[]): ParsedArgs;
8
+ export declare function run(argv: string[]): number;
9
+ export {};
10
+ //# sourceMappingURL=check.d.ts.map
package/dist/check.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * check.ts -- CLI wrapper for the context-aware `task check` orchestrator (#1854).
4
+ *
5
+ * Usage: deft-ts check --framework-root <path> --project-root <path>
6
+ *
7
+ * Thin shim: parses args and delegates to dispatchTaskCheck in @deftai/directive-core/check.
8
+ */
9
+ import { fileURLToPath } from "node:url";
10
+ import { dispatchTaskCheck } from "@deftai/directive-core/check";
11
+ export function parseArgs(argv) {
12
+ const parsed = {};
13
+ for (let i = 0; i < argv.length; i++) {
14
+ const arg = argv[i] ?? "";
15
+ if (arg === "--framework-root") {
16
+ const next = argv[i + 1];
17
+ if (next === undefined) {
18
+ return { ...parsed, error: "argument --framework-root: expected one argument" };
19
+ }
20
+ parsed.frameworkRoot = next;
21
+ i++;
22
+ }
23
+ else if (arg.startsWith("--framework-root=")) {
24
+ parsed.frameworkRoot = arg.slice("--framework-root=".length);
25
+ }
26
+ else if (arg === "--project-root") {
27
+ const next = argv[i + 1];
28
+ if (next === undefined) {
29
+ return { ...parsed, error: "argument --project-root: expected one argument" };
30
+ }
31
+ parsed.projectRoot = next;
32
+ i++;
33
+ }
34
+ else if (arg.startsWith("--project-root=")) {
35
+ parsed.projectRoot = arg.slice("--project-root=".length);
36
+ }
37
+ else {
38
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
39
+ }
40
+ }
41
+ return parsed;
42
+ }
43
+ export function run(argv) {
44
+ const args = parseArgs(argv);
45
+ if (args.error !== undefined) {
46
+ process.stderr.write(`check: ${args.error}\n`);
47
+ return 2;
48
+ }
49
+ if (args.frameworkRoot === undefined || args.projectRoot === undefined) {
50
+ process.stderr.write("check: --framework-root and --project-root are required\n");
51
+ return 2;
52
+ }
53
+ return dispatchTaskCheck(args.frameworkRoot, args.projectRoot);
54
+ }
55
+ /* v8 ignore start -- entry guard */
56
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
57
+ process.exit(run(process.argv.slice(2)));
58
+ }
59
+ /* v8 ignore stop */
60
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * CLI router entry: `directive <namespace> <verb>` → flat dispatcher (#1670 / #11 S3).
3
+ */
4
+ import { type DispatchIo } from "../dispatch.js";
5
+ export { DEFERRED_TOP_LEVEL_VERBS, PR_VERB_MAP, type RoutedArgv, type RouteKind, routeArgv, SCOPE_LIFECYCLE_VERBS, STUBBED_TOP_LEVEL_VERBS, SUBCOMMAND_ROUTES, TOP_LEVEL_UX_VERBS, taskKeyToDispatchArgv, VERIFY_VERB_MAP, } from "./route-argv.js";
6
+ /** Route user argv then dispatch to the existing engine handlers. */
7
+ export declare function routeAndDispatch(argv: readonly string[], io?: DispatchIo): Promise<number>;
8
+ //# sourceMappingURL=index.d.ts.map