@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,138 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { evaluate, gitPorcelain, parseAllocationSection } from "@deftai/directive-core/story-ready";
6
+ /** Parse verify-story-ready CLI args, mirroring the Python argparse surface. */
7
+ export function parseArgs(argv) {
8
+ const parsed = {
9
+ vbriefPath: null,
10
+ projectRoot: ".",
11
+ allocationContext: null,
12
+ allowDirty: false,
13
+ emitJson: false,
14
+ };
15
+ for (let i = 0; i < argv.length; i += 1) {
16
+ const arg = argv[i];
17
+ if (arg === "--allow-dirty") {
18
+ parsed.allowDirty = true;
19
+ }
20
+ else if (arg === "--json") {
21
+ parsed.emitJson = true;
22
+ }
23
+ else if (arg === "--vbrief-path") {
24
+ const value = argv[i + 1];
25
+ if (value === undefined) {
26
+ return { ...parsed, error: "argument --vbrief-path: expected one argument" };
27
+ }
28
+ parsed.vbriefPath = value;
29
+ i += 1;
30
+ }
31
+ else if (arg?.startsWith("--vbrief-path=")) {
32
+ parsed.vbriefPath = arg.slice("--vbrief-path=".length);
33
+ }
34
+ else if (arg === "--project-root") {
35
+ const value = argv[i + 1];
36
+ if (value === undefined) {
37
+ return { ...parsed, error: "argument --project-root: expected one argument" };
38
+ }
39
+ parsed.projectRoot = value;
40
+ i += 1;
41
+ }
42
+ else if (arg?.startsWith("--project-root=")) {
43
+ parsed.projectRoot = arg.slice("--project-root=".length);
44
+ }
45
+ else if (arg === "--allocation-context") {
46
+ const value = argv[i + 1];
47
+ if (value === undefined) {
48
+ return { ...parsed, error: "argument --allocation-context: expected one argument" };
49
+ }
50
+ parsed.allocationContext = value;
51
+ i += 1;
52
+ }
53
+ else if (arg?.startsWith("--allocation-context=")) {
54
+ parsed.allocationContext = arg.slice("--allocation-context=".length);
55
+ }
56
+ else if (arg === "--help" || arg === "-h") {
57
+ return { ...parsed, help: true };
58
+ }
59
+ else {
60
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
61
+ }
62
+ }
63
+ if (parsed.vbriefPath === null) {
64
+ return { ...parsed, error: "argument --vbrief-path is required" };
65
+ }
66
+ return parsed;
67
+ }
68
+ const HELP_TEXT = `usage: verify-story-ready [--vbrief-path PATH] [--project-root PATH]
69
+ [--allocation-context PATH] [--allow-dirty] [--json]
70
+
71
+ Deterministic story-start Gate 0 (#1378). Three-state exit: 0 ready / 1 not ready / 2 config error.
72
+ `;
73
+ function emitJson(vbriefPath, exitCode, message, dispatchKind) {
74
+ const payload = {
75
+ dispatch_kind: dispatchKind,
76
+ exit_code: exitCode,
77
+ message,
78
+ ready: exitCode === 0,
79
+ vbrief_path: vbriefPath,
80
+ };
81
+ const sorted = Object.fromEntries(Object.keys(payload)
82
+ .sort()
83
+ .map((k) => [k, payload[k]]));
84
+ return JSON.stringify(sorted);
85
+ }
86
+ /** Run the gate and return the process exit code. */
87
+ export function run(argv) {
88
+ const args = parseArgs(argv);
89
+ if (args.help) {
90
+ process.stdout.write(HELP_TEXT);
91
+ return 0;
92
+ }
93
+ if (args.error !== undefined) {
94
+ process.stderr.write(`verify_story_ready: ${args.error}\n`);
95
+ return 2;
96
+ }
97
+ const vbriefPath = resolve(args.vbriefPath);
98
+ const projectRoot = resolve(args.projectRoot);
99
+ let allocationContextText = null;
100
+ if (args.allocationContext !== null) {
101
+ const envelopePath = resolve(args.allocationContext);
102
+ try {
103
+ allocationContextText = readFileSync(envelopePath, "utf8");
104
+ }
105
+ catch (err) {
106
+ const message = `config error: could not read --allocation-context file ${envelopePath}: ${String(err.message ?? err)}.`;
107
+ if (args.emitJson) {
108
+ process.stdout.write(`${emitJson(vbriefPath, 2, message, null)}\n`);
109
+ }
110
+ else {
111
+ process.stderr.write(`${message}\n`);
112
+ }
113
+ return 2;
114
+ }
115
+ }
116
+ const gitStatus = gitPorcelain(projectRoot);
117
+ const parsed = parseAllocationSection(allocationContextText);
118
+ const result = evaluate(vbriefPath, {
119
+ gitStatus,
120
+ allocationContext: allocationContextText,
121
+ allowDirty: args.allowDirty,
122
+ parsed,
123
+ });
124
+ if (args.emitJson) {
125
+ process.stdout.write(`${emitJson(vbriefPath, result.exitCode, result.message, result.dispatchKind)}\n`);
126
+ }
127
+ else if (result.exitCode === 0) {
128
+ process.stdout.write(`${result.message}\n`);
129
+ }
130
+ else {
131
+ process.stderr.write(`${result.message}\n`);
132
+ }
133
+ return result.exitCode;
134
+ }
135
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
136
+ process.exit(run(process.argv.slice(2)));
137
+ }
138
+ //# sourceMappingURL=verify-story-ready.js.map
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ install: boolean;
4
+ yes: boolean;
5
+ emitJson: boolean;
6
+ includeTask: boolean;
7
+ platform: string | undefined;
8
+ error?: string;
9
+ }
10
+ export declare function parseArgs(argv: string[]): ParsedArgs;
11
+ export declare function run(argv: string[]): number;
12
+ export {};
13
+ //# sourceMappingURL=verify-tools.d.ts.map
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ import { fileURLToPath } from "node:url";
3
+ import { verificationResultToJson, verifyRequiredTools } from "@deftai/directive-core/verify-env";
4
+ export function parseArgs(argv) {
5
+ const parsed = {
6
+ install: false,
7
+ yes: false,
8
+ emitJson: false,
9
+ includeTask: false,
10
+ platform: undefined,
11
+ };
12
+ for (let i = 0; i < argv.length; i += 1) {
13
+ const arg = argv[i];
14
+ if (arg === "--install")
15
+ parsed.install = true;
16
+ else if (arg === "--yes")
17
+ parsed.yes = true;
18
+ else if (arg === "--json")
19
+ parsed.emitJson = true;
20
+ else if (arg === "--include-task")
21
+ parsed.includeTask = true;
22
+ else if (arg === "--platform") {
23
+ const value = argv[i + 1];
24
+ if (value === undefined)
25
+ return { ...parsed, error: "argument --platform: expected one argument" };
26
+ parsed.platform = value;
27
+ i += 1;
28
+ }
29
+ else if (arg?.startsWith("--platform=")) {
30
+ parsed.platform = arg.slice("--platform=".length);
31
+ }
32
+ else {
33
+ return { ...parsed, error: `unrecognized arguments: ${arg}` };
34
+ }
35
+ }
36
+ return parsed;
37
+ }
38
+ export function run(argv) {
39
+ const args = parseArgs(argv);
40
+ if (args.error !== undefined) {
41
+ process.stderr.write(`verify_tools.py: error: ${args.error}\n`);
42
+ return 2;
43
+ }
44
+ const captured = [];
45
+ const result = verifyRequiredTools({
46
+ install: args.install,
47
+ assumeYes: args.yes,
48
+ includeTask: args.includeTask,
49
+ platformId: args.platform,
50
+ outputFn: (line) => {
51
+ captured.push(line);
52
+ },
53
+ });
54
+ if (args.emitJson) {
55
+ process.stdout.write(`${verificationResultToJson(result)}\n`);
56
+ }
57
+ else {
58
+ for (const line of captured) {
59
+ process.stdout.write(`${line}\n`);
60
+ }
61
+ }
62
+ return result.exitCode;
63
+ }
64
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
65
+ process.exit(run(process.argv.slice(2)));
66
+ }
67
+ //# sourceMappingURL=verify-tools.js.map
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ projectRoot: string;
4
+ allowOverCap: boolean;
5
+ quiet: boolean;
6
+ error?: string;
7
+ }
8
+ /** Parse verify-wip-cap CLI args, mirroring the Python argparse surface. */
9
+ export declare function parseArgs(argv: string[]): ParsedArgs;
10
+ /** Run the gate and return the process exit code. */
11
+ export declare function run(argv: string[]): number;
12
+ export {};
13
+ //# sourceMappingURL=verify-wip-cap.d.ts.map
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { evaluate } from "@deftai/directive-core/wip-cap";
5
+ /** Parse verify-wip-cap CLI args, mirroring the Python argparse surface. */
6
+ export function parseArgs(argv) {
7
+ const parsed = {
8
+ projectRoot: ".",
9
+ allowOverCap: false,
10
+ quiet: false,
11
+ };
12
+ for (let i = 0; i < argv.length; i += 1) {
13
+ const arg = argv[i];
14
+ if (arg === "--allow-over-cap") {
15
+ parsed.allowOverCap = true;
16
+ }
17
+ else if (arg === "--quiet") {
18
+ parsed.quiet = true;
19
+ }
20
+ else if (arg === "--project-root") {
21
+ const value = argv[i + 1];
22
+ if (value === undefined) {
23
+ return { ...parsed, error: "argument --project-root: expected one argument" };
24
+ }
25
+ parsed.projectRoot = value;
26
+ i += 1;
27
+ }
28
+ else if (arg?.startsWith("--project-root=")) {
29
+ parsed.projectRoot = arg.slice("--project-root=".length);
30
+ }
31
+ else {
32
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
33
+ }
34
+ }
35
+ return parsed;
36
+ }
37
+ /** Run the gate and return the process exit code. */
38
+ export function run(argv) {
39
+ const args = parseArgs(argv);
40
+ if (args.error !== undefined) {
41
+ process.stderr.write(`verify_wip_cap: ${args.error}\n`);
42
+ return 2;
43
+ }
44
+ const projectRoot = resolve(args.projectRoot);
45
+ const result = evaluate(projectRoot, {
46
+ allowOverCap: args.allowOverCap,
47
+ quiet: args.quiet,
48
+ });
49
+ if (result.message.length > 0) {
50
+ if (result.stream === "stdout") {
51
+ process.stdout.write(`${result.message}\n`);
52
+ }
53
+ else if (result.stream === "stderr") {
54
+ process.stderr.write(`${result.message}\n`);
55
+ }
56
+ }
57
+ return result.code;
58
+ }
59
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
60
+ process.exit(run(process.argv.slice(2)));
61
+ }
62
+ //# sourceMappingURL=verify-wip-cap.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 WipFixtureOptions {
8
+ readonly plan?: Record<string, unknown>;
9
+ readonly pendingFiles?: number;
10
+ readonly activeFiles?: number;
11
+ }
12
+ export interface ParityCase {
13
+ readonly name: string;
14
+ readonly argv: string[];
15
+ readonly fixture?: WipFixtureOptions;
16
+ }
17
+ export interface ParityDiff {
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
+ /** Strip volatile absolute paths before compare. */
30
+ export declare function normalizeOutput(text: string): string;
31
+ /** Build a throwaway project root with optional PROJECT-DEFINITION and WIP files. */
32
+ export declare function buildFixtureRepo(options?: WipFixtureOptions): string;
33
+ /** Diff one parity case between Python oracle and TS CLI. */
34
+ export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
35
+ export declare const PARITY_CASES: readonly ParityCase[];
36
+ /** Run all parity cases; returns aggregate result. */
37
+ export declare function runParity(): ParityResult;
38
+ export declare function renderReport(result: ParityResult): string;
39
+ //# sourceMappingURL=wip-cap-parity.d.ts.map
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Golden-output parity harness (#1723): builds throwaway fixture repos, runs
4
+ * BOTH the Python oracle (`scripts/preflight_wip_cap.py`) and the ported TS
5
+ * verify:wip-cap gate, and diffs exit codes + stdout/stderr (cache-off).
6
+ *
7
+ * Exit codes: 0 parity / 1 divergence / 2 harness setup error.
8
+ */
9
+ import { spawnSync } from "node:child_process";
10
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { dirname, join, resolve } from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+ /** Strip volatile absolute paths before compare. */
15
+ export function normalizeOutput(text) {
16
+ return text.replace(/project_root=[^\s)]+/g, "project_root=<ROOT>");
17
+ }
18
+ function runCapture(cmd, args, cwd, env = {}) {
19
+ const merged = { ...process.env, ...env };
20
+ for (const key of Object.keys(merged)) {
21
+ if (merged[key] === undefined)
22
+ delete merged[key];
23
+ }
24
+ const result = spawnSync(cmd, args, {
25
+ cwd,
26
+ encoding: "utf8",
27
+ env: merged,
28
+ stdio: ["ignore", "pipe", "pipe"],
29
+ });
30
+ return {
31
+ status: result.status ?? 2,
32
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
33
+ stderr: typeof result.stderr === "string" ? result.stderr : "",
34
+ };
35
+ }
36
+ function writeProjectDefinition(root, plan) {
37
+ const dir = join(root, "vbrief");
38
+ mkdirSync(dir, { recursive: true });
39
+ writeFileSync(join(dir, "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
40
+ vBRIEFInfo: { version: "0.6" },
41
+ plan: { title: "T", status: "running", items: [], ...plan },
42
+ }, null, 2)}\n`, { encoding: "utf8" });
43
+ }
44
+ function writeVbrief(root, folder, name) {
45
+ const dir = join(root, "vbrief", folder);
46
+ mkdirSync(dir, { recursive: true });
47
+ writeFileSync(join(dir, name), `${JSON.stringify({ vBRIEFInfo: { version: "0.6" }, plan: { status: "approved", title: "T", items: [] } })}\n`, { encoding: "utf8" });
48
+ }
49
+ /** Build a throwaway project root with optional PROJECT-DEFINITION and WIP files. */
50
+ export function buildFixtureRepo(options = {}) {
51
+ const root = mkdtempSync(join(tmpdir(), "deft-wip-cap-parity-"));
52
+ mkdirSync(join(root, "vbrief"), { recursive: true });
53
+ if (options.plan !== undefined) {
54
+ writeProjectDefinition(root, options.plan);
55
+ }
56
+ for (let i = 0; i < (options.pendingFiles ?? 0); i += 1) {
57
+ writeVbrief(root, "pending", `pending-${i}.vbrief.json`);
58
+ }
59
+ for (let i = 0; i < (options.activeFiles ?? 0); i += 1) {
60
+ writeVbrief(root, "active", `active-${i}.vbrief.json`);
61
+ }
62
+ return root;
63
+ }
64
+ function resolveDeftRoot() {
65
+ if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
66
+ return resolve(process.env.DEFT_ROOT);
67
+ }
68
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
69
+ }
70
+ function runPythonWipCap(deftRoot, repo, argv) {
71
+ const cap = runCapture("uv", [
72
+ "run",
73
+ "python",
74
+ join(deftRoot, "scripts", "preflight_wip_cap.py"),
75
+ ...argv,
76
+ "--project-root",
77
+ repo,
78
+ ], deftRoot);
79
+ return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
80
+ }
81
+ function runTsWipCap(deftRoot, repo, argv) {
82
+ const cap = runCapture("node", [
83
+ join(deftRoot, "packages", "cli", "dist", "verify-wip-cap.js"),
84
+ ...argv,
85
+ "--project-root",
86
+ repo,
87
+ ], deftRoot);
88
+ return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
89
+ }
90
+ /** Diff one parity case between Python oracle and TS CLI. */
91
+ export function diffCase(python, ts, caseName) {
92
+ const pyOut = normalizeOutput(python.stdout);
93
+ const tsOut = normalizeOutput(ts.stdout);
94
+ const pyErr = normalizeOutput(python.stderr);
95
+ const tsErr = normalizeOutput(ts.stderr);
96
+ return {
97
+ caseName,
98
+ exitMismatch: python.exitCode !== ts.exitCode,
99
+ stdoutMismatch: pyOut !== tsOut,
100
+ stderrMismatch: pyErr !== tsErr,
101
+ pythonExit: python.exitCode,
102
+ tsExit: ts.exitCode,
103
+ };
104
+ }
105
+ export const PARITY_CASES = [
106
+ {
107
+ name: "within-cap-typed-empty",
108
+ argv: [],
109
+ fixture: { plan: { policy: { wipCap: 5 } } },
110
+ },
111
+ {
112
+ name: "within-cap-with-files",
113
+ argv: [],
114
+ fixture: {
115
+ plan: { policy: { wipCap: 5 } },
116
+ pendingFiles: 2,
117
+ activeFiles: 1,
118
+ },
119
+ },
120
+ {
121
+ name: "over-cap-refusal",
122
+ argv: [],
123
+ fixture: {
124
+ plan: { policy: { wipCap: 2 } },
125
+ pendingFiles: 1,
126
+ activeFiles: 1,
127
+ },
128
+ },
129
+ {
130
+ name: "over-cap-allow-flag",
131
+ argv: ["--allow-over-cap"],
132
+ fixture: {
133
+ plan: { policy: { wipCap: 2 } },
134
+ pendingFiles: 2,
135
+ },
136
+ },
137
+ {
138
+ name: "malformed-wipCap",
139
+ argv: [],
140
+ fixture: { plan: { policy: { wipCap: -1 } } },
141
+ },
142
+ {
143
+ name: "within-cap-quiet",
144
+ argv: ["--quiet"],
145
+ fixture: { plan: { policy: { wipCap: 3 } }, pendingFiles: 1 },
146
+ },
147
+ {
148
+ name: "over-cap-allow-quiet",
149
+ argv: ["--allow-over-cap", "--quiet"],
150
+ fixture: {
151
+ plan: { policy: { wipCap: 1 } },
152
+ pendingFiles: 2,
153
+ },
154
+ },
155
+ ];
156
+ /** Run all parity cases; returns aggregate result. */
157
+ export function runParity() {
158
+ const deftRoot = resolveDeftRoot();
159
+ const diffs = [];
160
+ for (const testCase of PARITY_CASES) {
161
+ const pyRepo = buildFixtureRepo(testCase.fixture);
162
+ const tsRepo = buildFixtureRepo(testCase.fixture);
163
+ try {
164
+ const python = runPythonWipCap(deftRoot, pyRepo, testCase.argv);
165
+ const ts = runTsWipCap(deftRoot, tsRepo, testCase.argv);
166
+ diffs.push(diffCase(python, ts, testCase.name));
167
+ }
168
+ finally {
169
+ rmSync(pyRepo, { recursive: true, force: true });
170
+ rmSync(tsRepo, { recursive: true, force: true });
171
+ }
172
+ }
173
+ const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
174
+ return { ok, diffs };
175
+ }
176
+ export function renderReport(result) {
177
+ if (result.ok) {
178
+ return `verify:wip-cap parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
179
+ }
180
+ const lines = ["verify:wip-cap parity: DIVERGENCE"];
181
+ for (const d of result.diffs) {
182
+ if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
183
+ lines.push(` case: ${d.caseName}`);
184
+ if (d.exitMismatch)
185
+ lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
186
+ if (d.stdoutMismatch)
187
+ lines.push(" stdout mismatch");
188
+ if (d.stderrMismatch)
189
+ lines.push(" stderr mismatch");
190
+ }
191
+ }
192
+ return lines.join("\n");
193
+ }
194
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
195
+ try {
196
+ const result = runParity();
197
+ if (result.ok) {
198
+ process.stdout.write(`${renderReport(result)}\n`);
199
+ process.exit(0);
200
+ }
201
+ process.stderr.write(`${renderReport(result)}\n`);
202
+ process.exit(1);
203
+ }
204
+ catch (err) {
205
+ process.stderr.write(`verify:wip-cap parity: harness error -- ${String(err)}\n`);
206
+ process.exit(2);
207
+ }
208
+ }
209
+ //# sourceMappingURL=wip-cap-parity.js.map
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@deftai/directive",
3
+ "version": "0.55.0",
4
+ "description": "Directive CLI — npm install path for the Deft Directive framework.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "directive": "./dist/bin.js",
10
+ "deft": "./dist/bin.js",
11
+ "deft-ts": "./dist/bin.js",
12
+ "deft-verify-encoding": "./dist/verify-encoding.js",
13
+ "deft-encoding-parity": "./dist/parity.js",
14
+ "deft-policy": "./dist/policy.js",
15
+ "deft-policy-parity": "./dist/policy-parity.js",
16
+ "deft-vbrief-preflight": "./dist/vbrief-preflight.js",
17
+ "deft-vbrief-preflight-parity": "./dist/vbrief-preflight-parity.js",
18
+ "deft-verify-story-ready": "./dist/verify-story-ready.js",
19
+ "deft-story-ready-parity": "./dist/story-ready-parity.js",
20
+ "deft-verify-branch": "./dist/verify-branch.js",
21
+ "deft-branch-parity": "./dist/branch-parity.js",
22
+ "deft-verify-wip-cap": "./dist/verify-wip-cap.js",
23
+ "deft-wip-cap-parity": "./dist/wip-cap-parity.js"
24
+ },
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "default": "./dist/index.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist/**/*.js",
33
+ "dist/**/*.d.ts"
34
+ ],
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/deftai/directive.git",
38
+ "directory": "packages/cli"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "dependencies": {
45
+ "@deftai/directive-core": "^0.55.0"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc -b"
49
+ }
50
+ }