snow-ai 0.1.12 → 0.2.1
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/dist/api/chat.d.ts +65 -2
- package/dist/api/chat.js +299 -16
- package/dist/api/responses.d.ts +52 -0
- package/dist/api/responses.js +541 -0
- package/dist/api/systemPrompt.d.ts +4 -0
- package/dist/api/systemPrompt.js +43 -0
- package/dist/app.js +15 -4
- package/dist/cli.js +17 -1
- package/dist/hooks/useConversation.d.ts +32 -0
- package/dist/hooks/useConversation.js +403 -0
- package/dist/hooks/useGlobalNavigation.d.ts +6 -0
- package/dist/hooks/useGlobalNavigation.js +15 -0
- package/dist/hooks/useSessionManagement.d.ts +10 -0
- package/dist/hooks/useSessionManagement.js +43 -0
- package/dist/hooks/useSessionSave.d.ts +8 -0
- package/dist/hooks/useSessionSave.js +52 -0
- package/dist/hooks/useToolConfirmation.d.ts +18 -0
- package/dist/hooks/useToolConfirmation.js +49 -0
- package/dist/mcp/bash.d.ts +57 -0
- package/dist/mcp/bash.js +138 -0
- package/dist/mcp/filesystem.d.ts +307 -0
- package/dist/mcp/filesystem.js +520 -0
- package/dist/mcp/todo.d.ts +55 -0
- package/dist/mcp/todo.js +329 -0
- package/dist/test/logger-test.d.ts +1 -0
- package/dist/test/logger-test.js +7 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/ui/components/ChatInput.d.ts +15 -2
- package/dist/ui/components/ChatInput.js +445 -59
- package/dist/ui/components/CommandPanel.d.ts +2 -2
- package/dist/ui/components/CommandPanel.js +11 -7
- package/dist/ui/components/DiffViewer.d.ts +9 -0
- package/dist/ui/components/DiffViewer.js +93 -0
- package/dist/ui/components/FileList.d.ts +14 -0
- package/dist/ui/components/FileList.js +131 -0
- package/dist/ui/components/MCPInfoPanel.d.ts +2 -0
- package/dist/ui/components/MCPInfoPanel.js +74 -0
- package/dist/ui/components/MCPInfoScreen.d.ts +7 -0
- package/dist/ui/components/MCPInfoScreen.js +27 -0
- package/dist/ui/components/MarkdownRenderer.d.ts +7 -0
- package/dist/ui/components/MarkdownRenderer.js +110 -0
- package/dist/ui/components/Menu.d.ts +5 -2
- package/dist/ui/components/Menu.js +60 -9
- package/dist/ui/components/MessageList.d.ts +30 -2
- package/dist/ui/components/MessageList.js +64 -12
- package/dist/ui/components/PendingMessages.js +1 -1
- package/dist/ui/components/ScrollableSelectInput.d.ts +29 -0
- package/dist/ui/components/ScrollableSelectInput.js +157 -0
- package/dist/ui/components/SessionListScreen.d.ts +7 -0
- package/dist/ui/components/SessionListScreen.js +196 -0
- package/dist/ui/components/SessionListScreenWrapper.d.ts +7 -0
- package/dist/ui/components/SessionListScreenWrapper.js +14 -0
- package/dist/ui/components/TodoTree.d.ts +15 -0
- package/dist/ui/components/TodoTree.js +60 -0
- package/dist/ui/components/ToolConfirmation.d.ts +8 -0
- package/dist/ui/components/ToolConfirmation.js +38 -0
- package/dist/ui/components/ToolResultPreview.d.ts +12 -0
- package/dist/ui/components/ToolResultPreview.js +115 -0
- package/dist/ui/pages/ChatScreen.d.ts +4 -0
- package/dist/ui/pages/ChatScreen.js +385 -196
- package/dist/ui/pages/MCPConfigScreen.d.ts +6 -0
- package/dist/ui/pages/MCPConfigScreen.js +55 -0
- package/dist/ui/pages/ModelConfigScreen.js +73 -12
- package/dist/ui/pages/WelcomeScreen.js +17 -11
- package/dist/utils/apiConfig.d.ts +12 -0
- package/dist/utils/apiConfig.js +95 -9
- package/dist/utils/commandExecutor.d.ts +2 -1
- package/dist/utils/commands/init.d.ts +2 -0
- package/dist/utils/commands/init.js +93 -0
- package/dist/utils/commands/mcp.d.ts +2 -0
- package/dist/utils/commands/mcp.js +12 -0
- package/dist/utils/commands/resume.d.ts +2 -0
- package/dist/utils/commands/resume.js +12 -0
- package/dist/utils/commands/yolo.d.ts +2 -0
- package/dist/utils/commands/yolo.js +12 -0
- package/dist/utils/fileUtils.d.ts +44 -0
- package/dist/utils/fileUtils.js +222 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/logger.d.ts +31 -0
- package/dist/utils/logger.js +97 -0
- package/dist/utils/mcpToolsManager.d.ts +47 -0
- package/dist/utils/mcpToolsManager.js +476 -0
- package/dist/utils/messageFormatter.d.ts +12 -0
- package/dist/utils/messageFormatter.js +32 -0
- package/dist/utils/sessionConverter.d.ts +6 -0
- package/dist/utils/sessionConverter.js +61 -0
- package/dist/utils/sessionManager.d.ts +39 -0
- package/dist/utils/sessionManager.js +141 -0
- package/dist/utils/textBuffer.d.ts +36 -7
- package/dist/utils/textBuffer.js +265 -179
- package/dist/utils/todoPreprocessor.d.ts +5 -0
- package/dist/utils/todoPreprocessor.js +19 -0
- package/dist/utils/toolExecutor.d.ts +21 -0
- package/dist/utils/toolExecutor.js +28 -0
- package/package.json +12 -3
- package/readme.md +2 -2
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
/**
|
|
5
|
+
* Get line count for a file
|
|
6
|
+
*/
|
|
7
|
+
export function getFileLineCount(filePath) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
try {
|
|
10
|
+
if (!fs.existsSync(filePath)) {
|
|
11
|
+
resolve(0);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
15
|
+
const lines = content.split('\n').length;
|
|
16
|
+
resolve(lines);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
resolve(0);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if file is an image based on extension
|
|
25
|
+
*/
|
|
26
|
+
function isImageFile(filePath) {
|
|
27
|
+
const imageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg'];
|
|
28
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
29
|
+
return imageExtensions.includes(ext);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get MIME type from file extension
|
|
33
|
+
*/
|
|
34
|
+
function getMimeType(filePath) {
|
|
35
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
36
|
+
const mimeTypes = {
|
|
37
|
+
'.png': 'image/png',
|
|
38
|
+
'.jpg': 'image/jpeg',
|
|
39
|
+
'.jpeg': 'image/jpeg',
|
|
40
|
+
'.gif': 'image/gif',
|
|
41
|
+
'.webp': 'image/webp',
|
|
42
|
+
'.bmp': 'image/bmp',
|
|
43
|
+
'.svg': 'image/svg+xml'
|
|
44
|
+
};
|
|
45
|
+
return mimeTypes[ext] || 'application/octet-stream';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get file information including line count
|
|
49
|
+
*/
|
|
50
|
+
export async function getFileInfo(filePath) {
|
|
51
|
+
try {
|
|
52
|
+
// Try multiple path resolutions in order of preference
|
|
53
|
+
const pathsToTry = [
|
|
54
|
+
filePath, // Original path as provided
|
|
55
|
+
path.resolve(process.cwd(), filePath), // Relative to current working directory
|
|
56
|
+
path.resolve(filePath), // Absolute resolution
|
|
57
|
+
];
|
|
58
|
+
// Remove duplicates while preserving order
|
|
59
|
+
const uniquePaths = [...new Set(pathsToTry)];
|
|
60
|
+
let actualPath = filePath;
|
|
61
|
+
let exists = false;
|
|
62
|
+
// Try each path until we find one that exists
|
|
63
|
+
for (const tryPath of uniquePaths) {
|
|
64
|
+
if (fs.existsSync(tryPath)) {
|
|
65
|
+
actualPath = tryPath;
|
|
66
|
+
exists = true;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Check if it's an image file
|
|
71
|
+
const isImage = isImageFile(actualPath);
|
|
72
|
+
let imageData;
|
|
73
|
+
let mimeType;
|
|
74
|
+
let lineCount = 0;
|
|
75
|
+
if (exists) {
|
|
76
|
+
if (isImage) {
|
|
77
|
+
// Read image as base64
|
|
78
|
+
const buffer = fs.readFileSync(actualPath);
|
|
79
|
+
const base64 = buffer.toString('base64');
|
|
80
|
+
mimeType = getMimeType(actualPath);
|
|
81
|
+
imageData = `data:${mimeType};base64,${base64}`;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
lineCount = await getFileLineCount(actualPath);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
path: filePath, // Keep original path for display
|
|
89
|
+
lineCount,
|
|
90
|
+
exists,
|
|
91
|
+
isImage,
|
|
92
|
+
imageData,
|
|
93
|
+
mimeType
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
path: filePath,
|
|
99
|
+
lineCount: 0,
|
|
100
|
+
exists: false
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Format file tree display for messages
|
|
106
|
+
*/
|
|
107
|
+
export function formatFileTree(files) {
|
|
108
|
+
if (files.length === 0)
|
|
109
|
+
return '';
|
|
110
|
+
return files.map(file => `└─ Read \`${file.path}\`${file.exists ? ` (total line ${file.lineCount})` : ' (file not found)'}`).join('\n');
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Parse @file references from message content and check if they exist
|
|
114
|
+
* Also supports direct file paths (pasted from VSCode drag & drop)
|
|
115
|
+
*/
|
|
116
|
+
export async function parseAndValidateFileReferences(content) {
|
|
117
|
+
const foundFiles = [];
|
|
118
|
+
// Pattern 1: @file references (e.g., @path/to/file.ts)
|
|
119
|
+
const atFileRegex = /@([A-Za-z0-9\-._/\\:]+\.[a-zA-Z]+)(?=\s|$)/g;
|
|
120
|
+
let match;
|
|
121
|
+
while ((match = atFileRegex.exec(content)) !== null) {
|
|
122
|
+
if (match[1]) {
|
|
123
|
+
foundFiles.push(match[1]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Pattern 2: Direct absolute/relative paths (e.g., c:\Users\...\file.ts or ./src/file.ts)
|
|
127
|
+
// Match paths that look like file paths with extensions, but NOT @-prefixed ones
|
|
128
|
+
const directPathRegex = /(?<!@)(?:^|\s)((?:[a-zA-Z]:[\\\/]|\.{1,2}[\\\/]|[\\\/])(?:[A-Za-z0-9\-._/\\:()[\] ]+)\.[a-zA-Z]+)(?=\s|$)/g;
|
|
129
|
+
while ((match = directPathRegex.exec(content)) !== null) {
|
|
130
|
+
if (match[1]) {
|
|
131
|
+
const trimmedPath = match[1].trim();
|
|
132
|
+
// Only add if it looks like a real file path
|
|
133
|
+
if (trimmedPath && !foundFiles.includes(trimmedPath)) {
|
|
134
|
+
foundFiles.push(trimmedPath);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Remove duplicates
|
|
139
|
+
const uniqueFiles = [...new Set(foundFiles)];
|
|
140
|
+
// Check which files actually exist
|
|
141
|
+
const fileInfos = await Promise.all(uniqueFiles.map(async (filePath) => {
|
|
142
|
+
const info = await getFileInfo(filePath);
|
|
143
|
+
return info;
|
|
144
|
+
}));
|
|
145
|
+
// Filter only existing files
|
|
146
|
+
const validFiles = fileInfos.filter(file => file.exists);
|
|
147
|
+
// Clean content - keep paths as user typed them
|
|
148
|
+
const cleanContent = content;
|
|
149
|
+
return {
|
|
150
|
+
cleanContent,
|
|
151
|
+
validFiles
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create message with file read instructions for AI
|
|
156
|
+
*/
|
|
157
|
+
export function createMessageWithFileInstructions(content, files, systemInfo) {
|
|
158
|
+
const parts = [content];
|
|
159
|
+
// Add system info if provided
|
|
160
|
+
if (systemInfo) {
|
|
161
|
+
const systemInfoLines = [
|
|
162
|
+
`└─ Platform: ${systemInfo.platform}`,
|
|
163
|
+
`└─ Shell: ${systemInfo.shell}`,
|
|
164
|
+
`└─ Working Directory: ${systemInfo.workingDirectory}`
|
|
165
|
+
];
|
|
166
|
+
parts.push(systemInfoLines.join('\n'));
|
|
167
|
+
}
|
|
168
|
+
// Add file instructions if provided
|
|
169
|
+
if (files.length > 0) {
|
|
170
|
+
const fileInstructions = files
|
|
171
|
+
.map(f => `└─ Read \`${f.path}\` (total line ${f.lineCount})`)
|
|
172
|
+
.join('\n');
|
|
173
|
+
parts.push(fileInstructions);
|
|
174
|
+
}
|
|
175
|
+
return parts.join('\n');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get system information (OS, shell, working directory)
|
|
179
|
+
*/
|
|
180
|
+
export function getSystemInfo() {
|
|
181
|
+
// Get OS platform
|
|
182
|
+
const platform = (() => {
|
|
183
|
+
const platformType = os.platform();
|
|
184
|
+
switch (platformType) {
|
|
185
|
+
case 'win32':
|
|
186
|
+
return 'Windows';
|
|
187
|
+
case 'darwin':
|
|
188
|
+
return 'macOS';
|
|
189
|
+
case 'linux':
|
|
190
|
+
return 'Linux';
|
|
191
|
+
default:
|
|
192
|
+
return platformType;
|
|
193
|
+
}
|
|
194
|
+
})();
|
|
195
|
+
// Get shell type
|
|
196
|
+
const shell = (() => {
|
|
197
|
+
const shellPath = process.env['SHELL'] || process.env['ComSpec'] || '';
|
|
198
|
+
const shellName = path.basename(shellPath).toLowerCase();
|
|
199
|
+
if (shellName.includes('cmd'))
|
|
200
|
+
return 'cmd.exe';
|
|
201
|
+
if (shellName.includes('powershell'))
|
|
202
|
+
return 'PowerShell';
|
|
203
|
+
if (shellName.includes('pwsh'))
|
|
204
|
+
return 'PowerShell';
|
|
205
|
+
if (shellName.includes('zsh'))
|
|
206
|
+
return 'zsh';
|
|
207
|
+
if (shellName.includes('bash'))
|
|
208
|
+
return 'bash';
|
|
209
|
+
if (shellName.includes('fish'))
|
|
210
|
+
return 'fish';
|
|
211
|
+
if (shellName.includes('sh'))
|
|
212
|
+
return 'sh';
|
|
213
|
+
return shellName || 'shell';
|
|
214
|
+
})();
|
|
215
|
+
// Get working directory
|
|
216
|
+
const workingDirectory = process.cwd();
|
|
217
|
+
return {
|
|
218
|
+
platform,
|
|
219
|
+
shell,
|
|
220
|
+
workingDirectory
|
|
221
|
+
};
|
|
222
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { Command } from '../types/index.js';
|
|
2
|
+
import './commands/clear.js';
|
|
3
|
+
import './commands/resume.js';
|
|
4
|
+
export { Logger, LogLevel, logger } from './logger.js';
|
|
5
|
+
export { default as defaultLogger } from './logger.js';
|
|
2
6
|
export declare function formatCommand(command: Command): string;
|
|
3
7
|
export declare function parseInput(input: string): {
|
|
4
8
|
command: string;
|
package/dist/utils/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
// Import commands to register them
|
|
2
|
+
import './commands/clear.js';
|
|
3
|
+
import './commands/resume.js';
|
|
4
|
+
// Export logger
|
|
5
|
+
export { Logger, LogLevel, logger } from './logger.js';
|
|
6
|
+
export { default as defaultLogger } from './logger.js';
|
|
1
7
|
export function formatCommand(command) {
|
|
2
8
|
return `${command.name.padEnd(12)} ${command.description}`;
|
|
3
9
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare enum LogLevel {
|
|
2
|
+
ERROR = 0,
|
|
3
|
+
WARN = 1,
|
|
4
|
+
INFO = 2,
|
|
5
|
+
DEBUG = 3
|
|
6
|
+
}
|
|
7
|
+
export interface LoggerConfig {
|
|
8
|
+
logDir?: string;
|
|
9
|
+
maxFileSize?: number;
|
|
10
|
+
dateFormat?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class Logger {
|
|
13
|
+
private readonly logDir;
|
|
14
|
+
private readonly maxFileSize;
|
|
15
|
+
constructor(config?: LoggerConfig);
|
|
16
|
+
private ensureLogDirectory;
|
|
17
|
+
private formatDate;
|
|
18
|
+
private formatTimestamp;
|
|
19
|
+
private getLogFilePath;
|
|
20
|
+
private shouldRotateLog;
|
|
21
|
+
private rotateLog;
|
|
22
|
+
private writeLog;
|
|
23
|
+
error(message: string, meta?: any): void;
|
|
24
|
+
warn(message: string, meta?: any): void;
|
|
25
|
+
info(message: string, meta?: any): void;
|
|
26
|
+
debug(message: string, meta?: any): void;
|
|
27
|
+
log(level: LogLevel, message: string, meta?: any): void;
|
|
28
|
+
}
|
|
29
|
+
declare const defaultLogger: Logger;
|
|
30
|
+
export default defaultLogger;
|
|
31
|
+
export { defaultLogger as logger };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
export var LogLevel;
|
|
5
|
+
(function (LogLevel) {
|
|
6
|
+
LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
|
|
7
|
+
LogLevel[LogLevel["WARN"] = 1] = "WARN";
|
|
8
|
+
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
|
9
|
+
LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
|
|
10
|
+
})(LogLevel || (LogLevel = {}));
|
|
11
|
+
export class Logger {
|
|
12
|
+
constructor(config = {}) {
|
|
13
|
+
Object.defineProperty(this, "logDir", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: void 0
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "maxFileSize", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: void 0
|
|
24
|
+
});
|
|
25
|
+
this.logDir = config.logDir || path.join(homedir(), '.snow', 'log');
|
|
26
|
+
this.maxFileSize = config.maxFileSize || 10 * 1024 * 1024; // 10MB
|
|
27
|
+
this.ensureLogDirectory();
|
|
28
|
+
}
|
|
29
|
+
ensureLogDirectory() {
|
|
30
|
+
if (!fs.existsSync(this.logDir)) {
|
|
31
|
+
fs.mkdirSync(this.logDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
formatDate(date) {
|
|
35
|
+
const year = date.getFullYear();
|
|
36
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
37
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
38
|
+
return `${year}-${month}-${day}`;
|
|
39
|
+
}
|
|
40
|
+
formatTimestamp(date) {
|
|
41
|
+
return date.toISOString();
|
|
42
|
+
}
|
|
43
|
+
getLogFilePath(level) {
|
|
44
|
+
const dateString = this.formatDate(new Date());
|
|
45
|
+
const levelName = LogLevel[level].toLowerCase();
|
|
46
|
+
return path.join(this.logDir, `${dateString}-${levelName}.log`);
|
|
47
|
+
}
|
|
48
|
+
shouldRotateLog(filePath) {
|
|
49
|
+
if (!fs.existsSync(filePath)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
const stats = fs.statSync(filePath);
|
|
53
|
+
return stats.size >= this.maxFileSize;
|
|
54
|
+
}
|
|
55
|
+
rotateLog(filePath) {
|
|
56
|
+
const timestamp = Date.now();
|
|
57
|
+
const ext = path.extname(filePath);
|
|
58
|
+
const basename = path.basename(filePath, ext);
|
|
59
|
+
const dirname = path.dirname(filePath);
|
|
60
|
+
const rotatedPath = path.join(dirname, `${basename}-${timestamp}${ext}`);
|
|
61
|
+
fs.renameSync(filePath, rotatedPath);
|
|
62
|
+
}
|
|
63
|
+
writeLog(level, message, meta) {
|
|
64
|
+
const timestamp = this.formatTimestamp(new Date());
|
|
65
|
+
const levelName = LogLevel[level].toUpperCase().padEnd(5);
|
|
66
|
+
const logEntry = {
|
|
67
|
+
timestamp,
|
|
68
|
+
level: levelName.trim(),
|
|
69
|
+
message,
|
|
70
|
+
...(meta && { meta }),
|
|
71
|
+
};
|
|
72
|
+
const logLine = JSON.stringify(logEntry) + '\n';
|
|
73
|
+
const filePath = this.getLogFilePath(level);
|
|
74
|
+
if (this.shouldRotateLog(filePath)) {
|
|
75
|
+
this.rotateLog(filePath);
|
|
76
|
+
}
|
|
77
|
+
fs.appendFileSync(filePath, logLine, 'utf8');
|
|
78
|
+
}
|
|
79
|
+
error(message, meta) {
|
|
80
|
+
this.writeLog(LogLevel.ERROR, message, meta);
|
|
81
|
+
}
|
|
82
|
+
warn(message, meta) {
|
|
83
|
+
this.writeLog(LogLevel.WARN, message, meta);
|
|
84
|
+
}
|
|
85
|
+
info(message, meta) {
|
|
86
|
+
this.writeLog(LogLevel.INFO, message, meta);
|
|
87
|
+
}
|
|
88
|
+
debug(message, meta) {
|
|
89
|
+
this.writeLog(LogLevel.DEBUG, message, meta);
|
|
90
|
+
}
|
|
91
|
+
log(level, message, meta) {
|
|
92
|
+
this.writeLog(level, message, meta);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const defaultLogger = new Logger();
|
|
96
|
+
export default defaultLogger;
|
|
97
|
+
export { defaultLogger as logger };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { TodoService } from '../mcp/todo.js';
|
|
2
|
+
export interface MCPTool {
|
|
3
|
+
type: "function";
|
|
4
|
+
function: {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
parameters: any;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface MCPServiceTools {
|
|
11
|
+
serviceName: string;
|
|
12
|
+
tools: Array<{
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: any;
|
|
16
|
+
}>;
|
|
17
|
+
isBuiltIn: boolean;
|
|
18
|
+
connected: boolean;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get the TODO service instance
|
|
23
|
+
*/
|
|
24
|
+
export declare function getTodoService(): TodoService;
|
|
25
|
+
/**
|
|
26
|
+
* Manually refresh the tools cache (for configuration changes)
|
|
27
|
+
*/
|
|
28
|
+
export declare function refreshMCPToolsCache(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Clear the tools cache (useful for testing or forcing refresh)
|
|
31
|
+
*/
|
|
32
|
+
export declare function clearMCPToolsCache(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Collect all available MCP tools from built-in and user-configured services
|
|
35
|
+
* Uses caching to avoid reconnecting on every message
|
|
36
|
+
*/
|
|
37
|
+
export declare function collectAllMCPTools(): Promise<MCPTool[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Get detailed information about all MCP services and their tools
|
|
40
|
+
* Uses cached data when available
|
|
41
|
+
*/
|
|
42
|
+
export declare function getMCPServicesInfo(): Promise<MCPServiceTools[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Execute an MCP tool by parsing the prefixed tool name
|
|
45
|
+
* Only connects to the service when actually needed
|
|
46
|
+
*/
|
|
47
|
+
export declare function executeMCPTool(toolName: string, args: any): Promise<any>;
|