autodocs-engine 0.5.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 (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/analysis-builder.d.ts +13 -0
  4. package/dist/analysis-builder.js +268 -0
  5. package/dist/analysis-builder.js.map +1 -0
  6. package/dist/anti-pattern-detector.d.ts +9 -0
  7. package/dist/anti-pattern-detector.js +58 -0
  8. package/dist/anti-pattern-detector.js.map +1 -0
  9. package/dist/architecture-detector.d.ts +7 -0
  10. package/dist/architecture-detector.js +212 -0
  11. package/dist/architecture-detector.js.map +1 -0
  12. package/dist/ast-parser.d.ts +5 -0
  13. package/dist/ast-parser.js +635 -0
  14. package/dist/ast-parser.js.map +1 -0
  15. package/dist/benchmark/code-generator.d.ts +20 -0
  16. package/dist/benchmark/code-generator.js +206 -0
  17. package/dist/benchmark/code-generator.js.map +1 -0
  18. package/dist/benchmark/pr-miner.d.ts +61 -0
  19. package/dist/benchmark/pr-miner.js +304 -0
  20. package/dist/benchmark/pr-miner.js.map +1 -0
  21. package/dist/benchmark/pr-runner.d.ts +58 -0
  22. package/dist/benchmark/pr-runner.js +346 -0
  23. package/dist/benchmark/pr-runner.js.map +1 -0
  24. package/dist/benchmark/pr-scorer.d.ts +48 -0
  25. package/dist/benchmark/pr-scorer.js +222 -0
  26. package/dist/benchmark/pr-scorer.js.map +1 -0
  27. package/dist/benchmark/pr-task-gen.d.ts +16 -0
  28. package/dist/benchmark/pr-task-gen.js +129 -0
  29. package/dist/benchmark/pr-task-gen.js.map +1 -0
  30. package/dist/benchmark/report.d.ts +9 -0
  31. package/dist/benchmark/report.js +131 -0
  32. package/dist/benchmark/report.js.map +1 -0
  33. package/dist/benchmark/runner.d.ts +6 -0
  34. package/dist/benchmark/runner.js +183 -0
  35. package/dist/benchmark/runner.js.map +1 -0
  36. package/dist/benchmark/scorer.d.ts +6 -0
  37. package/dist/benchmark/scorer.js +549 -0
  38. package/dist/benchmark/scorer.js.map +1 -0
  39. package/dist/benchmark/shuffler.d.ts +5 -0
  40. package/dist/benchmark/shuffler.js +70 -0
  41. package/dist/benchmark/shuffler.js.map +1 -0
  42. package/dist/benchmark/statistics.d.ts +36 -0
  43. package/dist/benchmark/statistics.js +159 -0
  44. package/dist/benchmark/statistics.js.map +1 -0
  45. package/dist/benchmark/task-generator.d.ts +20 -0
  46. package/dist/benchmark/task-generator.js +388 -0
  47. package/dist/benchmark/task-generator.js.map +1 -0
  48. package/dist/benchmark/types.d.ts +111 -0
  49. package/dist/benchmark/types.js +3 -0
  50. package/dist/benchmark/types.js.map +1 -0
  51. package/dist/bin/autodocs-engine.d.ts +2 -0
  52. package/dist/bin/autodocs-engine.js +296 -0
  53. package/dist/bin/autodocs-engine.js.map +1 -0
  54. package/dist/bin/benchmark.d.ts +14 -0
  55. package/dist/bin/benchmark.js +172 -0
  56. package/dist/bin/benchmark.js.map +1 -0
  57. package/dist/bin/check.d.ts +13 -0
  58. package/dist/bin/check.js +79 -0
  59. package/dist/bin/check.js.map +1 -0
  60. package/dist/bin/init.d.ts +11 -0
  61. package/dist/bin/init.js +268 -0
  62. package/dist/bin/init.js.map +1 -0
  63. package/dist/bin/serve.d.ts +4 -0
  64. package/dist/bin/serve.js +29 -0
  65. package/dist/bin/serve.js.map +1 -0
  66. package/dist/budget-validator.d.ts +22 -0
  67. package/dist/budget-validator.js +119 -0
  68. package/dist/budget-validator.js.map +1 -0
  69. package/dist/command-extractor.d.ts +10 -0
  70. package/dist/command-extractor.js +276 -0
  71. package/dist/command-extractor.js.map +1 -0
  72. package/dist/config-analyzer.d.ts +5 -0
  73. package/dist/config-analyzer.js +364 -0
  74. package/dist/config-analyzer.js.map +1 -0
  75. package/dist/config.d.ts +33 -0
  76. package/dist/config.js +172 -0
  77. package/dist/config.js.map +1 -0
  78. package/dist/contribution-patterns.d.ts +6 -0
  79. package/dist/contribution-patterns.js +263 -0
  80. package/dist/contribution-patterns.js.map +1 -0
  81. package/dist/convention-extractor.d.ts +17 -0
  82. package/dist/convention-extractor.js +90 -0
  83. package/dist/convention-extractor.js.map +1 -0
  84. package/dist/cross-package.d.ts +5 -0
  85. package/dist/cross-package.js +71 -0
  86. package/dist/cross-package.js.map +1 -0
  87. package/dist/dependency-analyzer.d.ts +5 -0
  88. package/dist/dependency-analyzer.js +233 -0
  89. package/dist/dependency-analyzer.js.map +1 -0
  90. package/dist/detectors/build-tool.d.ts +2 -0
  91. package/dist/detectors/build-tool.js +67 -0
  92. package/dist/detectors/build-tool.js.map +1 -0
  93. package/dist/detectors/component-patterns.d.ts +2 -0
  94. package/dist/detectors/component-patterns.js +49 -0
  95. package/dist/detectors/component-patterns.js.map +1 -0
  96. package/dist/detectors/data-fetching.d.ts +2 -0
  97. package/dist/detectors/data-fetching.js +127 -0
  98. package/dist/detectors/data-fetching.js.map +1 -0
  99. package/dist/detectors/database.d.ts +2 -0
  100. package/dist/detectors/database.js +54 -0
  101. package/dist/detectors/database.js.map +1 -0
  102. package/dist/detectors/error-handling.d.ts +2 -0
  103. package/dist/detectors/error-handling.js +47 -0
  104. package/dist/detectors/error-handling.js.map +1 -0
  105. package/dist/detectors/export-patterns.d.ts +2 -0
  106. package/dist/detectors/export-patterns.js +64 -0
  107. package/dist/detectors/export-patterns.js.map +1 -0
  108. package/dist/detectors/file-naming.d.ts +2 -0
  109. package/dist/detectors/file-naming.js +74 -0
  110. package/dist/detectors/file-naming.js.map +1 -0
  111. package/dist/detectors/graphql-patterns.d.ts +2 -0
  112. package/dist/detectors/graphql-patterns.js +47 -0
  113. package/dist/detectors/graphql-patterns.js.map +1 -0
  114. package/dist/detectors/hook-patterns.d.ts +2 -0
  115. package/dist/detectors/hook-patterns.js +105 -0
  116. package/dist/detectors/hook-patterns.js.map +1 -0
  117. package/dist/detectors/import-patterns.d.ts +2 -0
  118. package/dist/detectors/import-patterns.js +88 -0
  119. package/dist/detectors/import-patterns.js.map +1 -0
  120. package/dist/detectors/telemetry-patterns.d.ts +2 -0
  121. package/dist/detectors/telemetry-patterns.js +42 -0
  122. package/dist/detectors/telemetry-patterns.js.map +1 -0
  123. package/dist/detectors/test-framework-ecosystem.d.ts +2 -0
  124. package/dist/detectors/test-framework-ecosystem.js +95 -0
  125. package/dist/detectors/test-framework-ecosystem.js.map +1 -0
  126. package/dist/detectors/test-patterns.d.ts +2 -0
  127. package/dist/detectors/test-patterns.js +60 -0
  128. package/dist/detectors/test-patterns.js.map +1 -0
  129. package/dist/detectors/web-framework.d.ts +2 -0
  130. package/dist/detectors/web-framework.js +51 -0
  131. package/dist/detectors/web-framework.js.map +1 -0
  132. package/dist/deterministic-formatter.d.ts +54 -0
  133. package/dist/deterministic-formatter.js +922 -0
  134. package/dist/deterministic-formatter.js.map +1 -0
  135. package/dist/diff-analyzer.d.ts +7 -0
  136. package/dist/diff-analyzer.js +126 -0
  137. package/dist/diff-analyzer.js.map +1 -0
  138. package/dist/example-extractor.d.ts +6 -0
  139. package/dist/example-extractor.js +115 -0
  140. package/dist/example-extractor.js.map +1 -0
  141. package/dist/existing-docs.d.ts +36 -0
  142. package/dist/existing-docs.js +257 -0
  143. package/dist/existing-docs.js.map +1 -0
  144. package/dist/file-discovery.d.ts +6 -0
  145. package/dist/file-discovery.js +154 -0
  146. package/dist/file-discovery.js.map +1 -0
  147. package/dist/git-history.d.ts +41 -0
  148. package/dist/git-history.js +401 -0
  149. package/dist/git-history.js.map +1 -0
  150. package/dist/impact-classifier.d.ts +22 -0
  151. package/dist/impact-classifier.js +87 -0
  152. package/dist/impact-classifier.js.map +1 -0
  153. package/dist/impact-radius.d.ts +23 -0
  154. package/dist/impact-radius.js +130 -0
  155. package/dist/impact-radius.js.map +1 -0
  156. package/dist/import-chain.d.ts +12 -0
  157. package/dist/import-chain.js +93 -0
  158. package/dist/import-chain.js.map +1 -0
  159. package/dist/index.d.ts +40 -0
  160. package/dist/index.js +72 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/inferability.d.ts +16 -0
  163. package/dist/inferability.js +142 -0
  164. package/dist/inferability.js.map +1 -0
  165. package/dist/llm/adapter.d.ts +33 -0
  166. package/dist/llm/adapter.js +202 -0
  167. package/dist/llm/adapter.js.map +1 -0
  168. package/dist/llm/client.d.ts +5 -0
  169. package/dist/llm/client.js +68 -0
  170. package/dist/llm/client.js.map +1 -0
  171. package/dist/llm/hierarchical.d.ts +23 -0
  172. package/dist/llm/hierarchical.js +126 -0
  173. package/dist/llm/hierarchical.js.map +1 -0
  174. package/dist/llm/serializer.d.ts +19 -0
  175. package/dist/llm/serializer.js +363 -0
  176. package/dist/llm/serializer.js.map +1 -0
  177. package/dist/llm/template-selector.d.ts +7 -0
  178. package/dist/llm/template-selector.js +21 -0
  179. package/dist/llm/template-selector.js.map +1 -0
  180. package/dist/llm-adapter.d.ts +2 -0
  181. package/dist/llm-adapter.js +5 -0
  182. package/dist/llm-adapter.js.map +1 -0
  183. package/dist/mcp/cache.d.ts +30 -0
  184. package/dist/mcp/cache.js +112 -0
  185. package/dist/mcp/cache.js.map +1 -0
  186. package/dist/mcp/errors.d.ts +21 -0
  187. package/dist/mcp/errors.js +27 -0
  188. package/dist/mcp/errors.js.map +1 -0
  189. package/dist/mcp/queries.d.ts +27 -0
  190. package/dist/mcp/queries.js +121 -0
  191. package/dist/mcp/queries.js.map +1 -0
  192. package/dist/mcp/server.d.ts +14 -0
  193. package/dist/mcp/server.js +131 -0
  194. package/dist/mcp/server.js.map +1 -0
  195. package/dist/mcp/tools.d.ts +39 -0
  196. package/dist/mcp/tools.js +249 -0
  197. package/dist/mcp/tools.js.map +1 -0
  198. package/dist/mermaid-generator.d.ts +6 -0
  199. package/dist/mermaid-generator.js +59 -0
  200. package/dist/mermaid-generator.js.map +1 -0
  201. package/dist/meta-tool-detector.d.ts +23 -0
  202. package/dist/meta-tool-detector.js +177 -0
  203. package/dist/meta-tool-detector.js.map +1 -0
  204. package/dist/output-validator.d.ts +6 -0
  205. package/dist/output-validator.js +471 -0
  206. package/dist/output-validator.js.map +1 -0
  207. package/dist/pattern-fingerprinter.d.ts +7 -0
  208. package/dist/pattern-fingerprinter.js +241 -0
  209. package/dist/pattern-fingerprinter.js.map +1 -0
  210. package/dist/pipeline.d.ts +5 -0
  211. package/dist/pipeline.js +374 -0
  212. package/dist/pipeline.js.map +1 -0
  213. package/dist/plugin-loader.d.ts +19 -0
  214. package/dist/plugin-loader.js +124 -0
  215. package/dist/plugin-loader.js.map +1 -0
  216. package/dist/role-inferrer.d.ts +5 -0
  217. package/dist/role-inferrer.js +159 -0
  218. package/dist/role-inferrer.js.map +1 -0
  219. package/dist/symbol-graph.d.ts +11 -0
  220. package/dist/symbol-graph.js +613 -0
  221. package/dist/symbol-graph.js.map +1 -0
  222. package/dist/templates/agents-md.d.ts +20 -0
  223. package/dist/templates/agents-md.js +346 -0
  224. package/dist/templates/agents-md.js.map +1 -0
  225. package/dist/templates/claude-md.d.ts +4 -0
  226. package/dist/templates/claude-md.js +23 -0
  227. package/dist/templates/claude-md.js.map +1 -0
  228. package/dist/templates/cursorrules.d.ts +4 -0
  229. package/dist/templates/cursorrules.js +18 -0
  230. package/dist/templates/cursorrules.js.map +1 -0
  231. package/dist/tier-classifier.d.ts +7 -0
  232. package/dist/tier-classifier.js +32 -0
  233. package/dist/tier-classifier.js.map +1 -0
  234. package/dist/types.d.ts +428 -0
  235. package/dist/types.js +42 -0
  236. package/dist/types.js.map +1 -0
  237. package/dist/workflow-rules.d.ts +18 -0
  238. package/dist/workflow-rules.js +131 -0
  239. package/dist/workflow-rules.js.map +1 -0
  240. package/package.json +62 -0
@@ -0,0 +1,20 @@
1
+ import type { ResolvedConfig } from "../types.js";
2
+ import type { BenchmarkTask, BenchmarkCondition, GeneratedFile } from "./types.js";
3
+ export interface CodeGenResult {
4
+ files: GeneratedFile[];
5
+ tokensUsed: number;
6
+ latencyMs: number;
7
+ error?: string;
8
+ }
9
+ /**
10
+ * Generate code for a benchmark task under a specific condition.
11
+ */
12
+ export declare function generateCode(task: BenchmarkTask, condition: BenchmarkCondition, agentsMd: string | null, shuffledAgentsMd: string | null, llmConfig: ResolvedConfig["llm"]): Promise<CodeGenResult>;
13
+ /**
14
+ * Parse LLM response to extract generated files from code blocks.
15
+ * Handles multiple format variants:
16
+ * - ```filepath\ncontent```
17
+ * - ```ts\n// filepath: path/to/file.ts\ncontent```
18
+ * - ```typescript path/to/file.ts\ncontent```
19
+ */
20
+ export declare function parseCodeBlocks(response: string): GeneratedFile[];
@@ -0,0 +1,206 @@
1
+ // src/benchmark/code-generator.ts — Generate code via LLM for benchmark conditions
2
+ // Builds fair prompts for treatment (A), realistic control (B),
3
+ // impoverished control (C), and negative control (N).
4
+ import { callLLMWithRetry } from "../llm/client.js";
5
+ /**
6
+ * Generate code for a benchmark task under a specific condition.
7
+ */
8
+ export async function generateCode(task, condition, agentsMd, shuffledAgentsMd, llmConfig) {
9
+ const systemPrompt = buildSystemPrompt(task.packageName, task.taskType);
10
+ const userPrompt = buildUserPrompt(task, condition, agentsMd, shuffledAgentsMd);
11
+ const start = performance.now();
12
+ try {
13
+ const response = await callLLMWithRetry(systemPrompt, userPrompt, llmConfig);
14
+ const latencyMs = Math.round(performance.now() - start);
15
+ let files = parseCodeBlocks(response);
16
+ // Rough token estimate: 1 token ≈ 4 chars
17
+ const tokensUsed = Math.round((systemPrompt.length + userPrompt.length + response.length) / 4);
18
+ // For Q&A tasks (command, architecture), the raw response IS the answer.
19
+ // If no code blocks were parsed, wrap the full response as a virtual file.
20
+ if (files.length === 0 && response.trim().length > 0) {
21
+ files = [{ path: "__response__", content: response }];
22
+ }
23
+ return { files, tokensUsed, latencyMs };
24
+ }
25
+ catch (err) {
26
+ const msg = err instanceof Error ? err.message : String(err);
27
+ return {
28
+ files: [],
29
+ tokensUsed: 0,
30
+ latencyMs: Math.round(performance.now() - start),
31
+ error: `LLM call failed: ${msg}`,
32
+ };
33
+ }
34
+ }
35
+ // ─── Prompt Construction ─────────────────────────────────────────────────────
36
+ function buildSystemPrompt(packageName, taskType) {
37
+ if (taskType === "command") {
38
+ return [
39
+ `You are an expert TypeScript developer working on the ${packageName} project.`,
40
+ `Your task is to write a build/CI configuration using this project's exact commands.`,
41
+ `Output the configuration file in a code block with filepath:`,
42
+ "",
43
+ "```filepath",
44
+ "// file content here",
45
+ "```",
46
+ "",
47
+ `Use the EXACT commands and package manager from this project. Do not guess or use defaults.`,
48
+ ].join("\n");
49
+ }
50
+ if (taskType === "architecture") {
51
+ return [
52
+ `You are an expert TypeScript developer working on the ${packageName} project.`,
53
+ `Your task is to determine where new code should be placed in this project's structure.`,
54
+ `Respond with:`,
55
+ `1. The directory path where the code should go`,
56
+ `2. A brief justification (2-3 sentences) explaining why`,
57
+ ``,
58
+ `Be specific — use actual directory names from this project, not generic suggestions.`,
59
+ ].join("\n");
60
+ }
61
+ return [
62
+ `You are an expert TypeScript developer working on the ${packageName} project.`,
63
+ `Your task is to add new code to this codebase.`,
64
+ `For each file you create or modify, output it in this format:`,
65
+ "",
66
+ "```filepath",
67
+ "// file content here",
68
+ "```",
69
+ "",
70
+ `If you modify an existing file, output the COMPLETE modified file (all existing code plus your changes).`,
71
+ `Include ALL files needed: implementation, tests, and any existing files that need updates.`,
72
+ `Do not add explanations outside the code blocks.`,
73
+ ].join("\n");
74
+ }
75
+ function buildUserPrompt(task, condition, agentsMd, shuffledAgentsMd) {
76
+ const parts = [];
77
+ // Shared context: registration and barrel files (ALL conditions get these)
78
+ if (task.context.registrationFile) {
79
+ parts.push(`<file path="${task.context.registrationFile.path}">`);
80
+ parts.push(task.context.registrationFile.content);
81
+ parts.push(`</file>`);
82
+ parts.push("");
83
+ }
84
+ if (task.context.barrelFile) {
85
+ parts.push(`<file path="${task.context.barrelFile.path}">`);
86
+ parts.push(task.context.barrelFile.content);
87
+ parts.push(`</file>`);
88
+ parts.push("");
89
+ }
90
+ // Condition-specific context
91
+ switch (condition) {
92
+ case "treatment":
93
+ // A: AGENTS.md + sibling files + dir listing
94
+ if (agentsMd) {
95
+ parts.push("<agents-md>");
96
+ parts.push(agentsMd);
97
+ parts.push("</agents-md>");
98
+ parts.push("");
99
+ }
100
+ for (const sibling of task.context.siblingFiles) {
101
+ parts.push(`<file path="${sibling.path}">`);
102
+ parts.push(sibling.content);
103
+ parts.push(`</file>`);
104
+ parts.push("");
105
+ }
106
+ break;
107
+ case "realistic-control":
108
+ // B: sibling files + dir listing (no AGENTS.md)
109
+ for (const sibling of task.context.siblingFiles) {
110
+ parts.push(`<file path="${sibling.path}">`);
111
+ parts.push(sibling.content);
112
+ parts.push(`</file>`);
113
+ parts.push("");
114
+ }
115
+ break;
116
+ case "impoverished-control":
117
+ // C: dir listing only (no siblings, no AGENTS.md)
118
+ break;
119
+ case "negative-control":
120
+ // N: shuffled AGENTS.md + dir listing (no siblings)
121
+ if (shuffledAgentsMd) {
122
+ parts.push("<agents-md>");
123
+ parts.push(shuffledAgentsMd);
124
+ parts.push("</agents-md>");
125
+ parts.push("");
126
+ }
127
+ break;
128
+ }
129
+ // Directory listing (all conditions)
130
+ if (task.context.directoryListing.length > 0) {
131
+ parts.push(`Directory listing of ${task.expectedDirectory}:`);
132
+ for (const file of task.context.directoryListing.slice(0, 30)) {
133
+ parts.push(` ${file}`);
134
+ }
135
+ parts.push("");
136
+ }
137
+ // Task prompt
138
+ parts.push(`Task: ${task.prompt}`);
139
+ return parts.join("\n");
140
+ }
141
+ // ─── Code Block Parsing ──────────────────────────────────────────────────────
142
+ /**
143
+ * Parse LLM response to extract generated files from code blocks.
144
+ * Handles multiple format variants:
145
+ * - ```filepath\ncontent```
146
+ * - ```ts\n// filepath: path/to/file.ts\ncontent```
147
+ * - ```typescript path/to/file.ts\ncontent```
148
+ */
149
+ export function parseCodeBlocks(response) {
150
+ const files = [];
151
+ // Match fenced code blocks: ```[lang] [path]\n...\n```
152
+ const blockRegex = /```([^\n]*)\n([\s\S]*?)```/g;
153
+ let match;
154
+ while ((match = blockRegex.exec(response)) !== null) {
155
+ const header = match[1].trim();
156
+ const body = match[2];
157
+ let filepath = extractFilePath(header, body);
158
+ if (!filepath)
159
+ continue;
160
+ // Normalize path
161
+ filepath = filepath.replace(/\\/g, "/").replace(/^\.\//, "");
162
+ files.push({ path: filepath, content: body.trimEnd() });
163
+ }
164
+ return files;
165
+ }
166
+ /**
167
+ * Extract file path from code block header or first line of body.
168
+ */
169
+ function extractFilePath(header, body) {
170
+ // Case 1: Header IS the filepath (e.g., ```src/foo.ts)
171
+ if (header && looksLikeFilePath(header)) {
172
+ return header;
173
+ }
174
+ // Case 2: Header is "lang filepath" (e.g., ```typescript src/foo.ts)
175
+ if (header) {
176
+ const parts = header.split(/\s+/);
177
+ if (parts.length >= 2) {
178
+ const maybePath = parts.slice(1).join(" ");
179
+ if (looksLikeFilePath(maybePath))
180
+ return maybePath;
181
+ }
182
+ }
183
+ // Case 3: First line of body is a filepath comment (e.g., // filepath: src/foo.ts)
184
+ const firstLine = body.split("\n")[0]?.trim() ?? "";
185
+ const commentMatch = firstLine.match(/^\/\/\s*(?:filepath:\s*)?(.+\.[a-z]{1,4})\s*$/i);
186
+ if (commentMatch && looksLikeFilePath(commentMatch[1])) {
187
+ return commentMatch[1];
188
+ }
189
+ // Case 4: First line IS a filepath (e.g., src/foo.ts)
190
+ if (looksLikeFilePath(firstLine)) {
191
+ return firstLine;
192
+ }
193
+ return null;
194
+ }
195
+ function looksLikeFilePath(s) {
196
+ // Must contain a dot, no spaces (spaces suggest "lang path" format), not a language name
197
+ if (!s || !s.includes(".") || s.includes(" "))
198
+ return false;
199
+ // Language names to reject
200
+ const langs = new Set(["typescript", "ts", "tsx", "javascript", "js", "jsx", "json", "md", "yaml", "yml", "bash", "sh"]);
201
+ if (langs.has(s.toLowerCase()))
202
+ return false;
203
+ // Must end with a file extension
204
+ return /\.[a-z]{1,5}$/i.test(s);
205
+ }
206
+ //# sourceMappingURL=code-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-generator.js","sourceRoot":"","sources":["../../src/benchmark/code-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ export interface MinedTask {
2
+ id: string;
3
+ commitSha: string;
4
+ commitMessage: string;
5
+ commitDate: string;
6
+ groundTruth: {
7
+ path: string;
8
+ content: string;
9
+ directory: string;
10
+ filename: string;
11
+ lineCount: number;
12
+ };
13
+ context: {
14
+ siblingFiles: {
15
+ path: string;
16
+ content: string;
17
+ }[];
18
+ directoryListing: string[];
19
+ barrelFile?: {
20
+ path: string;
21
+ content: string;
22
+ };
23
+ };
24
+ }
25
+ export interface MinerOptions {
26
+ maxTasks?: number;
27
+ maxCommits?: number;
28
+ sinceDays?: number;
29
+ minFileLines?: number;
30
+ maxFileLines?: number;
31
+ minSiblings?: number;
32
+ minMessageLength?: number;
33
+ maxFilesPerCommit?: number;
34
+ verbose?: boolean;
35
+ }
36
+ export interface MinerStats {
37
+ totalCommits: number;
38
+ commitsWithAddedTs: number;
39
+ afterQualityFilter: number;
40
+ afterDiversityFilter: number;
41
+ selected: number;
42
+ filterReasons: Record<string, number>;
43
+ }
44
+ /**
45
+ * Mine a git repository for qualifying "add file" commits.
46
+ * Returns tasks sorted by recency, with diverse directory coverage.
47
+ */
48
+ export declare function mineCommits(repoPath: string, options?: MinerOptions): {
49
+ tasks: MinedTask[];
50
+ stats: MinerStats;
51
+ };
52
+ /**
53
+ * Read a file's content at a specific commit SHA.
54
+ * Returns null if the file doesn't exist at that commit.
55
+ */
56
+ export declare function readFileAtCommit(gitRoot: string, sha: string, filePath: string): string | null;
57
+ /**
58
+ * List files in a directory at a specific commit SHA.
59
+ * Returns repo-relative paths.
60
+ */
61
+ export declare function listDirAtCommit(gitRoot: string, sha: string, dirPath: string): string[];
@@ -0,0 +1,304 @@
1
+ // src/benchmark/pr-miner.ts — Mine git history for real "add file" commits
2
+ // Uses actual developer commits as ground truth for benchmark tasks.
3
+ // Reads all files at commit time (not HEAD) to avoid time-travel leakage.
4
+ import { execSync } from "node:child_process";
5
+ import { resolve, dirname, basename, extname } from "node:path";
6
+ // ─── Constants ──────────────────────────────────────────────────────────────
7
+ const DEFAULTS = {
8
+ maxTasks: 30,
9
+ maxCommits: 500,
10
+ sinceDays: 365,
11
+ minFileLines: 20,
12
+ maxFileLines: 500,
13
+ minSiblings: 3,
14
+ minMessageLength: 15,
15
+ maxFilesPerCommit: 10,
16
+ verbose: false,
17
+ };
18
+ const TS_EXTENSIONS = /\.(ts|tsx)$/;
19
+ const SKIP_PATTERNS = [
20
+ /\.test\.(ts|tsx)$/,
21
+ /\.spec\.(ts|tsx)$/,
22
+ /\.d\.(ts|tsx)$/,
23
+ /\.config\.(ts|tsx)$/,
24
+ /\.stories\.(ts|tsx)$/,
25
+ /\.e2e\.(ts|tsx)$/,
26
+ /\/__tests__\//,
27
+ /\/test\//,
28
+ /\/fixtures?\//,
29
+ /\/mocks?\//,
30
+ ];
31
+ const SKIP_FILENAMES = new Set([
32
+ "index.ts", "index.tsx", "mod.ts", // barrel files
33
+ "types.ts", "constants.ts", // typically type-only
34
+ "package.json", "tsconfig.json",
35
+ ]);
36
+ // ─── Public API ─────────────────────────────────────────────────────────────
37
+ /**
38
+ * Mine a git repository for qualifying "add file" commits.
39
+ * Returns tasks sorted by recency, with diverse directory coverage.
40
+ */
41
+ export function mineCommits(repoPath, options = {}) {
42
+ const opts = { ...DEFAULTS, ...options };
43
+ const absRepo = resolve(repoPath);
44
+ const gitRoot = getGitRoot(absRepo);
45
+ if (!gitRoot) {
46
+ throw new Error(`Not a git repository: ${absRepo}`);
47
+ }
48
+ const stats = {
49
+ totalCommits: 0,
50
+ commitsWithAddedTs: 0,
51
+ afterQualityFilter: 0,
52
+ afterDiversityFilter: 0,
53
+ selected: 0,
54
+ filterReasons: {},
55
+ };
56
+ // Phase 1: Find commits that added TS files
57
+ const rawCommits = findAddFileCommits(gitRoot, opts);
58
+ stats.totalCommits = rawCommits.length;
59
+ // Phase 2: Filter each commit's added files by quality criteria
60
+ const candidates = [];
61
+ for (const commit of rawCommits) {
62
+ stats.commitsWithAddedTs++;
63
+ for (const filePath of commit.addedFiles) {
64
+ const task = processCandidate(gitRoot, commit, filePath, opts, stats);
65
+ if (task)
66
+ candidates.push(task);
67
+ }
68
+ }
69
+ stats.afterQualityFilter = candidates.length;
70
+ // Phase 3: Enforce directory diversity (max 2 tasks per directory)
71
+ const diverse = enforceDiversity(candidates);
72
+ stats.afterDiversityFilter = diverse.length;
73
+ // Phase 4: Select top N, preferring recent and diverse
74
+ const selected = diverse.slice(0, opts.maxTasks);
75
+ stats.selected = selected.length;
76
+ if (opts.verbose) {
77
+ logStats(stats);
78
+ }
79
+ return { tasks: selected, stats };
80
+ }
81
+ /**
82
+ * Find commits that added TypeScript files.
83
+ * Uses `git log --diff-filter=A --name-only` to efficiently find additions.
84
+ */
85
+ function findAddFileCommits(gitRoot, opts) {
86
+ const raw = gitExec(gitRoot, `git log --no-merges --diff-filter=A --name-only ` +
87
+ `--format="COMMIT:%H|%s|%aI" ` +
88
+ `--since="${opts.sinceDays} days ago" ` +
89
+ `-n ${opts.maxCommits} ` +
90
+ `-- "*.ts" "*.tsx"`);
91
+ if (!raw)
92
+ return [];
93
+ const commits = [];
94
+ let current = null;
95
+ for (const line of raw.split("\n")) {
96
+ if (line.startsWith("COMMIT:")) {
97
+ if (current)
98
+ commits.push(current);
99
+ const parts = line.slice(7).split("|");
100
+ current = {
101
+ sha: parts[0],
102
+ message: parts.slice(1, -1).join("|"), // message may contain |
103
+ date: parts[parts.length - 1],
104
+ totalFilesChanged: 0,
105
+ addedFiles: [],
106
+ };
107
+ }
108
+ else if (line.trim() && current) {
109
+ current.addedFiles.push(line.trim());
110
+ }
111
+ }
112
+ if (current)
113
+ commits.push(current);
114
+ // Get total files changed per commit (including non-additions)
115
+ for (const commit of commits) {
116
+ const stat = gitExec(gitRoot, `git diff-tree --no-commit-id --name-only -r ${commit.sha}`);
117
+ commit.totalFilesChanged = stat
118
+ ? stat.split("\n").filter(l => l.trim()).length
119
+ : commit.addedFiles.length;
120
+ }
121
+ return commits;
122
+ }
123
+ /**
124
+ * Read a file's content at a specific commit SHA.
125
+ * Returns null if the file doesn't exist at that commit.
126
+ */
127
+ export function readFileAtCommit(gitRoot, sha, filePath) {
128
+ return gitExec(gitRoot, `git show ${sha}:${filePath}`);
129
+ }
130
+ /**
131
+ * List files in a directory at a specific commit SHA.
132
+ * Returns repo-relative paths.
133
+ */
134
+ export function listDirAtCommit(gitRoot, sha, dirPath) {
135
+ // Ensure dirPath ends with / for git ls-tree
136
+ const dir = dirPath.endsWith("/") ? dirPath : dirPath + "/";
137
+ const raw = gitExec(gitRoot, `git ls-tree --name-only ${sha} ${dir}`);
138
+ if (!raw)
139
+ return [];
140
+ return raw.split("\n").filter(l => l.trim()).map(f => basename(f));
141
+ }
142
+ // ─── Candidate Processing ───────────────────────────────────────────────────
143
+ function processCandidate(gitRoot, commit, filePath, opts, stats) {
144
+ const reason = (r) => {
145
+ stats.filterReasons[r] = (stats.filterReasons[r] ?? 0) + 1;
146
+ return null;
147
+ };
148
+ // Filter: commit changed too many files (bulk import/refactor)
149
+ if (commit.totalFilesChanged > opts.maxFilesPerCommit) {
150
+ return reason("too-many-files-changed");
151
+ }
152
+ // Filter: commit message too short
153
+ if (commit.message.length < opts.minMessageLength) {
154
+ return reason("short-commit-message");
155
+ }
156
+ // Filter: skip test/config/type/fixture files
157
+ const fileName = basename(filePath);
158
+ if (SKIP_FILENAMES.has(fileName)) {
159
+ return reason("skip-filename");
160
+ }
161
+ if (SKIP_PATTERNS.some(p => p.test(filePath))) {
162
+ return reason("skip-pattern");
163
+ }
164
+ // Filter: must be TS/TSX
165
+ if (!TS_EXTENSIONS.test(filePath)) {
166
+ return reason("not-typescript");
167
+ }
168
+ // Read ground truth at commit time
169
+ const content = readFileAtCommit(gitRoot, commit.sha, filePath);
170
+ if (!content) {
171
+ return reason("file-unreadable");
172
+ }
173
+ // Filter: file size
174
+ const lineCount = content.split("\n").length;
175
+ if (lineCount < opts.minFileLines) {
176
+ return reason("too-small");
177
+ }
178
+ if (lineCount > opts.maxFileLines) {
179
+ return reason("too-large");
180
+ }
181
+ // Get directory context from PARENT commit (before the file was added)
182
+ const dir = dirname(filePath);
183
+ const parentSha = commit.sha + "^";
184
+ // List siblings at parent commit
185
+ const siblings = listDirAtCommit(gitRoot, parentSha, dir);
186
+ const tsSiblings = siblings.filter(f => TS_EXTENSIONS.test(f) && f !== fileName);
187
+ // Filter: must have enough siblings for context
188
+ if (tsSiblings.length < opts.minSiblings) {
189
+ return reason("too-few-siblings");
190
+ }
191
+ // Read sibling files (up to 5, sorted alphabetically for determinism)
192
+ const siblingFiles = [];
193
+ const sibsToRead = tsSiblings.sort().slice(0, 5);
194
+ for (const sib of sibsToRead) {
195
+ const sibPath = dir + "/" + sib;
196
+ const sibContent = readFileAtCommit(gitRoot, parentSha, sibPath);
197
+ if (sibContent) {
198
+ siblingFiles.push({
199
+ path: sibPath,
200
+ content: truncate(sibContent, 100),
201
+ });
202
+ }
203
+ }
204
+ // Check for barrel file at parent commit
205
+ let barrelFile;
206
+ for (const barrelName of ["index.ts", "index.tsx"]) {
207
+ const barrelPath = dir + "/" + barrelName;
208
+ const barrelContent = readFileAtCommit(gitRoot, parentSha, barrelPath);
209
+ if (barrelContent) {
210
+ barrelFile = { path: barrelPath, content: barrelContent };
211
+ break;
212
+ }
213
+ }
214
+ // Directory listing at parent commit (all files, not just TS)
215
+ const dirListing = listDirAtCommit(gitRoot, parentSha, dir);
216
+ // Build task ID from directory and filename
217
+ const id = `pr-${dir.replace(/\//g, "-")}-${basename(filePath, extname(filePath))}`;
218
+ return {
219
+ id,
220
+ commitSha: commit.sha,
221
+ commitMessage: commit.message.trim(),
222
+ commitDate: commit.date,
223
+ groundTruth: {
224
+ path: filePath,
225
+ content,
226
+ directory: dir,
227
+ filename: fileName,
228
+ lineCount,
229
+ },
230
+ context: {
231
+ siblingFiles,
232
+ directoryListing: dirListing,
233
+ barrelFile,
234
+ },
235
+ };
236
+ }
237
+ // ─── Diversity & Selection ──────────────────────────────────────────────────
238
+ /**
239
+ * Enforce directory diversity: max 2 tasks per directory, max 4 per package.
240
+ * Preserves order (most recent first from git log).
241
+ */
242
+ function enforceDiversity(candidates) {
243
+ const dirCounts = new Map();
244
+ const pkgCounts = new Map();
245
+ const result = [];
246
+ for (const task of candidates) {
247
+ const dir = task.groundTruth.directory;
248
+ const pkg = getPackageRoot(dir);
249
+ const dirCount = dirCounts.get(dir) ?? 0;
250
+ const pkgCount = pkgCounts.get(pkg) ?? 0;
251
+ if (dirCount >= 2 || pkgCount >= 4)
252
+ continue;
253
+ dirCounts.set(dir, dirCount + 1);
254
+ pkgCounts.set(pkg, pkgCount + 1);
255
+ result.push(task);
256
+ }
257
+ return result;
258
+ }
259
+ function getPackageRoot(dir) {
260
+ // Extract package root: packages/<name>/ or apps/<name>/ or just the first 2 segments
261
+ const parts = dir.split("/");
262
+ if (parts[0] === "packages" || parts[0] === "apps") {
263
+ return parts.slice(0, 2).join("/");
264
+ }
265
+ return parts.slice(0, Math.min(2, parts.length)).join("/");
266
+ }
267
+ // ─── Helpers ────────────────────────────────────────────────────────────────
268
+ function gitExec(cwd, command) {
269
+ try {
270
+ return execSync(command, {
271
+ cwd,
272
+ encoding: "utf-8",
273
+ timeout: 15_000,
274
+ stdio: ["pipe", "pipe", "pipe"],
275
+ maxBuffer: 10 * 1024 * 1024,
276
+ }).trimEnd();
277
+ }
278
+ catch {
279
+ return null;
280
+ }
281
+ }
282
+ function getGitRoot(dir) {
283
+ return gitExec(dir, "git rev-parse --show-toplevel");
284
+ }
285
+ function truncate(content, maxLines) {
286
+ const lines = content.split("\n");
287
+ if (lines.length <= maxLines)
288
+ return content;
289
+ return lines.slice(0, maxLines).join("\n") + "\n// ... truncated";
290
+ }
291
+ function logStats(stats) {
292
+ console.error(`[pr-miner] Commits scanned: ${stats.totalCommits}`);
293
+ console.error(`[pr-miner] With added TS files: ${stats.commitsWithAddedTs}`);
294
+ console.error(`[pr-miner] After quality filter: ${stats.afterQualityFilter}`);
295
+ console.error(`[pr-miner] After diversity filter: ${stats.afterDiversityFilter}`);
296
+ console.error(`[pr-miner] Selected: ${stats.selected}`);
297
+ if (Object.keys(stats.filterReasons).length > 0) {
298
+ console.error(`[pr-miner] Filter reasons:`);
299
+ for (const [reason, count] of Object.entries(stats.filterReasons).sort((a, b) => b[1] - a[1])) {
300
+ console.error(` ${reason}: ${count}`);
301
+ }
302
+ }
303
+ }
304
+ //# sourceMappingURL=pr-miner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-miner.js","sourceRoot":"","sources":["../../src/benchmark/pr-miner.ts"],"names":[],"mappings":"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"}