@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,4 @@
1
+ #!/usr/bin/env node
2
+ /** Run triage:scope with argv; returns process exit code. */
3
+ export declare function run(argv: string[]): number;
4
+ //# sourceMappingURL=triage-scope.d.ts.map
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Thin CLI entry for triage:scope (#1725).
4
+ * Delegates to the core implementation at packages/core/dist/triage/scope/cli.js.
5
+ */
6
+ import { spawnSync } from "node:child_process";
7
+ import { dirname, join } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ function coreCliPath() {
10
+ return join(dirname(fileURLToPath(import.meta.url)), "../../core/dist/triage/scope/cli.js");
11
+ }
12
+ /** Run triage:scope with argv; returns process exit code. */
13
+ export function run(argv) {
14
+ const result = spawnSync(process.execPath, [coreCliPath(), ...argv], {
15
+ encoding: "utf8",
16
+ stdio: ["ignore", "pipe", "pipe"],
17
+ });
18
+ if (typeof result.stdout === "string" && result.stdout.length > 0) {
19
+ process.stdout.write(result.stdout);
20
+ }
21
+ if (typeof result.stderr === "string" && result.stderr.length > 0) {
22
+ process.stderr.write(result.stderr);
23
+ }
24
+ return result.status ?? 2;
25
+ }
26
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
27
+ process.exit(run(process.argv.slice(2)));
28
+ }
29
+ //# sourceMappingURL=triage-scope.js.map
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function run(argv: string[]): number;
3
+ //# sourceMappingURL=triage-smoketest.d.ts.map
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, statSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { interceptHelp } from "../../core/dist/triage/help/index.js";
6
+ import { DEFAULT_FIXTURE_REL, parseSmoketestArgs, runSmoketest, } from "../../core/dist/triage/smoketest/index.js";
7
+ function resolveDeftRoot() {
8
+ if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
9
+ return resolve(process.env.DEFT_ROOT);
10
+ }
11
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
12
+ }
13
+ export function run(argv) {
14
+ const helpRc = interceptHelp("triage_smoketest", argv);
15
+ if (helpRc !== null) {
16
+ return helpRc;
17
+ }
18
+ const args = parseSmoketestArgs(argv);
19
+ if (args.error !== undefined) {
20
+ process.stderr.write(`${args.error}\n`);
21
+ return 2;
22
+ }
23
+ if (args.showHelp) {
24
+ return 0;
25
+ }
26
+ const deftRoot = resolveDeftRoot();
27
+ const fixtureRoot = resolve(args.fixture !== "" ? args.fixture : join(deftRoot, DEFAULT_FIXTURE_REL));
28
+ if (!existsSync(fixtureRoot) || !statSync(fixtureRoot).isDirectory()) {
29
+ process.stderr.write(`[triage:smoketest] FAIL: fixture root ${fixtureRoot} does not exist ` +
30
+ "or is not a directory.\n");
31
+ return 1;
32
+ }
33
+ return runSmoketest(fixtureRoot, {
34
+ verbose: args.verbose,
35
+ keepTempdir: args.keepTempdir,
36
+ cacheOnly: args.cacheOnly,
37
+ deftRoot,
38
+ });
39
+ }
40
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
41
+ process.exit(run(process.argv.slice(2)));
42
+ }
43
+ //# sourceMappingURL=triage-smoketest.js.map
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ op: string;
4
+ projectRoot: string;
5
+ label: string | null;
6
+ milestone: string | null;
7
+ issue: number | null;
8
+ issueNote: string;
9
+ actor: string | null;
10
+ error?: string;
11
+ }
12
+ export declare function parseArgs(argv: string[]): ParsedArgs;
13
+ export declare function run(argv: string[]): number;
14
+ export {};
15
+ //# sourceMappingURL=triage-subscribe.d.ts.map
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, statSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { interceptHelp } from "../../core/dist/triage/help/index.js";
6
+ import { RECONCILE_HINT, subscribe, unsubscribe } from "../../core/dist/triage/subscribe/index.js";
7
+ export function parseArgs(argv) {
8
+ const parsed = {
9
+ op: "",
10
+ projectRoot: process.env.DEFT_PROJECT_ROOT ?? ".",
11
+ label: null,
12
+ milestone: null,
13
+ issue: null,
14
+ issueNote: "added via task triage:subscribe",
15
+ actor: null,
16
+ };
17
+ const positional = [];
18
+ for (let i = 0; i < argv.length; i += 1) {
19
+ const arg = argv[i];
20
+ if (arg === undefined)
21
+ continue;
22
+ if (arg === "--project-root") {
23
+ const value = argv[i + 1];
24
+ if (value === undefined) {
25
+ return { ...parsed, error: "argument --project-root: expected one argument" };
26
+ }
27
+ parsed.projectRoot = value;
28
+ i += 1;
29
+ }
30
+ else if (arg.startsWith("--project-root=")) {
31
+ parsed.projectRoot = arg.slice("--project-root=".length);
32
+ }
33
+ else if (arg === "--label") {
34
+ const value = argv[i + 1];
35
+ if (value === undefined) {
36
+ return { ...parsed, error: "argument --label: expected one argument" };
37
+ }
38
+ parsed.label = value;
39
+ i += 1;
40
+ }
41
+ else if (arg.startsWith("--label=")) {
42
+ parsed.label = arg.slice("--label=".length);
43
+ }
44
+ else if (arg === "--milestone") {
45
+ const value = argv[i + 1];
46
+ if (value === undefined) {
47
+ return { ...parsed, error: "argument --milestone: expected one argument" };
48
+ }
49
+ parsed.milestone = value;
50
+ i += 1;
51
+ }
52
+ else if (arg.startsWith("--milestone=")) {
53
+ parsed.milestone = arg.slice("--milestone=".length);
54
+ }
55
+ else if (arg === "--issue") {
56
+ const value = argv[i + 1];
57
+ if (value === undefined) {
58
+ return { ...parsed, error: "argument --issue: expected one argument" };
59
+ }
60
+ parsed.issue = Number.parseInt(value, 10);
61
+ i += 1;
62
+ }
63
+ else if (arg.startsWith("--issue=")) {
64
+ parsed.issue = Number.parseInt(arg.slice("--issue=".length), 10);
65
+ }
66
+ else if (arg === "--issue-note") {
67
+ const value = argv[i + 1];
68
+ if (value === undefined) {
69
+ return { ...parsed, error: "argument --issue-note: expected one argument" };
70
+ }
71
+ parsed.issueNote = value;
72
+ i += 1;
73
+ }
74
+ else if (arg.startsWith("--issue-note=")) {
75
+ parsed.issueNote = arg.slice("--issue-note=".length);
76
+ }
77
+ else if (arg === "--actor") {
78
+ const value = argv[i + 1];
79
+ if (value === undefined) {
80
+ return { ...parsed, error: "argument --actor: expected one argument" };
81
+ }
82
+ parsed.actor = value;
83
+ i += 1;
84
+ }
85
+ else if (arg.startsWith("--actor=")) {
86
+ parsed.actor = arg.slice("--actor=".length);
87
+ }
88
+ else if (arg.startsWith("-")) {
89
+ return { ...parsed, error: `unrecognized arguments: ${arg}` };
90
+ }
91
+ else {
92
+ positional.push(arg);
93
+ }
94
+ }
95
+ if (positional.length > 0 && positional[0] !== undefined) {
96
+ parsed.op = positional[0];
97
+ }
98
+ return parsed;
99
+ }
100
+ export function run(argv) {
101
+ const helpRc = interceptHelp("triage_subscribe", argv);
102
+ if (helpRc !== null) {
103
+ return helpRc;
104
+ }
105
+ const args = parseArgs(argv);
106
+ if (args.error !== undefined) {
107
+ process.stderr.write(`${args.error}\n`);
108
+ return 2;
109
+ }
110
+ if (args.op !== "subscribe" && args.op !== "unsubscribe") {
111
+ process.stderr.write("triage:subscribe: first positional arg must be 'subscribe' or " +
112
+ "'unsubscribe'; e.g. task triage:subscribe -- --label=bug\n");
113
+ return 2;
114
+ }
115
+ const projectRoot = resolve(args.projectRoot);
116
+ if (!existsSync(projectRoot) || !statSync(projectRoot).isDirectory()) {
117
+ process.stderr.write(`triage:${args.op}: --project-root ${projectRoot} does not exist ` +
118
+ "or is not a directory.\n");
119
+ return 2;
120
+ }
121
+ const chosen = [args.label, args.milestone, args.issue].filter((v) => v !== null).length;
122
+ if (chosen !== 1) {
123
+ process.stderr.write(`triage:${args.op}: exactly one of --label / --milestone / --issue is required.\n`);
124
+ return 2;
125
+ }
126
+ try {
127
+ const [changed, message] = args.op === "subscribe"
128
+ ? subscribe(projectRoot, {
129
+ label: args.label,
130
+ milestone: args.milestone,
131
+ issue: args.issue,
132
+ issueNote: args.issueNote,
133
+ actor: args.actor,
134
+ })
135
+ : unsubscribe(projectRoot, {
136
+ label: args.label,
137
+ milestone: args.milestone,
138
+ issue: args.issue,
139
+ actor: args.actor,
140
+ });
141
+ if (!changed) {
142
+ process.stderr.write(`triage:${args.op}: ${message} (no-op).\n`);
143
+ return 0;
144
+ }
145
+ process.stdout.write(`triage:${args.op}: ${message}.\n`);
146
+ process.stderr.write(`${RECONCILE_HINT}\n`);
147
+ return 0;
148
+ }
149
+ catch (exc) {
150
+ process.stderr.write(`triage:${args.op}: ${String(exc)}\n`);
151
+ return 1;
152
+ }
153
+ }
154
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
155
+ process.exit(run(process.argv.slice(2)));
156
+ }
157
+ //# sourceMappingURL=triage-subscribe.js.map
@@ -0,0 +1,50 @@
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 SummaryFixtureOptions {
8
+ readonly wipCap?: number;
9
+ readonly triageScope?: Record<string, unknown>[] | null;
10
+ readonly cachedIssues?: ReadonlyArray<{
11
+ repo: string;
12
+ number: number;
13
+ }>;
14
+ readonly auditEntries?: Record<string, unknown>[];
15
+ readonly pendingVbriefs?: number;
16
+ readonly activeVbriefs?: ReadonlyArray<{
17
+ name: string;
18
+ status?: string;
19
+ }>;
20
+ }
21
+ export interface ParityCase {
22
+ readonly name: string;
23
+ readonly argv: string[];
24
+ readonly fixture?: SummaryFixtureOptions;
25
+ }
26
+ export interface ParityDiff {
27
+ readonly caseName: string;
28
+ readonly exitMismatch: boolean;
29
+ readonly stdoutMismatch: boolean;
30
+ readonly stderrMismatch: boolean;
31
+ readonly pythonExit: number;
32
+ readonly tsExit: number;
33
+ readonly pythonStdout: string;
34
+ readonly tsStdout: string;
35
+ }
36
+ export interface ParityResult {
37
+ readonly ok: boolean;
38
+ readonly diffs: ParityDiff[];
39
+ }
40
+ /** Strip volatile fields before compare. */
41
+ export declare function normalizeOutput(text: string): string;
42
+ /** Build a throwaway project root with optional cache / audit / vBRIEF state. */
43
+ export declare function buildFixtureRepo(options?: SummaryFixtureOptions): string;
44
+ /** Diff one parity case between Python oracle and TS CLI. */
45
+ export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
46
+ export declare const PARITY_CASES: readonly ParityCase[];
47
+ /** Run all parity cases; returns aggregate result. */
48
+ export declare function runParity(): ParityResult;
49
+ export declare function renderReport(result: ParityResult): string;
50
+ //# sourceMappingURL=triage-summary-parity.d.ts.map
@@ -0,0 +1,306 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Golden-output parity harness (#1725): builds throwaway fixture repos, runs
4
+ * BOTH the Python oracle (`scripts/triage_summary.py`) and the ported TS
5
+ * triage:summary CLI, and diffs stdout (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 fields before compare. */
15
+ export function normalizeOutput(text) {
16
+ return text
17
+ .replace(/\r\n/g, "\n")
18
+ .replace(/"emitted_at": "[^"]+"/g, '"emitted_at": "<TS>"')
19
+ .trimEnd();
20
+ }
21
+ function runCapture(cmd, args, cwd, env = {}) {
22
+ const merged = { ...process.env, ...env };
23
+ for (const key of Object.keys(merged)) {
24
+ if (merged[key] === undefined)
25
+ delete merged[key];
26
+ }
27
+ const result = spawnSync(cmd, args, {
28
+ cwd,
29
+ encoding: "utf8",
30
+ env: merged,
31
+ stdio: ["ignore", "pipe", "pipe"],
32
+ });
33
+ return {
34
+ status: result.status ?? 2,
35
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
36
+ stderr: typeof result.stderr === "string" ? result.stderr : "",
37
+ };
38
+ }
39
+ function writeProjectDefinition(root, options) {
40
+ const dir = join(root, "vbrief");
41
+ mkdirSync(dir, { recursive: true });
42
+ const policy = {};
43
+ if (options.wipCap !== undefined) {
44
+ policy.wipCap = options.wipCap;
45
+ }
46
+ if (options.triageScope !== undefined && options.triageScope !== null) {
47
+ policy.triageScope = options.triageScope;
48
+ }
49
+ writeFileSync(join(dir, "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
50
+ vBRIEFInfo: { version: "0.6" },
51
+ plan: { title: "T", status: "running", items: [], policy },
52
+ }, null, 2)}\n`, { encoding: "utf8" });
53
+ }
54
+ function makeCachedIssue(cacheRoot, repo, number) {
55
+ const [owner, name] = repo.split("/", 2);
56
+ const entry = join(cacheRoot, "github-issue", owner ?? "", name ?? "", String(number));
57
+ mkdirSync(entry, { recursive: true });
58
+ writeFileSync(join(entry, "meta.json"), "{}\n", { encoding: "utf8" });
59
+ writeFileSync(join(entry, "raw.json"), "{}\n", { encoding: "utf8" });
60
+ }
61
+ function writeAuditLog(root, entries) {
62
+ const logDir = join(root, "vbrief", ".eval");
63
+ mkdirSync(logDir, { recursive: true });
64
+ const lines = entries.map((e) => JSON.stringify(e, Object.keys(e).sort())).join("\n");
65
+ writeFileSync(join(logDir, "candidates.jsonl"), lines.length > 0 ? `${lines}\n` : "", {
66
+ encoding: "utf8",
67
+ });
68
+ }
69
+ function writeActiveVbrief(root, name, status) {
70
+ const dir = join(root, "vbrief", "active");
71
+ mkdirSync(dir, { recursive: true });
72
+ writeFileSync(join(dir, `${name}.vbrief.json`), `${JSON.stringify({
73
+ vBRIEFInfo: { version: "0.6" },
74
+ plan: { status, title: name },
75
+ })}\n`, { encoding: "utf8" });
76
+ }
77
+ function writePendingVbriefs(root, count) {
78
+ const dir = join(root, "vbrief", "pending");
79
+ mkdirSync(dir, { recursive: true });
80
+ for (let i = 0; i < count; i += 1) {
81
+ writeFileSync(join(dir, `pending-${i}.vbrief.json`), `${JSON.stringify({ vBRIEFInfo: { version: "0.6" }, plan: { status: "approved" } })}\n`, { encoding: "utf8" });
82
+ }
83
+ }
84
+ /** Build a throwaway project root with optional cache / audit / vBRIEF state. */
85
+ export function buildFixtureRepo(options = {}) {
86
+ const root = mkdtempSync(join(tmpdir(), "deft-triage-summary-parity-"));
87
+ mkdirSync(join(root, "vbrief"), { recursive: true });
88
+ if (options.wipCap !== undefined || options.triageScope !== undefined) {
89
+ writeProjectDefinition(root, {
90
+ wipCap: options.wipCap,
91
+ triageScope: options.triageScope,
92
+ });
93
+ }
94
+ const cacheRoot = join(root, ".deft-cache");
95
+ for (const issue of options.cachedIssues ?? []) {
96
+ makeCachedIssue(cacheRoot, issue.repo, issue.number);
97
+ }
98
+ if (options.auditEntries !== undefined && options.auditEntries.length > 0) {
99
+ writeAuditLog(root, options.auditEntries);
100
+ }
101
+ if (options.pendingVbriefs !== undefined && options.pendingVbriefs > 0) {
102
+ writePendingVbriefs(root, options.pendingVbriefs);
103
+ }
104
+ for (const vb of options.activeVbriefs ?? []) {
105
+ writeActiveVbrief(root, vb.name, vb.status ?? "running");
106
+ }
107
+ return root;
108
+ }
109
+ function resolveDeftRoot() {
110
+ if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
111
+ return resolve(process.env.DEFT_ROOT);
112
+ }
113
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
114
+ }
115
+ function runPythonSummary(deftRoot, repo, argv) {
116
+ const cap = runCapture("uv", [
117
+ "run",
118
+ "python",
119
+ join(deftRoot, "scripts", "triage_summary.py"),
120
+ ...argv,
121
+ "--project-root",
122
+ repo,
123
+ "--no-history",
124
+ ], deftRoot);
125
+ return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
126
+ }
127
+ function runTsSummary(deftRoot, repo, argv) {
128
+ const cap = runCapture("node", [
129
+ join(deftRoot, "packages", "cli", "dist", "triage-summary.js"),
130
+ ...argv,
131
+ "--project-root",
132
+ repo,
133
+ "--no-history",
134
+ ], deftRoot);
135
+ return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
136
+ }
137
+ /** Diff one parity case between Python oracle and TS CLI. */
138
+ export function diffCase(python, ts, caseName) {
139
+ const pyOut = normalizeOutput(python.stdout);
140
+ const tsOut = normalizeOutput(ts.stdout);
141
+ const pyErr = normalizeOutput(python.stderr);
142
+ const tsErr = normalizeOutput(ts.stderr);
143
+ return {
144
+ caseName,
145
+ exitMismatch: python.exitCode !== ts.exitCode,
146
+ stdoutMismatch: pyOut !== tsOut,
147
+ stderrMismatch: pyErr !== tsErr,
148
+ pythonExit: python.exitCode,
149
+ tsExit: ts.exitCode,
150
+ pythonStdout: pyOut,
151
+ tsStdout: tsOut,
152
+ };
153
+ }
154
+ const auditEntry = (repo, issueNumber, decision, decisionId) => ({
155
+ actor: "agent:test",
156
+ decision,
157
+ decision_id: decisionId,
158
+ issue_number: issueNumber,
159
+ repo,
160
+ timestamp: "2026-05-17T20:00:00Z",
161
+ });
162
+ export const PARITY_CASES = [
163
+ {
164
+ name: "empty-cache",
165
+ argv: [],
166
+ fixture: {},
167
+ },
168
+ {
169
+ name: "populated-zero-wip",
170
+ argv: [],
171
+ fixture: {
172
+ cachedIssues: [
173
+ { repo: "deftai/directive", number: 100 },
174
+ { repo: "deftai/directive", number: 101 },
175
+ { repo: "deftai/directive", number: 102 },
176
+ ],
177
+ auditEntries: [
178
+ auditEntry("deftai/directive", 100, "accept", "11111111-1111-1111-1111-111111111101"),
179
+ auditEntry("deftai/directive", 101, "accept", "11111111-1111-1111-1111-111111111102"),
180
+ ],
181
+ },
182
+ },
183
+ {
184
+ name: "zero-untriaged-still-prints",
185
+ argv: [],
186
+ fixture: {
187
+ cachedIssues: [{ repo: "deftai/directive", number: 200 }],
188
+ auditEntries: [
189
+ auditEntry("deftai/directive", 200, "accept", "22222222-2222-2222-2222-222222222200"),
190
+ ],
191
+ },
192
+ },
193
+ {
194
+ name: "wip-at-cap-warning",
195
+ argv: [],
196
+ fixture: {
197
+ wipCap: 12,
198
+ cachedIssues: [{ repo: "deftai/directive", number: 500 }],
199
+ pendingVbriefs: 12,
200
+ },
201
+ },
202
+ {
203
+ name: "wip-above-cap-warning",
204
+ argv: [],
205
+ fixture: {
206
+ wipCap: 5,
207
+ cachedIssues: [{ repo: "deftai/directive", number: 501 }],
208
+ activeVbriefs: Array.from({ length: 7 }, (_, i) => ({ name: `active-${i}` })),
209
+ },
210
+ },
211
+ {
212
+ name: "filesystem-in-flight-divergence",
213
+ argv: [],
214
+ fixture: {
215
+ cachedIssues: [
216
+ { repo: "deftai/directive", number: 600 },
217
+ { repo: "deftai/directive", number: 601 },
218
+ { repo: "deftai/directive", number: 602 },
219
+ ],
220
+ auditEntries: [
221
+ auditEntry("deftai/directive", 600, "accept", "66666666-6666-6666-6666-666666666600"),
222
+ auditEntry("deftai/directive", 601, "accept", "66666666-6666-6666-6666-666666666601"),
223
+ ],
224
+ activeVbriefs: [{ name: "only-running", status: "running" }],
225
+ },
226
+ },
227
+ {
228
+ name: "configured-scope-divergence",
229
+ argv: [],
230
+ fixture: {
231
+ triageScope: [{ rule: "labels", "any-of": ["phase-1"] }],
232
+ cachedIssues: [{ repo: "deftai/directive", number: 700 }],
233
+ auditEntries: [
234
+ auditEntry("deftai/directive", 700, "accept", "77777777-7777-7777-7777-777777777700"),
235
+ ],
236
+ activeVbriefs: [
237
+ { name: "one-running", status: "running" },
238
+ { name: "two-running", status: "running" },
239
+ ],
240
+ },
241
+ },
242
+ {
243
+ name: "json-mode",
244
+ argv: ["--json"],
245
+ fixture: {
246
+ cachedIssues: [{ repo: "deftai/directive", number: 900 }],
247
+ },
248
+ },
249
+ ];
250
+ /** Run all parity cases; returns aggregate result. */
251
+ export function runParity() {
252
+ const deftRoot = resolveDeftRoot();
253
+ const diffs = [];
254
+ for (const testCase of PARITY_CASES) {
255
+ const pyRepo = buildFixtureRepo(testCase.fixture);
256
+ const tsRepo = buildFixtureRepo(testCase.fixture);
257
+ try {
258
+ const python = runPythonSummary(deftRoot, pyRepo, testCase.argv);
259
+ const ts = runTsSummary(deftRoot, tsRepo, testCase.argv);
260
+ diffs.push(diffCase(python, ts, testCase.name));
261
+ }
262
+ finally {
263
+ rmSync(pyRepo, { recursive: true, force: true });
264
+ rmSync(tsRepo, { recursive: true, force: true });
265
+ }
266
+ }
267
+ const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
268
+ return { ok, diffs };
269
+ }
270
+ export function renderReport(result) {
271
+ if (result.ok) {
272
+ return `triage:summary parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
273
+ }
274
+ const lines = ["triage:summary parity: DIVERGENCE"];
275
+ for (const d of result.diffs) {
276
+ if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
277
+ lines.push(` case: ${d.caseName}`);
278
+ if (d.exitMismatch)
279
+ lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
280
+ if (d.stdoutMismatch) {
281
+ lines.push(` python stdout: ${d.pythonStdout}`);
282
+ lines.push(` ts stdout: ${d.tsStdout}`);
283
+ }
284
+ if (d.stderrMismatch)
285
+ lines.push(" stderr mismatch");
286
+ }
287
+ }
288
+ return lines.join("\n");
289
+ }
290
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
291
+ try {
292
+ const result = runParity();
293
+ if (result.ok) {
294
+ process.stdout.write(`${renderReport(result)}\n`);
295
+ process.exit(0);
296
+ }
297
+ process.stderr.write(`${renderReport(result)}\n`);
298
+ process.exit(1);
299
+ }
300
+ catch (err) {
301
+ const msg = String(err).replace(/\r?\n/g, " ");
302
+ process.stderr.write(`triage:summary parity: harness error -- ${msg}\n`);
303
+ process.exit(2);
304
+ }
305
+ }
306
+ //# sourceMappingURL=triage-summary-parity.js.map
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ projectRoot: string;
4
+ cacheRoot: string | null;
5
+ noHistory: boolean;
6
+ json: boolean;
7
+ error?: string;
8
+ }
9
+ /** Parse triage-summary CLI args, mirroring the Python argparse surface. */
10
+ export declare function parseArgs(argv: string[]): ParsedArgs;
11
+ /** Run the triage:summary CLI — always returns exit code 0. */
12
+ export declare function run(argv: string[]): number;
13
+ export {};
14
+ //# sourceMappingURL=triage-summary.d.ts.map