kramscan 0.1.0 → 0.2.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/README.md +392 -87
- package/dist/agent/confirmation.d.ts +38 -0
- package/dist/agent/confirmation.js +210 -0
- package/dist/agent/context.d.ts +81 -0
- package/dist/agent/context.js +227 -0
- package/dist/agent/index.d.ts +10 -0
- package/dist/agent/index.js +32 -0
- package/dist/agent/orchestrator.d.ts +63 -0
- package/dist/agent/orchestrator.js +370 -0
- package/dist/agent/prompts/system.d.ts +6 -0
- package/dist/agent/prompts/system.js +116 -0
- package/dist/agent/skill-registry.d.ts +78 -0
- package/dist/agent/skill-registry.js +202 -0
- package/dist/agent/skills/analyze-findings.d.ts +22 -0
- package/dist/agent/skills/analyze-findings.js +191 -0
- package/dist/agent/skills/generate-report.d.ts +26 -0
- package/dist/agent/skills/generate-report.js +436 -0
- package/dist/agent/skills/health-check.d.ts +28 -0
- package/dist/agent/skills/health-check.js +344 -0
- package/dist/agent/skills/index.d.ts +9 -0
- package/dist/agent/skills/index.js +17 -0
- package/dist/agent/skills/verify-finding.d.ts +17 -0
- package/dist/agent/skills/verify-finding.js +91 -0
- package/dist/agent/skills/web-scan.d.ts +22 -0
- package/dist/agent/skills/web-scan.js +203 -0
- package/dist/agent/types.d.ts +141 -0
- package/dist/agent/types.js +16 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +176 -139
- package/dist/commands/agent.d.ts +6 -0
- package/dist/commands/agent.js +250 -0
- package/dist/commands/ai.d.ts +2 -0
- package/dist/commands/ai.js +112 -0
- package/dist/commands/analyze.js +104 -55
- package/dist/commands/config.js +63 -37
- package/dist/commands/doctor.js +22 -17
- package/dist/commands/onboard.js +190 -125
- package/dist/commands/report.js +69 -77
- package/dist/commands/scan.js +261 -81
- package/dist/commands/scans.d.ts +2 -0
- package/dist/commands/scans.js +51 -0
- package/dist/core/ai-client.d.ts +7 -2
- package/dist/core/ai-client.js +231 -20
- package/dist/core/ai-payloads.d.ts +17 -0
- package/dist/core/ai-payloads.js +54 -0
- package/dist/core/config-schema.d.ts +197 -0
- package/dist/core/config-schema.js +68 -0
- package/dist/core/config-schema.test.d.ts +1 -0
- package/dist/core/config-schema.test.js +151 -0
- package/dist/core/config.d.ts +17 -36
- package/dist/core/config.js +261 -20
- package/dist/core/errors.d.ts +71 -0
- package/dist/core/errors.js +162 -0
- package/dist/core/scan-index.d.ts +19 -0
- package/dist/core/scan-index.js +52 -0
- package/dist/core/scan-storage.d.ts +11 -0
- package/dist/core/scan-storage.js +69 -0
- package/dist/core/scanner.d.ts +101 -4
- package/dist/core/scanner.js +432 -63
- package/dist/core/vulnerability-detector.d.ts +18 -2
- package/dist/core/vulnerability-detector.js +349 -38
- package/dist/core/vulnerability-detector.test.d.ts +1 -0
- package/dist/core/vulnerability-detector.test.js +210 -0
- package/dist/index.js +3 -0
- package/dist/plugins/PluginManager.d.ts +27 -0
- package/dist/plugins/PluginManager.js +166 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.js +19 -0
- package/dist/plugins/types.d.ts +55 -0
- package/dist/plugins/types.js +25 -0
- package/dist/plugins/vulnerabilities/CSRFPlugin.d.ts +8 -0
- package/dist/plugins/vulnerabilities/CSRFPlugin.js +34 -0
- package/dist/plugins/vulnerabilities/SQLInjectionPlugin.d.ts +11 -0
- package/dist/plugins/vulnerabilities/SQLInjectionPlugin.js +109 -0
- package/dist/plugins/vulnerabilities/SecurityHeadersPlugin.d.ts +11 -0
- package/dist/plugins/vulnerabilities/SecurityHeadersPlugin.js +63 -0
- package/dist/plugins/vulnerabilities/SensitiveDataPlugin.d.ts +9 -0
- package/dist/plugins/vulnerabilities/SensitiveDataPlugin.js +32 -0
- package/dist/plugins/vulnerabilities/XSSPlugin.d.ts +15 -0
- package/dist/plugins/vulnerabilities/XSSPlugin.js +81 -0
- package/dist/reports/PdfGenerator.d.ts +36 -0
- package/dist/reports/PdfGenerator.js +379 -0
- package/dist/utils/logger.d.ts +33 -1
- package/dist/utils/logger.js +127 -8
- package/dist/utils/theme.d.ts +55 -0
- package/dist/utils/theme.js +195 -0
- package/package.json +27 -6
- package/dist/core/executor.d.ts +0 -2
- package/dist/core/executor.js +0 -74
- package/dist/core/logger.d.ts +0 -12
- package/dist/core/logger.js +0 -51
- package/dist/core/registry.d.ts +0 -3
- package/dist/core/registry.js +0 -35
- package/dist/core/storage.d.ts +0 -4
- package/dist/core/storage.js +0 -39
- package/dist/core/types.d.ts +0 -24
- package/dist/core/types.js +0 -2
- package/dist/skills/base.d.ts +0 -8
- package/dist/skills/base.js +0 -6
- package/dist/skills/builtin.d.ts +0 -4
- package/dist/skills/builtin.js +0 -71
- package/dist/skills/loader.d.ts +0 -2
- package/dist/skills/loader.js +0 -27
- package/dist/skills/types.d.ts +0 -46
- package/dist/skills/types.js +0 -2
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Skill Registry and Execution System
|
|
4
|
+
* Manages AI-callable security skills with validation, confirmation, and execution
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.skillRegistry = exports.SkillRegistry = void 0;
|
|
8
|
+
const logger_1 = require("../utils/logger");
|
|
9
|
+
class SkillRegistry {
|
|
10
|
+
skills = new Map();
|
|
11
|
+
executionHistory = [];
|
|
12
|
+
/**
|
|
13
|
+
* Register a skill with the registry
|
|
14
|
+
*/
|
|
15
|
+
register(skill) {
|
|
16
|
+
if (this.skills.has(skill.id)) {
|
|
17
|
+
logger_1.logger.warn(`Skill ${skill.id} is already registered. Overwriting.`);
|
|
18
|
+
}
|
|
19
|
+
this.skills.set(skill.id, skill);
|
|
20
|
+
logger_1.logger.debug(`Registered skill: ${skill.id}`);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Unregister a skill
|
|
24
|
+
*/
|
|
25
|
+
unregister(skillId) {
|
|
26
|
+
return this.skills.delete(skillId);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get a skill by ID
|
|
30
|
+
*/
|
|
31
|
+
get(skillId) {
|
|
32
|
+
return this.skills.get(skillId);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get all registered skills
|
|
36
|
+
*/
|
|
37
|
+
getAll() {
|
|
38
|
+
return Array.from(this.skills.values());
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get all tool definitions for AI function calling
|
|
42
|
+
*/
|
|
43
|
+
getToolDefinitions() {
|
|
44
|
+
return this.getAll().map((skill) => skill.toolDefinition);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validate tool call parameters
|
|
48
|
+
*/
|
|
49
|
+
validateToolCall(toolCall) {
|
|
50
|
+
const skill = this.get(toolCall.name);
|
|
51
|
+
if (!skill) {
|
|
52
|
+
return {
|
|
53
|
+
valid: false,
|
|
54
|
+
errors: [`Unknown skill: ${toolCall.name}`],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return skill.validateParameters(toolCall.arguments);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if a tool call requires confirmation
|
|
61
|
+
*/
|
|
62
|
+
requiresConfirmation(toolName) {
|
|
63
|
+
const skill = this.get(toolName);
|
|
64
|
+
if (!skill)
|
|
65
|
+
return false;
|
|
66
|
+
return skill.requiresConfirmation;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get confirmation prompt for a tool call
|
|
70
|
+
*/
|
|
71
|
+
getConfirmationPrompt(toolCall) {
|
|
72
|
+
const skill = this.get(toolCall.name);
|
|
73
|
+
if (!skill)
|
|
74
|
+
return null;
|
|
75
|
+
return {
|
|
76
|
+
action: skill.name,
|
|
77
|
+
description: skill.description,
|
|
78
|
+
parameters: toolCall.arguments,
|
|
79
|
+
risk: skill.riskLevel,
|
|
80
|
+
estimatedTime: this.formatDuration(skill.estimatedDuration),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Execute a skill by tool call
|
|
85
|
+
*/
|
|
86
|
+
async execute(toolCall, context) {
|
|
87
|
+
const skill = this.get(toolCall.name);
|
|
88
|
+
if (!skill) {
|
|
89
|
+
return {
|
|
90
|
+
toolCallId: toolCall.id,
|
|
91
|
+
success: false,
|
|
92
|
+
error: `Unknown skill: ${toolCall.name}`,
|
|
93
|
+
executionTime: 0,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Validate parameters
|
|
97
|
+
const validation = skill.validateParameters(toolCall.arguments);
|
|
98
|
+
if (!validation.valid) {
|
|
99
|
+
return {
|
|
100
|
+
toolCallId: toolCall.id,
|
|
101
|
+
success: false,
|
|
102
|
+
error: `Validation failed: ${validation.errors.join(", ")}`,
|
|
103
|
+
executionTime: 0,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const startTime = Date.now();
|
|
107
|
+
let result;
|
|
108
|
+
let success = false;
|
|
109
|
+
let error;
|
|
110
|
+
try {
|
|
111
|
+
logger_1.logger.info(`Executing skill: ${skill.id}`);
|
|
112
|
+
result = await skill.execute(toolCall.arguments, context);
|
|
113
|
+
success = true;
|
|
114
|
+
logger_1.logger.success(`Skill ${skill.id} completed successfully`);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
error = err instanceof Error ? err.message : String(err);
|
|
118
|
+
logger_1.logger.error(`Skill ${skill.id} failed: ${error}`);
|
|
119
|
+
result = {
|
|
120
|
+
skillId: skill.id,
|
|
121
|
+
findings: [],
|
|
122
|
+
metadata: { error },
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const executionTime = Date.now() - startTime;
|
|
126
|
+
// Record execution history
|
|
127
|
+
this.executionHistory.push({
|
|
128
|
+
timestamp: new Date(),
|
|
129
|
+
skillName: skill.id,
|
|
130
|
+
success,
|
|
131
|
+
duration: executionTime,
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
toolCallId: toolCall.id,
|
|
135
|
+
success,
|
|
136
|
+
result,
|
|
137
|
+
error,
|
|
138
|
+
executionTime,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Execute multiple skills in parallel
|
|
143
|
+
*/
|
|
144
|
+
async executeBatch(toolCalls, context) {
|
|
145
|
+
const promises = toolCalls.map((call) => this.execute(call, context));
|
|
146
|
+
return Promise.all(promises);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get execution statistics
|
|
150
|
+
*/
|
|
151
|
+
getStats() {
|
|
152
|
+
const total = this.executionHistory.length;
|
|
153
|
+
const successful = this.executionHistory.filter((e) => e.success).length;
|
|
154
|
+
const failed = total - successful;
|
|
155
|
+
const avgDuration = total > 0
|
|
156
|
+
? this.executionHistory.reduce((sum, e) => sum + e.duration, 0) / total
|
|
157
|
+
: 0;
|
|
158
|
+
const skillUsage = {};
|
|
159
|
+
for (const entry of this.executionHistory) {
|
|
160
|
+
skillUsage[entry.skillName] = (skillUsage[entry.skillName] || 0) + 1;
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
totalExecutions: total,
|
|
164
|
+
successfulExecutions: successful,
|
|
165
|
+
failedExecutions: failed,
|
|
166
|
+
averageDuration: Math.round(avgDuration),
|
|
167
|
+
skillUsage,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Clear execution history
|
|
172
|
+
*/
|
|
173
|
+
clearHistory() {
|
|
174
|
+
this.executionHistory = [];
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* List available skills with descriptions
|
|
178
|
+
*/
|
|
179
|
+
listSkills() {
|
|
180
|
+
return this.getAll().map((skill) => ({
|
|
181
|
+
id: skill.id,
|
|
182
|
+
name: skill.name,
|
|
183
|
+
description: skill.description,
|
|
184
|
+
risk: skill.riskLevel,
|
|
185
|
+
requiresConfirmation: skill.requiresConfirmation,
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
formatDuration(seconds) {
|
|
189
|
+
if (seconds < 60) {
|
|
190
|
+
return `${seconds}s`;
|
|
191
|
+
}
|
|
192
|
+
const minutes = Math.floor(seconds / 60);
|
|
193
|
+
const remainingSeconds = seconds % 60;
|
|
194
|
+
if (remainingSeconds === 0) {
|
|
195
|
+
return `${minutes}m`;
|
|
196
|
+
}
|
|
197
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
exports.SkillRegistry = SkillRegistry;
|
|
201
|
+
// Global skill registry instance
|
|
202
|
+
exports.skillRegistry = new SkillRegistry();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyze Findings Skill
|
|
3
|
+
* AI-powered analysis of security scan results with remediation recommendations
|
|
4
|
+
*/
|
|
5
|
+
import { AgentSkill, ToolDefinition, AgentContext, SkillResult } from "../types";
|
|
6
|
+
export declare class AnalyzeFindingsSkill implements AgentSkill {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
requiresConfirmation: boolean;
|
|
12
|
+
riskLevel: "low";
|
|
13
|
+
estimatedDuration: number;
|
|
14
|
+
toolDefinition: ToolDefinition;
|
|
15
|
+
validateParameters(params: Record<string, unknown>): {
|
|
16
|
+
valid: boolean;
|
|
17
|
+
errors: string[];
|
|
18
|
+
};
|
|
19
|
+
execute(params: Record<string, unknown>, context: AgentContext): Promise<SkillResult>;
|
|
20
|
+
private buildAnalysisPrompt;
|
|
21
|
+
run(): Promise<SkillResult>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Analyze Findings Skill
|
|
4
|
+
* AI-powered analysis of security scan results with remediation recommendations
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.AnalyzeFindingsSkill = void 0;
|
|
8
|
+
const ai_client_1 = require("../../core/ai-client");
|
|
9
|
+
const logger_1 = require("../../utils/logger");
|
|
10
|
+
class AnalyzeFindingsSkill {
|
|
11
|
+
id = "analyze_findings";
|
|
12
|
+
name = "Analyze Findings";
|
|
13
|
+
description = "Uses AI to analyze security scan results and provide expert insights, risk assessment, and remediation recommendations.";
|
|
14
|
+
tags = ["analysis", "ai", "reporting", "recommendations"];
|
|
15
|
+
requiresConfirmation = false;
|
|
16
|
+
riskLevel = "low";
|
|
17
|
+
estimatedDuration = 15; // seconds
|
|
18
|
+
toolDefinition = {
|
|
19
|
+
name: "analyze_findings",
|
|
20
|
+
description: "Analyze security scan findings using AI to provide expert insights and remediation recommendations",
|
|
21
|
+
parameters: [
|
|
22
|
+
{
|
|
23
|
+
name: "useLastScan",
|
|
24
|
+
type: "boolean",
|
|
25
|
+
description: "Use results from the most recent scan. If true, scanResults parameter is optional.",
|
|
26
|
+
required: false,
|
|
27
|
+
default: true,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "scanResults",
|
|
31
|
+
type: "object",
|
|
32
|
+
description: "Scan results to analyze (if not using last scan). Must contain findings array.",
|
|
33
|
+
required: false,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "focus",
|
|
37
|
+
type: "string",
|
|
38
|
+
description: "Optional focus area for analysis: 'executive', 'technical', 'remediation', or 'all'",
|
|
39
|
+
required: false,
|
|
40
|
+
default: "all",
|
|
41
|
+
enum: ["executive", "technical", "remediation", "all"],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
validateParameters(params) {
|
|
46
|
+
const errors = [];
|
|
47
|
+
// If not using last scan, must provide scanResults
|
|
48
|
+
if (params.useLastScan === false && !params.scanResults) {
|
|
49
|
+
errors.push("scanResults is required when useLastScan is false");
|
|
50
|
+
}
|
|
51
|
+
// Validate focus if provided
|
|
52
|
+
if (params.focus) {
|
|
53
|
+
const validFocus = ["executive", "technical", "remediation", "all"];
|
|
54
|
+
if (!validFocus.includes(params.focus)) {
|
|
55
|
+
errors.push(`focus must be one of: ${validFocus.join(", ")}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
valid: errors.length === 0,
|
|
60
|
+
errors,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async execute(params, context) {
|
|
64
|
+
const useLastScan = params.useLastScan ?? true;
|
|
65
|
+
const focus = params.focus ?? "all";
|
|
66
|
+
let scanData;
|
|
67
|
+
// Get scan data
|
|
68
|
+
if (useLastScan) {
|
|
69
|
+
const lastResults = context.lastScanResults;
|
|
70
|
+
if (!lastResults) {
|
|
71
|
+
return {
|
|
72
|
+
skillId: this.id,
|
|
73
|
+
findings: [],
|
|
74
|
+
metadata: {
|
|
75
|
+
error: "No previous scan results found. Please run a scan first.",
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
scanData = lastResults;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
scanData = params.scanResults;
|
|
83
|
+
}
|
|
84
|
+
if (!scanData.findings || scanData.findings.length === 0) {
|
|
85
|
+
return {
|
|
86
|
+
skillId: this.id,
|
|
87
|
+
findings: [],
|
|
88
|
+
metadata: {
|
|
89
|
+
message: "No vulnerabilities to analyze.",
|
|
90
|
+
target: scanData.target,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
logger_1.logger.info(`Analyzing ${scanData.findings.length} findings with focus: ${focus}`);
|
|
95
|
+
try {
|
|
96
|
+
const aiClient = await (0, ai_client_1.createAIClient)();
|
|
97
|
+
const prompt = this.buildAnalysisPrompt(scanData, focus);
|
|
98
|
+
const response = await aiClient.analyze(prompt);
|
|
99
|
+
// Create a finding for the analysis itself
|
|
100
|
+
const analysisFinding = {
|
|
101
|
+
id: `analysis-${Date.now()}`,
|
|
102
|
+
skillId: this.id,
|
|
103
|
+
title: "AI Security Analysis",
|
|
104
|
+
severity: "info",
|
|
105
|
+
description: response.content,
|
|
106
|
+
metadata: {
|
|
107
|
+
focus,
|
|
108
|
+
target: scanData.target,
|
|
109
|
+
timestamp: new Date().toISOString(),
|
|
110
|
+
totalFindings: scanData.findings.length,
|
|
111
|
+
tokensUsed: response.usage,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
logger_1.logger.success("Analysis complete");
|
|
115
|
+
return {
|
|
116
|
+
skillId: this.id,
|
|
117
|
+
findings: [analysisFinding],
|
|
118
|
+
metadata: {
|
|
119
|
+
target: scanData.target,
|
|
120
|
+
focus,
|
|
121
|
+
totalFindings: scanData.findings.length,
|
|
122
|
+
tokensUsed: response.usage,
|
|
123
|
+
timestamp: new Date().toISOString(),
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
129
|
+
logger_1.logger.error(`Analysis failed: ${errorMessage}`);
|
|
130
|
+
return {
|
|
131
|
+
skillId: this.id,
|
|
132
|
+
findings: [],
|
|
133
|
+
metadata: {
|
|
134
|
+
error: errorMessage,
|
|
135
|
+
target: scanData.target,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
buildAnalysisPrompt(scanData, focus) {
|
|
141
|
+
const vulnList = scanData.findings
|
|
142
|
+
.map((f, i) => `${i + 1}. [${f.severity.toUpperCase()}] ${f.title}
|
|
143
|
+
Description: ${f.description}
|
|
144
|
+
${f.evidence ? `Evidence: ${f.evidence}` : ""}
|
|
145
|
+
${f.recommendation ? `Current recommendation: ${f.recommendation}` : ""}
|
|
146
|
+
${f.metadata?.cwe ? `CWE: ${f.metadata.cwe}` : ""}`)
|
|
147
|
+
.join("\n\n");
|
|
148
|
+
let focusInstructions = "";
|
|
149
|
+
switch (focus) {
|
|
150
|
+
case "executive":
|
|
151
|
+
focusInstructions =
|
|
152
|
+
"Focus on business impact and high-level recommendations. Keep technical details minimal.";
|
|
153
|
+
break;
|
|
154
|
+
case "technical":
|
|
155
|
+
focusInstructions =
|
|
156
|
+
"Provide detailed technical analysis including root causes and specific code/configuration fixes.";
|
|
157
|
+
break;
|
|
158
|
+
case "remediation":
|
|
159
|
+
focusInstructions =
|
|
160
|
+
"Focus primarily on step-by-step remediation actions and prioritization.";
|
|
161
|
+
break;
|
|
162
|
+
default:
|
|
163
|
+
focusInstructions =
|
|
164
|
+
"Provide comprehensive analysis covering all aspects.";
|
|
165
|
+
}
|
|
166
|
+
return `You are a senior security analyst reviewing web application vulnerabilities.
|
|
167
|
+
|
|
168
|
+
Target: ${scanData.target || "Unknown"}
|
|
169
|
+
Scan Date: ${scanData.timestamp || new Date().toISOString()}
|
|
170
|
+
Total Vulnerabilities: ${scanData.findings.length}
|
|
171
|
+
|
|
172
|
+
Vulnerabilities Found:
|
|
173
|
+
${vulnList}
|
|
174
|
+
|
|
175
|
+
Please provide a detailed analysis:
|
|
176
|
+
|
|
177
|
+
1. **Executive Summary**: Brief overview of security posture and business risk
|
|
178
|
+
2. **Risk Assessment**: Overall risk level with justification
|
|
179
|
+
3. **Prioritized Recommendations**: Top 3-5 issues to fix first with specific actions
|
|
180
|
+
4. **Attack Scenarios**: How vulnerabilities could be chained or exploited
|
|
181
|
+
5. **Remediation Roadmap**: Step-by-step plan with effort estimates
|
|
182
|
+
|
|
183
|
+
${focusInstructions}
|
|
184
|
+
|
|
185
|
+
Format in clear markdown with headers and bullet points.`;
|
|
186
|
+
}
|
|
187
|
+
async run() {
|
|
188
|
+
throw new Error("Use execute() method with AgentContext for analyze findings skill");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
exports.AnalyzeFindingsSkill = AnalyzeFindingsSkill;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Report Skill
|
|
3
|
+
* Creates professional security reports in multiple formats (DOCX, TXT, JSON)
|
|
4
|
+
*/
|
|
5
|
+
import { AgentSkill, ToolDefinition, AgentContext, SkillResult } from "../types";
|
|
6
|
+
export declare class GenerateReportSkill implements AgentSkill {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
requiresConfirmation: boolean;
|
|
12
|
+
riskLevel: "low";
|
|
13
|
+
estimatedDuration: number;
|
|
14
|
+
toolDefinition: ToolDefinition;
|
|
15
|
+
validateParameters(params: Record<string, unknown>): {
|
|
16
|
+
valid: boolean;
|
|
17
|
+
errors: string[];
|
|
18
|
+
};
|
|
19
|
+
execute(params: Record<string, unknown>, context: AgentContext): Promise<SkillResult>;
|
|
20
|
+
private generateDocxReport;
|
|
21
|
+
private generateTxtReport;
|
|
22
|
+
private generateJsonReport;
|
|
23
|
+
private getSeverityCount;
|
|
24
|
+
private getSeverityColor;
|
|
25
|
+
run(): Promise<SkillResult>;
|
|
26
|
+
}
|