@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
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { appendHistory, computeSummary, formatSummary, pythonStyleStringify, SUMMARY_HISTORY_REL_PATH, summaryResultToRecord, utcIso, } from "../../core/dist/triage/summary/index.js";
5
+ /** Parse triage-summary CLI args, mirroring the Python argparse surface. */
6
+ export function parseArgs(argv) {
7
+ const parsed = {
8
+ projectRoot: ".",
9
+ cacheRoot: null,
10
+ noHistory: false,
11
+ json: false,
12
+ };
13
+ for (let i = 0; i < argv.length; i += 1) {
14
+ const arg = argv[i];
15
+ if (arg === "--no-history") {
16
+ parsed.noHistory = true;
17
+ }
18
+ else if (arg === "--json") {
19
+ parsed.json = true;
20
+ }
21
+ else if (arg === "--project-root") {
22
+ const value = argv[i + 1];
23
+ if (value === undefined) {
24
+ return { ...parsed, error: "argument --project-root: expected one argument" };
25
+ }
26
+ parsed.projectRoot = value;
27
+ i += 1;
28
+ }
29
+ else if (arg?.startsWith("--project-root=")) {
30
+ parsed.projectRoot = arg.slice("--project-root=".length);
31
+ }
32
+ else if (arg === "--cache-root") {
33
+ const value = argv[i + 1];
34
+ if (value === undefined) {
35
+ return { ...parsed, error: "argument --cache-root: expected one argument" };
36
+ }
37
+ parsed.cacheRoot = value;
38
+ i += 1;
39
+ }
40
+ else if (arg?.startsWith("--cache-root=")) {
41
+ parsed.cacheRoot = arg.slice("--cache-root=".length);
42
+ }
43
+ else if (arg !== undefined && arg.length > 0) {
44
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
45
+ }
46
+ }
47
+ return parsed;
48
+ }
49
+ /** Run the triage:summary CLI — always returns exit code 0. */
50
+ export function run(argv) {
51
+ const args = parseArgs(argv);
52
+ if (args.error !== undefined) {
53
+ process.stderr.write(`triage_summary: ${args.error}\n`);
54
+ return 2;
55
+ }
56
+ const projectRoot = resolve(args.projectRoot);
57
+ const cacheRoot = args.cacheRoot !== null ? resolve(args.cacheRoot) : undefined;
58
+ const result = computeSummary(projectRoot, { cacheRoot });
59
+ const line = formatSummary(result);
60
+ const emittedAt = utcIso();
61
+ if (args.json) {
62
+ const record = summaryResultToRecord(result, { emittedAt, line });
63
+ process.stdout.write(`${pythonStyleStringify(record)}\n`);
64
+ }
65
+ else {
66
+ process.stdout.write(`${line}\n`);
67
+ }
68
+ if (!args.noHistory) {
69
+ const historyPath = resolve(projectRoot, SUMMARY_HISTORY_REL_PATH);
70
+ appendHistory(historyPath, result, line, { emittedAt });
71
+ }
72
+ return 0;
73
+ }
74
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
75
+ process.exit(run(process.argv.slice(2)));
76
+ }
77
+ //# sourceMappingURL=triage-summary.js.map
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ projectRoot: string;
4
+ onboard: boolean;
5
+ noHistory: boolean;
6
+ taskPrefix: string;
7
+ error?: string;
8
+ }
9
+ export declare function parseArgs(argv: string[]): ParsedArgs;
10
+ export declare function run(argv: string[]): number;
11
+ export {};
12
+ //# sourceMappingURL=triage-welcome.d.ts.map
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ import { statSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { runDefaultMode } from "../../core/dist/triage/welcome/default-mode.js";
6
+ export function parseArgs(argv) {
7
+ const parsed = {
8
+ projectRoot: process.env.DEFT_PROJECT_ROOT ?? ".",
9
+ onboard: false,
10
+ noHistory: false,
11
+ taskPrefix: process.env.DEFT_TASK_PREFIX ?? "",
12
+ };
13
+ for (let i = 0; i < argv.length; i += 1) {
14
+ const arg = argv[i];
15
+ if (arg === "--onboard")
16
+ parsed.onboard = true;
17
+ else if (arg === "--no-history")
18
+ parsed.noHistory = true;
19
+ else if (arg === "--project-root") {
20
+ const value = argv[i + 1];
21
+ if (value === undefined)
22
+ return { ...parsed, error: "argument --project-root: expected one argument" };
23
+ parsed.projectRoot = value;
24
+ i += 1;
25
+ }
26
+ else if (arg?.startsWith("--project-root=")) {
27
+ parsed.projectRoot = arg.slice("--project-root=".length);
28
+ }
29
+ else if (arg === "--task-prefix") {
30
+ const value = argv[i + 1];
31
+ if (value === undefined)
32
+ return { ...parsed, error: "argument --task-prefix: expected one argument" };
33
+ parsed.taskPrefix = value;
34
+ i += 1;
35
+ }
36
+ else if (arg?.startsWith("--task-prefix=")) {
37
+ parsed.taskPrefix = arg.slice("--task-prefix=".length);
38
+ }
39
+ else if (arg === "--no-subprocess" || arg === "--skip-bootstrap") {
40
+ // accepted for argparse parity; default mode ignores them
41
+ }
42
+ else {
43
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
44
+ }
45
+ }
46
+ return parsed;
47
+ }
48
+ export function run(argv) {
49
+ const args = parseArgs(argv);
50
+ if (args.error !== undefined) {
51
+ process.stderr.write(`triage:welcome: ${args.error}\n`);
52
+ return 2;
53
+ }
54
+ const projectRoot = resolve(args.projectRoot);
55
+ try {
56
+ if (!statSync(projectRoot).isDirectory()) {
57
+ process.stderr.write(`triage:welcome: --project-root ${projectRoot} is not a directory.\n`);
58
+ return 2;
59
+ }
60
+ }
61
+ catch {
62
+ process.stderr.write(`triage:welcome: --project-root ${projectRoot} is not a directory.\n`);
63
+ return 2;
64
+ }
65
+ if (args.onboard) {
66
+ process.stderr.write("triage:welcome: --onboard is not implemented in the TypeScript CLI yet.\n");
67
+ return 2;
68
+ }
69
+ const outcome = runDefaultMode(projectRoot, {
70
+ writeHistory: !args.noHistory,
71
+ taskPrefix: args.taskPrefix || null,
72
+ });
73
+ return outcome.exitCode;
74
+ }
75
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
76
+ process.exit(run(process.argv.slice(2)));
77
+ }
78
+ //# sourceMappingURL=triage-welcome.js.map
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ projectRoot?: string;
4
+ error?: string;
5
+ }
6
+ export declare function parseArgs(argv: string[]): ParsedArgs;
7
+ export declare function run(argv: string[]): number;
8
+ export {};
9
+ //# sourceMappingURL=ts-check-lane.d.ts.map
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ts-check-lane.ts -- CLI for the Node-toolchain-aware TS lane (#1530, #1790).
4
+ *
5
+ * Usage:
6
+ * deft-ts ts-check-lane --project-root <path>
7
+ *
8
+ * Thin shim -- delegates to @deftai/directive-core/ts-check-lane.
9
+ */
10
+ import { fileURLToPath } from "node:url";
11
+ import { resolvePnpm, runTsLane } from "@deftai/directive-core/ts-check-lane";
12
+ export function parseArgs(argv) {
13
+ const parsed = {};
14
+ for (let i = 0; i < argv.length; i++) {
15
+ const arg = argv[i] ?? "";
16
+ if (arg === "--project-root") {
17
+ const next = argv[i + 1];
18
+ if (next === undefined)
19
+ return { ...parsed, error: "argument --project-root: expected one argument" };
20
+ parsed.projectRoot = next;
21
+ i++;
22
+ }
23
+ else if (arg.startsWith("--project-root=")) {
24
+ const value = arg.slice("--project-root=".length);
25
+ if (value === "")
26
+ return { ...parsed, error: "argument --project-root: expected one argument" };
27
+ parsed.projectRoot = value;
28
+ }
29
+ else {
30
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
31
+ }
32
+ }
33
+ return parsed;
34
+ }
35
+ export function run(argv) {
36
+ const args = parseArgs(argv);
37
+ if (args.error !== undefined) {
38
+ process.stderr.write(`ts-check-lane: ${args.error}\n`);
39
+ return 2;
40
+ }
41
+ const projectRoot = args.projectRoot ?? ".";
42
+ return runTsLane(projectRoot, { pnpm: resolvePnpm() });
43
+ }
44
+ /* v8 ignore start -- entry guard */
45
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
46
+ process.exit(run(process.argv.slice(2)));
47
+ }
48
+ /* v8 ignore stop */
49
+ //# sourceMappingURL=ts-check-lane.js.map
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ export declare function normalizeOutput(text: string): string;
3
+ export interface CommandCapture {
4
+ readonly exitCode: number;
5
+ readonly stdout: string;
6
+ readonly stderr: string;
7
+ }
8
+ export interface ParityCase {
9
+ readonly gate: "validate-links" | "validate-strategy-output" | "verify-capacity";
10
+ readonly name: string;
11
+ readonly setup: (root: string) => void;
12
+ readonly argv?: string[];
13
+ readonly env?: Record<string, string>;
14
+ readonly now?: string;
15
+ }
16
+ export interface ParityDiff {
17
+ readonly gate: string;
18
+ readonly caseName: string;
19
+ readonly exitMismatch: boolean;
20
+ readonly stdoutMismatch: boolean;
21
+ readonly stderrMismatch: boolean;
22
+ readonly pythonExit: number;
23
+ readonly tsExit: number;
24
+ }
25
+ export interface ParityResult {
26
+ readonly ok: boolean;
27
+ readonly diffs: ParityDiff[];
28
+ }
29
+ export declare const PARITY_CASES: readonly ParityCase[];
30
+ export declare function diffCase(python: CommandCapture, ts: CommandCapture, gate: string, caseName: string): ParityDiff;
31
+ export declare function runParity(): ParityResult;
32
+ export declare function renderReport(result: ParityResult): string;
33
+ //# sourceMappingURL=validate-content-parity.d.ts.map
@@ -0,0 +1,356 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Golden-output parity harness (#1783 s3): runs BOTH the Python oracles
4
+ * (`validate-links.py`, `validate_strategy_output.py`, `verify_capacity.py`)
5
+ * and the ported TS validate-content gates over shared fixtures, then diffs
6
+ * exit codes + stdout/stderr (cache-off).
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
+ import { validateLinks, validateStrategyOutput, verifyCapacity, } from "@deftai/directive-core/validate-content";
16
+ export function normalizeOutput(text) {
17
+ return text.replace(/verify_capacity: --project-root is not a directory: [^\n]+/g, "verify_capacity: --project-root is not a directory: <ROOT>");
18
+ }
19
+ const NOW_ISO = "2026-06-04T12:00:00Z";
20
+ function runPythonGate(deftRoot, gate, repo, argv, env) {
21
+ const scriptsDir = join(deftRoot, "scripts").replace(/\\/g, "/");
22
+ const repoPath = repo.replace(/\\/g, "/");
23
+ let code;
24
+ if (gate === "validate-links") {
25
+ const strict = argv.includes("--strict") || env.LINK_CHECK_STRICT === "1";
26
+ code = [
27
+ "import sys,os,importlib.util",
28
+ `sys.path.insert(0, ${JSON.stringify(scriptsDir)})`,
29
+ `os.chdir(${JSON.stringify(repoPath)})`,
30
+ strict ? "os.environ['LINK_CHECK_STRICT']='1'" : "os.environ.pop('LINK_CHECK_STRICT', None)",
31
+ `spec=importlib.util.spec_from_file_location('validate_links', ${JSON.stringify(join(deftRoot, "scripts", "validate-links.py"))})`,
32
+ "mod=importlib.util.module_from_spec(spec); spec.loader.exec_module(mod)",
33
+ `sys.argv = ['validate-links.py'] + ${JSON.stringify(argv)}`,
34
+ "raise SystemExit(mod.main())",
35
+ ].join(";");
36
+ }
37
+ else if (gate === "validate-strategy-output") {
38
+ code = [
39
+ "import sys",
40
+ `sys.path.insert(0, ${JSON.stringify(scriptsDir)})`,
41
+ "from validate_strategy_output import main as m",
42
+ `raise SystemExit(m([${["--project-root", repoPath, ...argv].map((a) => JSON.stringify(a)).join(",")}]))`,
43
+ ].join(";");
44
+ }
45
+ else {
46
+ code = [
47
+ "import sys",
48
+ "from datetime import datetime",
49
+ "from pathlib import Path",
50
+ `sys.path.insert(0, ${JSON.stringify(scriptsDir)})`,
51
+ "from verify_capacity import evaluate as ev",
52
+ `root = Path(${JSON.stringify(repoPath)})`,
53
+ `now = datetime.fromisoformat(${JSON.stringify(NOW_ISO)}.replace("Z", "+00:00"))`,
54
+ "code, msg = ev(root, now=now)",
55
+ "stream = sys.stdout if code == 0 else sys.stderr",
56
+ "stream.write(msg)",
57
+ 'if not msg.endswith("\\n"):',
58
+ ' stream.write("\\n")',
59
+ "raise SystemExit(code)",
60
+ ].join("\n");
61
+ }
62
+ try {
63
+ const stdout = execFileSync("uv", ["run", "python", "-c", code], {
64
+ cwd: deftRoot,
65
+ encoding: "utf8",
66
+ env: { ...process.env, ...env, DEFT_CACHE_DISABLE: "1", PYTHONUTF8: "1" },
67
+ stdio: ["ignore", "pipe", "pipe"],
68
+ });
69
+ return { exitCode: 0, stdout: typeof stdout === "string" ? stdout : "", stderr: "" };
70
+ }
71
+ catch (err) {
72
+ const e = err;
73
+ return {
74
+ exitCode: e.status ?? 2,
75
+ stdout: typeof e.stdout === "string" ? e.stdout : "",
76
+ stderr: typeof e.stderr === "string" ? e.stderr : "",
77
+ };
78
+ }
79
+ }
80
+ function runTsGate(gate, repo, testCase) {
81
+ const argv = testCase.argv ?? [];
82
+ const env = testCase.env ?? {};
83
+ const now = testCase.now ? new Date(testCase.now) : new Date(NOW_ISO);
84
+ let result;
85
+ if (gate === "validate-links") {
86
+ result = validateLinks.evaluate({
87
+ cwd: repo,
88
+ argv,
89
+ linkCheckStrict: env.LINK_CHECK_STRICT === "1",
90
+ strict: argv.includes("--strict"),
91
+ });
92
+ }
93
+ else if (gate === "validate-strategy-output") {
94
+ result = validateStrategyOutput.evaluate({
95
+ projectRoot: repo,
96
+ strict: argv.includes("--strict"),
97
+ quiet: argv.includes("--quiet"),
98
+ });
99
+ }
100
+ else {
101
+ result = verifyCapacity.evaluate({ projectRoot: repo, now });
102
+ }
103
+ const stream = result.stream;
104
+ return {
105
+ exitCode: result.code,
106
+ stdout: stream === "stdout" ? `${result.message}\n` : "",
107
+ stderr: stream === "stderr" ? `${result.message}\n` : "",
108
+ };
109
+ }
110
+ function writeJson(path, data) {
111
+ writeFileSync(path, `${JSON.stringify(data)}\n`, { encoding: "utf8" });
112
+ }
113
+ function makeLifecycle(root) {
114
+ for (const folder of ["proposed", "pending", "active", "completed", "cancelled"]) {
115
+ mkdirSync(join(root, "vbrief", folder), { recursive: true });
116
+ }
117
+ }
118
+ export const PARITY_CASES = [
119
+ {
120
+ gate: "validate-links",
121
+ name: "links-clean",
122
+ setup: (root) => {
123
+ writeFileSync(join(root, "README.md"), "See [guide](guide.md)\n", { encoding: "utf8" });
124
+ writeFileSync(join(root, "guide.md"), "# Guide\n", { encoding: "utf8" });
125
+ },
126
+ },
127
+ {
128
+ gate: "validate-links",
129
+ name: "links-broken-warning",
130
+ setup: (root) => {
131
+ writeFileSync(join(root, "README.md"), "See [missing](nope.md)\n", { encoding: "utf8" });
132
+ },
133
+ env: { LINK_CHECK_STRICT: "" },
134
+ },
135
+ {
136
+ gate: "validate-links",
137
+ name: "links-broken-strict",
138
+ setup: (root) => {
139
+ writeFileSync(join(root, "doc.md"), "See [nope](nope.md).\n", { encoding: "utf8" });
140
+ },
141
+ argv: ["--strict"],
142
+ },
143
+ {
144
+ gate: "validate-strategy-output",
145
+ name: "strategy-conformant",
146
+ setup: (root) => {
147
+ mkdirSync(join(root, "vbrief", "proposed"), { recursive: true });
148
+ writeFileSync(join(root, "vbrief", "PROJECT-DEFINITION.vbrief.json"), "{}", {
149
+ encoding: "utf8",
150
+ });
151
+ writeFileSync(join(root, "vbrief", "proposed", "2026-05-26-good.vbrief.json"), "{}", {
152
+ encoding: "utf8",
153
+ });
154
+ },
155
+ },
156
+ {
157
+ gate: "validate-strategy-output",
158
+ name: "strategy-missing-projdef",
159
+ setup: (root) => {
160
+ mkdirSync(join(root, "vbrief", "proposed"), { recursive: true });
161
+ writeFileSync(join(root, "vbrief", "proposed", "2026-05-26-good.vbrief.json"), "{}", {
162
+ encoding: "utf8",
163
+ });
164
+ },
165
+ },
166
+ {
167
+ gate: "validate-strategy-output",
168
+ name: "strategy-strict-missing-vbrief",
169
+ setup: () => {
170
+ /* empty root */
171
+ },
172
+ argv: ["--strict"],
173
+ },
174
+ {
175
+ gate: "verify-capacity",
176
+ name: "capacity-unconfigured",
177
+ setup: (root) => {
178
+ makeLifecycle(root);
179
+ writeJson(join(root, "vbrief", "PROJECT-DEFINITION.vbrief.json"), {
180
+ vBRIEFInfo: { version: "0.6" },
181
+ plan: { title: "T", status: "running", items: [] },
182
+ });
183
+ },
184
+ },
185
+ {
186
+ gate: "verify-capacity",
187
+ name: "capacity-advise-posture",
188
+ setup: (root) => {
189
+ makeLifecycle(root);
190
+ writeJson(join(root, "vbrief", "PROJECT-DEFINITION.vbrief.json"), {
191
+ vBRIEFInfo: { version: "0.6" },
192
+ plan: {
193
+ title: "T",
194
+ status: "running",
195
+ items: [],
196
+ policy: {
197
+ capacityAllocation: {
198
+ unit: "vbrief-count",
199
+ window: 30,
200
+ enforcement: "advise",
201
+ minSampleSize: 2,
202
+ defaultBucket: "feature",
203
+ buckets: [
204
+ { id: "debt", target: 0.4 },
205
+ { id: "feature", target: 0.6 },
206
+ ],
207
+ },
208
+ },
209
+ },
210
+ });
211
+ const completedAt = "2026-06-03T12:00:00Z";
212
+ for (let i = 0; i < 4; i += 1) {
213
+ writeJson(join(root, "vbrief", "completed", `feat-${i}.vbrief.json`), {
214
+ vBRIEFInfo: { version: "0.6" },
215
+ plan: {
216
+ title: `feat-${i}`,
217
+ status: "completed",
218
+ items: [],
219
+ metadata: { capacityBucket: "feature", completedAt },
220
+ },
221
+ });
222
+ }
223
+ },
224
+ },
225
+ {
226
+ gate: "verify-capacity",
227
+ name: "capacity-enforce-deficit",
228
+ setup: (root) => {
229
+ makeLifecycle(root);
230
+ writeJson(join(root, "vbrief", "PROJECT-DEFINITION.vbrief.json"), {
231
+ vBRIEFInfo: { version: "0.6" },
232
+ plan: {
233
+ title: "T",
234
+ status: "running",
235
+ items: [],
236
+ policy: {
237
+ capacityAllocation: {
238
+ unit: "vbrief-count",
239
+ window: 30,
240
+ enforcement: "enforce",
241
+ minSampleSize: 2,
242
+ defaultBucket: "feature",
243
+ buckets: [
244
+ { id: "debt", target: 0.4 },
245
+ { id: "feature", target: 0.6 },
246
+ ],
247
+ },
248
+ },
249
+ },
250
+ });
251
+ const completedAt = "2026-06-03T12:00:00Z";
252
+ for (let i = 0; i < 4; i += 1) {
253
+ writeJson(join(root, "vbrief", "completed", `feat-${i}.vbrief.json`), {
254
+ vBRIEFInfo: { version: "0.6" },
255
+ plan: {
256
+ title: `feat-${i}`,
257
+ status: "completed",
258
+ items: [],
259
+ metadata: { capacityBucket: "feature", completedAt },
260
+ },
261
+ });
262
+ }
263
+ },
264
+ },
265
+ {
266
+ gate: "verify-capacity",
267
+ name: "capacity-config-error",
268
+ setup: (root) => {
269
+ writeFileSync(join(root, "not-a-dir.txt"), "x", { encoding: "utf8" });
270
+ },
271
+ },
272
+ ];
273
+ export function diffCase(python, ts, gate, caseName) {
274
+ const pyOut = normalizeOutput(python.stdout);
275
+ const tsOut = normalizeOutput(ts.stdout);
276
+ const pyErr = normalizeOutput(python.stderr);
277
+ const tsErr = normalizeOutput(ts.stderr);
278
+ return {
279
+ gate,
280
+ caseName,
281
+ exitMismatch: python.exitCode !== ts.exitCode,
282
+ stdoutMismatch: pyOut !== tsOut,
283
+ stderrMismatch: pyErr !== tsErr,
284
+ pythonExit: python.exitCode,
285
+ tsExit: ts.exitCode,
286
+ };
287
+ }
288
+ function resolveDeftRoot() {
289
+ if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
290
+ return resolve(process.env.DEFT_ROOT);
291
+ }
292
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
293
+ }
294
+ export function runParity() {
295
+ const deftRoot = resolveDeftRoot();
296
+ const diffs = [];
297
+ for (const testCase of PARITY_CASES) {
298
+ const pyRepo = mkdtempSync(join(tmpdir(), "deft-vc-parity-py-"));
299
+ const tsRepo = mkdtempSync(join(tmpdir(), "deft-vc-parity-ts-"));
300
+ try {
301
+ testCase.setup(pyRepo);
302
+ testCase.setup(tsRepo);
303
+ const argv = testCase.argv ?? [];
304
+ const env = testCase.env ?? {};
305
+ const configErrorRoot = testCase.name === "capacity-config-error" ? join(pyRepo, "not-a-dir.txt") : pyRepo;
306
+ const tsConfigRoot = testCase.name === "capacity-config-error" ? join(tsRepo, "not-a-dir.txt") : tsRepo;
307
+ const python = testCase.gate === "verify-capacity" && testCase.name === "capacity-config-error"
308
+ ? runPythonGate(deftRoot, testCase.gate, configErrorRoot, argv, env)
309
+ : runPythonGate(deftRoot, testCase.gate, pyRepo, argv, env);
310
+ const ts = testCase.gate === "verify-capacity" && testCase.name === "capacity-config-error"
311
+ ? runTsGate(testCase.gate, tsConfigRoot, testCase)
312
+ : runTsGate(testCase.gate, tsRepo, testCase);
313
+ diffs.push(diffCase(python, ts, testCase.gate, testCase.name));
314
+ }
315
+ finally {
316
+ rmSync(pyRepo, { recursive: true, force: true });
317
+ rmSync(tsRepo, { recursive: true, force: true });
318
+ }
319
+ }
320
+ const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
321
+ return { ok, diffs };
322
+ }
323
+ export function renderReport(result) {
324
+ if (result.ok) {
325
+ return `validate-content parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
326
+ }
327
+ const lines = ["validate-content parity: DIVERGENCE"];
328
+ for (const d of result.diffs) {
329
+ if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
330
+ lines.push(` gate: ${d.gate} case: ${d.caseName}`);
331
+ if (d.exitMismatch)
332
+ lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
333
+ if (d.stdoutMismatch)
334
+ lines.push(" stdout mismatch");
335
+ if (d.stderrMismatch)
336
+ lines.push(" stderr mismatch");
337
+ }
338
+ }
339
+ return lines.join("\n");
340
+ }
341
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
342
+ try {
343
+ const result = runParity();
344
+ if (result.ok) {
345
+ process.stdout.write(`${renderReport(result)}\n`);
346
+ process.exit(0);
347
+ }
348
+ process.stderr.write(`${renderReport(result)}\n`);
349
+ process.exit(1);
350
+ }
351
+ catch (err) {
352
+ process.stderr.write(`validate-content parity: harness error -- ${String(err)}\n`);
353
+ process.exit(2);
354
+ }
355
+ }
356
+ //# sourceMappingURL=validate-content-parity.js.map
@@ -0,0 +1,39 @@
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 folder: string;
10
+ readonly status: string;
11
+ readonly mutates?: boolean;
12
+ readonly rawOverride?: string;
13
+ readonly payloadOverride?: Record<string, unknown>;
14
+ readonly preSeedActive?: boolean;
15
+ readonly missingPath?: boolean;
16
+ }
17
+ export interface ParityDiff {
18
+ readonly caseName: string;
19
+ readonly exitMismatch: boolean;
20
+ readonly stdoutMismatch: boolean;
21
+ readonly stderrMismatch: boolean;
22
+ readonly sideEffectMismatch: boolean;
23
+ readonly pythonExit: number;
24
+ readonly tsExit: number;
25
+ readonly pythonStdout: string;
26
+ readonly pythonStderr: string;
27
+ readonly tsStdout: string;
28
+ readonly tsStderr: string;
29
+ }
30
+ export interface ParityResult {
31
+ readonly ok: boolean;
32
+ readonly diffs: ParityDiff[];
33
+ }
34
+ export declare const PARITY_CASES: readonly ParityCase[];
35
+ export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string, sideEffectMismatch: boolean): ParityDiff;
36
+ export declare function runParity(): ParityResult;
37
+ export declare function renderReport(result: ParityResult): string;
38
+ export declare function runParityCli(): number;
39
+ //# sourceMappingURL=vbrief-activate-parity.d.ts.map