ghagga-core 2.8.1 → 2.9.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.
- package/dist/acp/adapter.d.ts +91 -0
- package/dist/acp/adapter.d.ts.map +1 -0
- package/dist/acp/adapter.js +315 -0
- package/dist/acp/adapter.js.map +1 -0
- package/dist/acp/index.d.ts +4 -0
- package/dist/acp/index.d.ts.map +1 -0
- package/dist/acp/index.js +2 -0
- package/dist/acp/index.js.map +1 -0
- package/dist/acp/types.d.ts +142 -0
- package/dist/acp/types.d.ts.map +1 -0
- package/dist/acp/types.js +13 -0
- package/dist/acp/types.js.map +1 -0
- package/dist/adversarial-qa.d.ts +60 -0
- package/dist/adversarial-qa.d.ts.map +1 -0
- package/dist/adversarial-qa.js +85 -0
- package/dist/adversarial-qa.js.map +1 -0
- package/dist/agents/audit.d.ts +18 -0
- package/dist/agents/audit.d.ts.map +1 -0
- package/dist/agents/audit.js +78 -0
- package/dist/agents/audit.js.map +1 -0
- package/dist/agents/consensus.d.ts +1 -1
- package/dist/agents/consensus.d.ts.map +1 -1
- package/dist/agents/consensus.js +10 -8
- package/dist/agents/consensus.js.map +1 -1
- package/dist/agents/diagnostic.d.ts.map +1 -1
- package/dist/agents/diagnostic.js +22 -20
- package/dist/agents/diagnostic.js.map +1 -1
- package/dist/agents/fan-out-lenses.d.ts +41 -0
- package/dist/agents/fan-out-lenses.d.ts.map +1 -1
- package/dist/agents/fan-out-lenses.js +117 -3
- package/dist/agents/fan-out-lenses.js.map +1 -1
- package/dist/agents/prompts.d.ts +12 -0
- package/dist/agents/prompts.d.ts.map +1 -1
- package/dist/agents/prompts.js +31 -0
- 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 +10 -6
- package/dist/agents/simple.js.map +1 -1
- package/dist/agents/workflow.d.ts +1 -1
- package/dist/agents/workflow.d.ts.map +1 -1
- package/dist/agents/workflow.js +9 -8
- package/dist/agents/workflow.js.map +1 -1
- package/dist/aisvs.d.ts +44 -0
- package/dist/aisvs.d.ts.map +1 -0
- package/dist/aisvs.js +189 -0
- package/dist/aisvs.js.map +1 -0
- package/dist/checklist/context.d.ts.map +1 -1
- package/dist/checklist/context.js +2 -8
- package/dist/checklist/context.js.map +1 -1
- package/dist/checklist/defaults.d.ts.map +1 -1
- package/dist/checklist/defaults.js.map +1 -1
- package/dist/checklist/scorer.d.ts.map +1 -1
- package/dist/checklist/scorer.js +105 -12
- package/dist/checklist/scorer.js.map +1 -1
- package/dist/code-intel/client.d.ts +30 -0
- package/dist/code-intel/client.d.ts.map +1 -0
- package/dist/code-intel/client.js +91 -0
- package/dist/code-intel/client.js.map +1 -0
- package/dist/code-intel/context.d.ts +21 -0
- package/dist/code-intel/context.d.ts.map +1 -0
- package/dist/code-intel/context.js +72 -0
- package/dist/code-intel/context.js.map +1 -0
- package/dist/code-intel/index.d.ts +10 -0
- package/dist/code-intel/index.d.ts.map +1 -0
- package/dist/code-intel/index.js +11 -0
- package/dist/code-intel/index.js.map +1 -0
- package/dist/code-intel/types.d.ts +63 -0
- package/dist/code-intel/types.d.ts.map +1 -0
- package/dist/code-intel/types.js +9 -0
- package/dist/code-intel/types.js.map +1 -0
- package/dist/compress/index.d.ts +55 -0
- package/dist/compress/index.d.ts.map +1 -0
- package/dist/compress/index.js +166 -0
- package/dist/compress/index.js.map +1 -0
- package/dist/cost-footer.d.ts +38 -0
- package/dist/cost-footer.d.ts.map +1 -0
- package/dist/cost-footer.js +95 -0
- package/dist/cost-footer.js.map +1 -0
- package/dist/critique/critique.d.ts +40 -0
- package/dist/critique/critique.d.ts.map +1 -0
- package/dist/critique/critique.js +194 -0
- package/dist/critique/critique.js.map +1 -0
- package/dist/critique/cross-model.d.ts +123 -0
- package/dist/critique/cross-model.d.ts.map +1 -0
- package/dist/critique/cross-model.js +265 -0
- package/dist/critique/cross-model.js.map +1 -0
- package/dist/critique/index.d.ts +7 -0
- package/dist/critique/index.d.ts.map +1 -0
- package/dist/critique/index.js +5 -0
- package/dist/critique/index.js.map +1 -0
- package/dist/critique/prompts.d.ts +11 -0
- package/dist/critique/prompts.d.ts.map +1 -0
- package/dist/critique/prompts.js +66 -0
- package/dist/critique/prompts.js.map +1 -0
- package/dist/critique/types.d.ts +84 -0
- package/dist/critique/types.d.ts.map +1 -0
- package/dist/critique/types.js +13 -0
- package/dist/critique/types.js.map +1 -0
- package/dist/doc-validation/index.d.ts +9 -0
- package/dist/doc-validation/index.d.ts.map +1 -0
- package/dist/doc-validation/index.js +9 -0
- package/dist/doc-validation/index.js.map +1 -0
- package/dist/doc-validation/scanner.d.ts +40 -0
- package/dist/doc-validation/scanner.d.ts.map +1 -0
- package/dist/doc-validation/scanner.js +163 -0
- package/dist/doc-validation/scanner.js.map +1 -0
- package/dist/doc-validation/types.d.ts +27 -0
- package/dist/doc-validation/types.d.ts.map +1 -0
- package/dist/doc-validation/types.js +8 -0
- package/dist/doc-validation/types.js.map +1 -0
- package/dist/embed.d.ts +27 -0
- package/dist/embed.d.ts.map +1 -0
- package/dist/embed.js +47 -0
- package/dist/embed.js.map +1 -0
- package/dist/enhance/enhance.d.ts.map +1 -1
- package/dist/enhance/enhance.js +7 -25
- package/dist/enhance/enhance.js.map +1 -1
- package/dist/enhance/types.d.ts +5 -0
- package/dist/enhance/types.d.ts.map +1 -1
- package/dist/exploitability/analyzer.d.ts +42 -0
- package/dist/exploitability/analyzer.d.ts.map +1 -1
- package/dist/exploitability/analyzer.js +225 -0
- package/dist/exploitability/analyzer.js.map +1 -1
- package/dist/exploitability/index.d.ts +3 -2
- package/dist/exploitability/index.d.ts.map +1 -1
- package/dist/exploitability/index.js +1 -2
- package/dist/exploitability/index.js.map +1 -1
- package/dist/exploitability/types.d.ts +27 -0
- package/dist/exploitability/types.d.ts.map +1 -1
- package/dist/fetch-fix.d.ts +60 -0
- package/dist/fetch-fix.d.ts.map +1 -0
- package/dist/fetch-fix.js +137 -0
- package/dist/fetch-fix.js.map +1 -0
- package/dist/flood/index.d.ts +34 -0
- package/dist/flood/index.d.ts.map +1 -0
- package/dist/flood/index.js +67 -0
- package/dist/flood/index.js.map +1 -0
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +6 -1
- package/dist/format.js.map +1 -1
- package/dist/graph/blast-radius.js +2 -2
- package/dist/graph/blast-radius.js.map +1 -1
- package/dist/graph/call-chain.d.ts +36 -0
- package/dist/graph/call-chain.d.ts.map +1 -0
- package/dist/graph/call-chain.js +291 -0
- package/dist/graph/call-chain.js.map +1 -0
- package/dist/graph/index.d.ts +4 -0
- package/dist/graph/index.d.ts.map +1 -1
- package/dist/graph/index.js +2 -0
- package/dist/graph/index.js.map +1 -1
- package/dist/graph/reverse-deps.d.ts +37 -0
- package/dist/graph/reverse-deps.d.ts.map +1 -0
- package/dist/graph/reverse-deps.js +136 -0
- package/dist/graph/reverse-deps.js.map +1 -0
- package/dist/index.d.ts +48 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -7
- package/dist/index.js.map +1 -1
- package/dist/injection-corpus.d.ts +41 -0
- package/dist/injection-corpus.d.ts.map +1 -0
- package/dist/injection-corpus.js +181 -0
- package/dist/injection-corpus.js.map +1 -0
- package/dist/latent-comms.d.ts +31 -0
- package/dist/latent-comms.d.ts.map +1 -0
- package/dist/latent-comms.js +139 -0
- package/dist/latent-comms.js.map +1 -0
- package/dist/memory/pageindex/chunker.d.ts +33 -0
- package/dist/memory/pageindex/chunker.d.ts.map +1 -0
- package/dist/memory/pageindex/chunker.js +112 -0
- package/dist/memory/pageindex/chunker.js.map +1 -0
- package/dist/memory/pageindex/example.d.ts +22 -0
- package/dist/memory/pageindex/example.d.ts.map +1 -0
- package/dist/memory/pageindex/example.js +93 -0
- package/dist/memory/pageindex/example.js.map +1 -0
- package/dist/memory/pageindex/index.d.ts +15 -0
- package/dist/memory/pageindex/index.d.ts.map +1 -0
- package/dist/memory/pageindex/index.js +17 -0
- package/dist/memory/pageindex/index.js.map +1 -0
- package/dist/memory/pageindex/service.d.ts +53 -0
- package/dist/memory/pageindex/service.d.ts.map +1 -0
- package/dist/memory/pageindex/service.js +230 -0
- package/dist/memory/pageindex/service.js.map +1 -0
- package/dist/memory/pageindex/types.d.ts +67 -0
- package/dist/memory/pageindex/types.d.ts.map +1 -0
- package/dist/memory/pageindex/types.js +14 -0
- package/dist/memory/pageindex/types.js.map +1 -0
- package/dist/memory/persist.d.ts.map +1 -1
- package/dist/memory/persist.js +6 -2
- package/dist/memory/persist.js.map +1 -1
- package/dist/memory/sqlite.d.ts +69 -2
- package/dist/memory/sqlite.d.ts.map +1 -1
- package/dist/memory/sqlite.js +312 -5
- package/dist/memory/sqlite.js.map +1 -1
- package/dist/memory/taxonomy.d.ts +34 -0
- package/dist/memory/taxonomy.d.ts.map +1 -0
- package/dist/memory/taxonomy.js +189 -0
- package/dist/memory/taxonomy.js.map +1 -0
- package/dist/memory/versioning.d.ts.map +1 -1
- package/dist/memory/versioning.js.map +1 -1
- package/dist/negative.d.ts +23 -0
- package/dist/negative.d.ts.map +1 -0
- package/dist/negative.js +40 -0
- package/dist/negative.js.map +1 -0
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +455 -46
- package/dist/pipeline.js.map +1 -1
- package/dist/prompt-intel.d.ts +39 -0
- package/dist/prompt-intel.d.ts.map +1 -0
- package/dist/prompt-intel.js +148 -0
- package/dist/prompt-intel.js.map +1 -0
- package/dist/providers/cli-bridge.d.ts +4 -0
- package/dist/providers/cli-bridge.d.ts.map +1 -1
- package/dist/providers/cli-bridge.js +4 -0
- package/dist/providers/cli-bridge.js.map +1 -1
- package/dist/providers/generate-fn.d.ts +3 -15
- package/dist/providers/generate-fn.d.ts.map +1 -1
- package/dist/providers/generate-fn.js +3 -30
- package/dist/providers/generate-fn.js.map +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ollama.d.ts +15 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +30 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/ranking/index.d.ts +9 -0
- package/dist/ranking/index.d.ts.map +1 -0
- package/dist/ranking/index.js +82 -0
- package/dist/ranking/index.js.map +1 -0
- package/dist/recursive/circuit-breaker.d.ts +36 -0
- package/dist/recursive/circuit-breaker.d.ts.map +1 -0
- package/dist/recursive/circuit-breaker.js +62 -0
- package/dist/recursive/circuit-breaker.js.map +1 -0
- package/dist/recursive/index.d.ts +4 -0
- package/dist/recursive/index.d.ts.map +1 -1
- package/dist/recursive/index.js +18 -1
- package/dist/recursive/index.js.map +1 -1
- package/dist/recursive/types.d.ts +2 -0
- package/dist/recursive/types.d.ts.map +1 -1
- package/dist/recursive/types.js +1 -0
- package/dist/recursive/types.js.map +1 -1
- package/dist/scope/diff-mapper.js.map +1 -1
- package/dist/scope/entity-diff.d.ts +58 -0
- package/dist/scope/entity-diff.d.ts.map +1 -0
- package/dist/scope/entity-diff.js +224 -0
- package/dist/scope/entity-diff.js.map +1 -0
- package/dist/scope/extractor.d.ts.map +1 -1
- package/dist/scope/extractor.js.map +1 -1
- package/dist/scope/index.d.ts +3 -1
- package/dist/scope/index.d.ts.map +1 -1
- package/dist/scope/index.js +3 -0
- package/dist/scope/index.js.map +1 -1
- package/dist/scope/parser.d.ts +1 -1
- package/dist/scope/parser.d.ts.map +1 -1
- package/dist/scope/parser.js.map +1 -1
- package/dist/scope/types.d.ts +32 -0
- package/dist/scope/types.d.ts.map +1 -1
- package/dist/scope/types.js +7 -1
- package/dist/scope/types.js.map +1 -1
- package/dist/search/index.d.ts +11 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +10 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/indexer.d.ts +67 -0
- package/dist/search/indexer.d.ts.map +1 -0
- package/dist/search/indexer.js +225 -0
- package/dist/search/indexer.js.map +1 -0
- package/dist/search/searcher.d.ts +34 -0
- package/dist/search/searcher.d.ts.map +1 -0
- package/dist/search/searcher.js +101 -0
- package/dist/search/searcher.js.map +1 -0
- package/dist/search/types.d.ts +81 -0
- package/dist/search/types.d.ts.map +1 -0
- package/dist/search/types.js +8 -0
- package/dist/search/types.js.map +1 -0
- package/dist/self-improve/index.d.ts +53 -0
- package/dist/self-improve/index.d.ts.map +1 -0
- package/dist/self-improve/index.js +136 -0
- package/dist/self-improve/index.js.map +1 -0
- package/dist/semantic-diff/index.d.ts +31 -0
- package/dist/semantic-diff/index.d.ts.map +1 -0
- package/dist/semantic-diff/index.js +215 -0
- package/dist/semantic-diff/index.js.map +1 -0
- package/dist/testing/index.d.ts +67 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +76 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/vitest-helpers.d.ts +26 -0
- package/dist/testing/vitest-helpers.d.ts.map +1 -0
- package/dist/testing/vitest-helpers.js +37 -0
- package/dist/testing/vitest-helpers.js.map +1 -0
- package/dist/tools/index.d.ts +3 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/remote-query.d.ts +40 -0
- package/dist/tools/remote-query.d.ts.map +1 -0
- package/dist/tools/remote-query.js +71 -0
- package/dist/tools/remote-query.js.map +1 -0
- package/dist/tracing/index.d.ts +39 -0
- package/dist/tracing/index.d.ts.map +1 -0
- package/dist/tracing/index.js +70 -0
- package/dist/tracing/index.js.map +1 -0
- package/dist/trajectory.d.ts +65 -0
- package/dist/trajectory.d.ts.map +1 -0
- package/dist/trajectory.js +126 -0
- package/dist/trajectory.js.map +1 -0
- package/dist/trust/index.d.ts +34 -0
- package/dist/trust/index.d.ts.map +1 -0
- package/dist/trust/index.js +78 -0
- package/dist/trust/index.js.map +1 -0
- package/dist/types.d.ts +144 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -11
- package/dist/types.js.map +1 -1
- package/package.json +1 -3
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-Improving Review Loop
|
|
3
|
+
*
|
|
4
|
+
* Tracks which findings get accepted/rejected by users and uses that
|
|
5
|
+
* signal to derive improvement rules for future reviews.
|
|
6
|
+
*/
|
|
7
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { dirname } from 'node:path';
|
|
9
|
+
// ─── Storage ─────────────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* Append a feedback record to the JSONL file at storagePath.
|
|
12
|
+
* Creates the file (and parent directories) if they do not exist.
|
|
13
|
+
*/
|
|
14
|
+
export async function recordFeedback(feedback, storagePath) {
|
|
15
|
+
const dir = dirname(storagePath);
|
|
16
|
+
if (!existsSync(dir)) {
|
|
17
|
+
mkdirSync(dir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
const line = `${JSON.stringify(feedback)}\n`;
|
|
20
|
+
appendFileSync(storagePath, line, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Load all feedback records from a JSONL file.
|
|
24
|
+
* Returns an empty array if the file does not exist.
|
|
25
|
+
*/
|
|
26
|
+
export async function loadFeedback(storagePath) {
|
|
27
|
+
if (!existsSync(storagePath)) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const raw = readFileSync(storagePath, 'utf-8').trim();
|
|
31
|
+
if (!raw)
|
|
32
|
+
return [];
|
|
33
|
+
const records = [];
|
|
34
|
+
for (const line of raw.split('\n')) {
|
|
35
|
+
const trimmed = line.trim();
|
|
36
|
+
if (!trimmed)
|
|
37
|
+
continue;
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(trimmed);
|
|
40
|
+
records.push(parsed);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Skip malformed lines
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return records;
|
|
47
|
+
}
|
|
48
|
+
// ─── Rule Derivation ─────────────────────────────────────────────
|
|
49
|
+
const MIN_SAMPLE_COUNT = 5;
|
|
50
|
+
const SUPPRESS_REJECTION_THRESHOLD = 0.7;
|
|
51
|
+
const BOOST_ACCEPTANCE_THRESHOLD = 0.8;
|
|
52
|
+
/**
|
|
53
|
+
* Derive improvement rules from accumulated feedback.
|
|
54
|
+
*
|
|
55
|
+
* Logic per category:
|
|
56
|
+
* - rejection_rate > 0.7 AND sampleCount >= 5 → suppress
|
|
57
|
+
* - acceptance_rate > 0.8 AND sampleCount >= 5 → boost_priority
|
|
58
|
+
*
|
|
59
|
+
* Returns rules sorted by confidence descending.
|
|
60
|
+
*/
|
|
61
|
+
export function deriveRules(feedback) {
|
|
62
|
+
if (feedback.length === 0)
|
|
63
|
+
return [];
|
|
64
|
+
// Group by category
|
|
65
|
+
const byCategory = new Map();
|
|
66
|
+
for (const fb of feedback) {
|
|
67
|
+
const existing = byCategory.get(fb.category) ?? [];
|
|
68
|
+
existing.push(fb);
|
|
69
|
+
byCategory.set(fb.category, existing);
|
|
70
|
+
}
|
|
71
|
+
const rules = [];
|
|
72
|
+
for (const [category, records] of byCategory) {
|
|
73
|
+
const total = records.length;
|
|
74
|
+
if (total < MIN_SAMPLE_COUNT)
|
|
75
|
+
continue;
|
|
76
|
+
const rejected = records.filter((r) => r.outcome === 'rejected').length;
|
|
77
|
+
const accepted = records.filter((r) => r.outcome === 'accepted').length;
|
|
78
|
+
const rejectionRate = rejected / total;
|
|
79
|
+
const acceptanceRate = accepted / total;
|
|
80
|
+
if (rejectionRate > SUPPRESS_REJECTION_THRESHOLD) {
|
|
81
|
+
rules.push({
|
|
82
|
+
pattern: `category:${category}`,
|
|
83
|
+
category,
|
|
84
|
+
action: 'suppress',
|
|
85
|
+
confidence: Math.round(rejectionRate * 100) / 100,
|
|
86
|
+
sampleCount: total,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else if (acceptanceRate > BOOST_ACCEPTANCE_THRESHOLD) {
|
|
90
|
+
rules.push({
|
|
91
|
+
pattern: `category:${category}`,
|
|
92
|
+
category,
|
|
93
|
+
action: 'boost_priority',
|
|
94
|
+
confidence: Math.round(acceptanceRate * 100) / 100,
|
|
95
|
+
sampleCount: total,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Sort by confidence descending
|
|
100
|
+
return rules.sort((a, b) => b.confidence - a.confidence);
|
|
101
|
+
}
|
|
102
|
+
// ─── Prompt Formatting ────────────────────────────────────────────
|
|
103
|
+
/**
|
|
104
|
+
* Format derived improvement rules as a prompt section.
|
|
105
|
+
*
|
|
106
|
+
* Injects rules into the system prompt so the agent adjusts its behavior
|
|
107
|
+
* based on historical feedback.
|
|
108
|
+
*
|
|
109
|
+
* @param rules - Derived rules from deriveRules()
|
|
110
|
+
* @returns Formatted string for injection into system prompt
|
|
111
|
+
*/
|
|
112
|
+
export function formatRulesForPrompt(rules) {
|
|
113
|
+
if (rules.length === 0)
|
|
114
|
+
return '';
|
|
115
|
+
const lines = [
|
|
116
|
+
'## Review Improvement Rules',
|
|
117
|
+
'',
|
|
118
|
+
'Based on past feedback, apply these adjustments to your review:',
|
|
119
|
+
'',
|
|
120
|
+
];
|
|
121
|
+
for (const rule of rules) {
|
|
122
|
+
if (rule.action === 'suppress') {
|
|
123
|
+
lines.push(`- **SUPPRESS** findings in category \`${rule.category}\` — ` +
|
|
124
|
+
`${Math.round(rule.confidence * 100)}% rejection rate across ${rule.sampleCount} samples. ` +
|
|
125
|
+
`Only report if you have very strong evidence.`);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
lines.push(`- **PRIORITIZE** findings in category \`${rule.category}\` — ` +
|
|
129
|
+
`${Math.round(rule.confidence * 100)}% acceptance rate across ${rule.sampleCount} samples. ` +
|
|
130
|
+
`These findings are highly valued by the team.`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
lines.push('');
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/self-improve/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic diff extraction.
|
|
3
|
+
*
|
|
4
|
+
* Instead of raw line diffs, extracts WHAT changed at the entity level:
|
|
5
|
+
* function renamed, class added, method signature changed, etc.
|
|
6
|
+
*
|
|
7
|
+
* Implementation is regex-based — no tree-sitter required.
|
|
8
|
+
*/
|
|
9
|
+
export type EntityChangeKind = 'function_added' | 'function_removed' | 'function_modified' | 'class_added' | 'class_removed' | 'method_added' | 'method_removed' | 'method_modified' | 'import_added' | 'import_removed' | 'export_added' | 'export_removed' | 'type_added' | 'type_removed' | 'type_modified';
|
|
10
|
+
export interface EntityChange {
|
|
11
|
+
kind: EntityChangeKind;
|
|
12
|
+
name: string;
|
|
13
|
+
filePath: string;
|
|
14
|
+
/** Full declaration line for the old version (modifications only). */
|
|
15
|
+
oldSignature?: string;
|
|
16
|
+
/** Full declaration line for the new version (modifications only). */
|
|
17
|
+
newSignature?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SemanticDiff {
|
|
20
|
+
changes: EntityChange[];
|
|
21
|
+
/** Human-readable summary, e.g. "3 functions modified, 1 class added" */
|
|
22
|
+
summary: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Extract entity-level changes from a unified diff string.
|
|
26
|
+
*
|
|
27
|
+
* Returns a SemanticDiff with individual EntityChange items and a
|
|
28
|
+
* human-readable summary string.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractSemanticDiff(unifiedDiff: string): SemanticDiff;
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/semantic-diff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,aAAa,GACb,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,YAAY,GACZ,cAAc,GACd,eAAe,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAqJD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAiCrE"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic diff extraction.
|
|
3
|
+
*
|
|
4
|
+
* Instead of raw line diffs, extracts WHAT changed at the entity level:
|
|
5
|
+
* function renamed, class added, method signature changed, etc.
|
|
6
|
+
*
|
|
7
|
+
* Implementation is regex-based — no tree-sitter required.
|
|
8
|
+
*/
|
|
9
|
+
// ─── Regex Patterns ──────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* Patterns that match declaration lines.
|
|
12
|
+
* Each entry includes the entity category for grouping (function|class|method|import|export|type).
|
|
13
|
+
*/
|
|
14
|
+
const DECLARATION_PATTERNS = [
|
|
15
|
+
// import statements — match before export/function to avoid conflicts
|
|
16
|
+
{
|
|
17
|
+
kind: 'import',
|
|
18
|
+
pattern: /^\s*import\s+(?:type\s+)?(?:\{[^}]*\}|[\w*]+(?:\s+as\s+\w+)?)\s+from\s+['"][^'"]+['"]/,
|
|
19
|
+
},
|
|
20
|
+
// export default / named
|
|
21
|
+
{
|
|
22
|
+
kind: 'export',
|
|
23
|
+
pattern: /^\s*export\s+(?:default\s+)?(?:const|let|var|function\*?|async\s+function\*?)\s+(\w+)/,
|
|
24
|
+
},
|
|
25
|
+
// export type / interface
|
|
26
|
+
{
|
|
27
|
+
kind: 'type',
|
|
28
|
+
pattern: /^\s*export\s+(?:type|interface|enum)\s+(\w+)/,
|
|
29
|
+
},
|
|
30
|
+
// standalone type / interface / enum
|
|
31
|
+
{
|
|
32
|
+
kind: 'type',
|
|
33
|
+
pattern: /^\s*(?:type|interface|enum)\s+(\w+)/,
|
|
34
|
+
},
|
|
35
|
+
// class declaration
|
|
36
|
+
{
|
|
37
|
+
kind: 'class',
|
|
38
|
+
pattern: /^\s*(?:export\s+)?(?:abstract\s+)?class\s+(\w+)/,
|
|
39
|
+
},
|
|
40
|
+
// method inside class (indented + no leading "function" keyword, has "()")
|
|
41
|
+
{
|
|
42
|
+
kind: 'method',
|
|
43
|
+
pattern: /^[ \t]+(?:(?:public|private|protected|static|async|override|readonly)\s+)*(\w+)\s*\(/,
|
|
44
|
+
},
|
|
45
|
+
// top-level function declaration
|
|
46
|
+
{
|
|
47
|
+
kind: 'function',
|
|
48
|
+
pattern: /^\s*(?:export\s+)?(?:async\s+)?function\*?\s+(\w+)\s*\(/,
|
|
49
|
+
},
|
|
50
|
+
// arrow function / const fn = ...
|
|
51
|
+
{
|
|
52
|
+
kind: 'function',
|
|
53
|
+
pattern: /^\s*(?:export\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s*)?\(/,
|
|
54
|
+
},
|
|
55
|
+
// const fn = async () => or const fn = () =>
|
|
56
|
+
{
|
|
57
|
+
kind: 'function',
|
|
58
|
+
pattern: /^\s*(?:export\s+)?(?:const|let|var)\s+(\w+)\s*(?::\s*\w[\w<>,\s]*?)?\s*=\s*(?:async\s+)?\(/,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
/**
|
|
62
|
+
* Extract the entity name from a declaration line.
|
|
63
|
+
* Returns [category, name] or null if no pattern matches.
|
|
64
|
+
*/
|
|
65
|
+
function extractDeclaration(line) {
|
|
66
|
+
for (const { kind, pattern } of DECLARATION_PATTERNS) {
|
|
67
|
+
const match = pattern.exec(line);
|
|
68
|
+
if (match) {
|
|
69
|
+
if (kind === 'import') {
|
|
70
|
+
// For imports, use the from-module as the "name" for deduplication
|
|
71
|
+
const fromMatch = /from\s+['"]([^'"]+)['"]/.exec(line);
|
|
72
|
+
return { kind, name: fromMatch?.[1] ?? line.trim().slice(0, 40) };
|
|
73
|
+
}
|
|
74
|
+
// Capture group 1 is the entity name for all other patterns
|
|
75
|
+
const name = match[1];
|
|
76
|
+
if (name)
|
|
77
|
+
return { kind, name };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Parse a unified diff and split added/removed declaration lines per file.
|
|
84
|
+
*/
|
|
85
|
+
function parseHunks(unifiedDiff) {
|
|
86
|
+
const result = [];
|
|
87
|
+
const filePattern = /^diff --git a\/.+ b\/(.+)$/m;
|
|
88
|
+
const sections = unifiedDiff.split(/^diff --git /m).filter(Boolean);
|
|
89
|
+
for (const section of sections) {
|
|
90
|
+
const pathMatch = /a\/.+ b\/(.+)$/.exec(section.split('\n')[0] ?? '');
|
|
91
|
+
const filePath = pathMatch?.[1] ?? 'unknown';
|
|
92
|
+
const added = new Map();
|
|
93
|
+
const removed = new Map();
|
|
94
|
+
for (const line of section.split('\n')) {
|
|
95
|
+
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
96
|
+
const content = line.slice(1);
|
|
97
|
+
const decl = extractDeclaration(content);
|
|
98
|
+
if (decl) {
|
|
99
|
+
added.set(decl.name, { name: decl.name, signature: content.trim(), kind: decl.kind });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (line.startsWith('-') && !line.startsWith('---')) {
|
|
103
|
+
const content = line.slice(1);
|
|
104
|
+
const decl = extractDeclaration(content);
|
|
105
|
+
if (decl) {
|
|
106
|
+
removed.set(decl.name, { name: decl.name, signature: content.trim(), kind: decl.kind });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
result.push({ filePath, added, removed });
|
|
111
|
+
}
|
|
112
|
+
// Suppress unused import warning — filePattern is used for documentation only
|
|
113
|
+
void filePattern;
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
// ─── Main Export ─────────────────────────────────────────────────
|
|
117
|
+
/**
|
|
118
|
+
* Extract entity-level changes from a unified diff string.
|
|
119
|
+
*
|
|
120
|
+
* Returns a SemanticDiff with individual EntityChange items and a
|
|
121
|
+
* human-readable summary string.
|
|
122
|
+
*/
|
|
123
|
+
export function extractSemanticDiff(unifiedDiff) {
|
|
124
|
+
const hunkSets = parseHunks(unifiedDiff);
|
|
125
|
+
const changes = [];
|
|
126
|
+
for (const { filePath, added, removed } of hunkSets) {
|
|
127
|
+
// Entities in both added and removed → modified
|
|
128
|
+
for (const [name, addedDecl] of added) {
|
|
129
|
+
if (removed.has(name)) {
|
|
130
|
+
const removedDecl = removed.get(name);
|
|
131
|
+
const kind = mapToChangeKind(addedDecl.kind, 'modified');
|
|
132
|
+
changes.push({
|
|
133
|
+
kind,
|
|
134
|
+
name,
|
|
135
|
+
filePath,
|
|
136
|
+
oldSignature: removedDecl?.signature,
|
|
137
|
+
newSignature: addedDecl.signature,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const kind = mapToChangeKind(addedDecl.kind, 'added');
|
|
142
|
+
changes.push({ kind, name, filePath, newSignature: addedDecl.signature });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Entities only in removed → removed
|
|
146
|
+
for (const [name, removedDecl] of removed) {
|
|
147
|
+
if (!added.has(name)) {
|
|
148
|
+
const kind = mapToChangeKind(removedDecl.kind, 'removed');
|
|
149
|
+
changes.push({ kind, name, filePath, oldSignature: removedDecl.signature });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return { changes, summary: buildSummary(changes) };
|
|
154
|
+
}
|
|
155
|
+
// ─── Helpers ─────────────────────────────────────────────────────
|
|
156
|
+
function mapToChangeKind(category, direction) {
|
|
157
|
+
switch (category) {
|
|
158
|
+
case 'function':
|
|
159
|
+
return direction === 'added'
|
|
160
|
+
? 'function_added'
|
|
161
|
+
: direction === 'removed'
|
|
162
|
+
? 'function_removed'
|
|
163
|
+
: 'function_modified';
|
|
164
|
+
case 'class':
|
|
165
|
+
return direction === 'added'
|
|
166
|
+
? 'class_added'
|
|
167
|
+
: direction === 'removed'
|
|
168
|
+
? 'class_removed'
|
|
169
|
+
: 'function_modified'; // classes cannot be "modified" at entity level, treat as function_modified
|
|
170
|
+
case 'method':
|
|
171
|
+
return direction === 'added'
|
|
172
|
+
? 'method_added'
|
|
173
|
+
: direction === 'removed'
|
|
174
|
+
? 'method_removed'
|
|
175
|
+
: 'method_modified';
|
|
176
|
+
case 'import':
|
|
177
|
+
return direction === 'added' ? 'import_added' : 'import_removed';
|
|
178
|
+
case 'export':
|
|
179
|
+
return direction === 'added' ? 'export_added' : 'export_removed';
|
|
180
|
+
case 'type':
|
|
181
|
+
return direction === 'added'
|
|
182
|
+
? 'type_added'
|
|
183
|
+
: direction === 'removed'
|
|
184
|
+
? 'type_removed'
|
|
185
|
+
: 'type_modified';
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function buildSummary(changes) {
|
|
189
|
+
const counts = {};
|
|
190
|
+
for (const c of changes) {
|
|
191
|
+
counts[c.kind] = (counts[c.kind] ?? 0) + 1;
|
|
192
|
+
}
|
|
193
|
+
const parts = [];
|
|
194
|
+
const groupSummary = (addedKind, removedKind, modifiedKind, label) => {
|
|
195
|
+
const added = counts[addedKind] ?? 0;
|
|
196
|
+
const removed = counts[removedKind] ?? 0;
|
|
197
|
+
const modified = counts[modifiedKind] ?? 0;
|
|
198
|
+
if (added)
|
|
199
|
+
parts.push(`${added} ${label} added`);
|
|
200
|
+
if (removed)
|
|
201
|
+
parts.push(`${removed} ${label} removed`);
|
|
202
|
+
if (modified)
|
|
203
|
+
parts.push(`${modified} ${label} modified`);
|
|
204
|
+
};
|
|
205
|
+
groupSummary('function_added', 'function_removed', 'function_modified', 'function');
|
|
206
|
+
groupSummary('class_added', 'class_removed', 'function_modified', 'class');
|
|
207
|
+
groupSummary('method_added', 'method_removed', 'method_modified', 'method');
|
|
208
|
+
groupSummary('import_added', 'import_removed', 'import_added', 'import');
|
|
209
|
+
groupSummary('export_added', 'export_removed', 'export_added', 'export');
|
|
210
|
+
groupSummary('type_added', 'type_removed', 'type_modified', 'type');
|
|
211
|
+
if (parts.length === 0)
|
|
212
|
+
return 'no entity-level changes detected';
|
|
213
|
+
return parts.join(', ');
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/semantic-diff/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression testing framework for GHAGGA reviews.
|
|
3
|
+
*
|
|
4
|
+
* Lets you record a ReviewInput → ReviewResult pair as a "trace",
|
|
5
|
+
* load it back later, and assert that the trace still satisfies a
|
|
6
|
+
* set of structural constraints.
|
|
7
|
+
*
|
|
8
|
+
* Designed to be used in CI to catch regressions in the review engine.
|
|
9
|
+
*/
|
|
10
|
+
import type { ReviewInput, ReviewResult } from '../types.js';
|
|
11
|
+
export interface ReviewTrace {
|
|
12
|
+
input: ReviewInput;
|
|
13
|
+
output: ReviewResult;
|
|
14
|
+
recordedAt: string;
|
|
15
|
+
label: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A single assertion spec for a recorded trace.
|
|
19
|
+
* `mustFind` requires at least one matching finding.
|
|
20
|
+
* `mustNotFind` requires zero matching findings.
|
|
21
|
+
*/
|
|
22
|
+
export interface TraceAssertion {
|
|
23
|
+
label: string;
|
|
24
|
+
/** Each entry must match at least one finding in the trace output. */
|
|
25
|
+
mustFind: Array<{
|
|
26
|
+
filePath?: string;
|
|
27
|
+
category?: string;
|
|
28
|
+
severity?: string;
|
|
29
|
+
messageContains?: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** Each entry must NOT match any finding in the trace output. */
|
|
32
|
+
mustNotFind?: Array<{
|
|
33
|
+
filePath?: string;
|
|
34
|
+
category?: string;
|
|
35
|
+
messageContains?: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Persist a ReviewTrace to disk as pretty-printed JSON.
|
|
40
|
+
*
|
|
41
|
+
* @param trace - The trace to record
|
|
42
|
+
* @param outputPath - Absolute or relative path for the output file
|
|
43
|
+
*/
|
|
44
|
+
export declare function recordTrace(trace: ReviewTrace, outputPath: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Load a ReviewTrace from a JSON file on disk.
|
|
47
|
+
*
|
|
48
|
+
* @param tracePath - Path to the trace file written by {@link recordTrace}
|
|
49
|
+
* @returns Parsed ReviewTrace
|
|
50
|
+
* @throws If the file does not exist or contains invalid JSON
|
|
51
|
+
*/
|
|
52
|
+
export declare function loadTrace(tracePath: string): Promise<ReviewTrace>;
|
|
53
|
+
/**
|
|
54
|
+
* Run a set of TraceAssertions against a loaded trace.
|
|
55
|
+
*
|
|
56
|
+
* Returns `{ passed: true, failures: [] }` when all assertions pass,
|
|
57
|
+
* or `{ passed: false, failures: [...] }` with a human-readable list
|
|
58
|
+
* of failures when something does not match.
|
|
59
|
+
*
|
|
60
|
+
* @param trace - The loaded ReviewTrace to validate
|
|
61
|
+
* @param assertions - Array of {@link TraceAssertion} to evaluate
|
|
62
|
+
*/
|
|
63
|
+
export declare function assertTrace(trace: ReviewTrace, assertions: TraceAssertion[]): Promise<{
|
|
64
|
+
passed: boolean;
|
|
65
|
+
failures: string[];
|
|
66
|
+
}>;
|
|
67
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAiB,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI5E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IAEd,sEAAsE;IACtE,QAAQ,EAAE,KAAK,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;IAEH,iEAAiE;IACjE,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;CACJ;AAID;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvF;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAGvE;AAsBD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,cAAc,EAAE,GAC3B,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA2BlD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression testing framework for GHAGGA reviews.
|
|
3
|
+
*
|
|
4
|
+
* Lets you record a ReviewInput → ReviewResult pair as a "trace",
|
|
5
|
+
* load it back later, and assert that the trace still satisfies a
|
|
6
|
+
* set of structural constraints.
|
|
7
|
+
*
|
|
8
|
+
* Designed to be used in CI to catch regressions in the review engine.
|
|
9
|
+
*/
|
|
10
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
11
|
+
// ─── I/O helpers ────────────────────────────────────────────────
|
|
12
|
+
/**
|
|
13
|
+
* Persist a ReviewTrace to disk as pretty-printed JSON.
|
|
14
|
+
*
|
|
15
|
+
* @param trace - The trace to record
|
|
16
|
+
* @param outputPath - Absolute or relative path for the output file
|
|
17
|
+
*/
|
|
18
|
+
export async function recordTrace(trace, outputPath) {
|
|
19
|
+
await writeFile(outputPath, JSON.stringify(trace, null, 2), 'utf8');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Load a ReviewTrace from a JSON file on disk.
|
|
23
|
+
*
|
|
24
|
+
* @param tracePath - Path to the trace file written by {@link recordTrace}
|
|
25
|
+
* @returns Parsed ReviewTrace
|
|
26
|
+
* @throws If the file does not exist or contains invalid JSON
|
|
27
|
+
*/
|
|
28
|
+
export async function loadTrace(tracePath) {
|
|
29
|
+
const raw = await readFile(tracePath, 'utf8');
|
|
30
|
+
return JSON.parse(raw);
|
|
31
|
+
}
|
|
32
|
+
// ─── Assertion engine ────────────────────────────────────────────
|
|
33
|
+
function findingMatchesMatcher(finding, matcher) {
|
|
34
|
+
if (matcher.filePath !== undefined && finding.file !== matcher.filePath)
|
|
35
|
+
return false;
|
|
36
|
+
if (matcher.category !== undefined && finding.category !== matcher.category)
|
|
37
|
+
return false;
|
|
38
|
+
if (matcher.severity !== undefined && finding.severity !== matcher.severity)
|
|
39
|
+
return false;
|
|
40
|
+
if (matcher.messageContains !== undefined && !finding.message.includes(matcher.messageContains)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run a set of TraceAssertions against a loaded trace.
|
|
47
|
+
*
|
|
48
|
+
* Returns `{ passed: true, failures: [] }` when all assertions pass,
|
|
49
|
+
* or `{ passed: false, failures: [...] }` with a human-readable list
|
|
50
|
+
* of failures when something does not match.
|
|
51
|
+
*
|
|
52
|
+
* @param trace - The loaded ReviewTrace to validate
|
|
53
|
+
* @param assertions - Array of {@link TraceAssertion} to evaluate
|
|
54
|
+
*/
|
|
55
|
+
export async function assertTrace(trace, assertions) {
|
|
56
|
+
const findings = trace.output.findings;
|
|
57
|
+
const failures = [];
|
|
58
|
+
for (const assertion of assertions) {
|
|
59
|
+
// ── mustFind ────────────────────────────────────────────
|
|
60
|
+
for (const matcher of assertion.mustFind) {
|
|
61
|
+
const found = findings.some((f) => findingMatchesMatcher(f, matcher));
|
|
62
|
+
if (!found) {
|
|
63
|
+
failures.push(`[${assertion.label}] mustFind: no finding matched ${JSON.stringify(matcher)}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// ── mustNotFind ─────────────────────────────────────────
|
|
67
|
+
for (const matcher of assertion.mustNotFind ?? []) {
|
|
68
|
+
const found = findings.some((f) => findingMatchesMatcher(f, matcher));
|
|
69
|
+
if (found) {
|
|
70
|
+
failures.push(`[${assertion.label}] mustNotFind: unexpected finding matched ${JSON.stringify(matcher)}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { passed: failures.length === 0, failures };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAoCvD,mEAAmE;AAEnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAkB,EAAE,UAAkB;IACtE,MAAM,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,SAAiB;IAC/C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;AACxC,CAAC;AAED,oEAAoE;AAEpE,SAAS,qBAAqB,CAC5B,OAAsB,EACtB,OAKC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtF,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1F,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1F,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QAChG,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAkB,EAClB,UAA4B;IAE5B,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;IACvC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,2DAA2D;QAC3D,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YACtE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,QAAQ,CAAC,IAAI,CACX,IAAI,SAAS,CAAC,KAAK,kCAAkC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC;QAED,2DAA2D;QAC3D,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YACtE,IAAI,KAAK,EAAE,CAAC;gBACV,QAAQ,CAAC,IAAI,CACX,IAAI,SAAS,CAAC,KAAK,6CAA6C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAC1F,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest integration helpers for the GHAGGA regression testing framework.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { describeTrace } from "@ghagga/core/testing/vitest-helpers.js";
|
|
6
|
+
*
|
|
7
|
+
* describeTrace("fixtures/my-trace.json", [
|
|
8
|
+
* {
|
|
9
|
+
* label: "finds SQL injection",
|
|
10
|
+
* mustFind: [{ category: "security", messageContains: "SQL injection" }],
|
|
11
|
+
* },
|
|
12
|
+
* ]);
|
|
13
|
+
*/
|
|
14
|
+
import { type TraceAssertion } from './index.js';
|
|
15
|
+
/**
|
|
16
|
+
* Create a vitest `describe` block that loads a trace from disk and runs
|
|
17
|
+
* all provided assertions as a single `it` test.
|
|
18
|
+
*
|
|
19
|
+
* Failing assertions produce an error message listing every failed check
|
|
20
|
+
* so the full picture is visible without multiple test-run iterations.
|
|
21
|
+
*
|
|
22
|
+
* @param tracePath - Path to the JSON trace file (absolute or cwd-relative)
|
|
23
|
+
* @param assertions - Array of structural assertions to evaluate
|
|
24
|
+
*/
|
|
25
|
+
export declare function describeTrace(tracePath: string, assertions: TraceAssertion[]): void;
|
|
26
|
+
//# sourceMappingURL=vitest-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest-helpers.d.ts","sourceRoot":"","sources":["../../src/testing/vitest-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,IAAI,CASnF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest integration helpers for the GHAGGA regression testing framework.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { describeTrace } from "@ghagga/core/testing/vitest-helpers.js";
|
|
6
|
+
*
|
|
7
|
+
* describeTrace("fixtures/my-trace.json", [
|
|
8
|
+
* {
|
|
9
|
+
* label: "finds SQL injection",
|
|
10
|
+
* mustFind: [{ category: "security", messageContains: "SQL injection" }],
|
|
11
|
+
* },
|
|
12
|
+
* ]);
|
|
13
|
+
*/
|
|
14
|
+
import { describe, expect, it } from 'vitest';
|
|
15
|
+
import { assertTrace, loadTrace } from './index.js';
|
|
16
|
+
/**
|
|
17
|
+
* Create a vitest `describe` block that loads a trace from disk and runs
|
|
18
|
+
* all provided assertions as a single `it` test.
|
|
19
|
+
*
|
|
20
|
+
* Failing assertions produce an error message listing every failed check
|
|
21
|
+
* so the full picture is visible without multiple test-run iterations.
|
|
22
|
+
*
|
|
23
|
+
* @param tracePath - Path to the JSON trace file (absolute or cwd-relative)
|
|
24
|
+
* @param assertions - Array of structural assertions to evaluate
|
|
25
|
+
*/
|
|
26
|
+
export function describeTrace(tracePath, assertions) {
|
|
27
|
+
describe(`Trace: ${tracePath}`, () => {
|
|
28
|
+
it('passes all assertions', async () => {
|
|
29
|
+
const trace = await loadTrace(tracePath);
|
|
30
|
+
const result = await assertTrace(trace, assertions);
|
|
31
|
+
if (!result.passed)
|
|
32
|
+
throw new Error(result.failures.join('\n'));
|
|
33
|
+
expect(result.passed).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=vitest-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest-helpers.js","sourceRoot":"","sources":["../../src/testing/vitest-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAuB,MAAM,YAAY,CAAC;AAEzE;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,UAA4B;IAC3E,QAAQ,CAAC,UAAU,SAAS,EAAE,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;YACrC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -13,5 +13,7 @@ export { runTools } from './orchestrator.js';
|
|
|
13
13
|
export { createNodeExecutionContext } from './execution.js';
|
|
14
14
|
export { initializeDefaultTools, resetInitialization } from './plugins/index.js';
|
|
15
15
|
/** @deprecated Always returns true. Kept for backward compatibility. */
|
|
16
|
-
export { isToolRegistryEnabled } from './runner.js';
|
|
16
|
+
export { formatStaticAnalysisContext, isToolRegistryEnabled } from './runner.js';
|
|
17
|
+
export type { RemoteQueryOptions } from './remote-query.js';
|
|
18
|
+
export { fetchRemoteFile, searchRemoteCode } from './remote-query.js';
|
|
17
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI3D,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAIrD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAIrE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAI5D,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAIjF,wEAAwE;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI3D,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAIrD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAIrE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAI5D,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAIjF,wEAAwE;AACxE,OAAO,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIjF,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|