@puukis/core 0.1.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 (162) hide show
  1. package/LICENSE +21 -0
  2. package/dist/brain/Brain.d.ts +39 -0
  3. package/dist/brain/Brain.d.ts.map +1 -0
  4. package/dist/brain/Brain.js +284 -0
  5. package/dist/brain/Brain.js.map +1 -0
  6. package/dist/brain/index.d.ts +2 -0
  7. package/dist/brain/index.d.ts.map +1 -0
  8. package/dist/brain/index.js +2 -0
  9. package/dist/brain/index.js.map +1 -0
  10. package/dist/cli/argv.d.ts +8 -0
  11. package/dist/cli/argv.d.ts.map +1 -0
  12. package/dist/cli/argv.js +41 -0
  13. package/dist/cli/argv.js.map +1 -0
  14. package/dist/cli/codexInstall.d.ts +17 -0
  15. package/dist/cli/codexInstall.d.ts.map +1 -0
  16. package/dist/cli/codexInstall.js +106 -0
  17. package/dist/cli/codexInstall.js.map +1 -0
  18. package/dist/cli/commands/auth.d.ts +3 -0
  19. package/dist/cli/commands/auth.d.ts.map +1 -0
  20. package/dist/cli/commands/auth.js +66 -0
  21. package/dist/cli/commands/auth.js.map +1 -0
  22. package/dist/cli/commands/install.d.ts +3 -0
  23. package/dist/cli/commands/install.d.ts.map +1 -0
  24. package/dist/cli/commands/install.js +21 -0
  25. package/dist/cli/commands/install.js.map +1 -0
  26. package/dist/cli/commands/onboard.d.ts +3 -0
  27. package/dist/cli/commands/onboard.d.ts.map +1 -0
  28. package/dist/cli/commands/onboard.js +43 -0
  29. package/dist/cli/commands/onboard.js.map +1 -0
  30. package/dist/cli/commands/uninstall.d.ts +3 -0
  31. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  32. package/dist/cli/commands/uninstall.js +193 -0
  33. package/dist/cli/commands/uninstall.js.map +1 -0
  34. package/dist/cli/commands/update.d.ts +3 -0
  35. package/dist/cli/commands/update.d.ts.map +1 -0
  36. package/dist/cli/commands/update.js +314 -0
  37. package/dist/cli/commands/update.js.map +1 -0
  38. package/dist/cli/index.d.ts +3 -0
  39. package/dist/cli/index.d.ts.map +1 -0
  40. package/dist/cli/index.js +60 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/codex/CodexRpcClient.d.ts +65 -0
  43. package/dist/codex/CodexRpcClient.d.ts.map +1 -0
  44. package/dist/codex/CodexRpcClient.js +395 -0
  45. package/dist/codex/CodexRpcClient.js.map +1 -0
  46. package/dist/codex/codexModels.d.ts +33 -0
  47. package/dist/codex/codexModels.d.ts.map +1 -0
  48. package/dist/codex/codexModels.js +226 -0
  49. package/dist/codex/codexModels.js.map +1 -0
  50. package/dist/codex/index.d.ts +5 -0
  51. package/dist/codex/index.d.ts.map +1 -0
  52. package/dist/codex/index.js +3 -0
  53. package/dist/codex/index.js.map +1 -0
  54. package/dist/codex/types.d.ts +97 -0
  55. package/dist/codex/types.d.ts.map +1 -0
  56. package/dist/codex/types.js +2 -0
  57. package/dist/codex/types.js.map +1 -0
  58. package/dist/config/env.d.ts +8 -0
  59. package/dist/config/env.d.ts.map +1 -0
  60. package/dist/config/env.js +130 -0
  61. package/dist/config/env.js.map +1 -0
  62. package/dist/config/index.d.ts +2 -0
  63. package/dist/config/index.d.ts.map +1 -0
  64. package/dist/config/index.js +2 -0
  65. package/dist/config/index.js.map +1 -0
  66. package/dist/db/index.d.ts +48 -0
  67. package/dist/db/index.d.ts.map +1 -0
  68. package/dist/db/index.js +147 -0
  69. package/dist/db/index.js.map +1 -0
  70. package/dist/gateway/Gateway.d.ts +69 -0
  71. package/dist/gateway/Gateway.d.ts.map +1 -0
  72. package/dist/gateway/Gateway.js +239 -0
  73. package/dist/gateway/Gateway.js.map +1 -0
  74. package/dist/gateway/LaneQueue.d.ts +24 -0
  75. package/dist/gateway/LaneQueue.d.ts.map +1 -0
  76. package/dist/gateway/LaneQueue.js +59 -0
  77. package/dist/gateway/LaneQueue.js.map +1 -0
  78. package/dist/gateway/index.d.ts +3 -0
  79. package/dist/gateway/index.d.ts.map +1 -0
  80. package/dist/gateway/index.js +3 -0
  81. package/dist/gateway/index.js.map +1 -0
  82. package/dist/index.d.ts +13 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +14 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/llm/GeminiProvider.d.ts +16 -0
  87. package/dist/llm/GeminiProvider.d.ts.map +1 -0
  88. package/dist/llm/GeminiProvider.js +172 -0
  89. package/dist/llm/GeminiProvider.js.map +1 -0
  90. package/dist/llm/OllamaProvider.d.ts +15 -0
  91. package/dist/llm/OllamaProvider.d.ts.map +1 -0
  92. package/dist/llm/OllamaProvider.js +108 -0
  93. package/dist/llm/OllamaProvider.js.map +1 -0
  94. package/dist/llm/OpenAICodexProvider.d.ts +51 -0
  95. package/dist/llm/OpenAICodexProvider.d.ts.map +1 -0
  96. package/dist/llm/OpenAICodexProvider.js +620 -0
  97. package/dist/llm/OpenAICodexProvider.js.map +1 -0
  98. package/dist/llm/OpenAIProvider.d.ts +16 -0
  99. package/dist/llm/OpenAIProvider.d.ts.map +1 -0
  100. package/dist/llm/OpenAIProvider.js +134 -0
  101. package/dist/llm/OpenAIProvider.js.map +1 -0
  102. package/dist/llm/index.d.ts +10 -0
  103. package/dist/llm/index.d.ts.map +1 -0
  104. package/dist/llm/index.js +30 -0
  105. package/dist/llm/index.js.map +1 -0
  106. package/dist/main.d.ts +7 -0
  107. package/dist/main.d.ts.map +1 -0
  108. package/dist/main.js +88 -0
  109. package/dist/main.js.map +1 -0
  110. package/dist/pipeline/index.d.ts +2 -0
  111. package/dist/pipeline/index.d.ts.map +1 -0
  112. package/dist/pipeline/index.js +2 -0
  113. package/dist/pipeline/index.js.map +1 -0
  114. package/dist/pipeline/normalize.d.ts +19 -0
  115. package/dist/pipeline/normalize.d.ts.map +1 -0
  116. package/dist/pipeline/normalize.js +34 -0
  117. package/dist/pipeline/normalize.js.map +1 -0
  118. package/dist/server/index.d.ts +28 -0
  119. package/dist/server/index.d.ts.map +1 -0
  120. package/dist/server/index.js +389 -0
  121. package/dist/server/index.js.map +1 -0
  122. package/dist/tools/ToolExecutor.d.ts +68 -0
  123. package/dist/tools/ToolExecutor.d.ts.map +1 -0
  124. package/dist/tools/ToolExecutor.js +177 -0
  125. package/dist/tools/ToolExecutor.js.map +1 -0
  126. package/dist/tools/builtin/browser.d.ts +27 -0
  127. package/dist/tools/builtin/browser.d.ts.map +1 -0
  128. package/dist/tools/builtin/browser.js +222 -0
  129. package/dist/tools/builtin/browser.js.map +1 -0
  130. package/dist/tools/builtin/filesystem.d.ts +22 -0
  131. package/dist/tools/builtin/filesystem.d.ts.map +1 -0
  132. package/dist/tools/builtin/filesystem.js +151 -0
  133. package/dist/tools/builtin/filesystem.js.map +1 -0
  134. package/dist/tools/builtin/index.d.ts +10 -0
  135. package/dist/tools/builtin/index.d.ts.map +1 -0
  136. package/dist/tools/builtin/index.js +21 -0
  137. package/dist/tools/builtin/index.js.map +1 -0
  138. package/dist/tools/builtin/sandbox.d.ts +11 -0
  139. package/dist/tools/builtin/sandbox.d.ts.map +1 -0
  140. package/dist/tools/builtin/sandbox.js +166 -0
  141. package/dist/tools/builtin/sandbox.js.map +1 -0
  142. package/dist/tools/builtin/search.d.ts +7 -0
  143. package/dist/tools/builtin/search.d.ts.map +1 -0
  144. package/dist/tools/builtin/search.js +76 -0
  145. package/dist/tools/builtin/search.js.map +1 -0
  146. package/dist/tools/builtin/shell.d.ts +7 -0
  147. package/dist/tools/builtin/shell.d.ts.map +1 -0
  148. package/dist/tools/builtin/shell.js +71 -0
  149. package/dist/tools/builtin/shell.js.map +1 -0
  150. package/dist/tools/index.d.ts +3 -0
  151. package/dist/tools/index.d.ts.map +1 -0
  152. package/dist/tools/index.js +3 -0
  153. package/dist/tools/index.js.map +1 -0
  154. package/dist/types.d.ts +167 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +3 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/workspace/agentWorkspace.d.ts +24 -0
  159. package/dist/workspace/agentWorkspace.d.ts.map +1 -0
  160. package/dist/workspace/agentWorkspace.js +210 -0
  161. package/dist/workspace/agentWorkspace.js.map +1 -0
  162. package/package.json +45 -0
@@ -0,0 +1,389 @@
1
+ import { createServer } from 'node:http';
2
+ import { WebSocketServer, WebSocket } from 'ws';
3
+ import { spawnSync } from 'node:child_process';
4
+ import path from 'node:path';
5
+ import { promises as fs } from 'node:fs';
6
+ import { Gateway } from '../gateway/index.js';
7
+ import { normalizeWebMessage, BaseChannel } from '../pipeline/index.js';
8
+ import { allBuiltinTools } from '../tools/index.js';
9
+ import 'dotenv/config';
10
+ /**
11
+ * WebSocket Channel adapter
12
+ */
13
+ class WebSocketChannel extends BaseChannel {
14
+ type = 'web';
15
+ ws;
16
+ sessionId;
17
+ pendingConfirmation = null;
18
+ constructor(ws, sessionId) {
19
+ super();
20
+ this.ws = ws;
21
+ this.sessionId = sessionId;
22
+ }
23
+ async send(content) {
24
+ this.ws.send(JSON.stringify({
25
+ type: 'message',
26
+ sessionId: this.sessionId,
27
+ content,
28
+ }));
29
+ }
30
+ async sendStream(stream) {
31
+ for await (const chunk of stream) {
32
+ this.ws.send(JSON.stringify({
33
+ type: 'chunk',
34
+ sessionId: this.sessionId,
35
+ content: chunk,
36
+ }));
37
+ }
38
+ this.ws.send(JSON.stringify({
39
+ type: 'stream_end',
40
+ sessionId: this.sessionId,
41
+ }));
42
+ }
43
+ async requestConfirmation(prompt) {
44
+ return new Promise((resolve) => {
45
+ this.pendingConfirmation = resolve;
46
+ this.ws.send(JSON.stringify({
47
+ type: 'confirm_request',
48
+ sessionId: this.sessionId,
49
+ prompt,
50
+ }));
51
+ // Timeout after 60 seconds
52
+ setTimeout(() => {
53
+ if (this.pendingConfirmation) {
54
+ this.pendingConfirmation(false);
55
+ this.pendingConfirmation = null;
56
+ }
57
+ }, 60000);
58
+ });
59
+ }
60
+ handleConfirmResponse(confirmed) {
61
+ if (this.pendingConfirmation) {
62
+ this.pendingConfirmation(confirmed);
63
+ this.pendingConfirmation = null;
64
+ }
65
+ }
66
+ }
67
+ /**
68
+ * Start the WebSocket server
69
+ */
70
+ export function startWebServer(config, options = {}) {
71
+ const gateway = Gateway.getInstance(config);
72
+ const staticAssetsDir = options.staticAssetsDir;
73
+ // Register all built-in tools
74
+ for (const tool of allBuiltinTools) {
75
+ gateway.toolExecutor.registerTool(tool);
76
+ }
77
+ const server = createServer((req, res) => {
78
+ // CORS headers
79
+ res.setHeader('Access-Control-Allow-Origin', '*');
80
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
81
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
82
+ if (req.method === 'OPTIONS') {
83
+ res.writeHead(204);
84
+ res.end();
85
+ return;
86
+ }
87
+ const url = new URL(req.url ?? '/', 'http://localhost');
88
+ // Simple REST endpoints
89
+ if (url.pathname === '/api/status') {
90
+ res.writeHead(200, { 'Content-Type': 'application/json' });
91
+ res.end(JSON.stringify({
92
+ status: 'ok',
93
+ mode: gateway.getSecurityMode(),
94
+ spicyEnabled: config.security.spicyModeEnabled,
95
+ llm: gateway.getLLMState(),
96
+ }));
97
+ return;
98
+ }
99
+ if (staticAssetsDir && req.method && ['GET', 'HEAD'].includes(req.method)) {
100
+ void serveStaticAsset(res, staticAssetsDir, url.pathname, req.method === 'HEAD');
101
+ return;
102
+ }
103
+ res.writeHead(404);
104
+ res.end('Not Found');
105
+ });
106
+ const wss = new WebSocketServer({ server });
107
+ const channels = new Map();
108
+ wss.on('connection', (ws) => {
109
+ const sessionId = crypto.randomUUID();
110
+ const channel = new WebSocketChannel(ws, sessionId);
111
+ channels.set(sessionId, channel);
112
+ const llmState = gateway.getLLMState();
113
+ console.log(`Client connected: ${sessionId}`);
114
+ // Send initial state
115
+ ws.send(JSON.stringify({
116
+ type: 'connected',
117
+ sessionId,
118
+ mode: gateway.getSecurityMode(),
119
+ spicyEnabled: config.security.spicyModeEnabled,
120
+ llm: llmState,
121
+ }));
122
+ void sendModels(ws, gateway, llmState.provider);
123
+ ws.on('message', async (data) => {
124
+ try {
125
+ const msg = JSON.parse(data.toString());
126
+ switch (msg.type) {
127
+ case 'message': {
128
+ const content = msg.content?.trim();
129
+ if (!content)
130
+ return;
131
+ const normalized = normalizeWebMessage(sessionId, 'web-user', content, channel);
132
+ // Send acknowledgment
133
+ ws.send(JSON.stringify({ type: 'message_received', sessionId }));
134
+ await gateway.processMessage(normalized);
135
+ break;
136
+ }
137
+ case 'confirm_response': {
138
+ channel.handleConfirmResponse(msg.confirmed ?? false);
139
+ break;
140
+ }
141
+ case 'set_mode': {
142
+ if (msg.mode) {
143
+ try {
144
+ gateway.setSecurityMode(msg.mode);
145
+ ws.send(JSON.stringify({
146
+ type: 'mode_changed',
147
+ mode: msg.mode,
148
+ }));
149
+ }
150
+ catch (error) {
151
+ ws.send(JSON.stringify({
152
+ type: 'error',
153
+ error: error instanceof Error ? error.message : 'Failed to change mode',
154
+ }));
155
+ }
156
+ }
157
+ break;
158
+ }
159
+ case 'clear_session': {
160
+ gateway.clearSession(`web:${sessionId}`);
161
+ ws.send(JSON.stringify({ type: 'session_cleared', sessionId }));
162
+ break;
163
+ }
164
+ case 'get_models': {
165
+ await sendModels(ws, gateway, msg.provider ?? gateway.getLLMState().provider);
166
+ break;
167
+ }
168
+ case 'set_model': {
169
+ const provider = msg.provider ?? gateway.getLLMState().provider;
170
+ const model = msg.model?.trim();
171
+ const reasoningEffort = provider === 'openai-codex'
172
+ ? normalizeCodexReasoningEffort(msg.reasoningEffort)
173
+ : undefined;
174
+ if (!model) {
175
+ ws.send(JSON.stringify({
176
+ type: 'error',
177
+ error: 'Model is required',
178
+ }));
179
+ break;
180
+ }
181
+ if (provider === 'openai-codex' && typeof msg.reasoningEffort === 'string' && !reasoningEffort) {
182
+ ws.send(JSON.stringify({
183
+ type: 'error',
184
+ error: 'Invalid reasoning effort. Expected low, medium, high, or xhigh.',
185
+ }));
186
+ break;
187
+ }
188
+ if (provider === 'openai-codex' && !isCodexInstalled()) {
189
+ ws.send(JSON.stringify({
190
+ type: 'codex_install_required',
191
+ provider,
192
+ message: 'Codex CLI is not installed. Run `keygate onboard --auth-choice openai-codex`.',
193
+ }));
194
+ break;
195
+ }
196
+ try {
197
+ await gateway.setLLMSelection(provider, model, reasoningEffort);
198
+ const state = gateway.getLLMState();
199
+ ws.send(JSON.stringify({
200
+ type: 'model_changed',
201
+ llm: state,
202
+ }));
203
+ await sendModels(ws, gateway, state.provider);
204
+ }
205
+ catch (error) {
206
+ ws.send(JSON.stringify({
207
+ type: 'error',
208
+ error: error instanceof Error ? error.message : 'Failed to switch model',
209
+ }));
210
+ }
211
+ break;
212
+ }
213
+ }
214
+ }
215
+ catch (error) {
216
+ console.error('WebSocket message error:', error);
217
+ ws.send(JSON.stringify({
218
+ type: 'error',
219
+ error: 'Invalid message format',
220
+ }));
221
+ }
222
+ });
223
+ ws.on('close', () => {
224
+ console.log(`Client disconnected: ${sessionId}`);
225
+ channels.delete(sessionId);
226
+ });
227
+ });
228
+ // Forward gateway events to all connected clients
229
+ gateway.on('tool:start', (event) => {
230
+ broadcast(wss, { type: 'tool_start', ...event });
231
+ });
232
+ gateway.on('tool:end', (event) => {
233
+ broadcast(wss, { type: 'tool_end', ...event });
234
+ });
235
+ gateway.on('mode:changed', (event) => {
236
+ broadcast(wss, { type: 'mode_changed', ...event });
237
+ });
238
+ gateway.on('provider:event', (event) => {
239
+ broadcast(wss, { type: 'provider_event', ...event });
240
+ });
241
+ server.listen(config.server.port, () => {
242
+ console.log(`🌐 Keygate Web Server running on http://localhost:${config.server.port}`);
243
+ if (options.onListening) {
244
+ void Promise.resolve(options.onListening()).catch((error) => {
245
+ console.error('Startup hook failed:', error);
246
+ });
247
+ }
248
+ });
249
+ }
250
+ function broadcast(wss, data) {
251
+ const msg = JSON.stringify(data);
252
+ wss.clients.forEach((client) => {
253
+ if (client.readyState === WebSocket.OPEN) {
254
+ client.send(msg);
255
+ }
256
+ });
257
+ }
258
+ export { WebSocketChannel };
259
+ async function sendModels(ws, gateway, provider) {
260
+ try {
261
+ const models = await gateway.listAvailableModels(provider);
262
+ ws.send(JSON.stringify({
263
+ type: 'models',
264
+ provider,
265
+ models,
266
+ }));
267
+ }
268
+ catch (error) {
269
+ ws.send(JSON.stringify({
270
+ type: 'models',
271
+ provider,
272
+ models: [],
273
+ error: error instanceof Error ? error.message : 'Failed to fetch models',
274
+ }));
275
+ }
276
+ }
277
+ function isCodexInstalled() {
278
+ const result = spawnSync('codex', ['--version'], {
279
+ stdio: 'pipe',
280
+ });
281
+ return result.status === 0;
282
+ }
283
+ function normalizeCodexReasoningEffort(value) {
284
+ if (typeof value !== 'string') {
285
+ return undefined;
286
+ }
287
+ const normalized = value.trim().toLowerCase();
288
+ switch (normalized) {
289
+ case 'low':
290
+ case 'medium':
291
+ case 'high':
292
+ return normalized;
293
+ case 'xhigh':
294
+ case 'extra-high':
295
+ case 'extra_high':
296
+ case 'extra high':
297
+ return 'xhigh';
298
+ default:
299
+ return undefined;
300
+ }
301
+ }
302
+ async function serveStaticAsset(res, staticAssetsDir, requestPath, headOnly) {
303
+ const normalizedPath = sanitizePathname(requestPath);
304
+ const resolvedAssetsDir = path.resolve(staticAssetsDir);
305
+ const tryPaths = normalizedPath === '/'
306
+ ? [path.join(resolvedAssetsDir, 'index.html')]
307
+ : [path.join(resolvedAssetsDir, normalizedPath.slice(1))];
308
+ // SPA fallback for routes without extension.
309
+ if (!path.extname(normalizedPath)) {
310
+ tryPaths.push(path.join(resolvedAssetsDir, 'index.html'));
311
+ }
312
+ for (const filePath of tryPaths) {
313
+ const resolved = path.resolve(filePath);
314
+ if (!resolved.startsWith(resolvedAssetsDir + path.sep) && resolved !== path.join(resolvedAssetsDir, 'index.html')) {
315
+ continue;
316
+ }
317
+ try {
318
+ const stats = await fs.stat(resolved);
319
+ if (!stats.isFile()) {
320
+ continue;
321
+ }
322
+ const contentType = getContentType(resolved);
323
+ res.writeHead(200, {
324
+ 'Content-Type': contentType,
325
+ 'Cache-Control': getCacheControl(resolved),
326
+ });
327
+ if (headOnly) {
328
+ res.end();
329
+ return;
330
+ }
331
+ const content = await fs.readFile(resolved);
332
+ res.end(content);
333
+ return;
334
+ }
335
+ catch {
336
+ // Try next path candidate.
337
+ }
338
+ }
339
+ res.writeHead(404);
340
+ res.end('Not Found');
341
+ }
342
+ function sanitizePathname(input) {
343
+ const decoded = decodeURIComponent(input);
344
+ const normalized = path.posix.normalize(decoded);
345
+ if (!normalized.startsWith('/')) {
346
+ return `/${normalized}`;
347
+ }
348
+ return normalized;
349
+ }
350
+ function getContentType(filePath) {
351
+ const ext = path.extname(filePath).toLowerCase();
352
+ switch (ext) {
353
+ case '.html':
354
+ return 'text/html; charset=utf-8';
355
+ case '.js':
356
+ return 'application/javascript; charset=utf-8';
357
+ case '.mjs':
358
+ return 'application/javascript; charset=utf-8';
359
+ case '.css':
360
+ return 'text/css; charset=utf-8';
361
+ case '.json':
362
+ return 'application/json; charset=utf-8';
363
+ case '.svg':
364
+ return 'image/svg+xml';
365
+ case '.png':
366
+ return 'image/png';
367
+ case '.jpg':
368
+ case '.jpeg':
369
+ return 'image/jpeg';
370
+ case '.gif':
371
+ return 'image/gif';
372
+ case '.webp':
373
+ return 'image/webp';
374
+ case '.ico':
375
+ return 'image/x-icon';
376
+ case '.txt':
377
+ return 'text/plain; charset=utf-8';
378
+ default:
379
+ return 'application/octet-stream';
380
+ }
381
+ }
382
+ function getCacheControl(filePath) {
383
+ const base = path.basename(filePath);
384
+ if (base === 'index.html') {
385
+ return 'no-cache';
386
+ }
387
+ return 'public, max-age=31536000, immutable';
388
+ }
389
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { SecurityMode, Tool, ToolCall, ToolResult, Channel } from '../types.js';
2
+ import type { Gateway } from '../gateway/Gateway.js';
3
+ /**
4
+ * ToolExecutor - Mode-switching security middleware
5
+ *
6
+ * Safe Mode:
7
+ * - Path jail to workspace directory
8
+ * - Command allowlist (git, ls, npm, cat, node)
9
+ * - Human-in-the-loop confirmation for write/execute
10
+ *
11
+ * Spicy Mode:
12
+ * - Full host access
13
+ * - Unrestricted shell
14
+ * - Autonomous execution
15
+ */
16
+ export declare class ToolExecutor {
17
+ private mode;
18
+ private workspacePath;
19
+ private allowedBinaries;
20
+ private toolRegistry;
21
+ private gateway;
22
+ constructor(mode: SecurityMode, workspacePath: string, allowedBinaries: string[], gateway: Gateway);
23
+ /**
24
+ * Register a tool
25
+ */
26
+ registerTool(tool: Tool): void;
27
+ /**
28
+ * Get all registered tool definitions (for LLM)
29
+ */
30
+ getToolDefinitions(): Tool[];
31
+ /**
32
+ * Set security mode
33
+ */
34
+ setMode(mode: SecurityMode): void;
35
+ /**
36
+ * Execute a tool call with security checks
37
+ */
38
+ execute(call: ToolCall, channel: Channel): Promise<ToolResult>;
39
+ /**
40
+ * Apply safety checks for Safe Mode
41
+ */
42
+ private applySafetyChecks;
43
+ /**
44
+ * Assert that a path is within the workspace (jail)
45
+ */
46
+ private assertPathInWorkspace;
47
+ /**
48
+ * Assert that a command uses an allowed binary
49
+ */
50
+ private assertBinaryAllowed;
51
+ /**
52
+ * Request human confirmation for a tool call
53
+ */
54
+ private requestConfirmation;
55
+ /**
56
+ * Expand ~ to home directory
57
+ */
58
+ private expandPath;
59
+ /**
60
+ * Get the resolved workspace path
61
+ */
62
+ getWorkspacePath(): string;
63
+ /**
64
+ * Get current mode
65
+ */
66
+ getMode(): SecurityMode;
67
+ }
68
+ //# sourceMappingURL=ToolExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolExecutor.d.ts","sourceRoot":"","sources":["../../src/tools/ToolExecutor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,OAAO,EACR,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,OAAO,CAAU;gBAGvB,IAAI,EAAE,YAAY,EAClB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,EAAE,OAAO;IAQlB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAI9B;;OAEG;IACH,kBAAkB,IAAI,IAAI,EAAE;IAI5B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAIjC;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAqDpE;;OAEG;YACW,iBAAiB;IA8B/B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAY7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;YACW,mBAAmB;IAQjC;;OAEG;IACH,OAAO,CAAC,UAAU;IAOlB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,OAAO,IAAI,YAAY;CAGxB"}
@@ -0,0 +1,177 @@
1
+ import * as path from 'node:path';
2
+ import * as os from 'node:os';
3
+ /**
4
+ * ToolExecutor - Mode-switching security middleware
5
+ *
6
+ * Safe Mode:
7
+ * - Path jail to workspace directory
8
+ * - Command allowlist (git, ls, npm, cat, node)
9
+ * - Human-in-the-loop confirmation for write/execute
10
+ *
11
+ * Spicy Mode:
12
+ * - Full host access
13
+ * - Unrestricted shell
14
+ * - Autonomous execution
15
+ */
16
+ export class ToolExecutor {
17
+ mode;
18
+ workspacePath;
19
+ allowedBinaries;
20
+ toolRegistry = new Map();
21
+ gateway;
22
+ constructor(mode, workspacePath, allowedBinaries, gateway) {
23
+ this.mode = mode;
24
+ this.workspacePath = this.expandPath(workspacePath);
25
+ this.allowedBinaries = new Set(allowedBinaries);
26
+ this.gateway = gateway;
27
+ }
28
+ /**
29
+ * Register a tool
30
+ */
31
+ registerTool(tool) {
32
+ this.toolRegistry.set(tool.name, tool);
33
+ }
34
+ /**
35
+ * Get all registered tool definitions (for LLM)
36
+ */
37
+ getToolDefinitions() {
38
+ return Array.from(this.toolRegistry.values());
39
+ }
40
+ /**
41
+ * Set security mode
42
+ */
43
+ setMode(mode) {
44
+ this.mode = mode;
45
+ }
46
+ /**
47
+ * Execute a tool call with security checks
48
+ */
49
+ async execute(call, channel) {
50
+ const tool = this.toolRegistry.get(call.name);
51
+ if (!tool) {
52
+ return {
53
+ success: false,
54
+ output: '',
55
+ error: `Unknown tool: ${call.name}`,
56
+ };
57
+ }
58
+ // Emit tool:start event
59
+ this.gateway.emit('tool:start', {
60
+ sessionId: 'current', // TODO: Pass session context
61
+ tool: call.name,
62
+ args: call.arguments,
63
+ });
64
+ try {
65
+ // Apply security checks in Safe Mode
66
+ if (this.mode === 'safe') {
67
+ await this.applySafetyChecks(tool, call, channel);
68
+ }
69
+ // Execute the tool
70
+ const result = await tool.handler(call.arguments);
71
+ // Emit tool:end event
72
+ this.gateway.emit('tool:end', {
73
+ sessionId: 'current',
74
+ tool: call.name,
75
+ result,
76
+ });
77
+ return result;
78
+ }
79
+ catch (error) {
80
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
81
+ const result = {
82
+ success: false,
83
+ output: '',
84
+ error: errorMessage,
85
+ };
86
+ this.gateway.emit('tool:end', {
87
+ sessionId: 'current',
88
+ tool: call.name,
89
+ result,
90
+ });
91
+ return result;
92
+ }
93
+ }
94
+ /**
95
+ * Apply safety checks for Safe Mode
96
+ */
97
+ async applySafetyChecks(tool, call, channel) {
98
+ // Path validation for filesystem tools
99
+ if (tool.type === 'filesystem') {
100
+ const targetPath = call.arguments['path'];
101
+ if (targetPath) {
102
+ this.assertPathInWorkspace(targetPath);
103
+ }
104
+ }
105
+ // Command validation for shell tools
106
+ if (tool.type === 'shell') {
107
+ const command = call.arguments['command'];
108
+ if (command) {
109
+ this.assertBinaryAllowed(command);
110
+ }
111
+ }
112
+ // Human-in-the-loop confirmation for dangerous operations
113
+ if (tool.requiresConfirmation) {
114
+ const confirmed = await this.requestConfirmation(call, channel);
115
+ if (!confirmed) {
116
+ throw new Error('Action cancelled by user');
117
+ }
118
+ }
119
+ }
120
+ /**
121
+ * Assert that a path is within the workspace (jail)
122
+ */
123
+ assertPathInWorkspace(targetPath) {
124
+ const resolvedPath = path.resolve(this.workspacePath, targetPath);
125
+ const normalizedWorkspace = path.normalize(this.workspacePath);
126
+ if (!resolvedPath.startsWith(normalizedWorkspace)) {
127
+ throw new Error(`Access denied: Path "${targetPath}" is outside the workspace. ` +
128
+ `Only paths within "${this.workspacePath}" are allowed in Safe Mode.`);
129
+ }
130
+ }
131
+ /**
132
+ * Assert that a command uses an allowed binary
133
+ */
134
+ assertBinaryAllowed(command) {
135
+ // Extract the binary name from the command
136
+ const parts = command.trim().split(/\s+/);
137
+ const binary = parts[0];
138
+ if (!binary) {
139
+ throw new Error('Empty command');
140
+ }
141
+ // Handle absolute paths
142
+ const binaryName = path.basename(binary);
143
+ if (!this.allowedBinaries.has(binaryName)) {
144
+ throw new Error(`Access denied: Binary "${binaryName}" is not in the allowlist. ` +
145
+ `Allowed binaries: ${Array.from(this.allowedBinaries).join(', ')}`);
146
+ }
147
+ }
148
+ /**
149
+ * Request human confirmation for a tool call
150
+ */
151
+ async requestConfirmation(call, channel) {
152
+ const prompt = `🔐 Confirm action:\n\`${call.name}(${JSON.stringify(call.arguments)})\`\n\nProceed? [Y/n]`;
153
+ return channel.requestConfirmation(prompt);
154
+ }
155
+ /**
156
+ * Expand ~ to home directory
157
+ */
158
+ expandPath(inputPath) {
159
+ if (inputPath.startsWith('~')) {
160
+ return path.join(os.homedir(), inputPath.slice(1));
161
+ }
162
+ return inputPath;
163
+ }
164
+ /**
165
+ * Get the resolved workspace path
166
+ */
167
+ getWorkspacePath() {
168
+ return this.workspacePath;
169
+ }
170
+ /**
171
+ * Get current mode
172
+ */
173
+ getMode() {
174
+ return this.mode;
175
+ }
176
+ }
177
+ //# sourceMappingURL=ToolExecutor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolExecutor.js","sourceRoot":"","sources":["../../src/tools/ToolExecutor.ts"],"names":[],"mappings":"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"}