@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,174 @@
1
+ #!/usr/bin/env node
2
+ import { dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { activeReferencedIssueNumbers, buildQueue, collectOrphanIssueNumbers, DEFAULT_QUEUE_LIMIT, loadCachedIssues, loadSliceRecords, readAuditEntries, renderQueue, resolveRankingLabels, resolveRepo, } from "../../core/dist/triage/queue/index.js";
5
+ /** Parse triage-queue CLI args for the queue subcommand. */
6
+ export function parseArgs(argv) {
7
+ const parsed = {
8
+ projectRoot: process.env.DEFT_PROJECT_ROOT ?? ".",
9
+ repo: process.env.DEFT_TRIAGE_REPO ?? null,
10
+ limit: DEFAULT_QUEUE_LIMIT,
11
+ includeBlocked: false,
12
+ cacheRoot: null,
13
+ auditLog: null,
14
+ slicesLog: null,
15
+ };
16
+ for (let i = 0; i < argv.length; i += 1) {
17
+ const arg = argv[i];
18
+ if (arg === "queue") {
19
+ continue;
20
+ }
21
+ if (arg === "--include-blocked") {
22
+ parsed.includeBlocked = true;
23
+ continue;
24
+ }
25
+ if (arg === "--project-root") {
26
+ const value = argv[i + 1];
27
+ if (value === undefined) {
28
+ return { ...parsed, error: "argument --project-root: expected one argument" };
29
+ }
30
+ parsed.projectRoot = value;
31
+ i += 1;
32
+ continue;
33
+ }
34
+ if (arg?.startsWith("--project-root=")) {
35
+ parsed.projectRoot = arg.slice("--project-root=".length);
36
+ continue;
37
+ }
38
+ if (arg === "--repo") {
39
+ const value = argv[i + 1];
40
+ if (value === undefined) {
41
+ return { ...parsed, error: "argument --repo: expected one argument" };
42
+ }
43
+ parsed.repo = value;
44
+ i += 1;
45
+ continue;
46
+ }
47
+ if (arg?.startsWith("--repo=")) {
48
+ parsed.repo = arg.slice("--repo=".length);
49
+ continue;
50
+ }
51
+ if (arg === "--limit") {
52
+ const value = argv[i + 1];
53
+ if (value === undefined) {
54
+ return { ...parsed, error: "argument --limit: expected one argument" };
55
+ }
56
+ const parsedLimit = Number.parseInt(value, 10);
57
+ if (!Number.isFinite(parsedLimit)) {
58
+ return { ...parsed, error: `argument --limit: invalid int value: '${value}'` };
59
+ }
60
+ parsed.limit = parsedLimit;
61
+ i += 1;
62
+ continue;
63
+ }
64
+ if (arg?.startsWith("--limit=")) {
65
+ const value = arg.slice("--limit=".length);
66
+ const parsedLimit = Number.parseInt(value, 10);
67
+ if (!Number.isFinite(parsedLimit)) {
68
+ return { ...parsed, error: `argument --limit: invalid int value: '${value}'` };
69
+ }
70
+ parsed.limit = parsedLimit;
71
+ continue;
72
+ }
73
+ if (arg === "--cache-root") {
74
+ const value = argv[i + 1];
75
+ if (value === undefined) {
76
+ return { ...parsed, error: "argument --cache-root: expected one argument" };
77
+ }
78
+ parsed.cacheRoot = value;
79
+ i += 1;
80
+ continue;
81
+ }
82
+ if (arg?.startsWith("--cache-root=")) {
83
+ parsed.cacheRoot = arg.slice("--cache-root=".length);
84
+ continue;
85
+ }
86
+ if (arg === "--audit-log") {
87
+ const value = argv[i + 1];
88
+ if (value === undefined) {
89
+ return { ...parsed, error: "argument --audit-log: expected one argument" };
90
+ }
91
+ parsed.auditLog = value;
92
+ i += 1;
93
+ continue;
94
+ }
95
+ if (arg?.startsWith("--audit-log=")) {
96
+ parsed.auditLog = arg.slice("--audit-log=".length);
97
+ continue;
98
+ }
99
+ if (arg === "--slices-log") {
100
+ const value = argv[i + 1];
101
+ if (value === undefined) {
102
+ return { ...parsed, error: "argument --slices-log: expected one argument" };
103
+ }
104
+ parsed.slicesLog = value;
105
+ i += 1;
106
+ continue;
107
+ }
108
+ if (arg?.startsWith("--slices-log=")) {
109
+ parsed.slicesLog = arg.slice("--slices-log=".length);
110
+ continue;
111
+ }
112
+ if (arg?.startsWith("-")) {
113
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
114
+ }
115
+ }
116
+ return parsed;
117
+ }
118
+ function resolveFrameworkRoot() {
119
+ const fromEnv = process.env.DEFT_ROOT?.trim() ?? "";
120
+ if (fromEnv.length > 0) {
121
+ return resolve(fromEnv);
122
+ }
123
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
124
+ }
125
+ /** Run triage:queue and return process exit code. */
126
+ export function run(argv) {
127
+ const args = parseArgs(argv);
128
+ if (args.error !== undefined) {
129
+ process.stderr.write(`triage_queue: ${args.error}\n`);
130
+ return 2;
131
+ }
132
+ const projectRoot = resolve(args.projectRoot);
133
+ const repo = resolveRepo(args.repo, projectRoot);
134
+ if (repo === null) {
135
+ process.stderr.write("triage:queue: --repo OWNER/NAME (or $DEFT_TRIAGE_REPO) is required.\n");
136
+ return 2;
137
+ }
138
+ const issuesForQueue = loadCachedIssues(repo, { projectRoot });
139
+ const issuesWithClosed = loadCachedIssues(repo, { projectRoot, includeClosed: true });
140
+ const issuesByNumber = new Map(issuesWithClosed.map((row) => [row.number, row]));
141
+ const auditEntries = readAuditEntries(repo, {
142
+ frameworkRoot: resolveFrameworkRoot(),
143
+ auditLogPath: args.auditLog,
144
+ });
145
+ const rankingLabels = resolveRankingLabels(projectRoot);
146
+ const activeRefs = activeReferencedIssueNumbers(projectRoot);
147
+ const sliceRecords = loadSliceRecords({
148
+ frameworkRoot: resolveFrameworkRoot(),
149
+ slicesLogPath: args.slicesLog,
150
+ });
151
+ const orphanNumbers = collectOrphanIssueNumbers(sliceRecords, issuesByNumber);
152
+ const limit = args.limit === 0 ? null : Math.max(0, args.limit);
153
+ const items = buildQueue(issuesForQueue, auditEntries, {
154
+ repo,
155
+ queue: {
156
+ rankingLabels,
157
+ activeReferenced: activeRefs,
158
+ orphanIssueNumbers: orphanNumbers,
159
+ includeBlocked: args.includeBlocked,
160
+ limit,
161
+ },
162
+ });
163
+ process.stdout.write(`${renderQueue({
164
+ items,
165
+ repo,
166
+ limit,
167
+ rankingLabels,
168
+ })}\n`);
169
+ return 0;
170
+ }
171
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
172
+ process.exit(run(process.argv.slice(2)));
173
+ }
174
+ //# sourceMappingURL=triage-queue.js.map
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ export interface ParsedArgs {
3
+ projectRoot: string;
4
+ repo?: string;
5
+ dryRun: boolean;
6
+ emitJson: boolean;
7
+ error?: string;
8
+ }
9
+ export declare function parseArgs(argv: string[]): ParsedArgs;
10
+ export declare function run(argv: string[]): number;
11
+ //# sourceMappingURL=triage-reconcile.d.ts.map
@@ -0,0 +1,76 @@
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 { emitReconcileJson, reconcile, reconcileSummary, } from "../../core/dist/triage/reconcile/index.js";
6
+ export function parseArgs(argv) {
7
+ const parsed = {
8
+ projectRoot: process.env.DEFT_PROJECT_ROOT ?? ".",
9
+ dryRun: false,
10
+ emitJson: false,
11
+ };
12
+ for (let i = 0; i < argv.length; i += 1) {
13
+ const arg = argv[i];
14
+ if (arg === "--dry-run")
15
+ parsed.dryRun = true;
16
+ else if (arg === "--json")
17
+ parsed.emitJson = true;
18
+ else if (arg === "--project-root") {
19
+ const value = argv[i + 1];
20
+ if (value === undefined)
21
+ return { ...parsed, error: "argument --project-root: expected one argument" };
22
+ parsed.projectRoot = value;
23
+ i += 1;
24
+ }
25
+ else if (arg?.startsWith("--project-root=")) {
26
+ parsed.projectRoot = arg.slice("--project-root=".length);
27
+ }
28
+ else if (arg === "--repo") {
29
+ const value = argv[i + 1];
30
+ if (value === undefined)
31
+ return { ...parsed, error: "argument --repo: expected one argument" };
32
+ parsed.repo = value;
33
+ i += 1;
34
+ }
35
+ else if (arg?.startsWith("--repo=")) {
36
+ parsed.repo = arg.slice("--repo=".length);
37
+ }
38
+ else {
39
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
40
+ }
41
+ }
42
+ return parsed;
43
+ }
44
+ export function run(argv) {
45
+ const args = parseArgs(argv);
46
+ if (args.error !== undefined) {
47
+ process.stderr.write(`triage:reconcile: ${args.error}\n`);
48
+ return 2;
49
+ }
50
+ const projectRoot = resolve(args.projectRoot);
51
+ try {
52
+ if (!statSync(projectRoot).isDirectory()) {
53
+ process.stderr.write(`❌ triage:reconcile: --project-root ${projectRoot} does not exist or is not a directory.\n`);
54
+ return 2;
55
+ }
56
+ }
57
+ catch {
58
+ process.stderr.write(`❌ triage:reconcile: --project-root ${projectRoot} does not exist or is not a directory.\n`);
59
+ return 2;
60
+ }
61
+ const result = reconcile(projectRoot, {
62
+ repo: args.repo ?? process.env.DEFT_TRIAGE_REPO ?? null,
63
+ dryRun: args.dryRun,
64
+ });
65
+ if (args.emitJson) {
66
+ process.stdout.write(`${emitReconcileJson(result)}\n`);
67
+ }
68
+ else {
69
+ process.stdout.write(`${reconcileSummary(result)}\n`);
70
+ }
71
+ return result.exitCode;
72
+ }
73
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
74
+ process.exit(run(process.argv.slice(2)));
75
+ }
76
+ //# sourceMappingURL=triage-reconcile.js.map
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ export declare function parseArgs(argv: string[]): {
3
+ projectRoot: string;
4
+ error?: string;
5
+ };
6
+ export declare function run(argv: string[]): number;
7
+ //# sourceMappingURL=triage-refresh.d.ts.map
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { refreshActive } from "../../core/dist/triage/refresh/index.js";
5
+ export function parseArgs(argv) {
6
+ let projectRoot = ".";
7
+ for (let i = 0; i < argv.length; i += 1) {
8
+ const arg = argv[i];
9
+ if (arg === "--project-root") {
10
+ const value = argv[i + 1];
11
+ if (value === undefined)
12
+ return { projectRoot, error: "argument --project-root: expected one argument" };
13
+ projectRoot = value;
14
+ i += 1;
15
+ }
16
+ else if (arg?.startsWith("--project-root=")) {
17
+ projectRoot = arg.slice("--project-root=".length);
18
+ }
19
+ else if (arg !== undefined) {
20
+ return { projectRoot, error: `unrecognized argument: ${arg}` };
21
+ }
22
+ }
23
+ return { projectRoot };
24
+ }
25
+ export function run(argv) {
26
+ const args = parseArgs(argv);
27
+ if (args.error !== undefined) {
28
+ process.stderr.write(`triage:refresh-active: ${args.error}\n`);
29
+ return 2;
30
+ }
31
+ refreshActive(resolve(args.projectRoot));
32
+ return 0;
33
+ }
34
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
35
+ process.exit(run(process.argv.slice(2)));
36
+ }
37
+ //# sourceMappingURL=triage-refresh.js.map
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ export interface ParsedArgs {
3
+ projectRoot: string;
4
+ cacheRoot?: string;
5
+ threshold?: number;
6
+ ignoreLabel?: string;
7
+ ignoreMilestone?: string;
8
+ error?: string;
9
+ }
10
+ export declare function parseArgs(argv: string[]): ParsedArgs;
11
+ export declare function run(argv: string[]): number;
12
+ //# sourceMappingURL=triage-scope-drift.d.ts.map
@@ -0,0 +1,117 @@
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 { addIgnore, computeDrift, renderDriftReport, } from "../../core/dist/triage/scope-drift/index.js";
6
+ export function parseArgs(argv) {
7
+ const parsed = { projectRoot: process.env.DEFT_PROJECT_ROOT ?? "." };
8
+ for (let i = 0; i < argv.length; i += 1) {
9
+ const arg = argv[i];
10
+ if (arg === "--project-root") {
11
+ const value = argv[i + 1];
12
+ if (value === undefined)
13
+ return { ...parsed, error: "argument --project-root: expected one argument" };
14
+ parsed.projectRoot = value;
15
+ i += 1;
16
+ }
17
+ else if (arg?.startsWith("--project-root=")) {
18
+ parsed.projectRoot = arg.slice("--project-root=".length);
19
+ }
20
+ else if (arg === "--cache-root") {
21
+ const value = argv[i + 1];
22
+ if (value === undefined)
23
+ return { ...parsed, error: "argument --cache-root: expected one argument" };
24
+ parsed.cacheRoot = value;
25
+ i += 1;
26
+ }
27
+ else if (arg?.startsWith("--cache-root=")) {
28
+ parsed.cacheRoot = arg.slice("--cache-root=".length);
29
+ }
30
+ else if (arg === "--threshold") {
31
+ const value = argv[i + 1];
32
+ if (value === undefined)
33
+ return { ...parsed, error: "argument --threshold: expected one argument" };
34
+ parsed.threshold = Number(value);
35
+ i += 1;
36
+ }
37
+ else if (arg?.startsWith("--threshold=")) {
38
+ parsed.threshold = Number(arg.slice("--threshold=".length));
39
+ }
40
+ else if (arg === "--ignore-label") {
41
+ const value = argv[i + 1];
42
+ if (value === undefined)
43
+ return { ...parsed, error: "argument --ignore-label: expected one argument" };
44
+ parsed.ignoreLabel = value;
45
+ i += 1;
46
+ }
47
+ else if (arg?.startsWith("--ignore-label=")) {
48
+ parsed.ignoreLabel = arg.slice("--ignore-label=".length);
49
+ }
50
+ else if (arg === "--ignore-milestone") {
51
+ const value = argv[i + 1];
52
+ if (value === undefined)
53
+ return { ...parsed, error: "argument --ignore-milestone: expected one argument" };
54
+ parsed.ignoreMilestone = value;
55
+ i += 1;
56
+ }
57
+ else if (arg?.startsWith("--ignore-milestone=")) {
58
+ parsed.ignoreMilestone = arg.slice("--ignore-milestone=".length);
59
+ }
60
+ else {
61
+ return { ...parsed, error: `unrecognized argument: ${arg}` };
62
+ }
63
+ }
64
+ return parsed;
65
+ }
66
+ export function run(argv) {
67
+ const args = parseArgs(argv);
68
+ if (args.error !== undefined) {
69
+ process.stderr.write(`triage:scope-drift: ${args.error}\n`);
70
+ return 2;
71
+ }
72
+ const projectRoot = resolve(args.projectRoot);
73
+ try {
74
+ if (!statSync(projectRoot).isDirectory()) {
75
+ process.stderr.write(`triage:scope-drift: --project-root ${projectRoot} does not exist or is not a directory.\n`);
76
+ return 2;
77
+ }
78
+ }
79
+ catch {
80
+ process.stderr.write(`triage:scope-drift: --project-root ${projectRoot} does not exist or is not a directory.\n`);
81
+ return 2;
82
+ }
83
+ if (args.ignoreLabel !== undefined && args.ignoreMilestone !== undefined) {
84
+ process.stderr.write("triage:scope-drift: --ignore-label and --ignore-milestone are mutually exclusive (pick one per invocation).\n");
85
+ return 2;
86
+ }
87
+ if (args.ignoreLabel !== undefined || args.ignoreMilestone !== undefined) {
88
+ try {
89
+ const { changed, message } = addIgnore(projectRoot, {
90
+ label: args.ignoreLabel,
91
+ milestone: args.ignoreMilestone,
92
+ });
93
+ if (!changed) {
94
+ process.stderr.write(`triage:scope-drift: ${message} (no-op).\n`);
95
+ }
96
+ else {
97
+ process.stdout.write(`triage:scope-drift: ${message}.\n`);
98
+ process.stderr.write(" Next run of `task triage:scope-drift` will exclude this signal.\n");
99
+ }
100
+ }
101
+ catch (err) {
102
+ process.stderr.write(`triage:scope-drift: ${String(err)}\n`);
103
+ return 1;
104
+ }
105
+ return 0;
106
+ }
107
+ const report = computeDrift(projectRoot, {
108
+ cacheRoot: args.cacheRoot ? resolve(args.cacheRoot) : undefined,
109
+ threshold: args.threshold,
110
+ });
111
+ process.stdout.write(`${renderDriftReport(report)}\n`);
112
+ return 0;
113
+ }
114
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
115
+ process.exit(run(process.argv.slice(2)));
116
+ }
117
+ //# sourceMappingURL=triage-scope-drift.js.map
@@ -0,0 +1,34 @@
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 ScopeFixtureOptions {
8
+ readonly policy?: Record<string, unknown>;
9
+ }
10
+ export interface ParityCase {
11
+ readonly name: string;
12
+ readonly argv: string[];
13
+ readonly fixture?: ScopeFixtureOptions;
14
+ }
15
+ export interface ParityDiff {
16
+ readonly caseName: string;
17
+ readonly exitMismatch: boolean;
18
+ readonly stdoutMismatch: boolean;
19
+ readonly stderrMismatch: boolean;
20
+ readonly pythonExit: number;
21
+ readonly tsExit: number;
22
+ }
23
+ export interface ParityResult {
24
+ readonly ok: boolean;
25
+ readonly diffs: ParityDiff[];
26
+ }
27
+ /** Strip volatile absolute paths before compare. */
28
+ export declare function normalizeOutput(text: string): string;
29
+ export declare function buildFixtureRepo(options?: ScopeFixtureOptions): string;
30
+ export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
31
+ export declare const PARITY_CASES: readonly ParityCase[];
32
+ export declare function runParity(): ParityResult;
33
+ export declare function renderReport(result: ParityResult): string;
34
+ //# sourceMappingURL=triage-scope-parity.d.ts.map
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Golden-output parity harness (#1725): runs BOTH the Python oracle
4
+ * (`scripts/triage_scope.py`) and the ported TS triage:scope CLI, then
5
+ * diffs exit codes and normalised 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
17
+ .replace(/--project-root [^\s]+/g, "--project-root <ROOT>")
18
+ .replace(/--cache-root [^\s]+/g, "--cache-root <ROOT>")
19
+ .replace(/path=[^\s\n]+coverage\.json/g, "path=<ROOT>/coverage.json");
20
+ }
21
+ function runCapture(cmd, args, cwd) {
22
+ const result = spawnSync(cmd, args, {
23
+ cwd,
24
+ encoding: "utf8",
25
+ env: process.env,
26
+ stdio: ["ignore", "pipe", "pipe"],
27
+ });
28
+ return {
29
+ exitCode: result.status ?? 2,
30
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
31
+ stderr: typeof result.stderr === "string" ? result.stderr : "",
32
+ };
33
+ }
34
+ function writeProjectDefinition(root, policy = {}) {
35
+ const dir = join(root, "vbrief");
36
+ mkdirSync(dir, { recursive: true });
37
+ writeFileSync(join(dir, "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
38
+ vBRIEFInfo: { version: "0.6" },
39
+ plan: { title: "T", status: "running", items: [], policy },
40
+ }, null, 2)}\n`, "utf8");
41
+ }
42
+ export function buildFixtureRepo(options = {}) {
43
+ const root = mkdtempSync(join(tmpdir(), "deft-triage-scope-parity-"));
44
+ mkdirSync(join(root, "vbrief"), { recursive: true });
45
+ writeProjectDefinition(root, options.policy ?? {});
46
+ return root;
47
+ }
48
+ function resolveDeftRoot() {
49
+ if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
50
+ return resolve(process.env.DEFT_ROOT);
51
+ }
52
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
53
+ }
54
+ function runPythonScope(deftRoot, repo, argv) {
55
+ return runCapture("uv", [
56
+ "run",
57
+ "python",
58
+ join(deftRoot, "scripts", "triage_scope.py"),
59
+ ...argv,
60
+ "--project-root",
61
+ repo,
62
+ ], deftRoot);
63
+ }
64
+ function runTsScope(deftRoot, repo, argv) {
65
+ return runCapture("node", [join(deftRoot, "packages", "cli", "dist", "triage-scope.js"), ...argv, "--project-root", repo], deftRoot);
66
+ }
67
+ export function diffCase(python, ts, caseName) {
68
+ const pyOut = normalizeOutput(python.stdout);
69
+ const tsOut = normalizeOutput(ts.stdout);
70
+ const pyErr = normalizeOutput(python.stderr);
71
+ const tsErr = normalizeOutput(ts.stderr);
72
+ return {
73
+ caseName,
74
+ exitMismatch: python.exitCode !== ts.exitCode,
75
+ stdoutMismatch: pyOut !== tsOut,
76
+ stderrMismatch: pyErr !== tsErr,
77
+ pythonExit: python.exitCode,
78
+ tsExit: ts.exitCode,
79
+ };
80
+ }
81
+ export const PARITY_CASES = [
82
+ {
83
+ name: "list-default",
84
+ argv: ["--list"],
85
+ },
86
+ {
87
+ name: "list-custom-scope-ignores",
88
+ argv: ["--list"],
89
+ fixture: {
90
+ policy: {
91
+ triageScope: [{ rule: "labels", "any-of": ["bug"] }],
92
+ triageScopeIgnores: [
93
+ { label: "wontfix" },
94
+ { rule: "author", "any-of": ["dependabot[bot]"] },
95
+ ],
96
+ },
97
+ },
98
+ },
99
+ {
100
+ name: "add-label",
101
+ argv: ["--add-label=priority:p0"],
102
+ },
103
+ {
104
+ name: "add-milestone",
105
+ argv: ["--add-milestone=v2.0-blocker"],
106
+ },
107
+ {
108
+ name: "ignore-label",
109
+ argv: ["--ignore-label=wontfix"],
110
+ },
111
+ {
112
+ name: "mutations-mutually-exclusive",
113
+ argv: ["--add-label=bug", "--ignore-label=wontfix"],
114
+ },
115
+ {
116
+ name: "diff-from-upstream-missing-repo",
117
+ argv: ["--diff-from-upstream"],
118
+ fixture: { policy: {} },
119
+ },
120
+ {
121
+ name: "refresh-denominator-missing-repo",
122
+ argv: ["--refresh-denominator", "--count", "10"],
123
+ },
124
+ {
125
+ name: "invalid-project-root",
126
+ argv: ["--list"],
127
+ fixture: undefined,
128
+ },
129
+ {
130
+ name: "schema-error",
131
+ argv: ["--list"],
132
+ fixture: {
133
+ policy: {
134
+ triageScope: [{ rule: "bogus-type" }],
135
+ },
136
+ },
137
+ },
138
+ {
139
+ name: "refresh-denominator-success",
140
+ argv: [
141
+ "--refresh-denominator",
142
+ "--repo",
143
+ "deftai/directive",
144
+ "--count",
145
+ "247",
146
+ "--source",
147
+ "github-issue",
148
+ ],
149
+ fixture: {
150
+ policy: { triageScope: [{ rule: "all-open" }] },
151
+ },
152
+ },
153
+ ];
154
+ export function runParity() {
155
+ const deftRoot = resolveDeftRoot();
156
+ const diffs = [];
157
+ for (const testCase of PARITY_CASES) {
158
+ if (testCase.name === "invalid-project-root") {
159
+ const missing = join(tmpdir(), `deft-missing-${Date.now()}`);
160
+ const python = runPythonScope(deftRoot, missing, testCase.argv);
161
+ const ts = runTsScope(deftRoot, missing, testCase.argv);
162
+ diffs.push(diffCase(python, ts, testCase.name));
163
+ continue;
164
+ }
165
+ const pyRepo = buildFixtureRepo(testCase.fixture);
166
+ const tsRepo = buildFixtureRepo(testCase.fixture);
167
+ try {
168
+ const extraArgv = [...testCase.argv];
169
+ if (testCase.name === "refresh-denominator-success") {
170
+ const cacheRoot = mkdtempSync(join(tmpdir(), "deft-scope-cache-"));
171
+ extraArgv.push("--cache-root", cacheRoot);
172
+ }
173
+ const python = runPythonScope(deftRoot, pyRepo, extraArgv);
174
+ const ts = runTsScope(deftRoot, tsRepo, extraArgv);
175
+ diffs.push(diffCase(python, ts, testCase.name));
176
+ }
177
+ finally {
178
+ rmSync(pyRepo, { recursive: true, force: true });
179
+ rmSync(tsRepo, { recursive: true, force: true });
180
+ }
181
+ }
182
+ const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
183
+ return { ok, diffs };
184
+ }
185
+ export function renderReport(result) {
186
+ if (result.ok) {
187
+ return `triage:scope parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
188
+ }
189
+ const lines = ["triage:scope parity: DIVERGENCE"];
190
+ for (const d of result.diffs) {
191
+ if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
192
+ lines.push(` case: ${d.caseName}`);
193
+ if (d.exitMismatch)
194
+ lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
195
+ if (d.stdoutMismatch)
196
+ lines.push(" stdout mismatch");
197
+ if (d.stderrMismatch)
198
+ lines.push(" stderr mismatch");
199
+ }
200
+ }
201
+ return lines.join("\n");
202
+ }
203
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
204
+ try {
205
+ const result = runParity();
206
+ if (result.ok) {
207
+ process.stdout.write(`${renderReport(result)}\n`);
208
+ process.exit(0);
209
+ }
210
+ process.stderr.write(`${renderReport(result)}\n`);
211
+ process.exit(1);
212
+ }
213
+ catch (err) {
214
+ process.stderr.write(`triage:scope parity: harness error -- ${String(err)}\n`);
215
+ process.exit(2);
216
+ }
217
+ }
218
+ //# sourceMappingURL=triage-scope-parity.js.map