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.
Files changed (105) hide show
  1. package/README.md +392 -87
  2. package/dist/agent/confirmation.d.ts +38 -0
  3. package/dist/agent/confirmation.js +210 -0
  4. package/dist/agent/context.d.ts +81 -0
  5. package/dist/agent/context.js +227 -0
  6. package/dist/agent/index.d.ts +10 -0
  7. package/dist/agent/index.js +32 -0
  8. package/dist/agent/orchestrator.d.ts +63 -0
  9. package/dist/agent/orchestrator.js +370 -0
  10. package/dist/agent/prompts/system.d.ts +6 -0
  11. package/dist/agent/prompts/system.js +116 -0
  12. package/dist/agent/skill-registry.d.ts +78 -0
  13. package/dist/agent/skill-registry.js +202 -0
  14. package/dist/agent/skills/analyze-findings.d.ts +22 -0
  15. package/dist/agent/skills/analyze-findings.js +191 -0
  16. package/dist/agent/skills/generate-report.d.ts +26 -0
  17. package/dist/agent/skills/generate-report.js +436 -0
  18. package/dist/agent/skills/health-check.d.ts +28 -0
  19. package/dist/agent/skills/health-check.js +344 -0
  20. package/dist/agent/skills/index.d.ts +9 -0
  21. package/dist/agent/skills/index.js +17 -0
  22. package/dist/agent/skills/verify-finding.d.ts +17 -0
  23. package/dist/agent/skills/verify-finding.js +91 -0
  24. package/dist/agent/skills/web-scan.d.ts +22 -0
  25. package/dist/agent/skills/web-scan.js +203 -0
  26. package/dist/agent/types.d.ts +141 -0
  27. package/dist/agent/types.js +16 -0
  28. package/dist/cli.d.ts +3 -0
  29. package/dist/cli.js +176 -139
  30. package/dist/commands/agent.d.ts +6 -0
  31. package/dist/commands/agent.js +250 -0
  32. package/dist/commands/ai.d.ts +2 -0
  33. package/dist/commands/ai.js +112 -0
  34. package/dist/commands/analyze.js +104 -55
  35. package/dist/commands/config.js +63 -37
  36. package/dist/commands/doctor.js +22 -17
  37. package/dist/commands/onboard.js +190 -125
  38. package/dist/commands/report.js +69 -77
  39. package/dist/commands/scan.js +261 -81
  40. package/dist/commands/scans.d.ts +2 -0
  41. package/dist/commands/scans.js +51 -0
  42. package/dist/core/ai-client.d.ts +7 -2
  43. package/dist/core/ai-client.js +231 -20
  44. package/dist/core/ai-payloads.d.ts +17 -0
  45. package/dist/core/ai-payloads.js +54 -0
  46. package/dist/core/config-schema.d.ts +197 -0
  47. package/dist/core/config-schema.js +68 -0
  48. package/dist/core/config-schema.test.d.ts +1 -0
  49. package/dist/core/config-schema.test.js +151 -0
  50. package/dist/core/config.d.ts +17 -36
  51. package/dist/core/config.js +261 -20
  52. package/dist/core/errors.d.ts +71 -0
  53. package/dist/core/errors.js +162 -0
  54. package/dist/core/scan-index.d.ts +19 -0
  55. package/dist/core/scan-index.js +52 -0
  56. package/dist/core/scan-storage.d.ts +11 -0
  57. package/dist/core/scan-storage.js +69 -0
  58. package/dist/core/scanner.d.ts +101 -4
  59. package/dist/core/scanner.js +432 -63
  60. package/dist/core/vulnerability-detector.d.ts +18 -2
  61. package/dist/core/vulnerability-detector.js +349 -38
  62. package/dist/core/vulnerability-detector.test.d.ts +1 -0
  63. package/dist/core/vulnerability-detector.test.js +210 -0
  64. package/dist/index.js +3 -0
  65. package/dist/plugins/PluginManager.d.ts +27 -0
  66. package/dist/plugins/PluginManager.js +166 -0
  67. package/dist/plugins/index.d.ts +7 -0
  68. package/dist/plugins/index.js +19 -0
  69. package/dist/plugins/types.d.ts +55 -0
  70. package/dist/plugins/types.js +25 -0
  71. package/dist/plugins/vulnerabilities/CSRFPlugin.d.ts +8 -0
  72. package/dist/plugins/vulnerabilities/CSRFPlugin.js +34 -0
  73. package/dist/plugins/vulnerabilities/SQLInjectionPlugin.d.ts +11 -0
  74. package/dist/plugins/vulnerabilities/SQLInjectionPlugin.js +109 -0
  75. package/dist/plugins/vulnerabilities/SecurityHeadersPlugin.d.ts +11 -0
  76. package/dist/plugins/vulnerabilities/SecurityHeadersPlugin.js +63 -0
  77. package/dist/plugins/vulnerabilities/SensitiveDataPlugin.d.ts +9 -0
  78. package/dist/plugins/vulnerabilities/SensitiveDataPlugin.js +32 -0
  79. package/dist/plugins/vulnerabilities/XSSPlugin.d.ts +15 -0
  80. package/dist/plugins/vulnerabilities/XSSPlugin.js +81 -0
  81. package/dist/reports/PdfGenerator.d.ts +36 -0
  82. package/dist/reports/PdfGenerator.js +379 -0
  83. package/dist/utils/logger.d.ts +33 -1
  84. package/dist/utils/logger.js +127 -8
  85. package/dist/utils/theme.d.ts +55 -0
  86. package/dist/utils/theme.js +195 -0
  87. package/package.json +27 -6
  88. package/dist/core/executor.d.ts +0 -2
  89. package/dist/core/executor.js +0 -74
  90. package/dist/core/logger.d.ts +0 -12
  91. package/dist/core/logger.js +0 -51
  92. package/dist/core/registry.d.ts +0 -3
  93. package/dist/core/registry.js +0 -35
  94. package/dist/core/storage.d.ts +0 -4
  95. package/dist/core/storage.js +0 -39
  96. package/dist/core/types.d.ts +0 -24
  97. package/dist/core/types.js +0 -2
  98. package/dist/skills/base.d.ts +0 -8
  99. package/dist/skills/base.js +0 -6
  100. package/dist/skills/builtin.d.ts +0 -4
  101. package/dist/skills/builtin.js +0 -71
  102. package/dist/skills/loader.d.ts +0 -2
  103. package/dist/skills/loader.js +0 -27
  104. package/dist/skills/types.d.ts +0 -46
  105. package/dist/skills/types.js +0 -2
@@ -0,0 +1,370 @@
1
+ "use strict";
2
+ /**
3
+ * Agent Orchestrator
4
+ * Coordinates AI conversations, tool calling, skill execution, and user interactions
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.AgentOrchestrator = void 0;
11
+ const context_1 = require("./context");
12
+ const confirmation_1 = require("./confirmation");
13
+ const system_1 = require("./prompts/system");
14
+ const types_1 = require("./types");
15
+ const ai_client_1 = require("../core/ai-client");
16
+ const logger_1 = require("../utils/logger");
17
+ const chalk_1 = __importDefault(require("chalk"));
18
+ class AgentOrchestrator {
19
+ context;
20
+ skillRegistry;
21
+ confirmationHandler;
22
+ config;
23
+ aiClient = null;
24
+ isRunning = false;
25
+ constructor(skillRegistry, config = {}) {
26
+ this.skillRegistry = skillRegistry;
27
+ this.config = { ...types_1.DEFAULT_AGENT_CONFIG, ...config };
28
+ this.context = new context_1.ConversationContext(this.config);
29
+ this.confirmationHandler = new confirmation_1.ConfirmationHandler();
30
+ }
31
+ setReadlineInterface(rl) {
32
+ this.confirmationHandler.setInterface(rl);
33
+ }
34
+ /**
35
+ * Initialize the orchestrator and AI client
36
+ */
37
+ async initialize() {
38
+ try {
39
+ this.aiClient = await (0, ai_client_1.createAIClient)();
40
+ logger_1.logger.success("AI client initialized successfully");
41
+ }
42
+ catch (error) {
43
+ logger_1.logger.error("Failed to initialize AI client. Run 'kramscan onboard' first.");
44
+ throw error;
45
+ }
46
+ // Add system message
47
+ this.context.addMessage("system", (0, system_1.getSystemPrompt)());
48
+ // Try to load previous conversation
49
+ await this.context.load();
50
+ }
51
+ /**
52
+ * Process a user message and generate a response
53
+ */
54
+ async processUserMessage(userInput) {
55
+ // Add user message to context
56
+ this.context.addMessage("user", userInput);
57
+ // Get AI response
58
+ const aiResponse = await this.getAIResponse();
59
+ // Check for tool calls in the response
60
+ const toolCalls = this.parseToolCalls(aiResponse);
61
+ if (toolCalls.length > 0) {
62
+ // Handle tool execution with confirmation
63
+ return this.handleToolExecution(toolCalls, aiResponse);
64
+ }
65
+ // No tool calls - just return the message
66
+ this.context.addMessage("assistant", aiResponse);
67
+ return {
68
+ message: aiResponse,
69
+ requiresConfirmation: false,
70
+ };
71
+ }
72
+ /**
73
+ * Execute a specific tool/skill directly
74
+ */
75
+ async executeTool(toolName, parameters, skipConfirmation = false) {
76
+ const toolCall = {
77
+ id: `manual-${Date.now()}`,
78
+ name: toolName,
79
+ arguments: parameters,
80
+ };
81
+ if (!skipConfirmation && this.skillRegistry.requiresConfirmation(toolName)) {
82
+ const confirmation = this.skillRegistry.getConfirmationPrompt(toolCall);
83
+ if (confirmation) {
84
+ const result = await this.confirmationHandler.prompt(confirmation);
85
+ if (result.showDetails) {
86
+ this.confirmationHandler.showDetails(confirmation);
87
+ return {
88
+ message: "Please confirm to proceed after reviewing the details.",
89
+ requiresConfirmation: true,
90
+ pendingAction: {
91
+ toolName,
92
+ description: confirmation.description,
93
+ parameters,
94
+ risk: confirmation.risk,
95
+ },
96
+ };
97
+ }
98
+ if (!result.confirmed || result.cancelled) {
99
+ return {
100
+ message: result.cancelled
101
+ ? "Action cancelled."
102
+ : "Action not confirmed. You can ask me to perform this action again when you're ready.",
103
+ requiresConfirmation: false,
104
+ };
105
+ }
106
+ }
107
+ }
108
+ // Execute the tool
109
+ const result = await this.skillRegistry.execute(toolCall, this.context.getContext());
110
+ // Format response
111
+ const responseMessage = this.formatToolResult(result);
112
+ this.context.addMessage("assistant", responseMessage, [toolCall], [result]);
113
+ // Store scan results if applicable
114
+ if (toolName === "web_scan" && result.success && result.result) {
115
+ this.context.setLastScanResults(result.result);
116
+ const target = parameters.targetUrl;
117
+ this.context.setCurrentTarget(target);
118
+ }
119
+ return {
120
+ message: responseMessage,
121
+ toolCalls: [toolCall],
122
+ toolCallResults: [result],
123
+ requiresConfirmation: false,
124
+ };
125
+ }
126
+ /**
127
+ * Get conversation summary
128
+ */
129
+ getConversationSummary() {
130
+ return this.context.getSummary();
131
+ }
132
+ /**
133
+ * Clear conversation history
134
+ */
135
+ clearConversation() {
136
+ this.context.clear();
137
+ this.context.addMessage("system", (0, system_1.getSystemPrompt)());
138
+ logger_1.logger.info("Conversation history cleared");
139
+ }
140
+ /**
141
+ * Save conversation state
142
+ */
143
+ async saveState() {
144
+ await this.context.save();
145
+ }
146
+ /**
147
+ * Get available skills list
148
+ */
149
+ getAvailableSkills() {
150
+ return this.skillRegistry.listSkills();
151
+ }
152
+ /**
153
+ * Shutdown the orchestrator
154
+ */
155
+ async shutdown() {
156
+ this.isRunning = false;
157
+ this.confirmationHandler.close();
158
+ await this.saveState();
159
+ }
160
+ /**
161
+ * Check if orchestrator is running
162
+ */
163
+ isActive() {
164
+ return this.isRunning;
165
+ }
166
+ /**
167
+ * Start the agent session
168
+ */
169
+ start() {
170
+ this.isRunning = true;
171
+ }
172
+ // Private methods
173
+ async getAIResponse() {
174
+ if (!this.aiClient) {
175
+ throw new Error("AI client not initialized");
176
+ }
177
+ try {
178
+ const messages = this.context.formatForAI();
179
+ const prompt = this.buildPromptWithTools(messages);
180
+ const response = await this.aiClient.analyze(prompt);
181
+ return response.content;
182
+ }
183
+ catch (error) {
184
+ logger_1.logger.error(`Failed to get AI response: ${error}`);
185
+ return "I apologize, but I'm having trouble processing your request right now. Please try again.";
186
+ }
187
+ }
188
+ buildPromptWithTools(messages) {
189
+ const conversation = messages
190
+ .map((m) => `${m.role}: ${m.content}`)
191
+ .join("\n\n");
192
+ const tools = this.skillRegistry.getToolDefinitions();
193
+ const toolsDescription = tools
194
+ .map((tool) => `
195
+ Tool: ${tool.name}
196
+ Description: ${tool.description}
197
+ Parameters:
198
+ ${tool.parameters
199
+ .map((p) => ` - ${p.name} (${p.type}${p.required ? ", required" : ""}): ${p.description}${p.default !== undefined ? ` (default: ${p.default})` : ""}`)
200
+ .join("\n")}
201
+ `)
202
+ .join("\n");
203
+ return `${conversation}
204
+
205
+ Available Tools:
206
+ ${toolsDescription}
207
+
208
+ When you need to use a tool, format your response exactly like this:
209
+
210
+ <tool_call>
211
+ {
212
+ "name": "tool_name",
213
+ "arguments": {
214
+ "param1": "value1",
215
+ "param2": "value2"
216
+ }
217
+ }
218
+ </tool_call>
219
+
220
+ If you don't need a tool, just respond naturally.`;
221
+ }
222
+ parseToolCalls(response) {
223
+ const toolCalls = [];
224
+ const regex = /<tool_call>\s*([\s\S]*?)\s*<\/tool_call>/g;
225
+ let match;
226
+ while ((match = regex.exec(response)) !== null) {
227
+ try {
228
+ const parsed = JSON.parse(match[1]);
229
+ toolCalls.push({
230
+ id: `tool-${Date.now()}-${toolCalls.length}`,
231
+ name: parsed.name,
232
+ arguments: parsed.arguments || {},
233
+ });
234
+ }
235
+ catch (error) {
236
+ logger_1.logger.warn(`Failed to parse tool call: ${match[1]}`);
237
+ }
238
+ }
239
+ // Fallback: some models respond with <web_scan> { ...args } </web_scan> blocks.
240
+ // Accept any <toolName>{json}</toolName> where json is either {arguments} or {name, arguments}.
241
+ if (toolCalls.length === 0) {
242
+ const alt = /<([a-zA-Z0-9_]+)>\s*([\s\S]*?)\s*<\/\1>/g;
243
+ let m;
244
+ while ((m = alt.exec(response)) !== null) {
245
+ const tag = m[1];
246
+ if (tag === "tool_call")
247
+ continue;
248
+ try {
249
+ const parsed = JSON.parse(m[2]);
250
+ const name = typeof parsed?.name === "string" ? parsed.name : tag;
251
+ const args = parsed && typeof parsed === "object" && "arguments" in parsed
252
+ ? parsed.arguments
253
+ : parsed;
254
+ toolCalls.push({
255
+ id: `tool-${Date.now()}-${toolCalls.length}`,
256
+ name,
257
+ arguments: args || {},
258
+ });
259
+ }
260
+ catch {
261
+ // Ignore non-json blocks.
262
+ }
263
+ }
264
+ }
265
+ return toolCalls;
266
+ }
267
+ async handleToolExecution(toolCalls, aiMessage) {
268
+ // Extract message without tool calls
269
+ const skillTags = this.skillRegistry
270
+ .getAll()
271
+ .map((s) => s.id)
272
+ .join("|");
273
+ const toolCallBlock = /<tool_call>[\s\S]*?<\/tool_call>/g;
274
+ const altToolBlocks = skillTags
275
+ ? new RegExp(`<(${skillTags})>\\s*[\\s\\S]*?\\s*<\\/\\1>`, "g")
276
+ : null;
277
+ const cleanMessage = aiMessage
278
+ .replace(toolCallBlock, "")
279
+ .replace(altToolBlocks ?? /$^/, "")
280
+ .trim();
281
+ // Check if any tool requires confirmation
282
+ const needsConfirmation = toolCalls.some((call) => this.skillRegistry.requiresConfirmation(call.name));
283
+ if (needsConfirmation && this.config.enableConfirmation) {
284
+ // Get confirmation for first tool (simplify UX)
285
+ const firstTool = toolCalls.find((call) => this.skillRegistry.requiresConfirmation(call.name));
286
+ const confirmation = this.skillRegistry.getConfirmationPrompt(firstTool);
287
+ if (confirmation) {
288
+ const result = await this.confirmationHandler.prompt(confirmation);
289
+ if (result.showDetails) {
290
+ this.confirmationHandler.showDetails(confirmation);
291
+ return {
292
+ message: cleanMessage || "Please review the details and confirm to proceed.",
293
+ requiresConfirmation: true,
294
+ pendingAction: {
295
+ toolName: firstTool.name,
296
+ description: confirmation.description,
297
+ parameters: firstTool.arguments,
298
+ risk: confirmation.risk,
299
+ },
300
+ };
301
+ }
302
+ if (!result.confirmed) {
303
+ return {
304
+ message: result.cancelled
305
+ ? "Action cancelled."
306
+ : "Action not confirmed. Let me know when you're ready to proceed.",
307
+ requiresConfirmation: false,
308
+ };
309
+ }
310
+ }
311
+ }
312
+ // Execute all tools
313
+ console.log(chalk_1.default.gray("\nExecuting tools...\n"));
314
+ const results = await this.skillRegistry.executeBatch(toolCalls, this.context.getContext());
315
+ // Format results
316
+ const resultMessage = results
317
+ .map((result) => this.formatToolResult(result))
318
+ .join("\n\n");
319
+ const fullMessage = cleanMessage
320
+ ? `${cleanMessage}\n\n${resultMessage}`
321
+ : resultMessage;
322
+ this.context.addMessage("assistant", fullMessage, toolCalls, results);
323
+ // Update context with scan results
324
+ const scanCall = toolCalls.find((t) => t.name === "web_scan");
325
+ if (scanCall) {
326
+ const scanExec = results.find((r) => r.toolCallId === scanCall.id);
327
+ if (scanExec?.success && scanExec.result) {
328
+ this.context.setLastScanResults(scanExec.result);
329
+ const target = scanCall.arguments.targetUrl;
330
+ if (target) {
331
+ this.context.setCurrentTarget(target);
332
+ }
333
+ }
334
+ }
335
+ return {
336
+ message: fullMessage,
337
+ toolCalls,
338
+ toolCallResults: results,
339
+ requiresConfirmation: false,
340
+ };
341
+ }
342
+ formatToolResult(result) {
343
+ if (!result.success) {
344
+ return chalk_1.default.red(`❌ Error: ${result.error || "Unknown error"}`);
345
+ }
346
+ const skillResult = result.result;
347
+ if (!skillResult) {
348
+ return chalk_1.default.gray("✓ Completed");
349
+ }
350
+ const findings = skillResult.findings || [];
351
+ if (findings.length === 0) {
352
+ return chalk_1.default.green("✓ No issues found");
353
+ }
354
+ const critical = findings.filter((f) => f.severity === "critical").length;
355
+ const high = findings.filter((f) => f.severity === "high").length;
356
+ const medium = findings.filter((f) => f.severity === "medium").length;
357
+ const low = findings.filter((f) => f.severity === "low").length;
358
+ const parts = [];
359
+ if (critical > 0)
360
+ parts.push(chalk_1.default.red(`${critical} Critical`));
361
+ if (high > 0)
362
+ parts.push(chalk_1.default.red(`${high} High`));
363
+ if (medium > 0)
364
+ parts.push(chalk_1.default.yellow(`${medium} Medium`));
365
+ if (low > 0)
366
+ parts.push(chalk_1.default.blue(`${low} Low`));
367
+ return `Found: ${parts.join(", ") || chalk_1.default.green("None")}`;
368
+ }
369
+ }
370
+ exports.AgentOrchestrator = AgentOrchestrator;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * System prompts for the AI Security Agent
3
+ * Defines the AI's role, capabilities, and behavior
4
+ */
5
+ export declare const SYSTEM_PROMPT = "You are KramScan Security Agent, an expert AI security assistant that helps users identify and fix vulnerabilities in web applications.\n\n## Your Role\n- Analyze security-related requests and select appropriate tools/skills\n- Guide users through security testing workflows\n- Explain findings in clear, actionable terms\n- Prioritize safety and never perform destructive actions without explicit confirmation\n\n## Available Tools\nYou have access to the following security testing tools:\n\n1. **web_scan** - Comprehensive web application security scan\n - Tests for XSS, SQL injection, CSRF, security headers\n - Crawls the target website\n - Provides detailed vulnerability report\n - Risk: Medium (may trigger WAFs)\n\n2. **analyze_findings** - AI-powered analysis of scan results\n - Reviews vulnerabilities and provides expert insights\n - Generates remediation recommendations\n - Assesses overall risk level\n - Risk: Low (read-only analysis)\n\n3. **generate_report** - Create professional security reports\n - Formats: DOCX, TXT, JSON\n - Includes executive summary and technical details\n - Risk: Low (file generation only)\n\n4. **health_check** - Verify system setup and configuration\n - Checks API keys, dependencies, permissions\n - Risk: Low (diagnostic only)\n\n## Guidelines\n\n### When to Use Tools\n- **Always** use web_scan when user asks to scan, test, or check a website\n- **Always** use analyze_findings after a scan completes to provide insights\n- Use generate_report when user asks for a report or documentation\n- Use health_check when user mentions setup issues\n\n### Tool Calling Format\nWhen you need to execute a tool, respond with a tool call in this format:\n\n<tool_call>\n{\n \"name\": \"web_scan\",\n \"arguments\": {\n \"targetUrl\": \"https://example.com\",\n \"depth\": 2,\n \"timeout\": 30000\n }\n}\n</tool_call>\n\nYou can make multiple tool calls if needed. Wait for results before proceeding.\n\nImportant:\n- Only use the <tool_call> ... </tool_call> wrapper. Do not invent tags like <web_scan> ... </web_scan>.\n\n### Confirmation Requirements\n- **High/Medium risk tools** (like web_scan): Always ask for confirmation before executing\n- **Low risk tools** (analyze, report): Can execute directly\n- **Destructive actions**: Never perform without explicit user approval\n\n### Response Format\n1. Acknowledge the user's request\n2. Explain what you plan to do\n3. If tool execution is needed, make the tool call\n4. After receiving results, provide:\n - Summary of findings\n - Severity assessment\n - Specific recommendations\n - Next steps\n\n### Safety Rules\n- Never scan targets without user confirmation\n- Respect rate limits and don't overwhelm targets\n- Clearly label all findings with severity levels\n- Provide remediation steps for each vulnerability\n- If uncertain, ask clarifying questions\n\n### Conversation Context\n- You can reference previous scans and findings in the conversation\n- Keep track of the current target being discussed\n- Remember user preferences from earlier in the conversation\n\n## Example Interactions\n\nUser: \"Check my website for security issues\"\nAssistant: \"I'll help you scan your website for security vulnerabilities. Could you please provide the URL you'd like me to scan?\"\n\nUser: \"Scan https://example.com\"\nAssistant: \"I'll perform a comprehensive security scan of https://example.com. This will check for XSS, SQL injection, CSRF vulnerabilities, and security header misconfigurations. The scan will crawl up to 2 levels deep and respect a 30-second timeout.\n\nWould you like me to proceed with the scan? [Y/n/details]\"\n\n[After confirmation]\n<tool_call>\n{\n \"name\": \"web_scan\",\n \"arguments\": {\n \"targetUrl\": \"https://example.com\",\n \"depth\": 2,\n \"timeout\": 30000\n }\n}\n</tool_call>";
6
+ export declare const getSystemPrompt: () => string;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * System prompts for the AI Security Agent
4
+ * Defines the AI's role, capabilities, and behavior
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getSystemPrompt = exports.SYSTEM_PROMPT = void 0;
8
+ exports.SYSTEM_PROMPT = `You are KramScan Security Agent, an expert AI security assistant that helps users identify and fix vulnerabilities in web applications.
9
+
10
+ ## Your Role
11
+ - Analyze security-related requests and select appropriate tools/skills
12
+ - Guide users through security testing workflows
13
+ - Explain findings in clear, actionable terms
14
+ - Prioritize safety and never perform destructive actions without explicit confirmation
15
+
16
+ ## Available Tools
17
+ You have access to the following security testing tools:
18
+
19
+ 1. **web_scan** - Comprehensive web application security scan
20
+ - Tests for XSS, SQL injection, CSRF, security headers
21
+ - Crawls the target website
22
+ - Provides detailed vulnerability report
23
+ - Risk: Medium (may trigger WAFs)
24
+
25
+ 2. **analyze_findings** - AI-powered analysis of scan results
26
+ - Reviews vulnerabilities and provides expert insights
27
+ - Generates remediation recommendations
28
+ - Assesses overall risk level
29
+ - Risk: Low (read-only analysis)
30
+
31
+ 3. **generate_report** - Create professional security reports
32
+ - Formats: DOCX, TXT, JSON
33
+ - Includes executive summary and technical details
34
+ - Risk: Low (file generation only)
35
+
36
+ 4. **health_check** - Verify system setup and configuration
37
+ - Checks API keys, dependencies, permissions
38
+ - Risk: Low (diagnostic only)
39
+
40
+ ## Guidelines
41
+
42
+ ### When to Use Tools
43
+ - **Always** use web_scan when user asks to scan, test, or check a website
44
+ - **Always** use analyze_findings after a scan completes to provide insights
45
+ - Use generate_report when user asks for a report or documentation
46
+ - Use health_check when user mentions setup issues
47
+
48
+ ### Tool Calling Format
49
+ When you need to execute a tool, respond with a tool call in this format:
50
+
51
+ <tool_call>
52
+ {
53
+ "name": "web_scan",
54
+ "arguments": {
55
+ "targetUrl": "https://example.com",
56
+ "depth": 2,
57
+ "timeout": 30000
58
+ }
59
+ }
60
+ </tool_call>
61
+
62
+ You can make multiple tool calls if needed. Wait for results before proceeding.
63
+
64
+ Important:
65
+ - Only use the <tool_call> ... </tool_call> wrapper. Do not invent tags like <web_scan> ... </web_scan>.
66
+
67
+ ### Confirmation Requirements
68
+ - **High/Medium risk tools** (like web_scan): Always ask for confirmation before executing
69
+ - **Low risk tools** (analyze, report): Can execute directly
70
+ - **Destructive actions**: Never perform without explicit user approval
71
+
72
+ ### Response Format
73
+ 1. Acknowledge the user's request
74
+ 2. Explain what you plan to do
75
+ 3. If tool execution is needed, make the tool call
76
+ 4. After receiving results, provide:
77
+ - Summary of findings
78
+ - Severity assessment
79
+ - Specific recommendations
80
+ - Next steps
81
+
82
+ ### Safety Rules
83
+ - Never scan targets without user confirmation
84
+ - Respect rate limits and don't overwhelm targets
85
+ - Clearly label all findings with severity levels
86
+ - Provide remediation steps for each vulnerability
87
+ - If uncertain, ask clarifying questions
88
+
89
+ ### Conversation Context
90
+ - You can reference previous scans and findings in the conversation
91
+ - Keep track of the current target being discussed
92
+ - Remember user preferences from earlier in the conversation
93
+
94
+ ## Example Interactions
95
+
96
+ User: "Check my website for security issues"
97
+ Assistant: "I'll help you scan your website for security vulnerabilities. Could you please provide the URL you'd like me to scan?"
98
+
99
+ User: "Scan https://example.com"
100
+ Assistant: "I'll perform a comprehensive security scan of https://example.com. This will check for XSS, SQL injection, CSRF vulnerabilities, and security header misconfigurations. The scan will crawl up to 2 levels deep and respect a 30-second timeout.
101
+
102
+ Would you like me to proceed with the scan? [Y/n/details]"
103
+
104
+ [After confirmation]
105
+ <tool_call>
106
+ {
107
+ "name": "web_scan",
108
+ "arguments": {
109
+ "targetUrl": "https://example.com",
110
+ "depth": 2,
111
+ "timeout": 30000
112
+ }
113
+ }
114
+ </tool_call>`;
115
+ const getSystemPrompt = () => exports.SYSTEM_PROMPT;
116
+ exports.getSystemPrompt = getSystemPrompt;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Skill Registry and Execution System
3
+ * Manages AI-callable security skills with validation, confirmation, and execution
4
+ */
5
+ import { AgentSkill, ToolDefinition, ToolCall, ToolCallResult, AgentContext, ConfirmationPrompt } from "./types";
6
+ export declare class SkillRegistry {
7
+ private skills;
8
+ private executionHistory;
9
+ /**
10
+ * Register a skill with the registry
11
+ */
12
+ register(skill: AgentSkill): void;
13
+ /**
14
+ * Unregister a skill
15
+ */
16
+ unregister(skillId: string): boolean;
17
+ /**
18
+ * Get a skill by ID
19
+ */
20
+ get(skillId: string): AgentSkill | undefined;
21
+ /**
22
+ * Get all registered skills
23
+ */
24
+ getAll(): AgentSkill[];
25
+ /**
26
+ * Get all tool definitions for AI function calling
27
+ */
28
+ getToolDefinitions(): ToolDefinition[];
29
+ /**
30
+ * Validate tool call parameters
31
+ */
32
+ validateToolCall(toolCall: ToolCall): {
33
+ valid: boolean;
34
+ errors: string[];
35
+ };
36
+ /**
37
+ * Check if a tool call requires confirmation
38
+ */
39
+ requiresConfirmation(toolName: string): boolean;
40
+ /**
41
+ * Get confirmation prompt for a tool call
42
+ */
43
+ getConfirmationPrompt(toolCall: ToolCall): ConfirmationPrompt | null;
44
+ /**
45
+ * Execute a skill by tool call
46
+ */
47
+ execute(toolCall: ToolCall, context: AgentContext): Promise<ToolCallResult>;
48
+ /**
49
+ * Execute multiple skills in parallel
50
+ */
51
+ executeBatch(toolCalls: ToolCall[], context: AgentContext): Promise<ToolCallResult[]>;
52
+ /**
53
+ * Get execution statistics
54
+ */
55
+ getStats(): {
56
+ totalExecutions: number;
57
+ successfulExecutions: number;
58
+ failedExecutions: number;
59
+ averageDuration: number;
60
+ skillUsage: Record<string, number>;
61
+ };
62
+ /**
63
+ * Clear execution history
64
+ */
65
+ clearHistory(): void;
66
+ /**
67
+ * List available skills with descriptions
68
+ */
69
+ listSkills(): Array<{
70
+ id: string;
71
+ name: string;
72
+ description: string;
73
+ risk: string;
74
+ requiresConfirmation: boolean;
75
+ }>;
76
+ private formatDuration;
77
+ }
78
+ export declare const skillRegistry: SkillRegistry;