ctxman 3.0.0 → 3.1.1

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 (224) hide show
  1. package/.ctxman/llm-profiles.json +1067 -39
  2. package/.ctxman/profiles/backend-team.json +13 -0
  3. package/.ctxman/profiles/default.json +12 -0
  4. package/.ctxman/profiles/devops-team.json +21 -0
  5. package/.ctxman/profiles/frontend-team.json +20 -0
  6. package/.ctxman/templates/bug-fix.json +17 -0
  7. package/.ctxman/templates/code-review.json +9 -0
  8. package/.ctxman/templates/documentation.json +9 -0
  9. package/.ctxman/templates/feature.json +9 -0
  10. package/.ctxman/templates/full-context.json +9 -0
  11. package/.ctxman/templates/refactoring.json +18 -0
  12. package/.ctxman/templates/testing.json +9 -0
  13. package/.ctxman/wizard-profiles/security-audit/profile.json +7 -1
  14. package/LICENSE +21 -0
  15. package/README.md +381 -136
  16. package/bin/cli.js +1880 -529
  17. package/bin/cm-ask.js +18 -67
  18. package/bin/cm-audit.js +121 -0
  19. package/bin/cm-count.js +151 -0
  20. package/bin/cm-gitingest.js +128 -115
  21. package/bin/cm-map.js +242 -0
  22. package/bin/cm-mcp.js +293 -0
  23. package/bin/cm-pack.js +405 -0
  24. package/bin/cm-policy.js +170 -0
  25. package/bin/cm-pr.js +248 -0
  26. package/bin/cm-search.js +178 -0
  27. package/bin/cm-update.js +128 -128
  28. package/bin/cm-why.js +197 -0
  29. package/bin/mcp-server.js +8 -24
  30. package/ctxman.js +237 -183
  31. package/examples/README.md +19 -4
  32. package/examples/github-actions/ctxman-check.yml +49 -0
  33. package/examples/wizard-profiles/security-audit/profile.json +7 -1
  34. package/index.d.ts +1422 -0
  35. package/index.js +55 -31
  36. package/lib/agents/pr-failure-agent.js +48 -45
  37. package/lib/analyzers/ai-suggester.js +451 -0
  38. package/lib/analyzers/dependency-scanner.js +505 -0
  39. package/lib/analyzers/duplicate-detector.js +264 -0
  40. package/lib/analyzers/go-method-analyzer.js +151 -110
  41. package/lib/analyzers/import-tracker.js +431 -0
  42. package/lib/analyzers/method-analyzer.js +1055 -434
  43. package/lib/analyzers/performance-dashboard.js +687 -0
  44. package/lib/analyzers/token-calculator.js +895 -504
  45. package/lib/analyzers/unused-exports-detector.js +336 -0
  46. package/lib/api/mcp/install.js +424 -0
  47. package/lib/api/mcp/prompts.js +281 -281
  48. package/lib/api/mcp/resources.js +300 -241
  49. package/lib/api/mcp/sandbox.js +89 -0
  50. package/lib/api/mcp/server.js +772 -312
  51. package/lib/api/mcp/start.js +125 -0
  52. package/lib/api/mcp/transports/HttpSseTransport.js +60 -52
  53. package/lib/api/rest/server.js +105 -28
  54. package/lib/cache/CacheManager.js +9 -17
  55. package/lib/core/Analyzer.js +16 -10
  56. package/lib/core/ContextBuilder.js +19 -28
  57. package/lib/core/Reporter.js +15 -14
  58. package/lib/core/Scanner.js +81 -12
  59. package/lib/count/index.js +100 -0
  60. package/lib/formatters/format-registry.js +394 -372
  61. package/lib/formatters/gitingest-formatter.js +656 -621
  62. package/lib/formatters/toon-formatter-v1.3.js +637 -632
  63. package/lib/formatters/toon-formatter.js +239 -240
  64. package/lib/integrations/git/BlameTracker.js +4 -4
  65. package/lib/integrations/git/DiffAnalyzer.js +38 -31
  66. package/lib/integrations/git/GitClient.js +71 -53
  67. package/lib/lsp/server.js +311 -0
  68. package/lib/map/graph.js +299 -0
  69. package/lib/map/imports.js +233 -0
  70. package/lib/map/index.js +33 -0
  71. package/lib/map/rank.js +253 -0
  72. package/lib/map/render.js +346 -0
  73. package/lib/map/resolver.js +574 -0
  74. package/lib/pack/budget.js +111 -0
  75. package/lib/pack/code-lexer.js +360 -0
  76. package/lib/pack/compress.js +414 -0
  77. package/lib/pack/index.js +354 -0
  78. package/lib/pack/renderers/common.js +134 -0
  79. package/lib/pack/renderers/index.js +24 -0
  80. package/lib/pack/renderers/json.js +47 -0
  81. package/lib/pack/renderers/markdown.js +54 -0
  82. package/lib/pack/renderers/plain.js +38 -0
  83. package/lib/pack/renderers/xml.js +85 -0
  84. package/lib/pack/select.js +177 -0
  85. package/lib/pack/split.js +182 -0
  86. package/lib/pack/tree.js +35 -0
  87. package/lib/parsers/gitignore-parser.js +116 -107
  88. package/lib/parsers/method-filter-parser.js +50 -33
  89. package/lib/plugins/ExporterPlugin.js +3 -3
  90. package/lib/plugins/LanguagePlugin.js +3 -3
  91. package/lib/plugins/PluginManager.js +7 -13
  92. package/lib/policy/audit.js +312 -0
  93. package/lib/policy/enforce.js +125 -0
  94. package/lib/policy/ignore-files.js +169 -0
  95. package/lib/policy/index.js +53 -0
  96. package/lib/policy/policy.js +489 -0
  97. package/lib/pr/diff-parser.js +267 -0
  98. package/lib/pr/method-mapper.js +148 -0
  99. package/lib/pr/pr-context.js +829 -0
  100. package/lib/pr/pr-git.js +149 -0
  101. package/lib/pr/pr-renderer.js +644 -0
  102. package/lib/pr/related-tests.js +296 -0
  103. package/lib/rag/DataSourcePlugin.js +5 -5
  104. package/lib/rag/EmbeddingProvider.js +19 -8
  105. package/lib/rag/Indexer.js +14 -5
  106. package/lib/rag/VectorStoreFactory.js +3 -3
  107. package/lib/rag/ask.js +122 -0
  108. package/lib/rag/sources/FileDataSource.js +12 -9
  109. package/lib/rag/stores/BaseVectorStore.js +5 -5
  110. package/lib/rag/stores/ChromaDBStore.js +10 -10
  111. package/lib/rag/stores/LanceDBStore.js +29 -19
  112. package/lib/rag/stores/PineconeStore.js +11 -9
  113. package/lib/search/bm25.js +433 -0
  114. package/lib/search/code-units.js +201 -0
  115. package/lib/search/symbols.js +189 -0
  116. package/lib/ui/dashboard.js +120 -89
  117. package/lib/ui/index.js +1 -6
  118. package/lib/ui/init-wizard-ui.js +550 -0
  119. package/lib/ui/progress-bar.js +94 -88
  120. package/lib/ui/select-input.js +40 -32
  121. package/lib/ui/template-selector.js +99 -0
  122. package/lib/ui/wizard.js +374 -329
  123. package/lib/utils/claude-token-counter.js +151 -0
  124. package/lib/utils/cli-output.js +17 -0
  125. package/lib/utils/clipboard-utils.js +49 -50
  126. package/lib/utils/config-utils.js +81 -66
  127. package/lib/utils/context-versioning.js +532 -0
  128. package/lib/utils/error-handler.js +112 -112
  129. package/lib/utils/file-utils.js +153 -69
  130. package/lib/utils/format-converter.js +356 -283
  131. package/lib/utils/git-utils.js +366 -294
  132. package/lib/utils/llm-cost-estimator.js +281 -0
  133. package/lib/utils/llm-detector.js +242 -78
  134. package/lib/utils/logger.js +246 -237
  135. package/lib/utils/messages.js +355 -0
  136. package/lib/utils/multi-repo-manager.js +364 -0
  137. package/lib/utils/profile-manager.js +380 -0
  138. package/lib/utils/safe-read.js +61 -0
  139. package/lib/utils/secret-redactor.js +61 -0
  140. package/lib/utils/snapshot-manager.js +679 -0
  141. package/lib/utils/template-manager.js +378 -0
  142. package/lib/utils/token-utils.js +201 -170
  143. package/lib/utils/tokenizer-adapter.js +421 -377
  144. package/lib/utils/updater.js +539 -506
  145. package/lib/watch/FileWatcher.js +12 -8
  146. package/lib/watch/IncrementalAnalyzer.js +7 -7
  147. package/lib/why/coupling.js +81 -0
  148. package/lib/why/errors.js +23 -0
  149. package/lib/why/git.js +169 -0
  150. package/lib/why/history.js +108 -0
  151. package/lib/why/index.js +720 -0
  152. package/lib/why/ownership.js +79 -0
  153. package/lib/why/paths.js +207 -0
  154. package/lib/why/references.js +259 -0
  155. package/lib/why/render.js +722 -0
  156. package/lib/why/search.js +358 -0
  157. package/lib/why/target.js +389 -0
  158. package/lib/wizards/config-generator.js +257 -0
  159. package/lib/wizards/project-detector.js +572 -0
  160. package/package.json +44 -10
  161. package/.ctxman/logs/ctxman-2026-07-02.log +0 -156
  162. package/.ctxman/self-knowledge/documents.lance/_transactions/0-b3dd1558-f95b-44b9-a154-18e8c330ae7a.txn +0 -0
  163. package/.ctxman/self-knowledge/documents.lance/_transactions/1-44bff6d4-e552-4010-a769-e09ad822698d.txn +0 -0
  164. package/.ctxman/self-knowledge/documents.lance/_transactions/10-37260794-5947-4ecb-b4c8-d732f58f40f1.txn +0 -0
  165. package/.ctxman/self-knowledge/documents.lance/_transactions/11-0d52a883-5518-463c-9b6d-986c3af89dfd.txn +0 -0
  166. package/.ctxman/self-knowledge/documents.lance/_transactions/12-ae354646-52f2-49c9-90fb-2e6ed8932663.txn +0 -0
  167. package/.ctxman/self-knowledge/documents.lance/_transactions/13-5d7d5e57-27da-498b-b734-091b9d38da13.txn +0 -0
  168. package/.ctxman/self-knowledge/documents.lance/_transactions/14-558ce928-810b-4252-a364-fdd1ee6f8a25.txn +0 -0
  169. package/.ctxman/self-knowledge/documents.lance/_transactions/15-27e3a58f-8b64-43b8-a9f4-e3369446968b.txn +0 -0
  170. package/.ctxman/self-knowledge/documents.lance/_transactions/16-a110c390-e5c8-4464-b976-bc7f5195fa15.txn +0 -0
  171. package/.ctxman/self-knowledge/documents.lance/_transactions/17-97513225-53de-4216-b61a-6337bd0cc4ad.txn +0 -0
  172. package/.ctxman/self-knowledge/documents.lance/_transactions/18-5ba450f0-c527-459c-bf4f-6d79b5e4285f.txn +0 -0
  173. package/.ctxman/self-knowledge/documents.lance/_transactions/19-600d3a63-5225-49e9-b8b7-30e037b564ab.txn +0 -0
  174. package/.ctxman/self-knowledge/documents.lance/_transactions/2-48a61b4e-92cf-4342-8376-914c1b99a9f9.txn +0 -0
  175. package/.ctxman/self-knowledge/documents.lance/_transactions/20-121dd912-5410-410e-84ff-82c7a23604a0.txn +0 -0
  176. package/.ctxman/self-knowledge/documents.lance/_transactions/3-bc6844ab-7ea3-4bb3-9ee1-538ce5664a9c.txn +0 -0
  177. package/.ctxman/self-knowledge/documents.lance/_transactions/4-d5e1754f-dbb5-454e-a9be-2a7da8d7bcf9.txn +0 -0
  178. package/.ctxman/self-knowledge/documents.lance/_transactions/5-4fae93df-0568-4b6f-8acf-8bef4bba6047.txn +0 -0
  179. package/.ctxman/self-knowledge/documents.lance/_transactions/6-4b1b8b87-068e-49a3-ba2b-d8dae628b252.txn +0 -0
  180. package/.ctxman/self-knowledge/documents.lance/_transactions/7-63d040fb-d2fa-4c0f-bed0-53411918a7b0.txn +0 -0
  181. package/.ctxman/self-knowledge/documents.lance/_transactions/8-c5628cf6-264c-420f-aab8-bc96a9083591.txn +0 -0
  182. package/.ctxman/self-knowledge/documents.lance/_transactions/9-c94570aa-5e53-4fcb-971f-cecc1d1d5492.txn +0 -0
  183. package/.ctxman/self-knowledge/documents.lance/_versions/1.manifest +0 -0
  184. package/.ctxman/self-knowledge/documents.lance/_versions/10.manifest +0 -0
  185. package/.ctxman/self-knowledge/documents.lance/_versions/11.manifest +0 -0
  186. package/.ctxman/self-knowledge/documents.lance/_versions/12.manifest +0 -0
  187. package/.ctxman/self-knowledge/documents.lance/_versions/13.manifest +0 -0
  188. package/.ctxman/self-knowledge/documents.lance/_versions/14.manifest +0 -0
  189. package/.ctxman/self-knowledge/documents.lance/_versions/15.manifest +0 -0
  190. package/.ctxman/self-knowledge/documents.lance/_versions/16.manifest +0 -0
  191. package/.ctxman/self-knowledge/documents.lance/_versions/17.manifest +0 -0
  192. package/.ctxman/self-knowledge/documents.lance/_versions/18.manifest +0 -0
  193. package/.ctxman/self-knowledge/documents.lance/_versions/19.manifest +0 -0
  194. package/.ctxman/self-knowledge/documents.lance/_versions/2.manifest +0 -0
  195. package/.ctxman/self-knowledge/documents.lance/_versions/20.manifest +0 -0
  196. package/.ctxman/self-knowledge/documents.lance/_versions/21.manifest +0 -0
  197. package/.ctxman/self-knowledge/documents.lance/_versions/3.manifest +0 -0
  198. package/.ctxman/self-knowledge/documents.lance/_versions/4.manifest +0 -0
  199. package/.ctxman/self-knowledge/documents.lance/_versions/5.manifest +0 -0
  200. package/.ctxman/self-knowledge/documents.lance/_versions/6.manifest +0 -0
  201. package/.ctxman/self-knowledge/documents.lance/_versions/7.manifest +0 -0
  202. package/.ctxman/self-knowledge/documents.lance/_versions/8.manifest +0 -0
  203. package/.ctxman/self-knowledge/documents.lance/_versions/9.manifest +0 -0
  204. package/.ctxman/self-knowledge/documents.lance/data/000010010011011101000010de8621405d9d5cb06540dbf02c.lance +0 -0
  205. package/.ctxman/self-knowledge/documents.lance/data/0000101001011100011000003fb62a4aa8978974075c144f1c.lance +0 -0
  206. package/.ctxman/self-knowledge/documents.lance/data/000011010000100111001011c6cc824d628f3bb1f4e04cd5d0.lance +0 -0
  207. package/.ctxman/self-knowledge/documents.lance/data/001000001000011001011100d8f74349ada090b332cd1df669.lance +0 -0
  208. package/.ctxman/self-knowledge/documents.lance/data/01000001111010001000010045ab44467bb1e7e4d8ae06bd58.lance +0 -0
  209. package/.ctxman/self-knowledge/documents.lance/data/01000101101110111110011131ef904241a89e1ffb6ddaf8e3.lance +0 -0
  210. package/.ctxman/self-knowledge/documents.lance/data/010010110000010000011010fbfcc145c6a8a827b28057a07e.lance +0 -0
  211. package/.ctxman/self-knowledge/documents.lance/data/1000011000101010001110003fb4f045c3835982efa1405324.lance +0 -0
  212. package/.ctxman/self-knowledge/documents.lance/data/100111011101110111101011f4396b410fa06af3b028d204e6.lance +0 -0
  213. package/.ctxman/self-knowledge/documents.lance/data/100111100111101000001100596b174e00995d6cc2969cc8dc.lance +0 -0
  214. package/.ctxman/self-knowledge/documents.lance/data/1010001100011000110010102ea16b484d887c7c9725feffd6.lance +0 -0
  215. package/.ctxman/self-knowledge/documents.lance/data/101101100010101111110111c5230944d9b3af7301b6392dda.lance +0 -0
  216. package/.ctxman/self-knowledge/documents.lance/data/1011011100100111111110105892bf41b5a530fedd7cf516f1.lance +0 -0
  217. package/.ctxman/self-knowledge/documents.lance/data/10111110000010001011110164e8774742bade87b483c10f36.lance +0 -0
  218. package/.ctxman/self-knowledge/documents.lance/data/1100000100010110001110103ffaca40a2a42c85067ebaf9ae.lance +0 -0
  219. package/.ctxman/self-knowledge/documents.lance/data/110000010001110110101110664bde4c76a78dfc14b05e83b8.lance +0 -0
  220. package/.ctxman/self-knowledge/documents.lance/data/11001100111000010100110050645c4281b1f35b2022234f7f.lance +0 -0
  221. package/.ctxman/self-knowledge/documents.lance/data/1101111011001100110111017214924a368f5719eab2246619.lance +0 -0
  222. package/.ctxman/self-knowledge/documents.lance/data/1110000111001010001000002150c24dcab653d39d07032e63.lance +0 -0
  223. package/.ctxman/self-knowledge/documents.lance/data/1110100000000100000011014d20534967a18b5c87721659ff.lance +0 -0
  224. package/.ctxman/self-knowledge/documents.lance/data/11110101111010000101011135a0114ef2b35dc6f1297a3381.lance +0 -0
package/index.js CHANGED
@@ -27,41 +27,65 @@ import { Logger, getLogger, createLogger } from './lib/utils/logger.js'; // v2.3
27
27
  import Updater from './lib/utils/updater.js'; // v2.3.6+
28
28
  import GitUtils from './lib/utils/git-utils.js'; // v2.3.6+
29
29
 
30
+ // Pull-request review context
31
+ import { buildPrContext } from './lib/pr/pr-context.js';
32
+
30
33
  // Orchestrator functions
31
34
  import { generateDigestFromReport, generateDigestFromContext } from './ctxman.js';
32
35
 
36
+ // Repository map (`ctxman map`)
37
+ import { buildRepoGraph, rankFiles, renderRepoMap } from './lib/map/index.js';
38
+
39
+ // Code history explanation (`ctxman why`)
40
+ import { explainHistory } from './lib/why/index.js';
41
+ // File contents in one document (`ctxman pack`)
42
+ import { packContext } from './lib/pack/index.js';
43
+
33
44
  export {
34
- // Analyzers
35
- TokenCalculator,
36
- MethodAnalyzer,
37
-
38
- // Parsers
39
- GitIgnoreParser,
40
- MethodFilterParser,
41
-
42
- // Formatters
43
- GitIngestFormatter,
44
- ToonFormatter,
45
- FormatRegistry,
46
-
47
- // Utils
48
- TokenUtils,
49
- FileUtils,
50
- ClipboardUtils,
51
- ConfigUtils,
52
- FormatConverter,
53
- ErrorHandler,
54
-
55
- // v2.3.6+ Utils
56
- Logger,
57
- getLogger,
58
- createLogger,
59
- Updater,
60
- GitUtils,
61
-
62
- // Functions
63
- generateDigestFromReport,
64
- generateDigestFromContext
45
+ // Analyzers
46
+ TokenCalculator,
47
+ MethodAnalyzer,
48
+
49
+ // Parsers
50
+ GitIgnoreParser,
51
+ MethodFilterParser,
52
+
53
+ // Formatters
54
+ GitIngestFormatter,
55
+ ToonFormatter,
56
+ FormatRegistry,
57
+
58
+ // Utils
59
+ TokenUtils,
60
+ FileUtils,
61
+ ClipboardUtils,
62
+ ConfigUtils,
63
+ FormatConverter,
64
+ ErrorHandler,
65
+
66
+ // v2.3.6+ Utils
67
+ Logger,
68
+ getLogger,
69
+ createLogger,
70
+ Updater,
71
+ GitUtils,
72
+
73
+ // Functions
74
+ generateDigestFromReport,
75
+ generateDigestFromContext,
76
+
77
+ // Repository map
78
+ buildRepoGraph,
79
+ rankFiles,
80
+ renderRepoMap,
81
+
82
+ // Pull-request context
83
+ buildPrContext,
84
+
85
+ // Code history explanation (`ctxman why`)
86
+ explainHistory,
87
+ // Packed file contents
88
+ packContext,
65
89
  };
66
90
 
67
91
  // Alias for backward compatibility
@@ -1,19 +1,22 @@
1
1
  import { ContextBuilder } from '../core/ContextBuilder.js';
2
2
  import { Scanner } from '../core/Scanner.js';
3
3
  import { Analyzer } from '../core/Analyzer.js';
4
+ import { DEFAULT_TARGET_MODEL } from '../utils/llm-detector.js';
4
5
 
5
6
  export class PRFailureAgent {
6
7
  constructor(projectRoot, options = {}) {
7
8
  this.projectRoot = projectRoot;
8
9
  this.options = options;
9
-
10
+
10
11
  // Initialize core components or use injected ones
11
12
  this.scanner = options.scanner || new Scanner(projectRoot);
12
13
  this.analyzer = options.analyzer || new Analyzer({ methodLevel: true }); // Enable method level for better context
13
- this.contextBuilder = options.contextBuilder || new ContextBuilder({
14
- targetModel: 'gpt-4', // Default to high capacity model
15
- ...options
16
- });
14
+ this.contextBuilder =
15
+ options.contextBuilder ||
16
+ new ContextBuilder({
17
+ targetModel: DEFAULT_TARGET_MODEL,
18
+ ...options,
19
+ });
17
20
  }
18
21
 
19
22
  /**
@@ -25,42 +28,42 @@ export class PRFailureAgent {
25
28
  async run(ciLog, diff) {
26
29
  // 1. Extract error from log
27
30
  const error = this.extractError(ciLog);
28
-
31
+
29
32
  // 2. Identify relevant files
30
33
  const relevantFiles = this.identifyRelevantFiles(error, diff);
31
-
34
+
32
35
  // 3. Scan codebase
33
36
  const allFiles = this.scanner.scan();
34
-
37
+
35
38
  // Filter for relevant files
36
39
  // If no specific files identified, we might fallback to all (or risk context overflow)
37
40
  // For POC, we'll try to fuzzy match the relevant files against scanned files
38
41
  let targetFiles = allFiles;
39
-
42
+
40
43
  if (relevantFiles.length > 0) {
41
- targetFiles = allFiles.filter(file => {
42
- return relevantFiles.some(relevant => file.relativePath.endsWith(relevant));
44
+ targetFiles = allFiles.filter((file) => {
45
+ return relevantFiles.some((relevant) => file.relativePath.endsWith(relevant));
43
46
  });
44
47
  }
45
48
 
46
49
  // 4. Analyze relevant files
47
50
  const analysis = await this.analyzer.analyze(targetFiles);
48
-
51
+
49
52
  // 5. Build Context
50
53
  const context = this.contextBuilder.build(analysis);
51
-
54
+
52
55
  // 6. Construct Prompt
53
56
  const prompt = this.constructPrompt(error, diff, context);
54
-
57
+
55
58
  // 7. Generate Fix
56
59
  const fix = await this.generateFix(prompt);
57
-
60
+
58
61
  return fix;
59
62
  }
60
63
 
61
64
  /**
62
65
  * Extract error message from CI log
63
- * @param {string} log
66
+ * @param {string} log
64
67
  * @returns {string}
65
68
  */
66
69
  extractError(log) {
@@ -68,32 +71,32 @@ export class PRFailureAgent {
68
71
  // Matches "Error:", "FAIL", "Exception" and the rest of the line
69
72
  const errorRegex = /(?:Error:|FAIL|Exception:|Caused by:).*/gi;
70
73
  const matches = log.match(errorRegex);
71
-
74
+
72
75
  if (matches && matches.length > 0) {
73
76
  // Return the unique errors found, joined
74
77
  return [...new Set(matches)].join('\n');
75
78
  }
76
-
77
- return "Could not extract specific error message from log.";
79
+
80
+ return 'Could not extract specific error message from log.';
78
81
  }
79
82
 
80
83
  /**
81
84
  * Identify relevant files from error and diff
82
- * @param {string} error
83
- * @param {string} diff
85
+ * @param {string} error
86
+ * @param {string} diff
84
87
  * @returns {string[]} - Array of file paths/names
85
88
  */
86
89
  identifyRelevantFiles(error, diff) {
87
90
  const files = new Set();
88
-
91
+
89
92
  // Regex for common source file extensions, allowing paths
90
93
  // Order matters: longer extensions first to avoid partial matches (e.g., .ts matching .tsx)
91
94
  const fileExtRegex = /[\w\-./]+\.(tsx|jsx|ts|js|py|java|rb|go|c|cpp|hpp|h|rs|php)/gi;
92
-
95
+
93
96
  // Find files in error message
94
97
  const errorFiles = error.match(fileExtRegex) || [];
95
- errorFiles.forEach(f => files.add(f));
96
-
98
+ errorFiles.forEach((f) => files.add(f));
99
+
97
100
  // Find files in diff
98
101
  // Look for lines like "diff --git a/path/to/file.js b/path/to/file.js"
99
102
  // or "+++ b/path/to/file.js"
@@ -102,7 +105,7 @@ export class PRFailureAgent {
102
105
  while ((match = diffFileRegex.exec(diff)) !== null) {
103
106
  const fullPath = match[1].trim();
104
107
  // extracting just the filename might be safer for fuzzy matching if paths differ
105
- // but let's try to keep the path if possible.
108
+ // but let's try to keep the path if possible.
106
109
  // scanner returns relativePath, so if we capture relative path here it's good.
107
110
  files.add(fullPath);
108
111
  }
@@ -112,29 +115,29 @@ export class PRFailureAgent {
112
115
 
113
116
  /**
114
117
  * Construct the prompt for the LLM
115
- * @param {string} error
116
- * @param {string} diff
117
- * @param {object} context
118
+ * @param {string} error
119
+ * @param {string} diff
120
+ * @param {object} context
118
121
  * @returns {string}
119
122
  */
120
123
  constructPrompt(error, diff, context) {
121
124
  // In a real agent, we might use a template engine or more sophisticated structure
122
-
125
+
123
126
  const contextSummary = this.contextBuilder.getSummary(context);
124
-
127
+
125
128
  // Serialize files from context
126
129
  // context.files is an object where keys are directories, values are arrays of file objects
127
130
  // We need the content, but ContextBuilder (in the version I saw) returns metadata.
128
131
  // Wait, Analyzer reads the content to count tokens, but does it return it?
129
132
  // Checking Analyzer.js: it returns { path, tokens, ... } but NOT content.
130
- //
131
- // Issue: The ContextBuilder builds metadata/structure but might not include full content
133
+ //
134
+ // Issue: The ContextBuilder builds metadata/structure but might not include full content
132
135
  // depending on how it was implemented or intended.
133
- //
136
+ //
134
137
  // Re-reading Analyzer.js: "const content = fs.readFileSync..." -> calculates tokens -> returns analysis object.
135
138
  // The analysis object does NOT contain 'content'.
136
139
  //
137
- // So for the prompt, I actually need the CONTENT.
140
+ // So for the prompt, I actually need the CONTENT.
138
141
  // The current ContextBuilder seems to be for *sizing* or *listing* context, or maybe I missed where content is stored.
139
142
  //
140
143
  // Let's re-read ContextBuilder build() method.
@@ -146,15 +149,15 @@ export class PRFailureAgent {
146
149
  // Or maybe it relies on the user to read the files based on the list?
147
150
  //
148
151
  // To make a functional POC, I should probably read the content of the relevant files.
149
- //
152
+ //
150
153
  // I will add a step to read content for the prompt.
151
-
152
- let fileContentsSection = "";
153
-
154
+
155
+ let _fileContentsSection = '';
156
+
154
157
  // Since I can't easily change the Analyzer/ContextBuilder right now without Scope creep,
155
- // I will just list the files and Mock the content reading for the prompt construction
158
+ // I will just list the files and Mock the content reading for the prompt construction
156
159
  // or import fs to read them.
157
-
160
+
158
161
  return `
159
162
  You are a PR Failure Fixing Agent.
160
163
 
@@ -177,13 +180,13 @@ Please analyze the error and the code, and provide a fix.
177
180
 
178
181
  /**
179
182
  * Mock LLM Generation
180
- * @param {string} prompt
183
+ * @param {string} prompt
181
184
  * @returns {Promise<string>}
182
185
  */
183
- async generateFix(prompt) {
186
+ async generateFix(_prompt) {
184
187
  // Simulate LLM delay
185
- await new Promise(resolve => setTimeout(resolve, 100));
186
-
188
+ await new Promise((resolve) => setTimeout(resolve, 100));
189
+
187
190
  return `
188
191
  Here is the fix for the reported error:
189
192