ghagga-core 2.8.0 → 2.9.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/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 +267 -0
- package/dist/critique/cross-model.js.map +1 -0
- package/dist/critique/index.d.ts +8 -0
- package/dist/critique/index.d.ts.map +1 -0
- package/dist/critique/index.js +6 -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 +50 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -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 +94 -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 +229 -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 +196 -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,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"}
|
package/dist/tools/index.js
CHANGED
|
@@ -17,5 +17,6 @@ export { createNodeExecutionContext } from './execution.js';
|
|
|
17
17
|
export { initializeDefaultTools, resetInitialization } from './plugins/index.js';
|
|
18
18
|
// ─── Runner ─────────────────────────────────────────────────────
|
|
19
19
|
/** @deprecated Always returns true. Kept for backward compatibility. */
|
|
20
|
-
export { isToolRegistryEnabled } from './runner.js';
|
|
20
|
+
export { formatStaticAnalysisContext, isToolRegistryEnabled } from './runner.js';
|
|
21
|
+
export { fetchRemoteFile, searchRemoteCode } from './remote-query.js';
|
|
21
22
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,mEAAmE;AAEnE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAK3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,mEAAmE;AAEnE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAErE,mEAAmE;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,mEAAmE;AAEnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D,mEAAmE;AAEnE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,mEAAmE;AAEnE,wEAAwE;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,mEAAmE;AAEnE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAK3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,mEAAmE;AAEnE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAErE,mEAAmE;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,mEAAmE;AAEnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D,mEAAmE;AAEnE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjF,mEAAmE;AAEnE,wEAAwE;AACxE,OAAO,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAKjF,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codedb_remote — query public GitHub repos without cloning.
|
|
3
|
+
*
|
|
4
|
+
* Provides two utilities:
|
|
5
|
+
* - fetchRemoteFile: fetch a single file by path via raw.githubusercontent.com
|
|
6
|
+
* - searchRemoteCode: search for code patterns via the GitHub Search API
|
|
7
|
+
*
|
|
8
|
+
* Both functions NEVER throw; they return null / [] on any error instead.
|
|
9
|
+
*/
|
|
10
|
+
export interface RemoteQueryOptions {
|
|
11
|
+
owner: string;
|
|
12
|
+
repo: string;
|
|
13
|
+
/** Git ref to target. Defaults to "HEAD". */
|
|
14
|
+
ref?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fetch a single file from a public (or token-accessible) GitHub repository.
|
|
18
|
+
*
|
|
19
|
+
* @param path - Path to the file relative to the repo root (e.g. "src/index.ts")
|
|
20
|
+
* @param opts - Owner, repo, and optional ref
|
|
21
|
+
* @param token - Optional GitHub personal-access token or installation token
|
|
22
|
+
* @returns File contents as a string, or null on any error (4xx, 5xx, network, etc.)
|
|
23
|
+
*/
|
|
24
|
+
export declare function fetchRemoteFile(path: string, opts: RemoteQueryOptions, token?: string): Promise<string | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Search for code matching a query inside a GitHub repository.
|
|
27
|
+
*
|
|
28
|
+
* Uses the GitHub Code Search API with text-match fragments enabled.
|
|
29
|
+
* Rate-limited: unauthenticated = 10 req/min, authenticated = 30 req/min.
|
|
30
|
+
*
|
|
31
|
+
* @param query - Search query (will be scoped to the repo automatically)
|
|
32
|
+
* @param opts - Owner and repo to search in (ref is not used by GitHub's search API)
|
|
33
|
+
* @param token - Optional GitHub token; strongly recommended to avoid rate-limit errors
|
|
34
|
+
* @returns Array of { path, snippet } objects, or [] on any error
|
|
35
|
+
*/
|
|
36
|
+
export declare function searchRemoteCode(query: string, opts: RemoteQueryOptions, token?: string): Promise<Array<{
|
|
37
|
+
path: string;
|
|
38
|
+
snippet: string;
|
|
39
|
+
}>>;
|
|
40
|
+
//# sourceMappingURL=remote-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-query.d.ts","sourceRoot":"","sources":["../../src/tools/remote-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,kBAAkB,EACxB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkBxB;AAiBD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,kBAAkB,EACxB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAyBnD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codedb_remote — query public GitHub repos without cloning.
|
|
3
|
+
*
|
|
4
|
+
* Provides two utilities:
|
|
5
|
+
* - fetchRemoteFile: fetch a single file by path via raw.githubusercontent.com
|
|
6
|
+
* - searchRemoteCode: search for code patterns via the GitHub Search API
|
|
7
|
+
*
|
|
8
|
+
* Both functions NEVER throw; they return null / [] on any error instead.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Fetch a single file from a public (or token-accessible) GitHub repository.
|
|
12
|
+
*
|
|
13
|
+
* @param path - Path to the file relative to the repo root (e.g. "src/index.ts")
|
|
14
|
+
* @param opts - Owner, repo, and optional ref
|
|
15
|
+
* @param token - Optional GitHub personal-access token or installation token
|
|
16
|
+
* @returns File contents as a string, or null on any error (4xx, 5xx, network, etc.)
|
|
17
|
+
*/
|
|
18
|
+
export async function fetchRemoteFile(path, opts, token) {
|
|
19
|
+
const ref = opts.ref ?? 'HEAD';
|
|
20
|
+
const url = `https://raw.githubusercontent.com/${opts.owner}/${opts.repo}/${ref}/${path}`;
|
|
21
|
+
try {
|
|
22
|
+
const headers = {};
|
|
23
|
+
if (token) {
|
|
24
|
+
headers.Authorization = `Bearer ${token}`;
|
|
25
|
+
}
|
|
26
|
+
const response = await fetch(url, { headers });
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return await response.text();
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Search for code matching a query inside a GitHub repository.
|
|
38
|
+
*
|
|
39
|
+
* Uses the GitHub Code Search API with text-match fragments enabled.
|
|
40
|
+
* Rate-limited: unauthenticated = 10 req/min, authenticated = 30 req/min.
|
|
41
|
+
*
|
|
42
|
+
* @param query - Search query (will be scoped to the repo automatically)
|
|
43
|
+
* @param opts - Owner and repo to search in (ref is not used by GitHub's search API)
|
|
44
|
+
* @param token - Optional GitHub token; strongly recommended to avoid rate-limit errors
|
|
45
|
+
* @returns Array of { path, snippet } objects, or [] on any error
|
|
46
|
+
*/
|
|
47
|
+
export async function searchRemoteCode(query, opts, token) {
|
|
48
|
+
const scopedQuery = `${query} repo:${opts.owner}/${opts.repo}`;
|
|
49
|
+
const url = `https://api.github.com/search/code?q=${encodeURIComponent(scopedQuery)}`;
|
|
50
|
+
try {
|
|
51
|
+
const headers = {
|
|
52
|
+
Accept: 'application/vnd.github.v3.text-match+json',
|
|
53
|
+
};
|
|
54
|
+
if (token) {
|
|
55
|
+
headers.Authorization = `Bearer ${token}`;
|
|
56
|
+
}
|
|
57
|
+
const response = await fetch(url, { headers });
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const data = (await response.json());
|
|
62
|
+
return (data.items ?? []).map((item) => ({
|
|
63
|
+
path: item.path,
|
|
64
|
+
snippet: item.text_matches?.[0]?.fragment ?? '',
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=remote-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-query.js","sourceRoot":"","sources":["../../src/tools/remote-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,IAAwB,EACxB,KAAc;IAEd,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC;IAC/B,MAAM,GAAG,GAAG,qCAAqC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IAE1F,IAAI,CAAC;QACH,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAC;QAC5C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAiBD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAa,EACb,IAAwB,EACxB,KAAc;IAEd,MAAM,WAAW,GAAG,GAAG,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/D,MAAM,GAAG,GAAG,wCAAwC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IAEtF,IAAI,CAAC;QACH,MAAM,OAAO,GAA2B;YACtC,MAAM,EAAE,2CAA2C;SACpD,CAAC;QACF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAC;QAC5C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAyB,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACvC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,EAAE;SAChD,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|