ctxman 3.0.0 → 3.1.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.
- package/.ctxman/llm-profiles.json +1067 -39
- package/.ctxman/profiles/backend-team.json +13 -0
- package/.ctxman/profiles/default.json +12 -0
- package/.ctxman/profiles/devops-team.json +21 -0
- package/.ctxman/profiles/frontend-team.json +20 -0
- package/.ctxman/templates/bug-fix.json +17 -0
- package/.ctxman/templates/code-review.json +9 -0
- package/.ctxman/templates/documentation.json +9 -0
- package/.ctxman/templates/feature.json +9 -0
- package/.ctxman/templates/full-context.json +9 -0
- package/.ctxman/templates/refactoring.json +18 -0
- package/.ctxman/templates/testing.json +9 -0
- package/.ctxman/wizard-profiles/security-audit/profile.json +7 -1
- package/LICENSE +21 -0
- package/README.md +380 -136
- package/bin/cli.js +1880 -529
- package/bin/cm-ask.js +18 -13
- package/bin/cm-audit.js +124 -0
- package/bin/cm-count.js +151 -0
- package/bin/cm-gitingest.js +128 -115
- package/bin/cm-map.js +242 -0
- package/bin/cm-mcp.js +293 -0
- package/bin/cm-pack.js +405 -0
- package/bin/cm-policy.js +170 -0
- package/bin/cm-pr.js +248 -0
- package/bin/cm-search.js +178 -0
- package/bin/cm-update.js +128 -128
- package/bin/cm-why.js +197 -0
- package/bin/mcp-server.js +8 -24
- package/ctxman.js +237 -183
- package/examples/README.md +19 -4
- package/examples/github-actions/ctxman-check.yml +49 -0
- package/examples/wizard-profiles/security-audit/profile.json +7 -1
- package/index.d.ts +1422 -0
- package/index.js +55 -31
- package/lib/agents/pr-failure-agent.js +48 -45
- package/lib/analyzers/ai-suggester.js +451 -0
- package/lib/analyzers/dependency-scanner.js +505 -0
- package/lib/analyzers/duplicate-detector.js +264 -0
- package/lib/analyzers/go-method-analyzer.js +151 -110
- package/lib/analyzers/import-tracker.js +431 -0
- package/lib/analyzers/method-analyzer.js +1055 -434
- package/lib/analyzers/performance-dashboard.js +683 -0
- package/lib/analyzers/token-calculator.js +895 -504
- package/lib/analyzers/unused-exports-detector.js +336 -0
- package/lib/api/mcp/install.js +424 -0
- package/lib/api/mcp/prompts.js +281 -281
- package/lib/api/mcp/resources.js +300 -241
- package/lib/api/mcp/sandbox.js +89 -0
- package/lib/api/mcp/server.js +675 -312
- package/lib/api/mcp/start.js +125 -0
- package/lib/api/mcp/transports/HttpSseTransport.js +60 -52
- package/lib/api/rest/server.js +105 -28
- package/lib/cache/CacheManager.js +9 -17
- package/lib/core/Analyzer.js +16 -10
- package/lib/core/ContextBuilder.js +19 -28
- package/lib/core/Reporter.js +15 -14
- package/lib/core/Scanner.js +81 -12
- package/lib/count/index.js +100 -0
- package/lib/formatters/format-registry.js +394 -372
- package/lib/formatters/gitingest-formatter.js +656 -621
- package/lib/formatters/toon-formatter-v1.3.js +637 -632
- package/lib/formatters/toon-formatter.js +239 -240
- package/lib/integrations/git/BlameTracker.js +4 -4
- package/lib/integrations/git/DiffAnalyzer.js +38 -31
- package/lib/integrations/git/GitClient.js +71 -53
- package/lib/lsp/server.js +311 -0
- package/lib/map/graph.js +299 -0
- package/lib/map/imports.js +233 -0
- package/lib/map/index.js +33 -0
- package/lib/map/rank.js +253 -0
- package/lib/map/render.js +346 -0
- package/lib/map/resolver.js +574 -0
- package/lib/pack/budget.js +111 -0
- package/lib/pack/code-lexer.js +360 -0
- package/lib/pack/compress.js +414 -0
- package/lib/pack/index.js +354 -0
- package/lib/pack/renderers/common.js +134 -0
- package/lib/pack/renderers/index.js +24 -0
- package/lib/pack/renderers/json.js +47 -0
- package/lib/pack/renderers/markdown.js +54 -0
- package/lib/pack/renderers/plain.js +38 -0
- package/lib/pack/renderers/xml.js +85 -0
- package/lib/pack/select.js +177 -0
- package/lib/pack/split.js +182 -0
- package/lib/pack/tree.js +35 -0
- package/lib/parsers/gitignore-parser.js +113 -107
- package/lib/parsers/method-filter-parser.js +50 -33
- package/lib/plugins/ExporterPlugin.js +3 -3
- package/lib/plugins/LanguagePlugin.js +3 -3
- package/lib/plugins/PluginManager.js +7 -13
- package/lib/policy/audit.js +294 -0
- package/lib/policy/enforce.js +125 -0
- package/lib/policy/ignore-files.js +169 -0
- package/lib/policy/index.js +52 -0
- package/lib/policy/policy.js +489 -0
- package/lib/pr/diff-parser.js +267 -0
- package/lib/pr/method-mapper.js +148 -0
- package/lib/pr/pr-context.js +829 -0
- package/lib/pr/pr-git.js +149 -0
- package/lib/pr/pr-renderer.js +644 -0
- package/lib/pr/related-tests.js +296 -0
- package/lib/rag/DataSourcePlugin.js +5 -5
- package/lib/rag/EmbeddingProvider.js +19 -8
- package/lib/rag/Indexer.js +14 -5
- package/lib/rag/VectorStoreFactory.js +3 -3
- package/lib/rag/sources/FileDataSource.js +6 -6
- package/lib/rag/stores/BaseVectorStore.js +5 -5
- package/lib/rag/stores/ChromaDBStore.js +10 -10
- package/lib/rag/stores/LanceDBStore.js +29 -19
- package/lib/rag/stores/PineconeStore.js +11 -9
- package/lib/search/bm25.js +433 -0
- package/lib/search/code-units.js +201 -0
- package/lib/search/symbols.js +189 -0
- package/lib/ui/dashboard.js +120 -89
- package/lib/ui/index.js +1 -6
- package/lib/ui/init-wizard-ui.js +550 -0
- package/lib/ui/progress-bar.js +94 -88
- package/lib/ui/select-input.js +40 -32
- package/lib/ui/template-selector.js +99 -0
- package/lib/ui/wizard.js +374 -329
- package/lib/utils/claude-token-counter.js +151 -0
- package/lib/utils/cli-output.js +17 -0
- package/lib/utils/clipboard-utils.js +49 -50
- package/lib/utils/config-utils.js +81 -66
- package/lib/utils/context-versioning.js +532 -0
- package/lib/utils/error-handler.js +112 -112
- package/lib/utils/file-utils.js +153 -69
- package/lib/utils/format-converter.js +356 -283
- package/lib/utils/git-utils.js +366 -294
- package/lib/utils/llm-cost-estimator.js +281 -0
- package/lib/utils/llm-detector.js +242 -78
- package/lib/utils/logger.js +243 -237
- package/lib/utils/messages.js +355 -0
- package/lib/utils/multi-repo-manager.js +364 -0
- package/lib/utils/profile-manager.js +380 -0
- package/lib/utils/safe-read.js +61 -0
- package/lib/utils/secret-redactor.js +61 -0
- package/lib/utils/snapshot-manager.js +679 -0
- package/lib/utils/template-manager.js +378 -0
- package/lib/utils/token-utils.js +201 -170
- package/lib/utils/tokenizer-adapter.js +421 -377
- package/lib/utils/updater.js +539 -506
- package/lib/watch/FileWatcher.js +12 -8
- package/lib/watch/IncrementalAnalyzer.js +7 -7
- package/lib/why/coupling.js +81 -0
- package/lib/why/errors.js +23 -0
- package/lib/why/git.js +169 -0
- package/lib/why/history.js +108 -0
- package/lib/why/index.js +720 -0
- package/lib/why/ownership.js +79 -0
- package/lib/why/paths.js +207 -0
- package/lib/why/references.js +259 -0
- package/lib/why/render.js +722 -0
- package/lib/why/search.js +358 -0
- package/lib/why/target.js +389 -0
- package/lib/wizards/config-generator.js +255 -0
- package/lib/wizards/project-detector.js +571 -0
- package/package.json +44 -10
- package/.ctxman/logs/ctxman-2026-07-02.log +0 -156
- package/.ctxman/self-knowledge/documents.lance/_transactions/0-b3dd1558-f95b-44b9-a154-18e8c330ae7a.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/1-44bff6d4-e552-4010-a769-e09ad822698d.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/10-37260794-5947-4ecb-b4c8-d732f58f40f1.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/11-0d52a883-5518-463c-9b6d-986c3af89dfd.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/12-ae354646-52f2-49c9-90fb-2e6ed8932663.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/13-5d7d5e57-27da-498b-b734-091b9d38da13.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/14-558ce928-810b-4252-a364-fdd1ee6f8a25.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/15-27e3a58f-8b64-43b8-a9f4-e3369446968b.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/16-a110c390-e5c8-4464-b976-bc7f5195fa15.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/17-97513225-53de-4216-b61a-6337bd0cc4ad.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/18-5ba450f0-c527-459c-bf4f-6d79b5e4285f.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/19-600d3a63-5225-49e9-b8b7-30e037b564ab.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/2-48a61b4e-92cf-4342-8376-914c1b99a9f9.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/20-121dd912-5410-410e-84ff-82c7a23604a0.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/3-bc6844ab-7ea3-4bb3-9ee1-538ce5664a9c.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/4-d5e1754f-dbb5-454e-a9be-2a7da8d7bcf9.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/5-4fae93df-0568-4b6f-8acf-8bef4bba6047.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/6-4b1b8b87-068e-49a3-ba2b-d8dae628b252.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/7-63d040fb-d2fa-4c0f-bed0-53411918a7b0.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/8-c5628cf6-264c-420f-aab8-bc96a9083591.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/9-c94570aa-5e53-4fcb-971f-cecc1d1d5492.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/1.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/10.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/11.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/12.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/13.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/14.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/15.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/16.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/17.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/18.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/19.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/2.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/20.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/21.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/3.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/4.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/5.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/6.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/7.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/8.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/9.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/000010010011011101000010de8621405d9d5cb06540dbf02c.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/0000101001011100011000003fb62a4aa8978974075c144f1c.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/000011010000100111001011c6cc824d628f3bb1f4e04cd5d0.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/001000001000011001011100d8f74349ada090b332cd1df669.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/01000001111010001000010045ab44467bb1e7e4d8ae06bd58.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/01000101101110111110011131ef904241a89e1ffb6ddaf8e3.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/010010110000010000011010fbfcc145c6a8a827b28057a07e.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1000011000101010001110003fb4f045c3835982efa1405324.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/100111011101110111101011f4396b410fa06af3b028d204e6.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/100111100111101000001100596b174e00995d6cc2969cc8dc.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1010001100011000110010102ea16b484d887c7c9725feffd6.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/101101100010101111110111c5230944d9b3af7301b6392dda.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1011011100100111111110105892bf41b5a530fedd7cf516f1.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/10111110000010001011110164e8774742bade87b483c10f36.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1100000100010110001110103ffaca40a2a42c85067ebaf9ae.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/110000010001110110101110664bde4c76a78dfc14b05e83b8.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/11001100111000010100110050645c4281b1f35b2022234f7f.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1101111011001100110111017214924a368f5719eab2246619.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1110000111001010001000002150c24dcab653d39d07032e63.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1110100000000100000011014d20534967a18b5c87721659ff.lance +0 -0
- 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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 =
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
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
|
|
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(
|
|
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
|
|