ghagga-core 2.9.1 → 3.0.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/LICENSE +21 -0
- package/dist/agents/consensus.d.ts.map +1 -1
- package/dist/agents/consensus.js +7 -2
- package/dist/agents/consensus.js.map +1 -1
- package/dist/agents/diagnostic.d.ts.map +1 -1
- package/dist/agents/diagnostic.js +7 -2
- package/dist/agents/diagnostic.js.map +1 -1
- package/dist/agents/fan-out-lenses.d.ts.map +1 -1
- package/dist/agents/fan-out-lenses.js +7 -2
- package/dist/agents/fan-out-lenses.js.map +1 -1
- package/dist/agents/prompts.d.ts +49 -1
- package/dist/agents/prompts.d.ts.map +1 -1
- package/dist/agents/prompts.js +133 -5
- package/dist/agents/prompts.js.map +1 -1
- package/dist/agents/simple.d.ts +1 -1
- package/dist/agents/simple.d.ts.map +1 -1
- package/dist/agents/simple.js +6 -4
- package/dist/agents/simple.js.map +1 -1
- package/dist/agents/workflow.d.ts.map +1 -1
- package/dist/agents/workflow.js +13 -4
- package/dist/agents/workflow.js.map +1 -1
- package/dist/critique/critique.d.ts.map +1 -1
- package/dist/critique/critique.js +14 -6
- package/dist/critique/critique.js.map +1 -1
- package/dist/diff/index.d.ts +12 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +11 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/parse.d.ts +41 -0
- package/dist/diff/parse.d.ts.map +1 -0
- package/dist/diff/parse.js +303 -0
- package/dist/diff/parse.js.map +1 -0
- package/dist/diff/types.d.ts +106 -0
- package/dist/diff/types.d.ts.map +1 -0
- package/dist/diff/types.js +23 -0
- package/dist/diff/types.js.map +1 -0
- package/dist/embed.d.ts +5 -2
- package/dist/embed.d.ts.map +1 -1
- package/dist/embed.js +7 -3
- package/dist/embed.js.map +1 -1
- package/dist/enhance/prompt.d.ts +5 -1
- package/dist/enhance/prompt.d.ts.map +1 -1
- package/dist/enhance/prompt.js +9 -2
- package/dist/enhance/prompt.js.map +1 -1
- package/dist/format.d.ts +31 -0
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +256 -15
- package/dist/format.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/pageindex/index.d.ts +2 -2
- package/dist/memory/pageindex/index.d.ts.map +1 -1
- package/dist/memory/pageindex/index.js.map +1 -1
- package/dist/memory/pageindex/service.d.ts +10 -1
- package/dist/memory/pageindex/service.d.ts.map +1 -1
- package/dist/memory/pageindex/service.js +2 -2
- package/dist/memory/pageindex/service.js.map +1 -1
- package/dist/memory/persist.d.ts.map +1 -1
- package/dist/memory/persist.js +10 -3
- package/dist/memory/persist.js.map +1 -1
- package/dist/memory/privacy.d.ts.map +1 -1
- package/dist/memory/privacy.js +45 -6
- package/dist/memory/privacy.js.map +1 -1
- package/dist/memory/sqlite.d.ts +1 -13
- package/dist/memory/sqlite.d.ts.map +1 -1
- package/dist/memory/sqlite.js +45 -27
- package/dist/memory/sqlite.js.map +1 -1
- package/dist/memory/taxonomy.d.ts.map +1 -1
- package/dist/memory/taxonomy.js +6 -1
- package/dist/memory/taxonomy.js.map +1 -1
- package/dist/pipeline/degrade.d.ts +61 -0
- package/dist/pipeline/degrade.d.ts.map +1 -0
- package/dist/pipeline/degrade.js +58 -0
- package/dist/pipeline/degrade.js.map +1 -0
- package/dist/pipeline/enrich.d.ts +29 -0
- package/dist/pipeline/enrich.d.ts.map +1 -0
- package/dist/pipeline/enrich.js +271 -0
- package/dist/pipeline/enrich.js.map +1 -0
- package/dist/pipeline/execute.d.ts +22 -0
- package/dist/pipeline/execute.d.ts.map +1 -0
- package/dist/pipeline/execute.js +250 -0
- package/dist/pipeline/execute.js.map +1 -0
- package/dist/pipeline/finalize.d.ts +26 -0
- package/dist/pipeline/finalize.d.ts.map +1 -0
- package/dist/pipeline/finalize.js +52 -0
- package/dist/pipeline/finalize.js.map +1 -0
- package/dist/pipeline/gather-context.d.ts +25 -0
- package/dist/pipeline/gather-context.d.ts.map +1 -0
- package/dist/pipeline/gather-context.js +169 -0
- package/dist/pipeline/gather-context.js.map +1 -0
- package/dist/pipeline/gather-safe.d.ts +39 -0
- package/dist/pipeline/gather-safe.d.ts.map +1 -0
- package/dist/pipeline/gather-safe.js +127 -0
- package/dist/pipeline/gather-safe.js.map +1 -0
- package/dist/pipeline/prepare-graph.d.ts +54 -0
- package/dist/pipeline/prepare-graph.d.ts.map +1 -0
- package/dist/pipeline/prepare-graph.js +174 -0
- package/dist/pipeline/prepare-graph.js.map +1 -0
- package/dist/pipeline/prepare.d.ts +40 -0
- package/dist/pipeline/prepare.d.ts.map +1 -0
- package/dist/pipeline/prepare.js +233 -0
- package/dist/pipeline/prepare.js.map +1 -0
- package/dist/pipeline/providers.d.ts +54 -0
- package/dist/pipeline/providers.d.ts.map +1 -0
- package/dist/pipeline/providers.js +163 -0
- package/dist/pipeline/providers.js.map +1 -0
- package/dist/pipeline/results.d.ts +35 -0
- package/dist/pipeline/results.d.ts.map +1 -0
- package/dist/pipeline/results.js +122 -0
- package/dist/pipeline/results.js.map +1 -0
- package/dist/pipeline/state.d.ts +92 -0
- package/dist/pipeline/state.d.ts.map +1 -0
- package/dist/pipeline/state.js +13 -0
- package/dist/pipeline/state.js.map +1 -0
- package/dist/pipeline.d.ts +10 -9
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +36 -1213
- package/dist/pipeline.js.map +1 -1
- package/dist/providers/gateway.d.ts.map +1 -1
- package/dist/providers/gateway.js +8 -0
- package/dist/providers/gateway.js.map +1 -1
- package/dist/recursive/index.d.ts +1 -0
- package/dist/recursive/index.d.ts.map +1 -1
- package/dist/recursive/index.js +7 -3
- package/dist/recursive/index.js.map +1 -1
- package/dist/recursive/patch-extractor.d.ts +58 -6
- package/dist/recursive/patch-extractor.d.ts.map +1 -1
- package/dist/recursive/patch-extractor.js +207 -26
- package/dist/recursive/patch-extractor.js.map +1 -1
- package/dist/sanitize.d.ts +51 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +90 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/scope/diff-mapper.d.ts +12 -0
- package/dist/scope/diff-mapper.d.ts.map +1 -1
- package/dist/scope/diff-mapper.js +25 -18
- package/dist/scope/diff-mapper.js.map +1 -1
- package/dist/scope/entity-diff.d.ts +21 -4
- package/dist/scope/entity-diff.d.ts.map +1 -1
- package/dist/scope/entity-diff.js +132 -34
- package/dist/scope/entity-diff.js.map +1 -1
- package/dist/scope/types.d.ts +10 -0
- package/dist/scope/types.d.ts.map +1 -1
- package/dist/semantic-diff/index.d.ts +25 -2
- package/dist/semantic-diff/index.d.ts.map +1 -1
- package/dist/semantic-diff/index.js +147 -53
- package/dist/semantic-diff/index.js.map +1 -1
- package/dist/tools/gitleaks-config.toml +35 -0
- package/dist/tools/plugins/gitleaks.d.ts +10 -0
- package/dist/tools/plugins/gitleaks.d.ts.map +1 -1
- package/dist/tools/plugins/gitleaks.js +29 -2
- package/dist/tools/plugins/gitleaks.js.map +1 -1
- package/dist/tools/plugins/semgrep.d.ts +11 -0
- package/dist/tools/plugins/semgrep.d.ts.map +1 -1
- package/dist/tools/plugins/semgrep.js +30 -1
- package/dist/tools/plugins/semgrep.js.map +1 -1
- package/dist/tools/semgrep-rules.yml +305 -0
- package/dist/types.d.ts +51 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/diff.d.ts +22 -2
- package/dist/utils/diff.d.ts.map +1 -1
- package/dist/utils/diff.js +36 -40
- package/dist/utils/diff.js.map +1 -1
- package/package.json +21 -22
- package/dist/providers/fallback.d.ts +0 -54
- package/dist/providers/fallback.d.ts.map +0 -1
- package/dist/providers/fallback.js +0 -102
- package/dist/providers/fallback.js.map +0 -1
- package/dist/providers/index.d.ts +0 -49
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -146
- package/dist/providers/index.js.map +0 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph-powered prepare steps: 2.5 blast-radius filter + 2.6 call-chain
|
|
3
|
+
* / reverse-deps context.
|
|
4
|
+
*
|
|
5
|
+
* Phase-private sibling of `prepare.ts` — split out so prepare stays under
|
|
6
|
+
* the 300-line module cap (same precedent as `gather-safe.ts` for the
|
|
7
|
+
* gather-context phase). Exported only because TS module boundaries
|
|
8
|
+
* require it; the ONLY intended importer is `prepare.ts`.
|
|
9
|
+
*
|
|
10
|
+
* Step bodies are moved LITERAL from the original `reviewPipeline`:
|
|
11
|
+
* - Blast-radius keeps its BESPOKE catch (sets a fallback
|
|
12
|
+
* `blastRadiusMetadata` and warns with the RAW error, not `.message`) —
|
|
13
|
+
* deliberately NOT migrated to `runDegradable` (see degrade.ts).
|
|
14
|
+
* - Call-chain degrades via `runDegradable` with `reportFailure: false`
|
|
15
|
+
* (DELIBERATE — warn only, never lands in failedSteps; pinned by the
|
|
16
|
+
* golden degradation suite). The degradation IS recorded in
|
|
17
|
+
* `warnOnlyDegradations` so `coverageComplete` reflects it.
|
|
18
|
+
*/
|
|
19
|
+
import { computeBlastRadius } from '../graph/blast-radius.js';
|
|
20
|
+
import { buildCallChainFromDiff } from '../graph/call-chain.js';
|
|
21
|
+
import { buildReverseDependencyMap, findDependents } from '../graph/reverse-deps.js';
|
|
22
|
+
import { isGraphStale } from '../graph/schema.js';
|
|
23
|
+
import { runDegradable } from './degrade.js';
|
|
24
|
+
/**
|
|
25
|
+
* Step 2.5: Blast-radius filter (optional).
|
|
26
|
+
* Narrows `filteredFiles`/`filteredDiff` to the blast radius when a
|
|
27
|
+
* dependency graph is available; falls back to the full diff otherwise.
|
|
28
|
+
*/
|
|
29
|
+
export async function applyBlastRadius(args) {
|
|
30
|
+
const { input, emit, failedSteps, fileList } = args;
|
|
31
|
+
let { filteredFiles, filteredDiff } = args;
|
|
32
|
+
let blastRadiusMetadata;
|
|
33
|
+
if (input.settings.enableBlastRadius && input.graphLoader) {
|
|
34
|
+
try {
|
|
35
|
+
const graph = await input.graphLoader.load();
|
|
36
|
+
if (graph) {
|
|
37
|
+
const metadata = await input.graphLoader.loadMetadata();
|
|
38
|
+
const stale = metadata ? isGraphStale(metadata) : false;
|
|
39
|
+
if (stale) {
|
|
40
|
+
emit({
|
|
41
|
+
step: 'blast-radius',
|
|
42
|
+
message: `Dependency graph is stale (last indexed: ${metadata?.lastIndexedAt})`,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const blastResult = computeBlastRadius(graph, fileList, {
|
|
46
|
+
maxDepth: input.settings.traversalDepth,
|
|
47
|
+
maxFiles: input.settings.maxBlastRadiusFiles,
|
|
48
|
+
});
|
|
49
|
+
if (blastResult.exceededCap) {
|
|
50
|
+
emit({
|
|
51
|
+
step: 'blast-radius',
|
|
52
|
+
message: `Blast radius exceeds ${input.settings.maxBlastRadiusFiles ?? 50} files — using full diff`,
|
|
53
|
+
});
|
|
54
|
+
blastRadiusMetadata = {
|
|
55
|
+
enabled: true,
|
|
56
|
+
graphAvailable: true,
|
|
57
|
+
totalFiles: filteredFiles.length,
|
|
58
|
+
blastRadiusFiles: filteredFiles.length,
|
|
59
|
+
fallbackReason: `blast radius exceeds ${input.settings.maxBlastRadiusFiles ?? 50} files`,
|
|
60
|
+
graphStale: stale,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Filter to blast-radius files
|
|
65
|
+
filteredFiles = filteredFiles.filter((f) => blastResult.files.has(f.path));
|
|
66
|
+
filteredDiff = filteredFiles.map((f) => f.content).join('\n');
|
|
67
|
+
emit({
|
|
68
|
+
step: 'blast-radius',
|
|
69
|
+
message: `Blast radius: ${blastResult.files.size} files (from ${fileList.length} in diff)`,
|
|
70
|
+
detail: [
|
|
71
|
+
` changed: ${blastResult.changedFiles.length}`,
|
|
72
|
+
` dependents: ${blastResult.dependents.length}`,
|
|
73
|
+
` tests: ${blastResult.testFiles.length}`,
|
|
74
|
+
].join('\n'),
|
|
75
|
+
});
|
|
76
|
+
blastRadiusMetadata = {
|
|
77
|
+
enabled: true,
|
|
78
|
+
graphAvailable: true,
|
|
79
|
+
totalFiles: fileList.length,
|
|
80
|
+
blastRadiusFiles: blastResult.files.size,
|
|
81
|
+
graphStale: stale,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
emit({ step: 'blast-radius', message: 'Blast radius: skipped (no graph available)' });
|
|
87
|
+
blastRadiusMetadata = {
|
|
88
|
+
enabled: true,
|
|
89
|
+
graphAvailable: false,
|
|
90
|
+
totalFiles: filteredFiles.length,
|
|
91
|
+
blastRadiusFiles: filteredFiles.length,
|
|
92
|
+
fallbackReason: 'no graph available',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.warn('[ghagga] Blast-radius failed (degrading gracefully):', error);
|
|
98
|
+
failedSteps.push({
|
|
99
|
+
step: 'blast-radius',
|
|
100
|
+
error: error instanceof Error ? error.message : String(error),
|
|
101
|
+
});
|
|
102
|
+
emit({ step: 'blast-radius', message: 'Blast radius: skipped (error loading graph)' });
|
|
103
|
+
blastRadiusMetadata = {
|
|
104
|
+
enabled: true,
|
|
105
|
+
graphAvailable: false,
|
|
106
|
+
totalFiles: filteredFiles.length,
|
|
107
|
+
blastRadiusFiles: filteredFiles.length,
|
|
108
|
+
fallbackReason: `error: ${error instanceof Error ? error.message : String(error)}`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { filteredFiles, filteredDiff, blastRadiusMetadata };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Step 2.6: Call-chain + reverse-deps context (optional, runs when
|
|
116
|
+
* blast-radius is enabled). Returns the prompt context string ('' when
|
|
117
|
+
* disabled, no symbols affected, or degraded).
|
|
118
|
+
*/
|
|
119
|
+
export async function buildCallChainContext(args) {
|
|
120
|
+
const { input, emit, failedSteps, warnOnlyDegradations, fileList, filteredDiff } = args;
|
|
121
|
+
let callChainContext = '';
|
|
122
|
+
if (input.settings.enableBlastRadius) {
|
|
123
|
+
// reportFailure: false is DELIBERATE — call-chain degrades with a warn only
|
|
124
|
+
// and never lands in failedSteps (pinned by the golden degradation suite).
|
|
125
|
+
// It IS recorded in warnOnlyDegradations → coverageComplete reflects it.
|
|
126
|
+
await runDegradable({ failedSteps, warnOnlyDegradations, emit }, {
|
|
127
|
+
step: 'call-chain',
|
|
128
|
+
warnLabel: '[ghagga] Call-chain/reverse-deps failed (degrading gracefully):',
|
|
129
|
+
reportFailure: false,
|
|
130
|
+
}, async () => {
|
|
131
|
+
if (input.fileReader) {
|
|
132
|
+
const fileContentsMap = new Map();
|
|
133
|
+
for (const fp of fileList) {
|
|
134
|
+
try {
|
|
135
|
+
const content = await input.fileReader(fp);
|
|
136
|
+
if (content)
|
|
137
|
+
fileContentsMap.set(fp, content);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// non-fatal — skip unreadable files
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (fileContentsMap.size > 0) {
|
|
144
|
+
const callChain = buildCallChainFromDiff(filteredDiff, fileContentsMap);
|
|
145
|
+
if (callChain.affectedSymbols.length > 0) {
|
|
146
|
+
const affectedFiles = [...new Set(callChain.affectedSymbols.map((s) => s.filePath))];
|
|
147
|
+
callChainContext = `\n## Call-Chain Impact\n${callChain.affectedSymbols.length} symbol(s) across ${affectedFiles.length} file(s) may be affected by these changes (depth: ${callChain.depth}).\n`;
|
|
148
|
+
emit({
|
|
149
|
+
step: 'call-chain',
|
|
150
|
+
message: `Call-chain: ${callChain.changedSymbols.length} changed symbol(s), ${callChain.affectedSymbols.length} affected symbol(s)`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const reverseDepMap = buildReverseDependencyMap([...fileContentsMap.keys()], fileContentsMap);
|
|
154
|
+
const highRiskFiles = [];
|
|
155
|
+
for (const fp of fileList) {
|
|
156
|
+
const result = findDependents(fp, reverseDepMap, 2);
|
|
157
|
+
if (result.transitiveCount >= 3) {
|
|
158
|
+
highRiskFiles.push(`${fp} (${result.transitiveCount} dependents)`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (highRiskFiles.length > 0) {
|
|
162
|
+
callChainContext += `\n## High-Risk Files (many dependents)\nThese changed files have many transitive dependents — review carefully:\n${highRiskFiles.map((f) => `- ${f}`).join('\n')}\n`;
|
|
163
|
+
emit({
|
|
164
|
+
step: 'reverse-deps',
|
|
165
|
+
message: `Reverse deps: ${highRiskFiles.length} high-risk file(s) detected`,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return callChainContext;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=prepare-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-graph.js","sourceRoot":"","sources":["../../src/pipeline/prepare-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepare phase: steps 1 → 4 of the review pipeline.
|
|
3
|
+
*
|
|
4
|
+
* 1 Validate input
|
|
5
|
+
* 2 Parse and filter the diff (path protection)
|
|
6
|
+
* 2.1 Flood / spam detection → may EARLY-RETURN a skipped result
|
|
7
|
+
* 2.2 All-files-filtered check → may EARLY-RETURN a skipped result
|
|
8
|
+
* 2.5 Blast-radius filter (prepare-graph.ts, bespoke catch)
|
|
9
|
+
* 2.6 Call-chain + reverse-deps (prepare-graph.ts, warn-only degrade)
|
|
10
|
+
* 3 Detect tech stacks
|
|
11
|
+
* 4 Token budget + diff truncation
|
|
12
|
+
*
|
|
13
|
+
* Because the two early-returns fire BEFORE a complete `PipelineStateBase`
|
|
14
|
+
* can exist (`fileList`/`allFiles` are readonly and only known post-parse),
|
|
15
|
+
* prepare CONSTRUCTS and RETURNS the base itself — analogous to how the
|
|
16
|
+
* execute phase returns the `ReviewResult` it creates. The outcome is a
|
|
17
|
+
* discriminated union: `early` carries the final `ReviewResult` (flood-skip
|
|
18
|
+
* / all-filtered), `continue` carries the base for the downstream phases.
|
|
19
|
+
*/
|
|
20
|
+
import type { ReviewInput, ReviewResult } from '../types.js';
|
|
21
|
+
import type { PipelineStateBase } from './state.js';
|
|
22
|
+
/**
|
|
23
|
+
* Result of the prepare phase.
|
|
24
|
+
* - `early`: the pipeline is done — return `result` as-is (flood-skip or
|
|
25
|
+
* all-files-filtered). No further phase runs.
|
|
26
|
+
* - `continue`: proceed with `base` through gather → execute → enrich →
|
|
27
|
+
* finalize.
|
|
28
|
+
*/
|
|
29
|
+
export type PrepareOutcome = {
|
|
30
|
+
readonly kind: 'early';
|
|
31
|
+
readonly result: ReviewResult;
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: 'continue';
|
|
34
|
+
readonly base: PipelineStateBase;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Run steps 1 → 4 and construct the shared `PipelineStateBase`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function prepare(input: ReviewInput): Promise<PrepareOutcome>;
|
|
40
|
+
//# sourceMappingURL=prepare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare.d.ts","sourceRoot":"","sources":["../../src/pipeline/prepare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAe,WAAW,EAAE,YAAY,EAAc,MAAM,aAAa,CAAC;AAOtF,OAAO,KAAK,EAAc,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAiEpE;;GAEG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CA8KzE"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepare phase: steps 1 → 4 of the review pipeline.
|
|
3
|
+
*
|
|
4
|
+
* 1 Validate input
|
|
5
|
+
* 2 Parse and filter the diff (path protection)
|
|
6
|
+
* 2.1 Flood / spam detection → may EARLY-RETURN a skipped result
|
|
7
|
+
* 2.2 All-files-filtered check → may EARLY-RETURN a skipped result
|
|
8
|
+
* 2.5 Blast-radius filter (prepare-graph.ts, bespoke catch)
|
|
9
|
+
* 2.6 Call-chain + reverse-deps (prepare-graph.ts, warn-only degrade)
|
|
10
|
+
* 3 Detect tech stacks
|
|
11
|
+
* 4 Token budget + diff truncation
|
|
12
|
+
*
|
|
13
|
+
* Because the two early-returns fire BEFORE a complete `PipelineStateBase`
|
|
14
|
+
* can exist (`fileList`/`allFiles` are readonly and only known post-parse),
|
|
15
|
+
* prepare CONSTRUCTS and RETURNS the base itself — analogous to how the
|
|
16
|
+
* execute phase returns the `ReviewResult` it creates. The outcome is a
|
|
17
|
+
* discriminated union: `early` carries the final `ReviewResult` (flood-skip
|
|
18
|
+
* / all-filtered), `continue` carries the base for the downstream phases.
|
|
19
|
+
*/
|
|
20
|
+
import { buildStackHints } from '../agents/prompts.js';
|
|
21
|
+
import { detectFlood } from '../flood/index.js';
|
|
22
|
+
import { filterDiffFiles, parseDiffFiles, truncateDiff } from '../utils/diff.js';
|
|
23
|
+
import { detectStacks } from '../utils/stack-detect.js';
|
|
24
|
+
import { calculateTokenBudget } from '../utils/token-budget.js';
|
|
25
|
+
import { applyBlastRadius, buildCallChainContext } from './prepare-graph.js';
|
|
26
|
+
import { resolveAiEnabled, resolvePrimaryModel } from './providers.js';
|
|
27
|
+
import { createSkippedResult } from './results.js';
|
|
28
|
+
// ─── Validation ─────────────────────────────────────────────────
|
|
29
|
+
/**
|
|
30
|
+
* Validate the review input for required fields.
|
|
31
|
+
* Throws descriptive errors for misconfiguration.
|
|
32
|
+
*/
|
|
33
|
+
function validateInput(input) {
|
|
34
|
+
if (!input.diff || input.diff.trim().length === 0) {
|
|
35
|
+
throw new Error('Review input must include a non-empty diff');
|
|
36
|
+
}
|
|
37
|
+
// If AI review is explicitly disabled, no provider/model/key needed
|
|
38
|
+
if (input.aiReviewEnabled === false) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Provider chain mode: validate the chain has entries
|
|
42
|
+
if (input.providerChain && input.providerChain.length > 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// CLI Bridge mode: no API key required (uses CLI auth)
|
|
46
|
+
if (input.provider === 'cli-bridge') {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Gateway mode: uses dashboard-configured token (stored as apiKey in chain entry)
|
|
50
|
+
if (input.provider === 'gateway') {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Ollama mode: no API key required (local instance)
|
|
54
|
+
if (input.provider === 'ollama') {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Single provider mode — must be one of the 3 supported providers
|
|
58
|
+
if (input.provider) {
|
|
59
|
+
const supported = ['gateway', 'cli-bridge', 'ollama'];
|
|
60
|
+
if (!supported.includes(input.provider)) {
|
|
61
|
+
throw new Error(`Provider '${input.provider}' is no longer supported directly. ` +
|
|
62
|
+
`Set provider: 'gateway' and configure credentials in mcp-llm-bridge. ` +
|
|
63
|
+
`See docs/configuration.md#gateway-mode-mcp-llm-bridge`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (!input.apiKey && input.provider !== 'cli-bridge' && input.provider !== 'ollama') {
|
|
67
|
+
throw new Error('Review input must include an API key');
|
|
68
|
+
}
|
|
69
|
+
if (!input.provider) {
|
|
70
|
+
throw new Error('Review input must specify an LLM provider');
|
|
71
|
+
}
|
|
72
|
+
if (!input.model) {
|
|
73
|
+
throw new Error('Review input must specify a model');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ─── Prepare phase ──────────────────────────────────────────────
|
|
77
|
+
/**
|
|
78
|
+
* Run steps 1 → 4 and construct the shared `PipelineStateBase`.
|
|
79
|
+
*/
|
|
80
|
+
export async function prepare(input) {
|
|
81
|
+
const startTime = Date.now();
|
|
82
|
+
const emit = input.onProgress ?? (() => { });
|
|
83
|
+
// Track steps that failed but were gracefully degraded
|
|
84
|
+
const failedSteps = [];
|
|
85
|
+
// Track warn-only degradations (reportFailure: false sites) — never
|
|
86
|
+
// surface in failedSteps but still count against coverageComplete.
|
|
87
|
+
const warnOnlyDegradations = [];
|
|
88
|
+
// Resolve whether AI review is enabled
|
|
89
|
+
const aiEnabled = resolveAiEnabled(input);
|
|
90
|
+
// ── Step 1: Validate ───────────────────────────────────────
|
|
91
|
+
validateInput(input);
|
|
92
|
+
emit({ step: 'validate', message: 'Input validated' });
|
|
93
|
+
// ── Step 2: Parse and filter the diff ──────────────────────
|
|
94
|
+
const allFiles = parseDiffFiles(input.diff);
|
|
95
|
+
let { filtered: filteredFiles, blocked, redacted, } = filterDiffFiles(allFiles, input.settings.ignorePatterns);
|
|
96
|
+
if (blocked.length > 0) {
|
|
97
|
+
emit({
|
|
98
|
+
step: 'path-protection',
|
|
99
|
+
message: `Blocked ${blocked.length} sensitive file(s) from review`,
|
|
100
|
+
detail: blocked.map((p) => ` [BLOCKED] ${p}`).join('\n'),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if (redacted.length > 0) {
|
|
104
|
+
emit({
|
|
105
|
+
step: 'path-protection',
|
|
106
|
+
message: `Redacted ${redacted.length} file(s) — paths visible, content hidden`,
|
|
107
|
+
detail: redacted.map((p) => ` [REDACTED] ${p}`).join('\n'),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
emit({
|
|
111
|
+
step: 'parse-diff',
|
|
112
|
+
message: `Parsed ${allFiles.length} files from diff, ${filteredFiles.length} after filtering (${blocked.length} blocked, ${redacted.length} redacted)`,
|
|
113
|
+
detail: filteredFiles.map((f) => ` ${f.path}`).join('\n'),
|
|
114
|
+
});
|
|
115
|
+
// ── Step 2.1: Flood / spam detection ──────────────────────
|
|
116
|
+
// Runs before any expensive operation (static analysis, LLM).
|
|
117
|
+
const linesChanged = allFiles.reduce((sum, f) => sum + f.additions + f.deletions, 0);
|
|
118
|
+
const floodResult = detectFlood({
|
|
119
|
+
authorLogin: input.author ?? '',
|
|
120
|
+
prTitle: input.context?.commitMessages[0] ?? '',
|
|
121
|
+
prBody: input.context?.commitMessages.slice(1).join('\n') ?? null,
|
|
122
|
+
linesChanged,
|
|
123
|
+
recentPrCount: undefined,
|
|
124
|
+
});
|
|
125
|
+
if (floodResult.isFlood) {
|
|
126
|
+
emit({
|
|
127
|
+
step: 'flood-detection',
|
|
128
|
+
message: `Flood detected: ${floodResult.recommendation}`,
|
|
129
|
+
detail: floodResult.signals.map((s) => ` [${s.type}] ${s.detail}`).join('\n'),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (floodResult.recommendation === 'skip') {
|
|
133
|
+
const skipped = createSkippedResult(input, startTime);
|
|
134
|
+
return {
|
|
135
|
+
kind: 'early',
|
|
136
|
+
result: {
|
|
137
|
+
...skipped,
|
|
138
|
+
summary: 'Flood detection: PR skipped (bot author or spam signal).',
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// If all files were filtered out, skip the review
|
|
143
|
+
if (filteredFiles.length === 0) {
|
|
144
|
+
return { kind: 'early', result: createSkippedResult(input, startTime) };
|
|
145
|
+
}
|
|
146
|
+
// Reconstruct filtered diff and get file list
|
|
147
|
+
let filteredDiff = filteredFiles.map((f) => f.content).join('\n');
|
|
148
|
+
const fileList = filteredFiles.map((f) => f.path);
|
|
149
|
+
// ── Step 2.5: Blast-radius filter (optional) ──────────────
|
|
150
|
+
const blast = await applyBlastRadius({
|
|
151
|
+
input,
|
|
152
|
+
emit,
|
|
153
|
+
failedSteps,
|
|
154
|
+
fileList,
|
|
155
|
+
filteredFiles,
|
|
156
|
+
filteredDiff,
|
|
157
|
+
});
|
|
158
|
+
filteredFiles = blast.filteredFiles;
|
|
159
|
+
filteredDiff = blast.filteredDiff;
|
|
160
|
+
const blastRadiusMetadata = blast.blastRadiusMetadata;
|
|
161
|
+
// ── Step 2.6: Call-chain + reverse-deps (optional, runs when blast-radius enabled) ──
|
|
162
|
+
const callChainContext = await buildCallChainContext({
|
|
163
|
+
input,
|
|
164
|
+
emit,
|
|
165
|
+
failedSteps,
|
|
166
|
+
warnOnlyDegradations,
|
|
167
|
+
fileList,
|
|
168
|
+
filteredDiff,
|
|
169
|
+
});
|
|
170
|
+
// ── Step 3: Detect tech stacks ─────────────────────────────
|
|
171
|
+
const stacks = detectStacks(fileList);
|
|
172
|
+
const stackHints = buildStackHints(stacks);
|
|
173
|
+
emit({
|
|
174
|
+
step: 'detect-stacks',
|
|
175
|
+
message: `Detected ${stacks.length} tech stack(s)`,
|
|
176
|
+
detail: stacks.length > 0 ? stacks.map((s) => ` ${s}`).join('\n') : ' (none detected)',
|
|
177
|
+
});
|
|
178
|
+
// ── Step 4: Truncate diff to fit token budget ──────────────
|
|
179
|
+
const primaryModel = resolvePrimaryModel(input);
|
|
180
|
+
const { diffBudget, contextBudget } = calculateTokenBudget(primaryModel);
|
|
181
|
+
const { truncated: truncatedDiff } = truncateDiff(filteredDiff, diffBudget);
|
|
182
|
+
emit({
|
|
183
|
+
step: 'token-budget',
|
|
184
|
+
message: `Token budget: ${diffBudget.toLocaleString()} tokens for diff, ${contextBudget.toLocaleString()} tokens for context`,
|
|
185
|
+
});
|
|
186
|
+
// ── Construct the shared PipelineState (sans result) ────────
|
|
187
|
+
// Locals settled by steps 1–4 migrate into the base here. The
|
|
188
|
+
// gather-context phase overwrites the gather-owned placeholders below
|
|
189
|
+
// UNCONDITIONALLY before any consumer reads them; the execute phase
|
|
190
|
+
// resolves provider flags / enhance / trust onto this state and
|
|
191
|
+
// RETURNS the ReviewResult it creates; enrich and finalize then
|
|
192
|
+
// mutate `state.result` in-place.
|
|
193
|
+
const pendingTool = () => ({ status: 'skipped', findings: [], executionTimeMs: 0 });
|
|
194
|
+
const base = {
|
|
195
|
+
input,
|
|
196
|
+
startTime,
|
|
197
|
+
emit,
|
|
198
|
+
aiEnabled,
|
|
199
|
+
allFiles,
|
|
200
|
+
fileList,
|
|
201
|
+
filteredFiles,
|
|
202
|
+
filteredDiff,
|
|
203
|
+
blastRadiusMetadata,
|
|
204
|
+
callChainContext,
|
|
205
|
+
stacks,
|
|
206
|
+
stackHints,
|
|
207
|
+
truncatedDiff,
|
|
208
|
+
diffBudget,
|
|
209
|
+
contextBudget,
|
|
210
|
+
// Gathered by the gather-context phase (placeholders until then —
|
|
211
|
+
// never read pre-gather):
|
|
212
|
+
staticResult: { semgrep: pendingTool(), trivy: pendingTool(), cpd: pendingTool() },
|
|
213
|
+
rawMemoryContext: null,
|
|
214
|
+
codeIntelResults: [],
|
|
215
|
+
staticContext: '',
|
|
216
|
+
memoryContext: null,
|
|
217
|
+
codeIntelContext: '',
|
|
218
|
+
checklistContext: '',
|
|
219
|
+
resolvedChecklist: null,
|
|
220
|
+
negativeExamplesPrompt: '',
|
|
221
|
+
selfImproveRulesPrompt: '',
|
|
222
|
+
// Resolved by the execute phase (placeholders until then):
|
|
223
|
+
activeProvider: '',
|
|
224
|
+
isCliBridge: false,
|
|
225
|
+
isGateway: false,
|
|
226
|
+
isOllama: false,
|
|
227
|
+
resolvedInputMode: input.mode, // pre-trust value; execute overwrites
|
|
228
|
+
failedSteps,
|
|
229
|
+
warnOnlyDegradations,
|
|
230
|
+
};
|
|
231
|
+
return { kind: 'continue', base };
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=prepare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare.js","sourceRoot":"","sources":["../../src/pipeline/prepare.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider resolution helpers for the review pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Moved verbatim from pipeline.ts (split-review-pipeline refactor).
|
|
5
|
+
*/
|
|
6
|
+
import { type GenerateTextFn } from '../providers/generate-fn.js';
|
|
7
|
+
import type { ProviderChainEntry, ReviewInput, ReviewMode } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Determine if AI review is enabled.
|
|
10
|
+
* Defaults to true for backward compatibility (CLI/Action don't set this).
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveAiEnabled(input: ReviewInput): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the primary provider from chain or flat fields.
|
|
15
|
+
* Returns the first entry in the chain, or builds one from flat fields.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolvePrimaryProvider(input: ReviewInput): ProviderChainEntry;
|
|
18
|
+
/**
|
|
19
|
+
* Build the 3-entry ConsensusModelConfig array for the for/against/neutral votes.
|
|
20
|
+
*
|
|
21
|
+
* Distribution rules (given a chain of length N):
|
|
22
|
+
* N >= 3 : chain[0]→for, chain[1]→against, chain[2]→neutral
|
|
23
|
+
* N == 2 : chain[0]→for, chain[1]→against, chain[0]→neutral
|
|
24
|
+
* N == 1 : all 3 votes use chain[0] (same as primary-only)
|
|
25
|
+
* N == 0 : all 3 votes use `primary` (backward compat)
|
|
26
|
+
*
|
|
27
|
+
* This spreads consensus votes across providers so each vote hits a
|
|
28
|
+
* different TPM budget instead of all three hammering the same limit.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildConsensusModels(chain: ProviderChainEntry[] | undefined, primary: ProviderChainEntry): import('../agents/consensus.js').ConsensusModelConfig[];
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the model name for token budget calculation.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolvePrimaryModel(input: ReviewInput): string;
|
|
35
|
+
/**
|
|
36
|
+
* Create the appropriate GenerateTextFn(s) based on the provider type.
|
|
37
|
+
*
|
|
38
|
+
* - cli-bridge: single fn wrapping generateViaCLI
|
|
39
|
+
* - gateway: one fn per gateway chain entry (for round-robin distribution)
|
|
40
|
+
* - ollama: single fn wrapping local Ollama OpenAI-compatible API
|
|
41
|
+
*
|
|
42
|
+
* Providers that are no longer supported directly (anthropic, openai, etc.)
|
|
43
|
+
* throw a migration error pointing users to gateway mode.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveGenerateTextFns(input: ReviewInput, isCliBridge: boolean, isGateway: boolean, isOllama: boolean): GenerateTextFn[];
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the effective review mode.
|
|
48
|
+
*
|
|
49
|
+
* Diagnostic mode requires direct model access. Ollama provides it
|
|
50
|
+
* (runDiagnosticReview uses createOllamaGenerateFn); CLI bridge and
|
|
51
|
+
* gateway do not, so they fall back to simple mode.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveEffectiveMode(mode: ReviewMode, isCliBridge: boolean, isGateway: boolean): ReviewMode;
|
|
54
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/pipeline/providers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI/E;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAU5D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,CAe7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,kBAAkB,EAAE,GAAG,SAAS,EACvC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,wBAAwB,EAAE,oBAAoB,EAAE,CAazD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAK9D;AAID;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,OAAO,GAChB,cAAc,EAAE,CAyElB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,OAAO,GACjB,UAAU,CAMZ"}
|