snow-ai 0.2.25 → 0.2.27
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/systemPrompt.d.ts +1 -1
- package/dist/api/systemPrompt.js +39 -17
- package/dist/cli.js +8 -0
- package/dist/hooks/useClipboard.js +4 -4
- package/dist/hooks/useKeyboardInput.d.ts +1 -0
- package/dist/hooks/useKeyboardInput.js +8 -4
- package/dist/hooks/useTerminalFocus.d.ts +5 -0
- package/dist/hooks/useTerminalFocus.js +22 -2
- package/dist/mcp/aceCodeSearch.d.ts +58 -4
- package/dist/mcp/aceCodeSearch.js +563 -20
- package/dist/mcp/filesystem.d.ts +36 -29
- package/dist/mcp/filesystem.js +288 -123
- package/dist/mcp/ideDiagnostics.d.ts +36 -0
- package/dist/mcp/ideDiagnostics.js +92 -0
- package/dist/ui/components/ChatInput.js +6 -3
- package/dist/ui/pages/ConfigProfileScreen.d.ts +7 -0
- package/dist/ui/pages/ConfigProfileScreen.js +300 -0
- package/dist/ui/pages/ConfigScreen.js +228 -29
- package/dist/ui/pages/WelcomeScreen.js +1 -1
- package/dist/utils/apiConfig.js +12 -0
- package/dist/utils/configManager.d.ts +45 -0
- package/dist/utils/configManager.js +274 -0
- package/dist/utils/contextCompressor.js +0 -8
- package/dist/utils/escapeHandler.d.ts +79 -0
- package/dist/utils/escapeHandler.js +153 -0
- package/dist/utils/incrementalSnapshot.js +2 -1
- package/dist/utils/mcpToolsManager.js +44 -0
- package/dist/utils/textBuffer.js +13 -15
- package/dist/utils/vscodeConnection.js +26 -11
- package/dist/utils/workspaceSnapshot.js +2 -1
- package/package.json +2 -1
package/dist/utils/textBuffer.js
CHANGED
|
@@ -4,21 +4,16 @@ import { cpLen, cpSlice, visualWidth, toCodePoints } from './textUtils.js';
|
|
|
4
4
|
*/
|
|
5
5
|
function sanitizeInput(str) {
|
|
6
6
|
// Replace problematic characters but preserve basic formatting
|
|
7
|
-
return str
|
|
7
|
+
return (str
|
|
8
8
|
.replace(/\r\n/g, '\n') // Normalize line endings
|
|
9
9
|
.replace(/\r/g, '\n') // Convert remaining \r to \n
|
|
10
10
|
.replace(/\t/g, ' ') // Convert tabs to spaces
|
|
11
|
-
// Remove focus events
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
.replace(
|
|
15
|
-
// Also remove standalone [I and [O if they appear at word boundaries
|
|
16
|
-
// This catches cases where escape sequences arrive fragmented
|
|
17
|
-
// But we preserve legitimate text like "FOO[I]BAR" or "[Inside]"
|
|
18
|
-
.replace(/(?:^|\s)\[I(?:\s|$)/g, ' ')
|
|
19
|
-
.replace(/(?:^|\s)\[O(?:\s|$)/g, ' ')
|
|
11
|
+
// Remove focus events emitted during terminal focus changes
|
|
12
|
+
.replace(/\x1b\[[IO]/g, '')
|
|
13
|
+
// Remove stray [I/[O] tokens that precede drag-and-drop payloads
|
|
14
|
+
.replace(/(^|\s+)\[(?:I|O)(?=(?:\s|$|["'~\\\/]|[A-Za-z]:))/g, '$1')
|
|
20
15
|
// Remove control characters except newlines
|
|
21
|
-
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
|
|
16
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ''));
|
|
22
17
|
}
|
|
23
18
|
export class TextBuffer {
|
|
24
19
|
constructor(viewport, onUpdate) {
|
|
@@ -145,7 +140,9 @@ export class TextBuffer {
|
|
|
145
140
|
let fullText = this.content;
|
|
146
141
|
for (const placeholder of this.pasteStorage.values()) {
|
|
147
142
|
if (placeholder.placeholder) {
|
|
148
|
-
fullText = fullText
|
|
143
|
+
fullText = fullText
|
|
144
|
+
.split(placeholder.placeholder)
|
|
145
|
+
.join(placeholder.content);
|
|
149
146
|
}
|
|
150
147
|
}
|
|
151
148
|
return fullText;
|
|
@@ -258,7 +255,7 @@ export class TextBuffer {
|
|
|
258
255
|
content: this.pasteAccumulator,
|
|
259
256
|
charCount: totalChars,
|
|
260
257
|
index: this.pasteCounter,
|
|
261
|
-
placeholder: placeholderText
|
|
258
|
+
placeholder: placeholderText,
|
|
262
259
|
});
|
|
263
260
|
// 在记录的位置插入占位符
|
|
264
261
|
const before = cpSlice(this.content, 0, this.pastePlaceholderPosition);
|
|
@@ -271,7 +268,8 @@ export class TextBuffer {
|
|
|
271
268
|
const before = cpSlice(this.content, 0, this.pastePlaceholderPosition);
|
|
272
269
|
const after = cpSlice(this.content, this.pastePlaceholderPosition);
|
|
273
270
|
this.content = before + this.pasteAccumulator + after;
|
|
274
|
-
this.cursorIndex =
|
|
271
|
+
this.cursorIndex =
|
|
272
|
+
this.pastePlaceholderPosition + cpLen(this.pasteAccumulator);
|
|
275
273
|
}
|
|
276
274
|
// 清理状态
|
|
277
275
|
this.pasteAccumulator = '';
|
|
@@ -501,7 +499,7 @@ export class TextBuffer {
|
|
|
501
499
|
data: base64Data,
|
|
502
500
|
mimeType: mimeType,
|
|
503
501
|
index: this.imageCounter,
|
|
504
|
-
placeholder: placeholderText
|
|
502
|
+
placeholder: placeholderText,
|
|
505
503
|
});
|
|
506
504
|
this.insertPlainText(placeholderText);
|
|
507
505
|
this.scheduleUpdate();
|
|
@@ -280,16 +280,21 @@ class VSCodeConnectionManager {
|
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
282
|
const requestId = Math.random().toString(36).substring(7);
|
|
283
|
+
let isResolved = false;
|
|
283
284
|
const timeout = setTimeout(() => {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
if (!isResolved) {
|
|
286
|
+
cleanup();
|
|
287
|
+
resolve([]); // Timeout, return empty array
|
|
288
|
+
}
|
|
289
|
+
}, 2000); // Reduce timeout from 5s to 2s to avoid long blocking
|
|
287
290
|
const handler = (message) => {
|
|
288
291
|
try {
|
|
289
292
|
const data = JSON.parse(message.toString());
|
|
290
293
|
if (data.type === 'diagnostics' && data.requestId === requestId) {
|
|
291
|
-
|
|
292
|
-
|
|
294
|
+
if (!isResolved) {
|
|
295
|
+
cleanup();
|
|
296
|
+
resolve(data.diagnostics || []);
|
|
297
|
+
}
|
|
293
298
|
}
|
|
294
299
|
}
|
|
295
300
|
catch (error) {
|
|
@@ -297,15 +302,25 @@ class VSCodeConnectionManager {
|
|
|
297
302
|
}
|
|
298
303
|
};
|
|
299
304
|
const cleanup = () => {
|
|
305
|
+
isResolved = true;
|
|
300
306
|
clearTimeout(timeout);
|
|
301
|
-
this.client
|
|
307
|
+
if (this.client) {
|
|
308
|
+
this.client.off('message', handler);
|
|
309
|
+
}
|
|
302
310
|
};
|
|
303
311
|
this.client.on('message', handler);
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
312
|
+
// Add error handling for send operation
|
|
313
|
+
try {
|
|
314
|
+
this.client.send(JSON.stringify({
|
|
315
|
+
type: 'getDiagnostics',
|
|
316
|
+
requestId,
|
|
317
|
+
filePath,
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
cleanup();
|
|
322
|
+
resolve([]); // If send fails, return empty array
|
|
323
|
+
}
|
|
309
324
|
});
|
|
310
325
|
}
|
|
311
326
|
/**
|
|
@@ -2,6 +2,7 @@ import fs from 'fs/promises';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import crypto from 'crypto';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
5
6
|
/**
|
|
6
7
|
* Workspace Snapshot Manager
|
|
7
8
|
* Provides git-like version control for workspace files
|
|
@@ -196,7 +197,7 @@ class WorkspaceSnapshotManager {
|
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
catch (error) {
|
|
199
|
-
|
|
200
|
+
logger.error('Failed to list snapshots:', error);
|
|
200
201
|
}
|
|
201
202
|
return snapshots.sort((a, b) => b.messageIndex - a.messageIndex);
|
|
202
203
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snow-ai",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.27",
|
|
4
4
|
"description": "Intelligent Command Line Assistant powered by AI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"cli-highlight": "^2.1.11",
|
|
48
48
|
"diff": "^8.0.2",
|
|
49
49
|
"figlet": "^1.8.2",
|
|
50
|
+
"fzf": "^0.5.2",
|
|
50
51
|
"https-proxy-agent": "^7.0.6",
|
|
51
52
|
"ink": "^5.2.1",
|
|
52
53
|
"ink-gradient": "^3.0.0",
|