snow-ai 0.1.12 → 0.2.2
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 +38 -2
- 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,141 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import { randomUUID } from 'crypto';
|
|
5
|
+
class SessionManager {
|
|
6
|
+
constructor() {
|
|
7
|
+
Object.defineProperty(this, "sessionsDir", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: void 0
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(this, "currentSession", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: null
|
|
18
|
+
});
|
|
19
|
+
this.sessionsDir = path.join(os.homedir(), '.snow', 'sessions');
|
|
20
|
+
}
|
|
21
|
+
async ensureSessionsDir() {
|
|
22
|
+
try {
|
|
23
|
+
await fs.mkdir(this.sessionsDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
// Directory already exists or other error
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
getSessionPath(sessionId) {
|
|
30
|
+
return path.join(this.sessionsDir, `${sessionId}.json`);
|
|
31
|
+
}
|
|
32
|
+
async createNewSession() {
|
|
33
|
+
await this.ensureSessionsDir();
|
|
34
|
+
// 使用 UUID v4 生成唯一会话 ID,避免并发冲突
|
|
35
|
+
const sessionId = randomUUID();
|
|
36
|
+
const session = {
|
|
37
|
+
id: sessionId,
|
|
38
|
+
title: 'New Chat',
|
|
39
|
+
summary: '',
|
|
40
|
+
createdAt: Date.now(),
|
|
41
|
+
updatedAt: Date.now(),
|
|
42
|
+
messages: [],
|
|
43
|
+
messageCount: 0
|
|
44
|
+
};
|
|
45
|
+
this.currentSession = session;
|
|
46
|
+
await this.saveSession(session);
|
|
47
|
+
return session;
|
|
48
|
+
}
|
|
49
|
+
async saveSession(session) {
|
|
50
|
+
await this.ensureSessionsDir();
|
|
51
|
+
const sessionPath = this.getSessionPath(session.id);
|
|
52
|
+
await fs.writeFile(sessionPath, JSON.stringify(session, null, 2));
|
|
53
|
+
}
|
|
54
|
+
async loadSession(sessionId) {
|
|
55
|
+
try {
|
|
56
|
+
const sessionPath = this.getSessionPath(sessionId);
|
|
57
|
+
const data = await fs.readFile(sessionPath, 'utf-8');
|
|
58
|
+
const session = JSON.parse(data);
|
|
59
|
+
this.currentSession = session;
|
|
60
|
+
return session;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async listSessions() {
|
|
67
|
+
await this.ensureSessionsDir();
|
|
68
|
+
try {
|
|
69
|
+
const files = await fs.readdir(this.sessionsDir);
|
|
70
|
+
const sessions = [];
|
|
71
|
+
for (const file of files) {
|
|
72
|
+
if (file.endsWith('.json')) {
|
|
73
|
+
try {
|
|
74
|
+
const sessionPath = path.join(this.sessionsDir, file);
|
|
75
|
+
const data = await fs.readFile(sessionPath, 'utf-8');
|
|
76
|
+
const session = JSON.parse(data);
|
|
77
|
+
sessions.push({
|
|
78
|
+
id: session.id,
|
|
79
|
+
title: session.title,
|
|
80
|
+
summary: session.summary,
|
|
81
|
+
createdAt: session.createdAt,
|
|
82
|
+
updatedAt: session.updatedAt,
|
|
83
|
+
messageCount: session.messageCount
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
// Skip invalid session files
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Sort by updatedAt (newest first)
|
|
93
|
+
return sessions.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async addMessage(message) {
|
|
100
|
+
if (!this.currentSession) {
|
|
101
|
+
this.currentSession = await this.createNewSession();
|
|
102
|
+
}
|
|
103
|
+
// Check if this exact message already exists to prevent duplicates
|
|
104
|
+
const existingMessage = this.currentSession.messages.find(m => m.role === message.role &&
|
|
105
|
+
m.content === message.content &&
|
|
106
|
+
Math.abs(m.timestamp - message.timestamp) < 5000 // Within 5 seconds
|
|
107
|
+
);
|
|
108
|
+
if (existingMessage) {
|
|
109
|
+
return; // Don't add duplicate message
|
|
110
|
+
}
|
|
111
|
+
this.currentSession.messages.push(message);
|
|
112
|
+
this.currentSession.messageCount = this.currentSession.messages.length;
|
|
113
|
+
this.currentSession.updatedAt = Date.now();
|
|
114
|
+
// Simple title generation from first user message (no API call)
|
|
115
|
+
if (this.currentSession.messageCount === 1 && message.role === 'user') {
|
|
116
|
+
this.currentSession.title = message.content.slice(0, 50);
|
|
117
|
+
this.currentSession.summary = message.content.slice(0, 100);
|
|
118
|
+
}
|
|
119
|
+
await this.saveSession(this.currentSession);
|
|
120
|
+
}
|
|
121
|
+
getCurrentSession() {
|
|
122
|
+
return this.currentSession;
|
|
123
|
+
}
|
|
124
|
+
setCurrentSession(session) {
|
|
125
|
+
this.currentSession = session;
|
|
126
|
+
}
|
|
127
|
+
clearCurrentSession() {
|
|
128
|
+
this.currentSession = null;
|
|
129
|
+
}
|
|
130
|
+
async deleteSession(sessionId) {
|
|
131
|
+
try {
|
|
132
|
+
const sessionPath = this.getSessionPath(sessionId);
|
|
133
|
+
await fs.unlink(sessionPath);
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export const sessionManager = new SessionManager();
|
|
@@ -5,19 +5,30 @@ export interface Viewport {
|
|
|
5
5
|
export interface PastePlaceholder {
|
|
6
6
|
id: string;
|
|
7
7
|
content: string;
|
|
8
|
-
|
|
8
|
+
charCount: number;
|
|
9
|
+
index: number;
|
|
10
|
+
placeholder: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ImageData {
|
|
13
|
+
id: string;
|
|
14
|
+
data: string;
|
|
15
|
+
mimeType: string;
|
|
9
16
|
index: number;
|
|
10
17
|
placeholder: string;
|
|
11
18
|
}
|
|
12
19
|
export declare class TextBuffer {
|
|
13
|
-
private
|
|
14
|
-
private
|
|
15
|
-
private cursorCol;
|
|
20
|
+
private content;
|
|
21
|
+
private cursorIndex;
|
|
16
22
|
private viewport;
|
|
17
|
-
private pendingUpdates;
|
|
18
23
|
private pasteStorage;
|
|
19
24
|
private pasteCounter;
|
|
20
25
|
private lastPasteTime;
|
|
26
|
+
private imageStorage;
|
|
27
|
+
private imageCounter;
|
|
28
|
+
private visualLines;
|
|
29
|
+
private visualLineStarts;
|
|
30
|
+
private visualCursorPos;
|
|
31
|
+
private preferredVisualCol;
|
|
21
32
|
constructor(viewport: Viewport);
|
|
22
33
|
get text(): string;
|
|
23
34
|
/**
|
|
@@ -25,13 +36,13 @@ export declare class TextBuffer {
|
|
|
25
36
|
*/
|
|
26
37
|
getFullText(): string;
|
|
27
38
|
get visualCursor(): [number, number];
|
|
39
|
+
getCursorPosition(): number;
|
|
28
40
|
get viewportVisualLines(): string[];
|
|
29
41
|
get maxWidth(): number;
|
|
30
|
-
private getCurrentLine;
|
|
31
42
|
private scheduleUpdate;
|
|
32
43
|
setText(text: string): void;
|
|
33
44
|
insert(input: string): void;
|
|
34
|
-
private
|
|
45
|
+
private insertPlainText;
|
|
35
46
|
backspace(): void;
|
|
36
47
|
delete(): void;
|
|
37
48
|
moveLeft(): void;
|
|
@@ -49,4 +60,22 @@ export declare class TextBuffer {
|
|
|
49
60
|
char: string;
|
|
50
61
|
isWideChar: boolean;
|
|
51
62
|
};
|
|
63
|
+
private clampCursorIndex;
|
|
64
|
+
private recalculateVisualState;
|
|
65
|
+
private wrapLineToWidth;
|
|
66
|
+
private computeVisualCursorFromIndex;
|
|
67
|
+
private moveCursorToVisualRow;
|
|
68
|
+
private recomputeVisualCursorOnly;
|
|
69
|
+
/**
|
|
70
|
+
* 插入图片数据
|
|
71
|
+
*/
|
|
72
|
+
insertImage(base64Data: string, mimeType: string): void;
|
|
73
|
+
/**
|
|
74
|
+
* 获取所有图片数据
|
|
75
|
+
*/
|
|
76
|
+
getImages(): ImageData[];
|
|
77
|
+
/**
|
|
78
|
+
* 清除所有图片
|
|
79
|
+
*/
|
|
80
|
+
clearImages(): void;
|
|
52
81
|
}
|