@owasp-aghast/aghast 0.8.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +127 -0
- package/assets/img/aghastowaspcaption.png +0 -0
- package/assets/txt/logo.txt +52 -0
- package/config/pricing.json +42 -0
- package/config/prompts/false-positive-validation.md +78 -0
- package/config/prompts/general-vuln-discovery.md +99 -0
- package/config/prompts/generic-instructions.md +59 -0
- package/config/prompts/test-cheaper-instructions.md +57 -0
- package/dist/budget.d.ts +62 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +137 -0
- package/dist/budget.js.map +1 -0
- package/dist/build-config.d.ts +15 -0
- package/dist/build-config.d.ts.map +1 -0
- package/dist/build-config.js +568 -0
- package/dist/build-config.js.map +1 -0
- package/dist/check-library.d.ts +88 -0
- package/dist/check-library.d.ts.map +1 -0
- package/dist/check-library.js +461 -0
- package/dist/check-library.js.map +1 -0
- package/dist/check-types.d.ts +35 -0
- package/dist/check-types.d.ts.map +1 -0
- package/dist/check-types.js +66 -0
- package/dist/check-types.js.map +1 -0
- package/dist/claude-code-provider.d.ts +29 -0
- package/dist/claude-code-provider.d.ts.map +1 -0
- package/dist/claude-code-provider.js +347 -0
- package/dist/claude-code-provider.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +109 -0
- package/dist/cli.js.map +1 -0
- package/dist/colors.d.ts +7 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +18 -0
- package/dist/colors.js.map +1 -0
- package/dist/cost-calculator.d.ts +80 -0
- package/dist/cost-calculator.d.ts.map +1 -0
- package/dist/cost-calculator.js +226 -0
- package/dist/cost-calculator.js.map +1 -0
- package/dist/defaults.d.ts +21 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +21 -0
- package/dist/defaults.js.map +1 -0
- package/dist/diff-filter.d.ts +50 -0
- package/dist/diff-filter.d.ts.map +1 -0
- package/dist/diff-filter.js +130 -0
- package/dist/diff-filter.js.map +1 -0
- package/dist/diff-parser.d.ts +40 -0
- package/dist/diff-parser.d.ts.map +1 -0
- package/dist/diff-parser.js +112 -0
- package/dist/diff-parser.js.map +1 -0
- package/dist/diff-unit-matcher.d.ts +53 -0
- package/dist/diff-unit-matcher.d.ts.map +1 -0
- package/dist/diff-unit-matcher.js +156 -0
- package/dist/diff-unit-matcher.js.map +1 -0
- package/dist/discoveries/openant-discovery.d.ts +10 -0
- package/dist/discoveries/openant-discovery.d.ts.map +1 -0
- package/dist/discoveries/openant-discovery.js +56 -0
- package/dist/discoveries/openant-discovery.js.map +1 -0
- package/dist/discoveries/sarif-discovery.d.ts +9 -0
- package/dist/discoveries/sarif-discovery.d.ts.map +1 -0
- package/dist/discoveries/sarif-discovery.js +56 -0
- package/dist/discoveries/sarif-discovery.js.map +1 -0
- package/dist/discoveries/semgrep-discovery.d.ts +9 -0
- package/dist/discoveries/semgrep-discovery.d.ts.map +1 -0
- package/dist/discoveries/semgrep-discovery.js +61 -0
- package/dist/discoveries/semgrep-discovery.js.map +1 -0
- package/dist/discovery.d.ts +100 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +49 -0
- package/dist/discovery.js.map +1 -0
- package/dist/error-codes.d.ts +46 -0
- package/dist/error-codes.d.ts.map +1 -0
- package/dist/error-codes.js +70 -0
- package/dist/error-codes.js.map +1 -0
- package/dist/formatters/index.d.ts +10 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +23 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json-formatter.d.ts +11 -0
- package/dist/formatters/json-formatter.d.ts.map +1 -0
- package/dist/formatters/json-formatter.js +11 -0
- package/dist/formatters/json-formatter.js.map +1 -0
- package/dist/formatters/sarif-formatter.d.ts +18 -0
- package/dist/formatters/sarif-formatter.d.ts.map +1 -0
- package/dist/formatters/sarif-formatter.js +103 -0
- package/dist/formatters/sarif-formatter.js.map +1 -0
- package/dist/formatters/types.d.ts +11 -0
- package/dist/formatters/types.d.ts.map +1 -0
- package/dist/formatters/types.js +6 -0
- package/dist/formatters/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +754 -0
- package/dist/index.js.map +1 -0
- package/dist/logging.d.ts +140 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +344 -0
- package/dist/logging.js.map +1 -0
- package/dist/mock-agent-provider.d.ts +24 -0
- package/dist/mock-agent-provider.d.ts.map +1 -0
- package/dist/mock-agent-provider.js +38 -0
- package/dist/mock-agent-provider.js.map +1 -0
- package/dist/mock-ai-provider.d.ts +21 -0
- package/dist/mock-ai-provider.d.ts.map +1 -0
- package/dist/mock-ai-provider.js +31 -0
- package/dist/mock-ai-provider.js.map +1 -0
- package/dist/new-check.d.ts +13 -0
- package/dist/new-check.d.ts.map +1 -0
- package/dist/new-check.js +515 -0
- package/dist/new-check.js.map +1 -0
- package/dist/openant-loader.d.ts +105 -0
- package/dist/openant-loader.d.ts.map +1 -0
- package/dist/openant-loader.js +135 -0
- package/dist/openant-loader.js.map +1 -0
- package/dist/openant-runner.d.ts +30 -0
- package/dist/openant-runner.d.ts.map +1 -0
- package/dist/openant-runner.js +113 -0
- package/dist/openant-runner.js.map +1 -0
- package/dist/opencode-provider.d.ts +63 -0
- package/dist/opencode-provider.d.ts.map +1 -0
- package/dist/opencode-provider.js +719 -0
- package/dist/opencode-provider.js.map +1 -0
- package/dist/prompt-template.d.ts +12 -0
- package/dist/prompt-template.d.ts.map +1 -0
- package/dist/prompt-template.js +36 -0
- package/dist/prompt-template.js.map +1 -0
- package/dist/provider-registry.d.ts +15 -0
- package/dist/provider-registry.d.ts.map +1 -0
- package/dist/provider-registry.js +29 -0
- package/dist/provider-registry.js.map +1 -0
- package/dist/provider-utils.d.ts +52 -0
- package/dist/provider-utils.d.ts.map +1 -0
- package/dist/provider-utils.js +40 -0
- package/dist/provider-utils.js.map +1 -0
- package/dist/repository-analyzer.d.ts +68 -0
- package/dist/repository-analyzer.d.ts.map +1 -0
- package/dist/repository-analyzer.js +238 -0
- package/dist/repository-analyzer.js.map +1 -0
- package/dist/response-parser.d.ts +14 -0
- package/dist/response-parser.d.ts.map +1 -0
- package/dist/response-parser.js +111 -0
- package/dist/response-parser.js.map +1 -0
- package/dist/runtime-config.d.ts +15 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +187 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/sarif-parser.d.ts +20 -0
- package/dist/sarif-parser.d.ts.map +1 -0
- package/dist/sarif-parser.js +76 -0
- package/dist/sarif-parser.js.map +1 -0
- package/dist/scan-history.d.ts +82 -0
- package/dist/scan-history.d.ts.map +1 -0
- package/dist/scan-history.js +127 -0
- package/dist/scan-history.js.map +1 -0
- package/dist/scan-runner.d.ts +122 -0
- package/dist/scan-runner.d.ts.map +1 -0
- package/dist/scan-runner.js +928 -0
- package/dist/scan-runner.js.map +1 -0
- package/dist/semgrep-runner.d.ts +25 -0
- package/dist/semgrep-runner.d.ts.map +1 -0
- package/dist/semgrep-runner.js +100 -0
- package/dist/semgrep-runner.js.map +1 -0
- package/dist/snippet-extractor.d.ts +25 -0
- package/dist/snippet-extractor.d.ts.map +1 -0
- package/dist/snippet-extractor.js +56 -0
- package/dist/snippet-extractor.js.map +1 -0
- package/dist/stats.d.ts +11 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +197 -0
- package/dist/stats.js.map +1 -0
- package/dist/types.d.ts +321 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response parser.
|
|
3
|
+
* Parses the raw text body of an agent provider's response into
|
|
4
|
+
* CheckResponse format (spec Appendix A.3b). Handles malformed JSON,
|
|
5
|
+
* missing fields, and edge cases.
|
|
6
|
+
*/
|
|
7
|
+
import { logDebug } from './logging.js';
|
|
8
|
+
const TAG = 'parser';
|
|
9
|
+
/**
|
|
10
|
+
* Attempt to parse the raw text body of an agent provider's response
|
|
11
|
+
* into a CheckResponse. Returns undefined if the response is not valid
|
|
12
|
+
* JSON or lacks the expected structure.
|
|
13
|
+
*/
|
|
14
|
+
export function parseAgentResponse(raw) {
|
|
15
|
+
logDebug(TAG, `Parsing response: ${raw.length} chars`);
|
|
16
|
+
const tryParse = (text) => {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(text);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
// 1) Direct parse
|
|
25
|
+
let parsed = tryParse(raw);
|
|
26
|
+
// 2) If that fails, look for a fenced code block (```json ... ```)
|
|
27
|
+
if (parsed === undefined) {
|
|
28
|
+
const fence = raw.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
29
|
+
if (fence?.[1]) {
|
|
30
|
+
logDebug(TAG, 'Trying fenced code block extraction');
|
|
31
|
+
parsed = tryParse(fence[1]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// 3) If still failing, grab the first balanced-looking JSON object
|
|
35
|
+
if (parsed === undefined) {
|
|
36
|
+
const firstBrace = raw.indexOf('{');
|
|
37
|
+
const lastBrace = raw.lastIndexOf('}');
|
|
38
|
+
if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
|
|
39
|
+
logDebug(TAG, 'Trying brace extraction');
|
|
40
|
+
const slice = raw.slice(firstBrace, lastBrace + 1);
|
|
41
|
+
parsed = tryParse(slice);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (parsed === undefined) {
|
|
45
|
+
logDebug(TAG, 'All parse strategies failed');
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const obj = parsed;
|
|
52
|
+
if (!Array.isArray(obj.issues)) {
|
|
53
|
+
logDebug(TAG, `Missing issues array, keys: ${Object.keys(obj).join(', ')}`);
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
const issues = [];
|
|
57
|
+
for (const item of obj.issues) {
|
|
58
|
+
if (typeof item !== 'object' || item === null) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const issue = item;
|
|
62
|
+
// Required fields: file, description, startLine, endLine (per spec A.3)
|
|
63
|
+
if (typeof issue.file !== 'string' || typeof issue.description !== 'string') {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// Line numbers are required - skip issues without valid line numbers
|
|
67
|
+
if (typeof issue.startLine !== 'number' || typeof issue.endLine !== 'number') {
|
|
68
|
+
logDebug(TAG, `Skipping issue missing required line numbers: ${issue.file}`);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const aiIssue = {
|
|
72
|
+
file: issue.file,
|
|
73
|
+
startLine: issue.startLine,
|
|
74
|
+
endLine: issue.endLine,
|
|
75
|
+
description: issue.description,
|
|
76
|
+
};
|
|
77
|
+
// Parse optional dataFlow array
|
|
78
|
+
if (Array.isArray(issue.dataFlow)) {
|
|
79
|
+
const validSteps = [];
|
|
80
|
+
for (const step of issue.dataFlow) {
|
|
81
|
+
if (typeof step === 'object' && step !== null &&
|
|
82
|
+
typeof step.file === 'string' &&
|
|
83
|
+
typeof step.lineNumber === 'number' &&
|
|
84
|
+
typeof step.label === 'string') {
|
|
85
|
+
validSteps.push({
|
|
86
|
+
file: step.file,
|
|
87
|
+
lineNumber: step.lineNumber,
|
|
88
|
+
label: step.label,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (validSteps.length > 0) {
|
|
93
|
+
aiIssue.dataFlow = validSteps;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
issues.push(aiIssue);
|
|
97
|
+
}
|
|
98
|
+
logDebug(TAG, `Parsed ${issues.length} issues`);
|
|
99
|
+
const response = { issues };
|
|
100
|
+
if (obj.flagged === true) {
|
|
101
|
+
response.flagged = true;
|
|
102
|
+
}
|
|
103
|
+
if (typeof obj.summary === 'string') {
|
|
104
|
+
response.summary = obj.summary;
|
|
105
|
+
}
|
|
106
|
+
if (typeof obj.analysisNotes === 'string') {
|
|
107
|
+
response.analysisNotes = obj.analysisNotes;
|
|
108
|
+
}
|
|
109
|
+
return response;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=response-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-parser.js","sourceRoot":"","sources":["../src/response-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime configuration loader.
|
|
3
|
+
* Loads runtime-config.json from the config directory to override agent provider and reporting settings.
|
|
4
|
+
* Spec Section 8.1 & Appendix C.10.
|
|
5
|
+
*/
|
|
6
|
+
import type { RuntimeConfig } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Load runtime configuration from file.
|
|
9
|
+
* @param configDir - Directory containing runtime-config.json. Optional when explicitPath is given.
|
|
10
|
+
* @param explicitPath - Explicit path to the runtime config file (from --runtime-config CLI flag).
|
|
11
|
+
* @returns Parsed RuntimeConfig object, or empty object if file absent
|
|
12
|
+
* @throws Error if file exists but contains invalid JSON, or if neither argument resolves a path
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadRuntimeConfig(configDir?: string, explicitPath?: string): Promise<RuntimeConfig>;
|
|
15
|
+
//# sourceMappingURL=runtime-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-config.d.ts","sourceRoot":"","sources":["../src/runtime-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA+KzG"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime configuration loader.
|
|
3
|
+
* Loads runtime-config.json from the config directory to override agent provider and reporting settings.
|
|
4
|
+
* Spec Section 8.1 & Appendix C.10.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile } from 'node:fs/promises';
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
/**
|
|
9
|
+
* Load runtime configuration from file.
|
|
10
|
+
* @param configDir - Directory containing runtime-config.json. Optional when explicitPath is given.
|
|
11
|
+
* @param explicitPath - Explicit path to the runtime config file (from --runtime-config CLI flag).
|
|
12
|
+
* @returns Parsed RuntimeConfig object, or empty object if file absent
|
|
13
|
+
* @throws Error if file exists but contains invalid JSON, or if neither argument resolves a path
|
|
14
|
+
*/
|
|
15
|
+
export async function loadRuntimeConfig(configDir, explicitPath) {
|
|
16
|
+
if (!explicitPath && !configDir) {
|
|
17
|
+
throw new Error('loadRuntimeConfig: one of configDir or explicitPath is required');
|
|
18
|
+
}
|
|
19
|
+
const pathToLoad = explicitPath ?? resolve(configDir, 'runtime-config.json');
|
|
20
|
+
let content;
|
|
21
|
+
try {
|
|
22
|
+
content = await readFile(pathToLoad, 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
// File absent: silently return defaults
|
|
26
|
+
if (err.code === 'ENOENT') {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
// File exists but may have invalid JSON
|
|
32
|
+
let parsed;
|
|
33
|
+
try {
|
|
34
|
+
parsed = JSON.parse(content);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
throw new Error(`Invalid JSON in runtime config file: ${pathToLoad}`);
|
|
38
|
+
}
|
|
39
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
40
|
+
throw new Error(`Runtime config file "${pathToLoad}" must contain a JSON object`);
|
|
41
|
+
}
|
|
42
|
+
// Validate field types
|
|
43
|
+
const obj = parsed;
|
|
44
|
+
if (obj.aiProvider !== undefined) {
|
|
45
|
+
throw new Error(`Runtime config "${pathToLoad}": "aiProvider" has been renamed to "agentProvider" in 0.5.0. ` +
|
|
46
|
+
`Update your runtime-config.json to use the new key.`);
|
|
47
|
+
}
|
|
48
|
+
if (obj.agentProvider !== undefined) {
|
|
49
|
+
if (typeof obj.agentProvider !== 'object' || obj.agentProvider === null || Array.isArray(obj.agentProvider)) {
|
|
50
|
+
throw new Error(`Runtime config "${pathToLoad}": "agentProvider" must be an object`);
|
|
51
|
+
}
|
|
52
|
+
const ap = obj.agentProvider;
|
|
53
|
+
if (ap.name !== undefined && typeof ap.name !== 'string') {
|
|
54
|
+
throw new Error(`Runtime config "${pathToLoad}": "agentProvider.name" must be a string`);
|
|
55
|
+
}
|
|
56
|
+
if (ap.model !== undefined && typeof ap.model !== 'string') {
|
|
57
|
+
throw new Error(`Runtime config "${pathToLoad}": "agentProvider.model" must be a string`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (obj.reporting !== undefined) {
|
|
61
|
+
if (typeof obj.reporting !== 'object' || obj.reporting === null || Array.isArray(obj.reporting)) {
|
|
62
|
+
throw new Error(`Runtime config "${pathToLoad}": "reporting" must be an object`);
|
|
63
|
+
}
|
|
64
|
+
const rpt = obj.reporting;
|
|
65
|
+
if (rpt.outputDirectory !== undefined && typeof rpt.outputDirectory !== 'string') {
|
|
66
|
+
throw new Error(`Runtime config "${pathToLoad}": "reporting.outputDirectory" must be a string`);
|
|
67
|
+
}
|
|
68
|
+
if (rpt.outputFormat !== undefined && typeof rpt.outputFormat !== 'string') {
|
|
69
|
+
throw new Error(`Runtime config "${pathToLoad}": "reporting.outputFormat" must be a string`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (obj.genericPrompt !== undefined && typeof obj.genericPrompt !== 'string') {
|
|
73
|
+
throw new Error(`Runtime config "${pathToLoad}": "genericPrompt" must be a string`);
|
|
74
|
+
}
|
|
75
|
+
if (obj.failOnCheckFailure !== undefined && typeof obj.failOnCheckFailure !== 'boolean') {
|
|
76
|
+
throw new Error(`Runtime config "${pathToLoad}": "failOnCheckFailure" must be a boolean`);
|
|
77
|
+
}
|
|
78
|
+
if (obj.budget !== undefined) {
|
|
79
|
+
if (typeof obj.budget !== 'object' || obj.budget === null || Array.isArray(obj.budget)) {
|
|
80
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget" must be an object`);
|
|
81
|
+
}
|
|
82
|
+
const budget = obj.budget;
|
|
83
|
+
if (budget.perScan !== undefined) {
|
|
84
|
+
if (typeof budget.perScan !== 'object' || budget.perScan === null || Array.isArray(budget.perScan)) {
|
|
85
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perScan" must be an object`);
|
|
86
|
+
}
|
|
87
|
+
const ps = budget.perScan;
|
|
88
|
+
if (ps.maxTokens !== undefined) {
|
|
89
|
+
if (typeof ps.maxTokens !== 'number' || !Number.isFinite(ps.maxTokens) || ps.maxTokens < 0) {
|
|
90
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perScan.maxTokens" must be a non-negative number`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (ps.maxCostUsd !== undefined) {
|
|
94
|
+
if (typeof ps.maxCostUsd !== 'number' || !Number.isFinite(ps.maxCostUsd) || ps.maxCostUsd < 0) {
|
|
95
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perScan.maxCostUsd" must be a non-negative number`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (budget.perPeriod !== undefined) {
|
|
100
|
+
if (typeof budget.perPeriod !== 'object' || budget.perPeriod === null || Array.isArray(budget.perPeriod)) {
|
|
101
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perPeriod" must be an object`);
|
|
102
|
+
}
|
|
103
|
+
const pp = budget.perPeriod;
|
|
104
|
+
if (pp.window !== undefined && pp.window !== 'day' && pp.window !== 'week' && pp.window !== 'month') {
|
|
105
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perPeriod.window" must be "day", "week", or "month"`);
|
|
106
|
+
}
|
|
107
|
+
if (pp.maxCostUsd !== undefined) {
|
|
108
|
+
if (typeof pp.maxCostUsd !== 'number' || !Number.isFinite(pp.maxCostUsd) || pp.maxCostUsd < 0) {
|
|
109
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perPeriod.maxCostUsd" must be a non-negative number`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// perPeriod requires both window and maxCostUsd to be functional. Reject
|
|
113
|
+
// partial config so misconfiguration is loud, not silently dropped at
|
|
114
|
+
// runtime. (The dual-undefined case is naturally caught by either
|
|
115
|
+
// single-field check below — they fire in source order, the window check
|
|
116
|
+
// wins. No separate guard needed.)
|
|
117
|
+
if (pp.window === undefined) {
|
|
118
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perPeriod.window" is required when "budget.perPeriod" is set (must be "day", "week", or "month")`);
|
|
119
|
+
}
|
|
120
|
+
if (pp.maxCostUsd === undefined) {
|
|
121
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.perPeriod.maxCostUsd" is required when "budget.perPeriod" is set`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (budget.thresholds !== undefined) {
|
|
125
|
+
if (typeof budget.thresholds !== 'object' || budget.thresholds === null || Array.isArray(budget.thresholds)) {
|
|
126
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.thresholds" must be an object`);
|
|
127
|
+
}
|
|
128
|
+
const th = budget.thresholds;
|
|
129
|
+
if (th.warnAt !== undefined) {
|
|
130
|
+
if (typeof th.warnAt !== 'number' || !Number.isFinite(th.warnAt) || th.warnAt < 0) {
|
|
131
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.thresholds.warnAt" must be a non-negative number`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (th.abortAt !== undefined) {
|
|
135
|
+
if (typeof th.abortAt !== 'number' || !Number.isFinite(th.abortAt) || th.abortAt < 0) {
|
|
136
|
+
throw new Error(`Runtime config "${pathToLoad}": "budget.thresholds.abortAt" must be a non-negative number`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (obj.pricing !== undefined) {
|
|
142
|
+
if (typeof obj.pricing !== 'object' || obj.pricing === null || Array.isArray(obj.pricing)) {
|
|
143
|
+
throw new Error(`Runtime config "${pathToLoad}": "pricing" must be an object`);
|
|
144
|
+
}
|
|
145
|
+
const pricing = obj.pricing;
|
|
146
|
+
if (pricing.currency !== undefined && typeof pricing.currency !== 'string') {
|
|
147
|
+
throw new Error(`Runtime config "${pathToLoad}": "pricing.currency" must be a string`);
|
|
148
|
+
}
|
|
149
|
+
if (pricing.models !== undefined) {
|
|
150
|
+
if (typeof pricing.models !== 'object' || pricing.models === null || Array.isArray(pricing.models)) {
|
|
151
|
+
throw new Error(`Runtime config "${pathToLoad}": "pricing.models" must be an object`);
|
|
152
|
+
}
|
|
153
|
+
for (const [modelName, def] of Object.entries(pricing.models)) {
|
|
154
|
+
if (!def || typeof def !== 'object' || Array.isArray(def)) {
|
|
155
|
+
throw new Error(`Runtime config "${pathToLoad}": "pricing.models.${modelName}" must be an object`);
|
|
156
|
+
}
|
|
157
|
+
const d = def;
|
|
158
|
+
if (typeof d.inputPerMillion !== 'number' || typeof d.outputPerMillion !== 'number') {
|
|
159
|
+
throw new Error(`Runtime config "${pathToLoad}": "pricing.models.${modelName}" must have numeric "inputPerMillion" and "outputPerMillion"`);
|
|
160
|
+
}
|
|
161
|
+
if (!Number.isFinite(d.inputPerMillion) || d.inputPerMillion < 0) {
|
|
162
|
+
throw new Error(`Runtime config "${pathToLoad}": "pricing.models.${modelName}.inputPerMillion" must be a non-negative number`);
|
|
163
|
+
}
|
|
164
|
+
if (!Number.isFinite(d.outputPerMillion) || d.outputPerMillion < 0) {
|
|
165
|
+
throw new Error(`Runtime config "${pathToLoad}": "pricing.models.${modelName}.outputPerMillion" must be a non-negative number`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (obj.logging !== undefined) {
|
|
171
|
+
if (typeof obj.logging !== 'object' || obj.logging === null || Array.isArray(obj.logging)) {
|
|
172
|
+
throw new Error(`Runtime config "${pathToLoad}": "logging" must be an object`);
|
|
173
|
+
}
|
|
174
|
+
const log = obj.logging;
|
|
175
|
+
if (log.logFile !== undefined && typeof log.logFile !== 'string') {
|
|
176
|
+
throw new Error(`Runtime config "${pathToLoad}": "logging.logFile" must be a string`);
|
|
177
|
+
}
|
|
178
|
+
if (log.logType !== undefined && typeof log.logType !== 'string') {
|
|
179
|
+
throw new Error(`Runtime config "${pathToLoad}": "logging.logType" must be a string`);
|
|
180
|
+
}
|
|
181
|
+
if (log.level !== undefined && typeof log.level !== 'string') {
|
|
182
|
+
throw new Error(`Runtime config "${pathToLoad}": "logging.level" must be a string`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return parsed;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=runtime-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-config.js","sourceRoot":"","sources":["../src/runtime-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF 2.1.0 parser for Semgrep output.
|
|
3
|
+
* Extracts CheckTarget[] from SARIF results.
|
|
4
|
+
*/
|
|
5
|
+
import type { CheckTarget } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Parse SARIF 2.1.0 JSON content into CheckTarget[].
|
|
8
|
+
* Skips results with missing location fields.
|
|
9
|
+
* Throws on invalid JSON or missing SARIF structure.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseSARIF(sarifContent: string): CheckTarget[];
|
|
12
|
+
/**
|
|
13
|
+
* Deduplicate targets by file:startLine:endLine key.
|
|
14
|
+
*/
|
|
15
|
+
export declare function deduplicateTargets(targets: CheckTarget[]): CheckTarget[];
|
|
16
|
+
/**
|
|
17
|
+
* Limit the number of targets to a maximum.
|
|
18
|
+
*/
|
|
19
|
+
export declare function limitTargets(targets: CheckTarget[], maxTargets: number): CheckTarget[];
|
|
20
|
+
//# sourceMappingURL=sarif-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif-parser.d.ts","sourceRoot":"","sources":["../src/sarif-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAyB9C;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,EAAE,CAsD9D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAaxE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,EAAE,CAEtF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF 2.1.0 parser for Semgrep output.
|
|
3
|
+
* Extracts CheckTarget[] from SARIF results.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Parse SARIF 2.1.0 JSON content into CheckTarget[].
|
|
7
|
+
* Skips results with missing location fields.
|
|
8
|
+
* Throws on invalid JSON or missing SARIF structure.
|
|
9
|
+
*/
|
|
10
|
+
export function parseSARIF(sarifContent) {
|
|
11
|
+
let doc;
|
|
12
|
+
try {
|
|
13
|
+
doc = JSON.parse(sarifContent);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
throw new Error('Invalid SARIF: malformed JSON');
|
|
17
|
+
}
|
|
18
|
+
if (!doc.runs || !Array.isArray(doc.runs)) {
|
|
19
|
+
throw new Error('Invalid SARIF: missing "runs" array');
|
|
20
|
+
}
|
|
21
|
+
const targets = [];
|
|
22
|
+
for (const run of doc.runs) {
|
|
23
|
+
if (!run.results || !Array.isArray(run.results)) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
for (const result of run.results) {
|
|
27
|
+
if (!result.locations || result.locations.length === 0) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const loc = result.locations[0];
|
|
31
|
+
const phys = loc?.physicalLocation;
|
|
32
|
+
if (!phys)
|
|
33
|
+
continue;
|
|
34
|
+
const file = phys.artifactLocation?.uri;
|
|
35
|
+
const startLine = phys.region?.startLine;
|
|
36
|
+
// Skip results missing required location fields
|
|
37
|
+
if (!file || startLine === undefined) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const endLine = phys.region?.endLine ?? startLine;
|
|
41
|
+
const target = {
|
|
42
|
+
file,
|
|
43
|
+
startLine,
|
|
44
|
+
endLine,
|
|
45
|
+
message: result.message?.text ?? '',
|
|
46
|
+
};
|
|
47
|
+
if (phys.region?.snippet?.text) {
|
|
48
|
+
target.snippet = phys.region.snippet.text;
|
|
49
|
+
}
|
|
50
|
+
targets.push(target);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return targets;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Deduplicate targets by file:startLine:endLine key.
|
|
57
|
+
*/
|
|
58
|
+
export function deduplicateTargets(targets) {
|
|
59
|
+
const seen = new Set();
|
|
60
|
+
const result = [];
|
|
61
|
+
for (const target of targets) {
|
|
62
|
+
const key = `${target.file}:${target.startLine}:${target.endLine}`;
|
|
63
|
+
if (!seen.has(key)) {
|
|
64
|
+
seen.add(key);
|
|
65
|
+
result.push(target);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Limit the number of targets to a maximum.
|
|
72
|
+
*/
|
|
73
|
+
export function limitTargets(targets, maxTargets) {
|
|
74
|
+
return targets.slice(0, maxTargets);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=sarif-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif-parser.js","sourceRoot":"","sources":["../src/sarif-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2BH;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,YAAoB;IAC7C,IAAI,GAAkB,CAAC;IACvB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAkB,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,SAAS;QACX,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvD,SAAS;YACX,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,IAAI,GAAG,GAAG,EAAE,gBAAgB,CAAC;YACnC,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC;YACxC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;YAEzC,gDAAgD;YAChD,IAAI,CAAC,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBACrC,SAAS;YACX,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,SAAS,CAAC;YAElD,MAAM,MAAM,GAAgB;gBAC1B,IAAI;gBACJ,SAAS;gBACT,OAAO;gBACP,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE;aACpC,CAAC;YAEF,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAC/B,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;YAC5C,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAsB;IACvD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAkB,EAAE,CAAC;IAEjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAsB,EAAE,UAAkB;IACrE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scan history: persisted record of completed scans for cost dashboards
|
|
3
|
+
* and budget controls.
|
|
4
|
+
*
|
|
5
|
+
* Storage: `~/.aghast/history.json` by default (one file per user). When the
|
|
6
|
+
* home directory cannot be resolved, falls back to project-local
|
|
7
|
+
* `.aghast-history.json`. The path can be overridden in tests via the
|
|
8
|
+
* `AGHAST_HISTORY_FILE` env var or by passing `historyFile` to the helpers.
|
|
9
|
+
*
|
|
10
|
+
* Format: a single JSON document `{ "records": [...] }`. We keep this simple
|
|
11
|
+
* (no SQLite) so the file is human-readable and can be edited / pruned by
|
|
12
|
+
* hand. Corrupt files are logged and rebuilt to avoid blocking scans on a
|
|
13
|
+
* malformed history file.
|
|
14
|
+
*/
|
|
15
|
+
import type { TokenUsage } from './types.js';
|
|
16
|
+
/** A single completed-scan record. */
|
|
17
|
+
export interface ScanRecord {
|
|
18
|
+
scanId: string;
|
|
19
|
+
/** ISO timestamp of scan start. */
|
|
20
|
+
startedAt: string;
|
|
21
|
+
/** ISO timestamp of scan end. */
|
|
22
|
+
endedAt: string;
|
|
23
|
+
/** Wall-clock duration in milliseconds. */
|
|
24
|
+
durationMs: number;
|
|
25
|
+
/** Repository path or remote URL. */
|
|
26
|
+
repository: string;
|
|
27
|
+
/** Repository remote URL when known. */
|
|
28
|
+
repositoryUrl?: string;
|
|
29
|
+
/** Models used during the scan. */
|
|
30
|
+
models: string[];
|
|
31
|
+
/** Aggregate token usage across the scan. */
|
|
32
|
+
tokenUsage?: TokenUsage;
|
|
33
|
+
/** Estimated total cost (in `currency`). */
|
|
34
|
+
totalCost: number;
|
|
35
|
+
/** ISO 4217 currency code. */
|
|
36
|
+
currency: string;
|
|
37
|
+
/** How the cost was determined. Absent on records written before this feature. */
|
|
38
|
+
costSource?: 'reported' | 'estimated' | 'estimated-unpriced' | 'legacy';
|
|
39
|
+
/** Which provider reported the cost when costSource === 'reported'. */
|
|
40
|
+
costReportedBy?: 'claude-agent-sdk' | 'opencode';
|
|
41
|
+
/** true when the scan ran with AGHAST_LOCAL_CLAUDE=true */
|
|
42
|
+
costCoveredBySubscription?: boolean;
|
|
43
|
+
/** Number of checks executed. */
|
|
44
|
+
checks: number;
|
|
45
|
+
/** Number of issues reported. */
|
|
46
|
+
issues: number;
|
|
47
|
+
}
|
|
48
|
+
/** Filters for queryScanHistory(). */
|
|
49
|
+
export interface HistoryFilters {
|
|
50
|
+
repository?: string;
|
|
51
|
+
/** Substring match against any element of `models`. */
|
|
52
|
+
model?: string;
|
|
53
|
+
/** Inclusive ISO timestamp lower bound on `startedAt`. */
|
|
54
|
+
since?: string;
|
|
55
|
+
/** Inclusive ISO timestamp upper bound on `startedAt`. */
|
|
56
|
+
until?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the history file path.
|
|
60
|
+
*
|
|
61
|
+
* Precedence:
|
|
62
|
+
* 1. explicit `historyFile` argument
|
|
63
|
+
* 2. AGHAST_HISTORY_FILE env var
|
|
64
|
+
* 3. ~/.aghast/history.json when homedir is available
|
|
65
|
+
* 4. project-local `.aghast-history.json`
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolveHistoryFilePath(historyFile?: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Append a record to the scan history, deduplicating by scanId.
|
|
70
|
+
* If a record with the same scanId already exists, it is replaced.
|
|
71
|
+
*/
|
|
72
|
+
export declare function saveScanRecord(record: ScanRecord, options?: {
|
|
73
|
+
historyFile?: string;
|
|
74
|
+
}): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Load all scan records, applying optional filters.
|
|
77
|
+
* Records are returned newest-first (descending startedAt).
|
|
78
|
+
*/
|
|
79
|
+
export declare function queryScanHistory(filters?: HistoryFilters, options?: {
|
|
80
|
+
historyFile?: string;
|
|
81
|
+
}): Promise<ScanRecord[]>;
|
|
82
|
+
//# sourceMappingURL=scan-history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-history.d.ts","sourceRoot":"","sources":["../src/scan-history.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO7C,sCAAsC;AACtC,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,UAAU,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,oBAAoB,GAAG,QAAQ,CAAC;IACxE,uEAAuE;IACvE,cAAc,CAAC,EAAE,kBAAkB,GAAG,UAAU,CAAC;IACjD,2DAA2D;IAC3D,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAOD,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAcnE;AAiCD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9G;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,cAAmB,EAC5B,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACrC,OAAO,CAAC,UAAU,EAAE,CAAC,CA8BvB"}
|