@panguard-ai/atr 1.4.3 → 1.5.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/action-executor.d.ts +44 -0
- package/dist/action-executor.d.ts.map +1 -0
- package/dist/action-executor.js +130 -0
- package/dist/action-executor.js.map +1 -0
- package/dist/adapters/default-adapter.d.ts +24 -0
- package/dist/adapters/default-adapter.d.ts.map +1 -0
- package/dist/adapters/default-adapter.js +51 -0
- package/dist/adapters/default-adapter.js.map +1 -0
- package/dist/adapters/stdio-adapter.d.ts +30 -0
- package/dist/adapters/stdio-adapter.d.ts.map +1 -0
- package/dist/adapters/stdio-adapter.js +128 -0
- package/dist/adapters/stdio-adapter.js.map +1 -0
- package/dist/badge.d.ts +42 -0
- package/dist/badge.d.ts.map +1 -0
- package/dist/badge.js +163 -0
- package/dist/badge.js.map +1 -0
- package/dist/capability-extractor.d.ts +35 -0
- package/dist/capability-extractor.d.ts.map +1 -0
- package/dist/capability-extractor.js +91 -0
- package/dist/capability-extractor.js.map +1 -0
- package/dist/cli/scan-handler.d.ts +21 -0
- package/dist/cli/scan-handler.d.ts.map +1 -0
- package/dist/cli/scan-handler.js +276 -0
- package/dist/cli/scan-handler.js.map +1 -0
- package/dist/cli/tc-pipeline.d.ts +18 -0
- package/dist/cli/tc-pipeline.d.ts.map +1 -0
- package/dist/cli/tc-pipeline.js +295 -0
- package/dist/cli/tc-pipeline.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +894 -0
- package/dist/cli.js.map +1 -0
- package/dist/content-hash.d.ts +7 -0
- package/dist/content-hash.d.ts.map +1 -0
- package/dist/content-hash.js +10 -0
- package/dist/content-hash.js.map +1 -0
- package/dist/converters/elastic.d.ts +36 -0
- package/dist/converters/elastic.d.ts.map +1 -0
- package/dist/converters/elastic.js +125 -0
- package/dist/converters/elastic.js.map +1 -0
- package/dist/converters/generic-regex.d.ts +37 -0
- package/dist/converters/generic-regex.d.ts.map +1 -0
- package/dist/converters/generic-regex.js +59 -0
- package/dist/converters/generic-regex.js.map +1 -0
- package/dist/converters/index.d.ts +32 -0
- package/dist/converters/index.d.ts.map +1 -0
- package/dist/converters/index.js +38 -0
- package/dist/converters/index.js.map +1 -0
- package/dist/converters/sarif.d.ts +18 -0
- package/dist/converters/sarif.d.ts.map +1 -0
- package/dist/converters/sarif.js +142 -0
- package/dist/converters/sarif.js.map +1 -0
- package/dist/converters/splunk.d.ts +19 -0
- package/dist/converters/splunk.d.ts.map +1 -0
- package/dist/converters/splunk.js +148 -0
- package/dist/converters/splunk.js.map +1 -0
- package/dist/coverage-analyzer.d.ts +43 -0
- package/dist/coverage-analyzer.d.ts.map +1 -0
- package/dist/coverage-analyzer.js +329 -0
- package/dist/coverage-analyzer.js.map +1 -0
- package/dist/embedding/build-corpus.d.ts +15 -0
- package/dist/embedding/build-corpus.d.ts.map +1 -0
- package/dist/embedding/build-corpus.js +105 -0
- package/dist/embedding/build-corpus.js.map +1 -0
- package/dist/embedding/model-loader.d.ts +41 -0
- package/dist/embedding/model-loader.d.ts.map +1 -0
- package/dist/embedding/model-loader.js +90 -0
- package/dist/embedding/model-loader.js.map +1 -0
- package/dist/embedding/vector-store.d.ts +41 -0
- package/dist/embedding/vector-store.d.ts.map +1 -0
- package/dist/embedding/vector-store.js +70 -0
- package/dist/embedding/vector-store.js.map +1 -0
- package/dist/engine.d.ts +222 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1185 -0
- package/dist/engine.js.map +1 -0
- package/dist/eval/corpus.d.ts +42 -0
- package/dist/eval/corpus.d.ts.map +1 -0
- package/dist/eval/corpus.js +427 -0
- package/dist/eval/corpus.js.map +1 -0
- package/dist/eval/eval-harness.d.ts +44 -0
- package/dist/eval/eval-harness.d.ts.map +1 -0
- package/dist/eval/eval-harness.js +296 -0
- package/dist/eval/eval-harness.js.map +1 -0
- package/dist/eval/index.d.ts +13 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +9 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/metrics.d.ts +74 -0
- package/dist/eval/metrics.d.ts.map +1 -0
- package/dist/eval/metrics.js +108 -0
- package/dist/eval/metrics.js.map +1 -0
- package/dist/eval/pint-corpus.d.ts +34 -0
- package/dist/eval/pint-corpus.d.ts.map +1 -0
- package/dist/eval/pint-corpus.js +113 -0
- package/dist/eval/pint-corpus.js.map +1 -0
- package/dist/eval/rule-corpus.d.ts +9 -0
- package/dist/eval/rule-corpus.d.ts.map +1 -0
- package/dist/eval/rule-corpus.js +4780 -0
- package/dist/eval/rule-corpus.js.map +1 -0
- package/dist/eval/rule-metrics.d.ts +34 -0
- package/dist/eval/rule-metrics.d.ts.map +1 -0
- package/dist/eval/rule-metrics.js +92 -0
- package/dist/eval/rule-metrics.js.map +1 -0
- package/dist/eval/run-eval.d.ts +7 -0
- package/dist/eval/run-eval.d.ts.map +1 -0
- package/dist/eval/run-eval.js +11 -0
- package/dist/eval/run-eval.js.map +1 -0
- package/dist/eval/run-pint-benchmark.d.ts +18 -0
- package/dist/eval/run-pint-benchmark.d.ts.map +1 -0
- package/dist/eval/run-pint-benchmark.js +159 -0
- package/dist/eval/run-pint-benchmark.js.map +1 -0
- package/dist/eval/skill-benchmark.d.ts +66 -0
- package/dist/eval/skill-benchmark.d.ts.map +1 -0
- package/dist/eval/skill-benchmark.js +194 -0
- package/dist/eval/skill-benchmark.js.map +1 -0
- package/dist/flywheel.d.ts +54 -0
- package/dist/flywheel.d.ts.map +1 -0
- package/dist/flywheel.js +121 -0
- package/dist/flywheel.js.map +1 -0
- package/dist/hook-handler.d.ts +61 -0
- package/dist/hook-handler.d.ts.map +1 -0
- package/dist/hook-handler.js +178 -0
- package/dist/hook-handler.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/{src/index.ts → dist/index.js} +1 -0
- package/dist/index.js.map +1 -0
- package/dist/layer-integration.d.ts +55 -0
- package/dist/layer-integration.d.ts.map +1 -0
- package/dist/layer-integration.js +187 -0
- package/dist/layer-integration.js.map +1 -0
- package/dist/loader.d.ts +18 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +129 -0
- package/dist/loader.js.map +1 -0
- package/dist/mcp-server.d.ts +13 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +246 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp-tools/coverage-gaps.d.ts +13 -0
- package/dist/mcp-tools/coverage-gaps.d.ts.map +1 -0
- package/dist/mcp-tools/coverage-gaps.js +55 -0
- package/dist/mcp-tools/coverage-gaps.js.map +1 -0
- package/dist/mcp-tools/list-rules.d.ts +17 -0
- package/dist/mcp-tools/list-rules.d.ts.map +1 -0
- package/dist/mcp-tools/list-rules.js +45 -0
- package/dist/mcp-tools/list-rules.js.map +1 -0
- package/dist/mcp-tools/scan-skill.d.ts +17 -0
- package/dist/mcp-tools/scan-skill.d.ts.map +1 -0
- package/dist/mcp-tools/scan-skill.js +65 -0
- package/dist/mcp-tools/scan-skill.js.map +1 -0
- package/dist/mcp-tools/scan.d.ts +24 -0
- package/dist/mcp-tools/scan.d.ts.map +1 -0
- package/dist/mcp-tools/scan.js +94 -0
- package/dist/mcp-tools/scan.js.map +1 -0
- package/dist/mcp-tools/submit-proposal.d.ts +12 -0
- package/dist/mcp-tools/submit-proposal.d.ts.map +1 -0
- package/dist/mcp-tools/submit-proposal.js +103 -0
- package/dist/mcp-tools/submit-proposal.js.map +1 -0
- package/dist/mcp-tools/threat-summary.d.ts +12 -0
- package/dist/mcp-tools/threat-summary.d.ts.map +1 -0
- package/dist/mcp-tools/threat-summary.js +74 -0
- package/dist/mcp-tools/threat-summary.js.map +1 -0
- package/dist/mcp-tools/validate.d.ts +15 -0
- package/dist/mcp-tools/validate.d.ts.map +1 -0
- package/dist/mcp-tools/validate.js +51 -0
- package/dist/mcp-tools/validate.js.map +1 -0
- package/dist/modules/embedding.d.ts +71 -0
- package/dist/modules/embedding.d.ts.map +1 -0
- package/dist/modules/embedding.js +141 -0
- package/dist/modules/embedding.js.map +1 -0
- package/dist/modules/index.d.ts +144 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +82 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/semantic.d.ts +106 -0
- package/dist/modules/semantic.d.ts.map +1 -0
- package/dist/modules/semantic.js +359 -0
- package/dist/modules/semantic.js.map +1 -0
- package/dist/modules/session.d.ts +70 -0
- package/dist/modules/session.d.ts.map +1 -0
- package/dist/modules/session.js +128 -0
- package/dist/modules/session.js.map +1 -0
- package/dist/quality/adapters/atr.d.ts +65 -0
- package/dist/quality/adapters/atr.d.ts.map +1 -0
- package/dist/quality/adapters/atr.js +154 -0
- package/dist/quality/adapters/atr.js.map +1 -0
- package/dist/quality/adapters/index.d.ts +10 -0
- package/dist/quality/adapters/index.d.ts.map +1 -0
- package/dist/quality/adapters/index.js +10 -0
- package/dist/quality/adapters/index.js.map +1 -0
- package/dist/quality/compute-confidence.d.ts +45 -0
- package/dist/quality/compute-confidence.d.ts.map +1 -0
- package/dist/quality/compute-confidence.js +133 -0
- package/dist/quality/compute-confidence.js.map +1 -0
- package/dist/quality/index.d.ts +36 -0
- package/dist/quality/index.d.ts.map +1 -0
- package/dist/quality/index.js +39 -0
- package/dist/quality/index.js.map +1 -0
- package/dist/quality/quality-gate.d.ts +86 -0
- package/dist/quality/quality-gate.d.ts.map +1 -0
- package/dist/quality/quality-gate.js +187 -0
- package/dist/quality/quality-gate.js.map +1 -0
- package/dist/quality/types.d.ts +129 -0
- package/dist/quality/types.d.ts.map +1 -0
- package/dist/quality/types.js +10 -0
- package/dist/quality/types.js.map +1 -0
- package/dist/quality/validate-maturity.d.ts +51 -0
- package/dist/quality/validate-maturity.d.ts.map +1 -0
- package/dist/quality/validate-maturity.js +134 -0
- package/dist/quality/validate-maturity.js.map +1 -0
- package/dist/quality.d.ts +8 -0
- package/dist/quality.d.ts.map +1 -0
- package/dist/quality.js +8 -0
- package/dist/quality.js.map +1 -0
- package/dist/rule-scaffolder.d.ts +53 -0
- package/dist/rule-scaffolder.d.ts.map +1 -0
- package/dist/rule-scaffolder.js +301 -0
- package/dist/rule-scaffolder.js.map +1 -0
- package/dist/session-tracker.d.ts +58 -0
- package/dist/session-tracker.d.ts.map +1 -0
- package/dist/session-tracker.js +176 -0
- package/dist/session-tracker.js.map +1 -0
- package/dist/shadow-evaluator.d.ts +48 -0
- package/dist/shadow-evaluator.d.ts.map +1 -0
- package/dist/shadow-evaluator.js +129 -0
- package/dist/shadow-evaluator.js.map +1 -0
- package/dist/skill-fingerprint.d.ts +85 -0
- package/dist/skill-fingerprint.d.ts.map +1 -0
- package/dist/skill-fingerprint.js +284 -0
- package/dist/skill-fingerprint.js.map +1 -0
- package/dist/tc-reporter.d.ts +50 -0
- package/dist/tc-reporter.d.ts.map +1 -0
- package/dist/tc-reporter.js +164 -0
- package/dist/tc-reporter.js.map +1 -0
- package/dist/tier0-invariant.d.ts +49 -0
- package/dist/tier0-invariant.d.ts.map +1 -0
- package/dist/tier0-invariant.js +185 -0
- package/dist/tier0-invariant.js.map +1 -0
- package/dist/tier1-blacklist.d.ts +48 -0
- package/dist/tier1-blacklist.d.ts.map +1 -0
- package/dist/tier1-blacklist.js +92 -0
- package/dist/tier1-blacklist.js.map +1 -0
- package/dist/types.d.ts +232 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/verdict.d.ts +26 -0
- package/dist/verdict.d.ts.map +1 -0
- package/dist/verdict.js +127 -0
- package/dist/verdict.js.map +1 -0
- package/package.json +16 -4
- package/.github/ISSUE_TEMPLATE/evasion-report.yml +0 -75
- package/.github/ISSUE_TEMPLATE/false-positive.yml +0 -31
- package/.github/ISSUE_TEMPLATE/mirofish-prediction.yml +0 -128
- package/.github/ISSUE_TEMPLATE/new-rule.yml +0 -37
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -23
- package/.github/workflows/rule-quality.yml +0 -203
- package/.github/workflows/validate.yml +0 -42
- package/CHANGELOG.md +0 -30
- package/CONTRIBUTING.md +0 -168
- package/CONTRIBUTORS.md +0 -28
- package/COVERAGE.md +0 -135
- package/LIMITATIONS.md +0 -154
- package/SECURITY.md +0 -48
- package/THREAT-MODEL.md +0 -243
- package/docs/contribution-paths.md +0 -202
- package/docs/mirofish-prediction-guide.md +0 -304
- package/docs/quick-start.md +0 -245
- package/docs/rule-writing-guide.md +0 -647
- package/docs/schema-spec.md +0 -594
- package/examples/how-to-write-a-rule.md +0 -251
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* atr_submit_proposal MCP tool - Generate ATR rule draft from threat description
|
|
3
|
+
* @module agent-threat-rules/mcp-tools/submit-proposal
|
|
4
|
+
*/
|
|
5
|
+
import { RuleScaffolder } from '../rule-scaffolder.js';
|
|
6
|
+
const VALID_CATEGORIES = new Set([
|
|
7
|
+
'prompt-injection',
|
|
8
|
+
'tool-poisoning',
|
|
9
|
+
'context-exfiltration',
|
|
10
|
+
'agent-manipulation',
|
|
11
|
+
'privilege-escalation',
|
|
12
|
+
'excessive-autonomy',
|
|
13
|
+
'data-poisoning',
|
|
14
|
+
'model-abuse',
|
|
15
|
+
'skill-compromise',
|
|
16
|
+
]);
|
|
17
|
+
const VALID_SEVERITIES = new Set([
|
|
18
|
+
'critical',
|
|
19
|
+
'high',
|
|
20
|
+
'medium',
|
|
21
|
+
'low',
|
|
22
|
+
'informational',
|
|
23
|
+
]);
|
|
24
|
+
export function handleSubmitProposal(args) {
|
|
25
|
+
const title = args['title'];
|
|
26
|
+
const category = args['category'];
|
|
27
|
+
const attackDescription = args['attack_description'];
|
|
28
|
+
const examplePayloads = args['example_payloads'];
|
|
29
|
+
const severity = args['severity'];
|
|
30
|
+
const mitreRefs = args['mitre_refs'];
|
|
31
|
+
// Validate required fields
|
|
32
|
+
if (typeof title !== 'string' || title.trim().length === 0) {
|
|
33
|
+
return {
|
|
34
|
+
content: [{ type: 'text', text: 'Error: "title" is required and must be a non-empty string.' }],
|
|
35
|
+
isError: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (typeof category !== 'string' || !VALID_CATEGORIES.has(category)) {
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: 'text', text: `Error: "category" must be one of: ${[...VALID_CATEGORIES].join(', ')}` }],
|
|
41
|
+
isError: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (typeof attackDescription !== 'string' || attackDescription.trim().length === 0) {
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: 'text', text: 'Error: "attack_description" is required and must be a non-empty string.' }],
|
|
47
|
+
isError: true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (!Array.isArray(examplePayloads) || examplePayloads.length === 0) {
|
|
51
|
+
return {
|
|
52
|
+
content: [{ type: 'text', text: 'Error: "example_payloads" must be a non-empty array of strings.' }],
|
|
53
|
+
isError: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
for (const payload of examplePayloads) {
|
|
57
|
+
if (typeof payload !== 'string') {
|
|
58
|
+
return {
|
|
59
|
+
content: [{ type: 'text', text: 'Error: All items in "example_payloads" must be strings.' }],
|
|
60
|
+
isError: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (severity && !VALID_SEVERITIES.has(severity)) {
|
|
65
|
+
return {
|
|
66
|
+
content: [{ type: 'text', text: `Error: "severity" must be one of: ${[...VALID_SEVERITIES].join(', ')}` }],
|
|
67
|
+
isError: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (mitreRefs !== undefined) {
|
|
71
|
+
if (!Array.isArray(mitreRefs) || mitreRefs.some((r) => typeof r !== 'string')) {
|
|
72
|
+
return {
|
|
73
|
+
content: [{ type: 'text', text: 'Error: "mitre_refs" must be an array of strings.' }],
|
|
74
|
+
isError: true,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const scaffolder = new RuleScaffolder();
|
|
79
|
+
const result = scaffolder.scaffold({
|
|
80
|
+
title: title.trim(),
|
|
81
|
+
category: category,
|
|
82
|
+
attackDescription: attackDescription.trim(),
|
|
83
|
+
examplePayloads: examplePayloads.map((p) => p.trim()),
|
|
84
|
+
severity: severity,
|
|
85
|
+
mitreRefs: mitreRefs,
|
|
86
|
+
});
|
|
87
|
+
const response = {
|
|
88
|
+
generated_id: result.id,
|
|
89
|
+
warnings: result.warnings,
|
|
90
|
+
yaml_rule: result.yaml,
|
|
91
|
+
next_steps: [
|
|
92
|
+
'Review and refine the generated detection patterns',
|
|
93
|
+
'Add more specific regex patterns for your use case',
|
|
94
|
+
'Test with atr_scan using example payloads',
|
|
95
|
+
'Validate with atr_validate_rule before submitting',
|
|
96
|
+
'Submit as a PR to the ATR repository',
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=submit-proposal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit-proposal.js","sourceRoot":"","sources":["../../src/mcp-tools/submit-proposal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* atr_threat_summary MCP tool - Aggregate threat statistics
|
|
3
|
+
* @module agent-threat-rules/mcp-tools/threat-summary
|
|
4
|
+
*/
|
|
5
|
+
import type { ATREngine } from '../engine.js';
|
|
6
|
+
export declare function handleThreatSummary(engine: ATREngine, args: Record<string, unknown>): {
|
|
7
|
+
content: Array<{
|
|
8
|
+
type: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=threat-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat-summary.d.ts","sourceRoot":"","sources":["../../src/mcp-tools/threat-summary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACrF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD,CA8EA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* atr_threat_summary MCP tool - Aggregate threat statistics
|
|
3
|
+
* @module agent-threat-rules/mcp-tools/threat-summary
|
|
4
|
+
*/
|
|
5
|
+
export function handleThreatSummary(engine, args) {
|
|
6
|
+
const category = args['category'];
|
|
7
|
+
const rules = [...engine.getRules()];
|
|
8
|
+
const filtered = category
|
|
9
|
+
? rules.filter((r) => r.tags.category === category)
|
|
10
|
+
: rules;
|
|
11
|
+
// Aggregate by category
|
|
12
|
+
const byCategory = {};
|
|
13
|
+
for (const rule of filtered) {
|
|
14
|
+
const cat = rule.tags.category;
|
|
15
|
+
byCategory[cat] = (byCategory[cat] ?? 0) + 1;
|
|
16
|
+
}
|
|
17
|
+
// Aggregate by severity
|
|
18
|
+
const bySeverity = {};
|
|
19
|
+
for (const rule of filtered) {
|
|
20
|
+
bySeverity[rule.severity] = (bySeverity[rule.severity] ?? 0) + 1;
|
|
21
|
+
}
|
|
22
|
+
// Aggregate by status
|
|
23
|
+
const byStatus = {};
|
|
24
|
+
for (const rule of filtered) {
|
|
25
|
+
byStatus[rule.status] = (byStatus[rule.status] ?? 0) + 1;
|
|
26
|
+
}
|
|
27
|
+
// Aggregate by source type
|
|
28
|
+
const bySourceType = {};
|
|
29
|
+
for (const rule of filtered) {
|
|
30
|
+
const src = rule.agent_source.type;
|
|
31
|
+
bySourceType[src] = (bySourceType[src] ?? 0) + 1;
|
|
32
|
+
}
|
|
33
|
+
// Count test cases
|
|
34
|
+
let totalTestCases = 0;
|
|
35
|
+
let rulesWithTests = 0;
|
|
36
|
+
for (const rule of filtered) {
|
|
37
|
+
if (rule.test_cases) {
|
|
38
|
+
rulesWithTests++;
|
|
39
|
+
totalTestCases +=
|
|
40
|
+
(rule.test_cases.true_positives?.length ?? 0) +
|
|
41
|
+
(rule.test_cases.true_negatives?.length ?? 0);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Top actions
|
|
45
|
+
const actionCounts = {};
|
|
46
|
+
for (const rule of filtered) {
|
|
47
|
+
for (const action of rule.response.actions) {
|
|
48
|
+
actionCounts[action] = (actionCounts[action] ?? 0) + 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const topActions = Object.entries(actionCounts)
|
|
52
|
+
.sort((a, b) => b[1] - a[1])
|
|
53
|
+
.slice(0, 5)
|
|
54
|
+
.map(([action, count]) => ({ action, count }));
|
|
55
|
+
const result = {
|
|
56
|
+
summary_timestamp: new Date().toISOString(),
|
|
57
|
+
...(category ? { filtered_category: category } : {}),
|
|
58
|
+
total_rules: filtered.length,
|
|
59
|
+
by_category: byCategory,
|
|
60
|
+
by_severity: bySeverity,
|
|
61
|
+
by_status: byStatus,
|
|
62
|
+
by_source_type: bySourceType,
|
|
63
|
+
test_coverage: {
|
|
64
|
+
rules_with_tests: rulesWithTests,
|
|
65
|
+
rules_without_tests: filtered.length - rulesWithTests,
|
|
66
|
+
total_test_cases: totalTestCases,
|
|
67
|
+
},
|
|
68
|
+
top_response_actions: topActions,
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=threat-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threat-summary.js","sourceRoot":"","sources":["../../src/mcp-tools/threat-summary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,IAA6B;IAGlF,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAuB,CAAC;IACxD,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAErC,MAAM,QAAQ,GAAG,QAAQ;QACvB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC;QACnD,CAAC,CAAC,KAAK,CAAC;IAEV,wBAAwB;IACxB,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/B,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;IAED,wBAAwB;IACxB,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,sBAAsB;IACtB,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;QACnC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC;IAED,mBAAmB;IACnB,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,cAAc,EAAE,CAAC;YACjB,cAAc;gBACZ,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CAAC;oBAC7C,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,cAAc;IACd,MAAM,YAAY,GAA2B,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC3C,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;SAC5C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SAC3B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG;QACb,iBAAiB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC3C,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,WAAW,EAAE,QAAQ,CAAC,MAAM;QAC5B,WAAW,EAAE,UAAU;QACvB,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,QAAQ;QACnB,cAAc,EAAE,YAAY;QAC5B,aAAa,EAAE;YACb,gBAAgB,EAAE,cAAc;YAChC,mBAAmB,EAAE,QAAQ,CAAC,MAAM,GAAG,cAAc;YACrD,gBAAgB,EAAE,cAAc;SACjC;QACD,oBAAoB,EAAE,UAAU;KACjC,CAAC;IAEF,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KACnE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* atr_validate_rule MCP tool - Validate ATR rule YAML
|
|
3
|
+
* @module agent-threat-rules/mcp-tools/validate
|
|
4
|
+
*/
|
|
5
|
+
export interface ValidateInput {
|
|
6
|
+
yaml_content: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function handleValidate(args: Record<string, unknown>): {
|
|
9
|
+
content: Array<{
|
|
10
|
+
type: string;
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
13
|
+
isError?: boolean;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/mcp-tools/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAC7D,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CA+CA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* atr_validate_rule MCP tool - Validate ATR rule YAML
|
|
3
|
+
* @module agent-threat-rules/mcp-tools/validate
|
|
4
|
+
*/
|
|
5
|
+
import yaml from 'js-yaml';
|
|
6
|
+
import { validateRule } from '../loader.js';
|
|
7
|
+
export function handleValidate(args) {
|
|
8
|
+
const yamlContent = args['yaml_content'];
|
|
9
|
+
if (typeof yamlContent !== 'string' || yamlContent.trim().length === 0) {
|
|
10
|
+
return {
|
|
11
|
+
content: [{ type: 'text', text: 'Error: "yaml_content" is required and must be a non-empty string.' }],
|
|
12
|
+
isError: true,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
if (yamlContent.length > 1_000_000) {
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: 'text', text: 'Error: YAML content exceeds 1MB limit.' }],
|
|
18
|
+
isError: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const parsed = yaml.load(yamlContent);
|
|
23
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: 'text', text: JSON.stringify({ valid: false, errors: ['YAML parsed to a non-object value.'] }, null, 2) }],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const result = validateRule(parsed);
|
|
29
|
+
const response = {
|
|
30
|
+
valid: result.valid,
|
|
31
|
+
errors: result.errors,
|
|
32
|
+
parsed_fields: {
|
|
33
|
+
id: parsed['id'] ?? null,
|
|
34
|
+
title: parsed['title'] ?? null,
|
|
35
|
+
severity: parsed['severity'] ?? null,
|
|
36
|
+
category: parsed['tags']?.['category'] ?? null,
|
|
37
|
+
status: parsed['status'] ?? null,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
46
|
+
return {
|
|
47
|
+
content: [{ type: 'text', text: JSON.stringify({ valid: false, errors: [`YAML parse error: ${msg}`] }, null, 2) }],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/mcp-tools/validate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAM5C,MAAM,UAAU,cAAc,CAAC,IAA6B;IAI1D,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;IACzC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,mEAAmE,EAAE,CAAC;YACtG,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QACnC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,wCAAwC,EAAE,CAAC;YAC3E,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,oCAAoC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC7H,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEpC,MAAM,QAAQ,GAAG;YACf,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,aAAa,EAAE;gBACb,EAAE,EAAG,MAAkC,CAAC,IAAI,CAAC,IAAI,IAAI;gBACrD,KAAK,EAAG,MAAkC,CAAC,OAAO,CAAC,IAAI,IAAI;gBAC3D,QAAQ,EAAG,MAAkC,CAAC,UAAU,CAAC,IAAI,IAAI;gBACjE,QAAQ,EAAI,MAAkC,CAAC,MAAM,CAAyC,EAAE,CAAC,UAAU,CAAC,IAAI,IAAI;gBACpH,MAAM,EAAG,MAAkC,CAAC,QAAQ,CAAC,IAAI,IAAI;aAC9D;SACF,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,qBAAqB,GAAG,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnH,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Module -- Tier 2.5 semantic similarity detection.
|
|
3
|
+
*
|
|
4
|
+
* Compares incoming text against pre-computed attack embeddings using
|
|
5
|
+
* cosine similarity. Catches paraphrases, multilingual attacks, and
|
|
6
|
+
* semantic variants that regex cannot detect.
|
|
7
|
+
*
|
|
8
|
+
* Uses all-MiniLM-L6-v2 (384 dimensions, ~22MB, runs locally in JS/WASM).
|
|
9
|
+
* No API calls. Optional dependency: @xenova/transformers.
|
|
10
|
+
*
|
|
11
|
+
* @module agent-threat-rules/modules/embedding
|
|
12
|
+
*/
|
|
13
|
+
import type { AgentEvent } from '../types.js';
|
|
14
|
+
import type { ATRModule, ModuleCondition, ModuleResult } from './index.js';
|
|
15
|
+
import { type VectorEntry, type SearchResult } from '../embedding/vector-store.js';
|
|
16
|
+
import type { EmbeddingModel } from '../embedding/model-loader.js';
|
|
17
|
+
export interface EmbeddingModuleConfig {
|
|
18
|
+
/** Pre-loaded attack vector entries */
|
|
19
|
+
readonly attackVectors?: readonly VectorEntry[];
|
|
20
|
+
/** Path to pre-computed attack-embeddings.json file */
|
|
21
|
+
readonly attackVectorsPath?: string;
|
|
22
|
+
/** Raw JSON data (alternative to file path) */
|
|
23
|
+
readonly attackVectorsData?: readonly {
|
|
24
|
+
id: string;
|
|
25
|
+
vector: number[];
|
|
26
|
+
label: string;
|
|
27
|
+
category: string;
|
|
28
|
+
severity: string;
|
|
29
|
+
}[];
|
|
30
|
+
/** Cosine similarity threshold (default: 0.65) */
|
|
31
|
+
readonly similarityThreshold?: number;
|
|
32
|
+
/** Top-K results to consider (default: 3) */
|
|
33
|
+
readonly topK?: number;
|
|
34
|
+
/** Custom embedding model (default: TransformersJSModel) */
|
|
35
|
+
readonly model?: EmbeddingModel;
|
|
36
|
+
}
|
|
37
|
+
export declare class EmbeddingModule implements ATRModule {
|
|
38
|
+
private readonly config;
|
|
39
|
+
readonly name = "embedding";
|
|
40
|
+
readonly description = "Vector similarity detection against known attack embeddings";
|
|
41
|
+
readonly version = "0.1.0";
|
|
42
|
+
readonly functions: {
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
args: ({
|
|
46
|
+
name: string;
|
|
47
|
+
type: "string";
|
|
48
|
+
required: boolean;
|
|
49
|
+
description: string;
|
|
50
|
+
} | {
|
|
51
|
+
name: string;
|
|
52
|
+
type: "number";
|
|
53
|
+
required: boolean;
|
|
54
|
+
description: string;
|
|
55
|
+
})[];
|
|
56
|
+
}[];
|
|
57
|
+
private store;
|
|
58
|
+
private model;
|
|
59
|
+
private readonly threshold;
|
|
60
|
+
private readonly topK;
|
|
61
|
+
private initialized;
|
|
62
|
+
constructor(config?: EmbeddingModuleConfig);
|
|
63
|
+
initialize(): Promise<void>;
|
|
64
|
+
evaluate(event: AgentEvent, condition: ModuleCondition): Promise<ModuleResult>;
|
|
65
|
+
/** Get search results with full details (for debugging/testing) */
|
|
66
|
+
searchDetailed(text: string, threshold?: number): Promise<readonly SearchResult[]>;
|
|
67
|
+
destroy(): Promise<void>;
|
|
68
|
+
/** Check if module is operational */
|
|
69
|
+
isAvailable(): boolean;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=embedding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../src/modules/embedding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAMnE,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAChD,uDAAuD;IACvD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,+CAA+C;IAC/C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS;QACpC,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,EAAE,CAAC;IACJ,kDAAkD;IAClD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC;AAMD,qBAAa,eAAgB,YAAW,SAAS;IAgCnC,OAAO,CAAC,QAAQ,CAAC,MAAM;IA/BnC,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,iEAAiE;IACrF,QAAQ,CAAC,OAAO,WAAW;IAE3B,QAAQ,CAAC,SAAS;;;;;;;;;;;;;;QAmBhB;IAEF,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAS;gBAEC,MAAM,GAAE,qBAA0B;IAOzD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IA2CpF,mEAAmE;IAC7D,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAMlF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,qCAAqC;IACrC,WAAW,IAAI,OAAO;CAGvB"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedding Module -- Tier 2.5 semantic similarity detection.
|
|
3
|
+
*
|
|
4
|
+
* Compares incoming text against pre-computed attack embeddings using
|
|
5
|
+
* cosine similarity. Catches paraphrases, multilingual attacks, and
|
|
6
|
+
* semantic variants that regex cannot detect.
|
|
7
|
+
*
|
|
8
|
+
* Uses all-MiniLM-L6-v2 (384 dimensions, ~22MB, runs locally in JS/WASM).
|
|
9
|
+
* No API calls. Optional dependency: @xenova/transformers.
|
|
10
|
+
*
|
|
11
|
+
* @module agent-threat-rules/modules/embedding
|
|
12
|
+
*/
|
|
13
|
+
import { VectorStore, loadVectorEntries, } from '../embedding/vector-store.js';
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Module
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export class EmbeddingModule {
|
|
18
|
+
config;
|
|
19
|
+
name = 'embedding';
|
|
20
|
+
description = 'Vector similarity detection against known attack embeddings';
|
|
21
|
+
version = '0.1.0';
|
|
22
|
+
functions = [
|
|
23
|
+
{
|
|
24
|
+
name: 'similarity_search',
|
|
25
|
+
description: 'Find nearest known attacks by embedding similarity',
|
|
26
|
+
args: [
|
|
27
|
+
{
|
|
28
|
+
name: 'field',
|
|
29
|
+
type: 'string',
|
|
30
|
+
required: false,
|
|
31
|
+
description: 'Event field to embed (default: content)',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'threshold',
|
|
35
|
+
type: 'number',
|
|
36
|
+
required: false,
|
|
37
|
+
description: 'Similarity threshold override',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
store;
|
|
43
|
+
model;
|
|
44
|
+
threshold;
|
|
45
|
+
topK;
|
|
46
|
+
initialized = false;
|
|
47
|
+
constructor(config = {}) {
|
|
48
|
+
this.config = config;
|
|
49
|
+
this.threshold = config.similarityThreshold ?? 0.65;
|
|
50
|
+
this.topK = config.topK ?? 3;
|
|
51
|
+
this.model = config.model ?? null;
|
|
52
|
+
this.store = new VectorStore(config.attackVectors);
|
|
53
|
+
}
|
|
54
|
+
async initialize() {
|
|
55
|
+
if (this.initialized)
|
|
56
|
+
return;
|
|
57
|
+
// Load attack vectors from data
|
|
58
|
+
if (this.config.attackVectorsData) {
|
|
59
|
+
const entries = loadVectorEntries(this.config.attackVectorsData);
|
|
60
|
+
this.store = this.store.withEntries(entries);
|
|
61
|
+
}
|
|
62
|
+
// Load attack vectors from file
|
|
63
|
+
if (this.config.attackVectorsPath) {
|
|
64
|
+
try {
|
|
65
|
+
const { readFileSync } = await import('node:fs');
|
|
66
|
+
const data = JSON.parse(readFileSync(this.config.attackVectorsPath, 'utf-8'));
|
|
67
|
+
const entries = loadVectorEntries(data);
|
|
68
|
+
this.store = this.store.withEntries(entries);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// File not found = no pre-computed vectors, continue without them
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Load model if not provided
|
|
75
|
+
if (!this.model) {
|
|
76
|
+
try {
|
|
77
|
+
const { TransformersJSModel } = await import('../embedding/model-loader.js');
|
|
78
|
+
this.model = new TransformersJSModel();
|
|
79
|
+
await this.model.initialize();
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
// Model not available = module degrades gracefully
|
|
83
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
84
|
+
console.warn(`[embedding] Model not available: ${msg}. Module disabled.`);
|
|
85
|
+
this.model = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.initialized = true;
|
|
89
|
+
}
|
|
90
|
+
async evaluate(event, condition) {
|
|
91
|
+
if (!this.model || this.store.size() === 0) {
|
|
92
|
+
return { matched: false, value: 0, description: 'Embedding module not initialized' };
|
|
93
|
+
}
|
|
94
|
+
// Extract text to embed
|
|
95
|
+
const field = condition.args?.field ?? 'content';
|
|
96
|
+
const text = field === 'content'
|
|
97
|
+
? event.content
|
|
98
|
+
: event.fields?.[field] ?? event.content;
|
|
99
|
+
if (!text || text.length < 5) {
|
|
100
|
+
return { matched: false, value: 0, description: 'Input too short for embedding' };
|
|
101
|
+
}
|
|
102
|
+
// Truncate to avoid excessive token usage
|
|
103
|
+
const truncated = text.slice(0, 512);
|
|
104
|
+
try {
|
|
105
|
+
// Encode input
|
|
106
|
+
const queryVec = await this.model.encode(truncated);
|
|
107
|
+
// Search for similar attacks
|
|
108
|
+
const threshold = condition.args?.threshold ?? this.threshold;
|
|
109
|
+
const results = this.store.search(queryVec, this.topK, threshold);
|
|
110
|
+
if (results.length === 0) {
|
|
111
|
+
return { matched: false, value: 0, description: 'No similar attacks found' };
|
|
112
|
+
}
|
|
113
|
+
const top = results[0];
|
|
114
|
+
return {
|
|
115
|
+
matched: true,
|
|
116
|
+
value: top.similarity,
|
|
117
|
+
description: `Similar to known attack: "${top.entry.label}" (${top.entry.category}, similarity: ${top.similarity.toFixed(3)})`,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
122
|
+
return { matched: false, value: 0, description: `Embedding error: ${msg}` };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** Get search results with full details (for debugging/testing) */
|
|
126
|
+
async searchDetailed(text, threshold) {
|
|
127
|
+
if (!this.model || this.store.size() === 0)
|
|
128
|
+
return [];
|
|
129
|
+
const queryVec = await this.model.encode(text.slice(0, 512));
|
|
130
|
+
return this.store.search(queryVec, this.topK, threshold ?? this.threshold);
|
|
131
|
+
}
|
|
132
|
+
async destroy() {
|
|
133
|
+
this.model = null;
|
|
134
|
+
this.initialized = false;
|
|
135
|
+
}
|
|
136
|
+
/** Check if module is operational */
|
|
137
|
+
isAvailable() {
|
|
138
|
+
return this.initialized && this.model !== null && this.store.size() > 0;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=embedding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../src/modules/embedding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EACL,WAAW,EACX,iBAAiB,GAGlB,MAAM,8BAA8B,CAAC;AA4BtC,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E,MAAM,OAAO,eAAe;IAgCG;IA/BpB,IAAI,GAAG,WAAW,CAAC;IACnB,WAAW,GAAG,6DAA6D,CAAC;IAC5E,OAAO,GAAG,OAAO,CAAC;IAElB,SAAS,GAAG;QACnB;YACE,IAAI,EAAE,mBAAmB;YACzB,WAAW,EAAE,oDAAoD;YACjE,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,QAAiB;oBACvB,QAAQ,EAAE,KAAK;oBACf,WAAW,EAAE,yCAAyC;iBACvD;gBACD;oBACE,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,QAAiB;oBACvB,QAAQ,EAAE,KAAK;oBACf,WAAW,EAAE,+BAA+B;iBAC7C;aACF;SACF;KACF,CAAC;IAEM,KAAK,CAAc;IACnB,KAAK,CAAwB;IACpB,SAAS,CAAS;IAClB,IAAI,CAAS;IACtB,WAAW,GAAG,KAAK,CAAC;IAE5B,YAA6B,SAAgC,EAAE;QAAlC,WAAM,GAAN,MAAM,CAA4B;QAC7D,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,mBAAmB,IAAI,IAAI,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,gCAAgC;QAChC,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;YACjE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC;QAED,gCAAgC;QAChC,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;gBACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC9E,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBACxC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;YACpE,CAAC;QACH,CAAC;QAED,6BAA6B;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;gBAC7E,IAAI,CAAC,KAAK,GAAG,IAAI,mBAAmB,EAAE,CAAC;gBACvC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YAChC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,mDAAmD;gBACnD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7D,OAAO,CAAC,IAAI,CAAC,oCAAoC,GAAG,oBAAoB,CAAC,CAAC;gBAC1E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAiB,EAAE,SAA0B;QAC1D,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;QACvF,CAAC;QAED,wBAAwB;QACxB,MAAM,KAAK,GAAI,SAAS,CAAC,IAAI,EAAE,KAAgB,IAAI,SAAS,CAAC;QAC7D,MAAM,IAAI,GACR,KAAK,KAAK,SAAS;YACjB,CAAC,CAAC,KAAK,CAAC,OAAO;YACf,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC;QAE7C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC;QACpF,CAAC;QAED,0CAA0C;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAErC,IAAI,CAAC;YACH,eAAe;YACf,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAEpD,6BAA6B;YAC7B,MAAM,SAAS,GAAI,SAAS,CAAC,IAAI,EAAE,SAAoB,IAAI,IAAI,CAAC,SAAS,CAAC;YAC1E,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAElE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;YAC/E,CAAC;YAED,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;YACxB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,GAAG,CAAC,UAAU;gBACrB,WAAW,EAAE,6BAA6B,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,iBAAiB,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;aAC/H,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,oBAAoB,GAAG,EAAE,EAAE,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,SAAkB;QACnD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,qCAAqC;IACrC,WAAW;QACT,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC1E,CAAC;CACF"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ATR Module System
|
|
3
|
+
*
|
|
4
|
+
* Extensible detection modules beyond regex pattern matching.
|
|
5
|
+
* Inspired by YARA modules, adapted for AI agent threat detection.
|
|
6
|
+
*
|
|
7
|
+
* Built-in modules:
|
|
8
|
+
* - session: Cross-event behavioral analysis using SessionTracker
|
|
9
|
+
* - semantic: AI-driven semantic threat analysis using LLM-as-judge (v0.2)
|
|
10
|
+
*
|
|
11
|
+
* Reserved namespaces (planned):
|
|
12
|
+
* - embedding: Vector similarity detection (v0.3)
|
|
13
|
+
* - protocol: MCP/transport-level inspection (v0.3)
|
|
14
|
+
* - entropy: Information-theoretic anomaly detection (v0.4)
|
|
15
|
+
* - tokenizer: Token-level analysis for smuggling detection (v0.4)
|
|
16
|
+
*
|
|
17
|
+
* @module agent-threat-rules/modules
|
|
18
|
+
*/
|
|
19
|
+
import type { AgentEvent } from '../types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Condition defined by a module (used in rule YAML).
|
|
22
|
+
*
|
|
23
|
+
* Example in YAML:
|
|
24
|
+
* ```yaml
|
|
25
|
+
* detection:
|
|
26
|
+
* conditions:
|
|
27
|
+
* high_frequency:
|
|
28
|
+
* module: session
|
|
29
|
+
* function: call_frequency
|
|
30
|
+
* args:
|
|
31
|
+
* tool_name: "execute_code"
|
|
32
|
+
* window: "5m"
|
|
33
|
+
* operator: gt
|
|
34
|
+
* threshold: 10
|
|
35
|
+
* condition: "high_frequency"
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export interface ModuleCondition {
|
|
39
|
+
/** Module name (e.g., "session", "embedding") */
|
|
40
|
+
module: string;
|
|
41
|
+
/** Function within the module to call */
|
|
42
|
+
function: string;
|
|
43
|
+
/** Arguments passed to the module function */
|
|
44
|
+
args: Record<string, unknown>;
|
|
45
|
+
/** Comparison operator for the result */
|
|
46
|
+
operator: 'gt' | 'lt' | 'eq' | 'gte' | 'lte';
|
|
47
|
+
/** Threshold value to compare against */
|
|
48
|
+
threshold: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Result returned by a module evaluation.
|
|
52
|
+
*/
|
|
53
|
+
export interface ModuleResult {
|
|
54
|
+
/** Whether the condition was met */
|
|
55
|
+
matched: boolean;
|
|
56
|
+
/** Numeric value produced by the module (for threshold comparison) */
|
|
57
|
+
value: number;
|
|
58
|
+
/** Human-readable description of the result */
|
|
59
|
+
description: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Interface that all ATR detection modules must implement.
|
|
63
|
+
*
|
|
64
|
+
* Modules extend ATR's detection beyond regex by providing
|
|
65
|
+
* custom evaluation logic (behavioral analysis, embedding
|
|
66
|
+
* similarity, protocol inspection, etc.).
|
|
67
|
+
*/
|
|
68
|
+
export interface ATRModule {
|
|
69
|
+
/** Unique module name (used in rule YAML) */
|
|
70
|
+
readonly name: string;
|
|
71
|
+
/** Human-readable description */
|
|
72
|
+
readonly description: string;
|
|
73
|
+
/** Module version */
|
|
74
|
+
readonly version: string;
|
|
75
|
+
/**
|
|
76
|
+
* List of functions this module provides.
|
|
77
|
+
* Each function can be referenced in rule conditions.
|
|
78
|
+
*/
|
|
79
|
+
readonly functions: ReadonlyArray<{
|
|
80
|
+
name: string;
|
|
81
|
+
description: string;
|
|
82
|
+
args: ReadonlyArray<{
|
|
83
|
+
name: string;
|
|
84
|
+
type: 'string' | 'number' | 'boolean';
|
|
85
|
+
required: boolean;
|
|
86
|
+
description: string;
|
|
87
|
+
}>;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Initialize the module. Called once when the engine starts.
|
|
91
|
+
* Use for setup, connection pooling, model loading, etc.
|
|
92
|
+
*/
|
|
93
|
+
initialize(): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Evaluate a module condition against an agent event.
|
|
96
|
+
*
|
|
97
|
+
* @param event - The agent event being evaluated
|
|
98
|
+
* @param condition - The module condition from the rule
|
|
99
|
+
* @returns Module evaluation result
|
|
100
|
+
*/
|
|
101
|
+
evaluate(event: AgentEvent, condition: ModuleCondition): Promise<ModuleResult>;
|
|
102
|
+
/**
|
|
103
|
+
* Clean up module resources. Called when the engine shuts down.
|
|
104
|
+
*/
|
|
105
|
+
destroy(): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Registry for ATR detection modules.
|
|
109
|
+
*/
|
|
110
|
+
export declare class ModuleRegistry {
|
|
111
|
+
private readonly modules;
|
|
112
|
+
/** Reserved module namespaces (cannot be registered by third parties) */
|
|
113
|
+
private static readonly RESERVED;
|
|
114
|
+
/**
|
|
115
|
+
* Register a detection module.
|
|
116
|
+
* @throws if module name is already registered or reserved
|
|
117
|
+
*/
|
|
118
|
+
register(module: ATRModule): void;
|
|
119
|
+
/**
|
|
120
|
+
* Check if a module name is reserved by the ATR core team.
|
|
121
|
+
*/
|
|
122
|
+
isReserved(name: string): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Get a registered module by name.
|
|
125
|
+
*/
|
|
126
|
+
get(name: string): ATRModule | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* List all registered modules.
|
|
129
|
+
*/
|
|
130
|
+
list(): ReadonlyArray<{
|
|
131
|
+
name: string;
|
|
132
|
+
version: string;
|
|
133
|
+
description: string;
|
|
134
|
+
}>;
|
|
135
|
+
/**
|
|
136
|
+
* Initialize all registered modules.
|
|
137
|
+
*/
|
|
138
|
+
initializeAll(): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Destroy all registered modules.
|
|
141
|
+
*/
|
|
142
|
+
destroyAll(): Promise<void>;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,yCAAyC;IACzC,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;IAC7C,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,iCAAiC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,qBAAqB;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;QAChC,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,aAAa,CAAC;YAClB,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;YACtC,QAAQ,EAAE,OAAO,CAAC;YAClB,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC,CAAC;KACJ,CAAC,CAAC;IAEH;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/E;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IAExD,yEAAyE;IACzE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAO7B;IAEH;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAOjC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIxC;;OAEG;IACH,IAAI,IAAI,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ7E;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAMpC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAKlC"}
|