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,210 @@
1
+ "use strict";
2
+ /**
3
+ * Confirmation Prompt System
4
+ * Handles user confirmation for skill execution with detailed risk assessment
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ var __importDefault = (this && this.__importDefault) || function (mod) {
40
+ return (mod && mod.__esModule) ? mod : { "default": mod };
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.ConfirmationHandler = void 0;
44
+ const readline = __importStar(require("readline"));
45
+ const chalk_1 = __importDefault(require("chalk"));
46
+ class ConfirmationHandler {
47
+ rl = null;
48
+ ownsRl = false;
49
+ constructor(rl) {
50
+ if (rl) {
51
+ this.rl = rl;
52
+ this.ownsRl = false;
53
+ }
54
+ }
55
+ setInterface(rl) {
56
+ // Prefer sharing a single readline interface to avoid double-reading stdin.
57
+ this.rl = rl;
58
+ this.ownsRl = false;
59
+ }
60
+ getInterface() {
61
+ if (!this.rl) {
62
+ this.rl = readline.createInterface({
63
+ input: process.stdin,
64
+ output: process.stdout,
65
+ });
66
+ this.ownsRl = true;
67
+ }
68
+ return this.rl;
69
+ }
70
+ /**
71
+ * Display confirmation prompt and get user response
72
+ */
73
+ async prompt(confirmation) {
74
+ console.log("");
75
+ console.log(chalk_1.default.bold.yellow("⚠️ Action Requires Confirmation"));
76
+ console.log(chalk_1.default.gray("─".repeat(50)));
77
+ console.log("");
78
+ // Display action details
79
+ console.log(chalk_1.default.white("Action:"), chalk_1.default.cyan(confirmation.action));
80
+ console.log(chalk_1.default.white("Description:"), confirmation.description);
81
+ console.log("");
82
+ // Display risk level with color coding
83
+ const riskColor = this.getRiskColor(confirmation.risk);
84
+ console.log(chalk_1.default.white("Risk Level:"), riskColor(confirmation.risk.toUpperCase()));
85
+ console.log(chalk_1.default.white("Estimated Time:"), confirmation.estimatedTime);
86
+ console.log("");
87
+ // Display parameters
88
+ console.log(chalk_1.default.white("Parameters:"));
89
+ Object.entries(confirmation.parameters).forEach(([key, value]) => {
90
+ const displayValue = typeof value === "object" ? JSON.stringify(value) : String(value);
91
+ console.log(` ${chalk_1.default.gray(key)}: ${chalk_1.default.white(displayValue)}`);
92
+ });
93
+ console.log("");
94
+ // Risk warnings
95
+ if (confirmation.risk === "high") {
96
+ console.log(chalk_1.default.red.bold("⚠️ WARNING: This action may have significant impact."));
97
+ }
98
+ else if (confirmation.risk === "medium") {
99
+ console.log(chalk_1.default.yellow("⚠️ This action will interact with external systems."));
100
+ }
101
+ console.log("");
102
+ // Get user input
103
+ return this.getUserInput();
104
+ }
105
+ /**
106
+ * Quick confirmation for low-risk actions
107
+ */
108
+ async quickConfirm(action) {
109
+ const rl = this.getInterface();
110
+ return new Promise((resolve) => {
111
+ rl.question(chalk_1.default.gray(`${action} [Y/n]: `), (answer) => {
112
+ const normalized = answer.trim().toLowerCase();
113
+ resolve(normalized === "" || normalized === "y" || normalized === "yes");
114
+ });
115
+ });
116
+ }
117
+ /**
118
+ * Display detailed information about the action
119
+ */
120
+ showDetails(confirmation) {
121
+ console.log("");
122
+ console.log(chalk_1.default.bold.cyan("📋 Action Details"));
123
+ console.log(chalk_1.default.gray("─".repeat(50)));
124
+ console.log("");
125
+ console.log(chalk_1.default.white("What will happen:"));
126
+ console.log(chalk_1.default.gray(this.getDetailedDescription(confirmation.action)));
127
+ console.log("");
128
+ console.log(chalk_1.default.white("Safety considerations:"));
129
+ console.log(chalk_1.default.gray(this.getSafetyInfo(confirmation.risk)));
130
+ console.log("");
131
+ if (confirmation.risk === "high") {
132
+ console.log(chalk_1.default.yellow("Recommendations:"));
133
+ console.log(chalk_1.default.gray("• Ensure you have proper authorization"));
134
+ console.log(chalk_1.default.gray("• Verify the target is correct"));
135
+ console.log(chalk_1.default.gray("• Consider testing in a safe environment first"));
136
+ console.log("");
137
+ }
138
+ }
139
+ /**
140
+ * Close the readline interface
141
+ */
142
+ close() {
143
+ if (this.rl && this.ownsRl) {
144
+ this.rl.close();
145
+ }
146
+ }
147
+ async getUserInput() {
148
+ const rl = this.getInterface();
149
+ return new Promise((resolve) => {
150
+ const askQuestion = () => {
151
+ rl.question(chalk_1.default.gray("Proceed? [Y/n/details/cancel]: "), (answer) => {
152
+ const normalized = answer.trim().toLowerCase();
153
+ if (normalized === "" || normalized === "y" || normalized === "yes") {
154
+ resolve({ confirmed: true, showDetails: false, cancelled: false });
155
+ }
156
+ else if (normalized === "n" || normalized === "no") {
157
+ resolve({ confirmed: false, showDetails: false, cancelled: false });
158
+ }
159
+ else if (normalized === "details" || normalized === "d") {
160
+ resolve({ confirmed: false, showDetails: true, cancelled: false });
161
+ }
162
+ else if (normalized === "cancel" || normalized === "c") {
163
+ resolve({ confirmed: false, showDetails: false, cancelled: true });
164
+ }
165
+ else {
166
+ console.log(chalk_1.default.gray("Please enter: Y, n, details, or cancel"));
167
+ askQuestion();
168
+ }
169
+ });
170
+ };
171
+ askQuestion();
172
+ });
173
+ }
174
+ getRiskColor(risk) {
175
+ switch (risk) {
176
+ case "high":
177
+ return chalk_1.default.red.bold;
178
+ case "medium":
179
+ return chalk_1.default.yellow;
180
+ case "low":
181
+ return chalk_1.default.green;
182
+ default:
183
+ return chalk_1.default.gray;
184
+ }
185
+ }
186
+ getDetailedDescription(action) {
187
+ const descriptions = {
188
+ "Web Scan": "This will crawl the target website and test for common vulnerabilities including XSS, SQL injection, CSRF, and security header misconfigurations. The scan sends HTTP requests to the target.",
189
+ "Analyze Findings": "This will use AI to analyze previously discovered vulnerabilities and provide detailed remediation recommendations.",
190
+ "Generate Report": "This will create a professional security report document based on scan results.",
191
+ "Check Environment": "This will verify your system configuration, API keys, and dependencies.",
192
+ "View Configuration": "This will display your current KramScan configuration settings.",
193
+ };
194
+ return (descriptions[action] ||
195
+ "This action will execute the requested security operation.");
196
+ }
197
+ getSafetyInfo(risk) {
198
+ switch (risk) {
199
+ case "high":
200
+ return "This action may trigger security systems, generate significant network traffic, or have other notable effects. Use with caution.";
201
+ case "medium":
202
+ return "This action will make network requests to external systems. Ensure you have permission to test the target.";
203
+ case "low":
204
+ return "This is a safe, read-only operation that won't modify any external systems.";
205
+ default:
206
+ return "Please review the action details carefully before proceeding.";
207
+ }
208
+ }
209
+ }
210
+ exports.ConfirmationHandler = ConfirmationHandler;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Conversation Context Manager
3
+ * Manages conversation history, user context, and session state
4
+ */
5
+ import { ConversationMessage, AgentContext, AgentConfig } from "./types";
6
+ export declare class ConversationContext {
7
+ private messages;
8
+ private context;
9
+ private config;
10
+ private historyFile;
11
+ constructor(config?: Partial<AgentConfig>);
12
+ private initializeContext;
13
+ /**
14
+ * Get the current agent context
15
+ */
16
+ getContext(): AgentContext;
17
+ /**
18
+ * Update the current target URL
19
+ */
20
+ setCurrentTarget(target: string): void;
21
+ /**
22
+ * Get the current target URL
23
+ */
24
+ getCurrentTarget(): string | undefined;
25
+ /**
26
+ * Store last scan results
27
+ */
28
+ setLastScanResults(results: unknown): void;
29
+ /**
30
+ * Get last scan results
31
+ */
32
+ getLastScanResults(): unknown | undefined;
33
+ /**
34
+ * Add a message to the conversation
35
+ */
36
+ addMessage(role: ConversationMessage["role"], content: string, toolCalls?: any[], toolCallResults?: any[]): ConversationMessage;
37
+ /**
38
+ * Get all conversation messages
39
+ */
40
+ getMessages(): ConversationMessage[];
41
+ /**
42
+ * Get recent messages (for AI context)
43
+ */
44
+ getRecentMessages(count?: number): ConversationMessage[];
45
+ /**
46
+ * Get the last message
47
+ */
48
+ getLastMessage(): ConversationMessage | undefined;
49
+ /**
50
+ * Get conversation summary for display
51
+ */
52
+ getSummary(): {
53
+ totalMessages: number;
54
+ sessionDuration: string;
55
+ currentTarget?: string;
56
+ hasScanResults: boolean;
57
+ };
58
+ /**
59
+ * Clear conversation history
60
+ */
61
+ clear(): void;
62
+ /**
63
+ * Trim history to max length
64
+ */
65
+ private trimHistory;
66
+ /**
67
+ * Persist conversation to disk
68
+ */
69
+ save(): Promise<void>;
70
+ /**
71
+ * Load conversation from disk
72
+ */
73
+ load(): Promise<boolean>;
74
+ /**
75
+ * Format messages for AI provider (OpenAI/Anthropic format)
76
+ */
77
+ formatForAI(): Array<{
78
+ role: string;
79
+ content: string;
80
+ }>;
81
+ }
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ /**
3
+ * Conversation Context Manager
4
+ * Manages conversation history, user context, and session state
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.ConversationContext = void 0;
41
+ const types_1 = require("./types");
42
+ const uuid_1 = require("uuid");
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ const fs = __importStar(require("fs/promises"));
46
+ class ConversationContext {
47
+ messages = [];
48
+ context;
49
+ config;
50
+ historyFile;
51
+ constructor(config = {}) {
52
+ this.config = { ...types_1.DEFAULT_AGENT_CONFIG, ...config };
53
+ this.context = this.initializeContext();
54
+ this.historyFile = path.join(os.homedir(), ".kramscan", "agent-history.json");
55
+ }
56
+ initializeContext() {
57
+ return {
58
+ sessionId: (0, uuid_1.v4)(),
59
+ userId: os.userInfo().username,
60
+ startTime: new Date(),
61
+ workingDirectory: process.cwd(),
62
+ environment: {
63
+ nodeVersion: process.version,
64
+ platform: process.platform,
65
+ },
66
+ };
67
+ }
68
+ /**
69
+ * Get the current agent context
70
+ */
71
+ getContext() {
72
+ return { ...this.context };
73
+ }
74
+ /**
75
+ * Update the current target URL
76
+ */
77
+ setCurrentTarget(target) {
78
+ this.context.currentTarget = target;
79
+ }
80
+ /**
81
+ * Get the current target URL
82
+ */
83
+ getCurrentTarget() {
84
+ return this.context.currentTarget;
85
+ }
86
+ /**
87
+ * Store last scan results
88
+ */
89
+ setLastScanResults(results) {
90
+ this.context.lastScanResults = results;
91
+ }
92
+ /**
93
+ * Get last scan results
94
+ */
95
+ getLastScanResults() {
96
+ return this.context.lastScanResults;
97
+ }
98
+ /**
99
+ * Add a message to the conversation
100
+ */
101
+ addMessage(role, content, toolCalls, toolCallResults) {
102
+ const message = {
103
+ id: (0, uuid_1.v4)(),
104
+ role,
105
+ content,
106
+ timestamp: new Date(),
107
+ toolCalls,
108
+ toolCallResults,
109
+ };
110
+ this.messages.push(message);
111
+ this.trimHistory();
112
+ return message;
113
+ }
114
+ /**
115
+ * Get all conversation messages
116
+ */
117
+ getMessages() {
118
+ return [...this.messages];
119
+ }
120
+ /**
121
+ * Get recent messages (for AI context)
122
+ */
123
+ getRecentMessages(count = this.config.maxConversationHistory) {
124
+ return this.messages.slice(-count);
125
+ }
126
+ /**
127
+ * Get the last message
128
+ */
129
+ getLastMessage() {
130
+ return this.messages[this.messages.length - 1];
131
+ }
132
+ /**
133
+ * Get conversation summary for display
134
+ */
135
+ getSummary() {
136
+ const duration = Date.now() - this.context.startTime.getTime();
137
+ const hours = Math.floor(duration / (1000 * 60 * 60));
138
+ const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60));
139
+ const seconds = Math.floor((duration % (1000 * 60)) / 1000);
140
+ let sessionDuration;
141
+ if (hours > 0) {
142
+ sessionDuration = `${hours}h ${minutes}m ${seconds}s`;
143
+ }
144
+ else if (minutes > 0) {
145
+ sessionDuration = `${minutes}m ${seconds}s`;
146
+ }
147
+ else {
148
+ sessionDuration = `${seconds}s`;
149
+ }
150
+ return {
151
+ totalMessages: this.messages.length,
152
+ sessionDuration,
153
+ currentTarget: this.context.currentTarget,
154
+ hasScanResults: !!this.context.lastScanResults,
155
+ };
156
+ }
157
+ /**
158
+ * Clear conversation history
159
+ */
160
+ clear() {
161
+ this.messages = [];
162
+ this.context.currentTarget = undefined;
163
+ this.context.lastScanResults = undefined;
164
+ }
165
+ /**
166
+ * Trim history to max length
167
+ */
168
+ trimHistory() {
169
+ if (this.messages.length > this.config.maxConversationHistory * 2) {
170
+ // Keep system message if present, then last N messages
171
+ const systemMessages = this.messages.filter((m) => m.role === "system");
172
+ const recentMessages = this.messages.slice(-this.config.maxConversationHistory);
173
+ this.messages = [...systemMessages, ...recentMessages];
174
+ }
175
+ }
176
+ /**
177
+ * Persist conversation to disk
178
+ */
179
+ async save() {
180
+ try {
181
+ const data = {
182
+ context: this.context,
183
+ messages: this.messages,
184
+ timestamp: new Date().toISOString(),
185
+ };
186
+ const dir = path.dirname(this.historyFile);
187
+ await fs.mkdir(dir, { recursive: true });
188
+ await fs.writeFile(this.historyFile, JSON.stringify(data, null, 2));
189
+ }
190
+ catch (error) {
191
+ console.error("Failed to save conversation history:", error);
192
+ }
193
+ }
194
+ /**
195
+ * Load conversation from disk
196
+ */
197
+ async load() {
198
+ try {
199
+ const data = await fs.readFile(this.historyFile, "utf-8");
200
+ const parsed = JSON.parse(data);
201
+ if (parsed.context) {
202
+ this.context = { ...this.context, ...parsed.context };
203
+ }
204
+ if (parsed.messages) {
205
+ this.messages = parsed.messages.map((m) => ({
206
+ ...m,
207
+ timestamp: new Date(m.timestamp),
208
+ }));
209
+ }
210
+ return true;
211
+ }
212
+ catch {
213
+ return false;
214
+ }
215
+ }
216
+ /**
217
+ * Format messages for AI provider (OpenAI/Anthropic format)
218
+ */
219
+ formatForAI() {
220
+ // Include system messages so the model receives core constraints and tool format instructions.
221
+ return this.messages.map((m) => ({
222
+ role: m.role,
223
+ content: m.content,
224
+ }));
225
+ }
226
+ }
227
+ exports.ConversationContext = ConversationContext;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Agent Module Index
3
+ * Main exports for the AI Agent system
4
+ */
5
+ export { AgentOrchestrator } from "./orchestrator";
6
+ export { ConversationContext } from "./context";
7
+ export { SkillRegistry, skillRegistry } from "./skill-registry";
8
+ export { ConfirmationHandler } from "./confirmation";
9
+ export * from "./types";
10
+ export * from "./skills";
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Agent Module Index
4
+ * Main exports for the AI Agent system
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.ConfirmationHandler = exports.skillRegistry = exports.SkillRegistry = exports.ConversationContext = exports.AgentOrchestrator = void 0;
22
+ var orchestrator_1 = require("./orchestrator");
23
+ Object.defineProperty(exports, "AgentOrchestrator", { enumerable: true, get: function () { return orchestrator_1.AgentOrchestrator; } });
24
+ var context_1 = require("./context");
25
+ Object.defineProperty(exports, "ConversationContext", { enumerable: true, get: function () { return context_1.ConversationContext; } });
26
+ var skill_registry_1 = require("./skill-registry");
27
+ Object.defineProperty(exports, "SkillRegistry", { enumerable: true, get: function () { return skill_registry_1.SkillRegistry; } });
28
+ Object.defineProperty(exports, "skillRegistry", { enumerable: true, get: function () { return skill_registry_1.skillRegistry; } });
29
+ var confirmation_1 = require("./confirmation");
30
+ Object.defineProperty(exports, "ConfirmationHandler", { enumerable: true, get: function () { return confirmation_1.ConfirmationHandler; } });
31
+ __exportStar(require("./types"), exports);
32
+ __exportStar(require("./skills"), exports);
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Agent Orchestrator
3
+ * Coordinates AI conversations, tool calling, skill execution, and user interactions
4
+ */
5
+ import { ConversationContext } from "./context";
6
+ import { SkillRegistry } from "./skill-registry";
7
+ import { AgentConfig, AgentResponse } from "./types";
8
+ import type * as readline from "readline";
9
+ export declare class AgentOrchestrator {
10
+ private context;
11
+ private skillRegistry;
12
+ private confirmationHandler;
13
+ private config;
14
+ private aiClient;
15
+ private isRunning;
16
+ constructor(skillRegistry: SkillRegistry, config?: Partial<AgentConfig>);
17
+ setReadlineInterface(rl: readline.Interface): void;
18
+ /**
19
+ * Initialize the orchestrator and AI client
20
+ */
21
+ initialize(): Promise<void>;
22
+ /**
23
+ * Process a user message and generate a response
24
+ */
25
+ processUserMessage(userInput: string): Promise<AgentResponse>;
26
+ /**
27
+ * Execute a specific tool/skill directly
28
+ */
29
+ executeTool(toolName: string, parameters: Record<string, unknown>, skipConfirmation?: boolean): Promise<AgentResponse>;
30
+ /**
31
+ * Get conversation summary
32
+ */
33
+ getConversationSummary(): ReturnType<ConversationContext["getSummary"]>;
34
+ /**
35
+ * Clear conversation history
36
+ */
37
+ clearConversation(): void;
38
+ /**
39
+ * Save conversation state
40
+ */
41
+ saveState(): Promise<void>;
42
+ /**
43
+ * Get available skills list
44
+ */
45
+ getAvailableSkills(): ReturnType<SkillRegistry["listSkills"]>;
46
+ /**
47
+ * Shutdown the orchestrator
48
+ */
49
+ shutdown(): Promise<void>;
50
+ /**
51
+ * Check if orchestrator is running
52
+ */
53
+ isActive(): boolean;
54
+ /**
55
+ * Start the agent session
56
+ */
57
+ start(): void;
58
+ private getAIResponse;
59
+ private buildPromptWithTools;
60
+ private parseToolCalls;
61
+ private handleToolExecution;
62
+ private formatToolResult;
63
+ }