@kirosnn/mosaic 0.0.91 → 0.73.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.
- package/LICENSE +1 -1
- package/README.md +2 -6
- package/package.json +55 -48
- package/src/agent/Agent.ts +353 -131
- package/src/agent/context.ts +4 -4
- package/src/agent/prompts/systemPrompt.ts +209 -70
- package/src/agent/prompts/toolsPrompt.ts +285 -138
- package/src/agent/provider/anthropic.ts +109 -105
- package/src/agent/provider/google.ts +111 -107
- package/src/agent/provider/mistral.ts +95 -95
- package/src/agent/provider/ollama.ts +73 -17
- package/src/agent/provider/openai.ts +146 -102
- package/src/agent/provider/rateLimit.ts +178 -0
- package/src/agent/provider/reasoning.ts +29 -0
- package/src/agent/provider/xai.ts +108 -104
- package/src/agent/tools/definitions.ts +15 -1
- package/src/agent/tools/executor.ts +717 -98
- package/src/agent/tools/exploreExecutor.ts +20 -22
- package/src/agent/tools/fetch.ts +58 -0
- package/src/agent/tools/glob.ts +20 -4
- package/src/agent/tools/grep.ts +64 -9
- package/src/agent/tools/plan.ts +27 -0
- package/src/agent/tools/question.ts +7 -1
- package/src/agent/tools/read.ts +2 -0
- package/src/agent/types.ts +15 -14
- package/src/components/App.tsx +50 -8
- package/src/components/CustomInput.tsx +461 -77
- package/src/components/Main.tsx +1459 -1112
- package/src/components/Setup.tsx +1 -1
- package/src/components/ShortcutsModal.tsx +11 -8
- package/src/components/Welcome.tsx +1 -1
- package/src/components/main/ApprovalPanel.tsx +4 -3
- package/src/components/main/ChatPage.tsx +858 -516
- package/src/components/main/HomePage.tsx +58 -39
- package/src/components/main/QuestionPanel.tsx +52 -7
- package/src/components/main/ThinkingIndicator.tsx +13 -2
- package/src/components/main/types.ts +11 -10
- package/src/index.tsx +53 -25
- package/src/mcp/approvalPolicy.ts +148 -0
- package/src/mcp/cli/add.ts +185 -0
- package/src/mcp/cli/doctor.ts +77 -0
- package/src/mcp/cli/index.ts +85 -0
- package/src/mcp/cli/list.ts +50 -0
- package/src/mcp/cli/logs.ts +24 -0
- package/src/mcp/cli/manage.ts +99 -0
- package/src/mcp/cli/show.ts +53 -0
- package/src/mcp/cli/tools.ts +77 -0
- package/src/mcp/config.ts +223 -0
- package/src/mcp/index.ts +80 -0
- package/src/mcp/processManager.ts +299 -0
- package/src/mcp/rateLimiter.ts +50 -0
- package/src/mcp/registry.ts +151 -0
- package/src/mcp/schemaConverter.ts +100 -0
- package/src/mcp/servers/navigation.ts +854 -0
- package/src/mcp/toolCatalog.ts +169 -0
- package/src/mcp/types.ts +95 -0
- package/src/utils/approvalBridge.ts +45 -12
- package/src/utils/approvalModeBridge.ts +17 -0
- package/src/utils/commands/approvals.ts +48 -0
- package/src/utils/commands/compact.ts +30 -0
- package/src/utils/commands/echo.ts +1 -1
- package/src/utils/commands/image.ts +109 -0
- package/src/utils/commands/index.ts +9 -7
- package/src/utils/commands/new.ts +15 -0
- package/src/utils/commands/types.ts +3 -0
- package/src/utils/config.ts +3 -1
- package/src/utils/diffRendering.tsx +13 -16
- package/src/utils/exploreBridge.ts +10 -0
- package/src/utils/history.ts +82 -40
- package/src/utils/imageBridge.ts +28 -0
- package/src/utils/images.ts +31 -0
- package/src/utils/markdown.tsx +163 -99
- package/src/utils/models.ts +31 -16
- package/src/utils/notificationBridge.ts +23 -0
- package/src/utils/questionBridge.ts +36 -1
- package/src/utils/tokenEstimator.ts +32 -0
- package/src/utils/toolFormatting.ts +428 -48
- package/src/web/app.tsx +65 -5
- package/src/web/assets/css/ChatPage.css +102 -30
- package/src/web/assets/css/MessageItem.css +26 -29
- package/src/web/assets/css/ThinkingIndicator.css +44 -6
- package/src/web/assets/css/ToolMessage.css +36 -14
- package/src/web/components/ChatPage.tsx +228 -105
- package/src/web/components/HomePage.tsx +3 -3
- package/src/web/components/MessageItem.tsx +80 -81
- package/src/web/components/QuestionPanel.tsx +72 -12
- package/src/web/components/Setup.tsx +1 -1
- package/src/web/components/Sidebar.tsx +1 -3
- package/src/web/components/ThinkingIndicator.tsx +41 -21
- package/src/web/router.ts +1 -1
- package/src/web/server.tsx +894 -662
- package/src/web/storage.ts +23 -1
- package/src/web/types.ts +7 -6
- package/src/utils/commands/redo.ts +0 -74
- package/src/utils/commands/sessions.ts +0 -129
- package/src/utils/commands/undo.ts +0 -75
- package/src/utils/undoRedo.ts +0 -429
- package/src/utils/undoRedoBridge.ts +0 -45
- package/src/utils/undoRedoDb.ts +0 -338
package/src/utils/undoRedoDb.ts
DELETED
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
import Database from 'bun:sqlite';
|
|
2
|
-
import { existsSync, mkdirSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
import type { Message } from '../components/main/types';
|
|
5
|
-
|
|
6
|
-
export interface FileSnapshot {
|
|
7
|
-
path: string;
|
|
8
|
-
content: string;
|
|
9
|
-
existed: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface UndoRedoState {
|
|
13
|
-
id: string;
|
|
14
|
-
timestamp: number;
|
|
15
|
-
messages: Message[];
|
|
16
|
-
gitCommitHash?: string;
|
|
17
|
-
fileSnapshots: FileSnapshot[];
|
|
18
|
-
useGit: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface Session {
|
|
22
|
-
id: string;
|
|
23
|
-
createdAt: number;
|
|
24
|
-
lastAccessedAt: number;
|
|
25
|
-
isCurrent: boolean;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
let db: Database | null = null;
|
|
29
|
-
|
|
30
|
-
function getWorkspaceMosaicDir(): string {
|
|
31
|
-
const workspace = process.cwd();
|
|
32
|
-
const mosaicDir = join(workspace, '.mosaic');
|
|
33
|
-
|
|
34
|
-
if (!existsSync(mosaicDir)) {
|
|
35
|
-
mkdirSync(mosaicDir, { recursive: true });
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return mosaicDir;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getDatabasePath(): string {
|
|
42
|
-
const mosaicDir = getWorkspaceMosaicDir();
|
|
43
|
-
return join(mosaicDir, 'undo-redo.db');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function getDatabase(): Database {
|
|
47
|
-
if (!db) {
|
|
48
|
-
const dbPath = getDatabasePath();
|
|
49
|
-
db = new Database(dbPath);
|
|
50
|
-
initializeDatabase(db);
|
|
51
|
-
}
|
|
52
|
-
return db;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function initializeDatabase(database: Database): void {
|
|
56
|
-
database.exec(`
|
|
57
|
-
CREATE TABLE IF NOT EXISTS sessions (
|
|
58
|
-
id TEXT PRIMARY KEY,
|
|
59
|
-
created_at INTEGER NOT NULL,
|
|
60
|
-
last_accessed_at INTEGER NOT NULL,
|
|
61
|
-
is_current INTEGER NOT NULL DEFAULT 0
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_current ON sessions(is_current);
|
|
65
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_last_accessed ON sessions(last_accessed_at);
|
|
66
|
-
|
|
67
|
-
CREATE TABLE IF NOT EXISTS undo_states (
|
|
68
|
-
id TEXT PRIMARY KEY,
|
|
69
|
-
session_id TEXT NOT NULL,
|
|
70
|
-
position INTEGER NOT NULL,
|
|
71
|
-
timestamp INTEGER NOT NULL,
|
|
72
|
-
messages TEXT NOT NULL,
|
|
73
|
-
git_commit_hash TEXT,
|
|
74
|
-
file_snapshots TEXT NOT NULL,
|
|
75
|
-
use_git INTEGER NOT NULL,
|
|
76
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
CREATE INDEX IF NOT EXISTS idx_undo_states_session ON undo_states(session_id, position);
|
|
80
|
-
|
|
81
|
-
CREATE TABLE IF NOT EXISTS redo_states (
|
|
82
|
-
id TEXT PRIMARY KEY,
|
|
83
|
-
session_id TEXT NOT NULL,
|
|
84
|
-
position INTEGER NOT NULL,
|
|
85
|
-
timestamp INTEGER NOT NULL,
|
|
86
|
-
messages TEXT NOT NULL,
|
|
87
|
-
git_commit_hash TEXT,
|
|
88
|
-
file_snapshots TEXT NOT NULL,
|
|
89
|
-
use_git INTEGER NOT NULL,
|
|
90
|
-
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
CREATE INDEX IF NOT EXISTS idx_redo_states_session ON redo_states(session_id, position);
|
|
94
|
-
`);
|
|
95
|
-
|
|
96
|
-
database.exec('PRAGMA journal_mode = WAL;');
|
|
97
|
-
database.exec('PRAGMA synchronous = NORMAL;');
|
|
98
|
-
database.exec('PRAGMA cache_size = -64000;');
|
|
99
|
-
database.exec('PRAGMA temp_store = MEMORY;');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function generateId(): string {
|
|
103
|
-
return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function createSession(): string {
|
|
107
|
-
const database = getDatabase();
|
|
108
|
-
const sessionId = generateId();
|
|
109
|
-
const now = Date.now();
|
|
110
|
-
|
|
111
|
-
database.exec('UPDATE sessions SET is_current = 0 WHERE is_current = 1');
|
|
112
|
-
|
|
113
|
-
const stmt = database.prepare(
|
|
114
|
-
'INSERT INTO sessions (id, created_at, last_accessed_at, is_current) VALUES (?, ?, ?, 1)'
|
|
115
|
-
);
|
|
116
|
-
stmt.run(sessionId, now, now);
|
|
117
|
-
|
|
118
|
-
return sessionId;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function getCurrentSession(): Session | null {
|
|
122
|
-
const database = getDatabase();
|
|
123
|
-
const stmt = database.prepare<Session, []>(
|
|
124
|
-
'SELECT id, created_at as createdAt, last_accessed_at as lastAccessedAt, is_current as isCurrent FROM sessions WHERE is_current = 1'
|
|
125
|
-
);
|
|
126
|
-
const row = stmt.get();
|
|
127
|
-
return row ? { ...row, isCurrent: Boolean(row.isCurrent) } : null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export function setCurrentSession(sessionId: string): void {
|
|
131
|
-
const database = getDatabase();
|
|
132
|
-
const now = Date.now();
|
|
133
|
-
|
|
134
|
-
database.exec('BEGIN TRANSACTION');
|
|
135
|
-
try {
|
|
136
|
-
database.exec('UPDATE sessions SET is_current = 0 WHERE is_current = 1');
|
|
137
|
-
|
|
138
|
-
const stmt = database.prepare(
|
|
139
|
-
'UPDATE sessions SET is_current = 1, last_accessed_at = ? WHERE id = ?'
|
|
140
|
-
);
|
|
141
|
-
stmt.run(now, sessionId);
|
|
142
|
-
|
|
143
|
-
database.exec('COMMIT');
|
|
144
|
-
} catch (error) {
|
|
145
|
-
database.exec('ROLLBACK');
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export function getAllSessions(): Session[] {
|
|
151
|
-
const database = getDatabase();
|
|
152
|
-
const stmt = database.prepare<Session, []>(
|
|
153
|
-
'SELECT id, created_at as createdAt, last_accessed_at as lastAccessedAt, is_current as isCurrent FROM sessions ORDER BY last_accessed_at DESC'
|
|
154
|
-
);
|
|
155
|
-
const rows = stmt.all();
|
|
156
|
-
return rows.map(row => ({ ...row, isCurrent: Boolean(row.isCurrent) }));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function deleteSession(sessionId: string): void {
|
|
160
|
-
const database = getDatabase();
|
|
161
|
-
const stmt = database.prepare('DELETE FROM sessions WHERE id = ?');
|
|
162
|
-
stmt.run(sessionId);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function cleanupOldSessions(daysToKeep: number = 7): number {
|
|
166
|
-
const database = getDatabase();
|
|
167
|
-
const cutoffTime = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);
|
|
168
|
-
|
|
169
|
-
const stmt = database.prepare(
|
|
170
|
-
'DELETE FROM sessions WHERE last_accessed_at < ? AND is_current = 0'
|
|
171
|
-
);
|
|
172
|
-
const result = stmt.run(cutoffTime);
|
|
173
|
-
|
|
174
|
-
return result.changes;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export function pushUndoState(sessionId: string, state: UndoRedoState): void {
|
|
178
|
-
const database = getDatabase();
|
|
179
|
-
|
|
180
|
-
const getMaxPos = database.prepare<{ maxPos: number | null }, [string]>(
|
|
181
|
-
'SELECT MAX(position) as maxPos FROM undo_states WHERE session_id = ?'
|
|
182
|
-
);
|
|
183
|
-
const maxPosResult = getMaxPos.get(sessionId);
|
|
184
|
-
const nextPosition = (maxPosResult?.maxPos ?? -1) + 1;
|
|
185
|
-
|
|
186
|
-
const stmt = database.prepare(
|
|
187
|
-
`INSERT INTO undo_states (id, session_id, position, timestamp, messages, git_commit_hash, file_snapshots, use_git)
|
|
188
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
stmt.run(
|
|
192
|
-
state.id,
|
|
193
|
-
sessionId,
|
|
194
|
-
nextPosition,
|
|
195
|
-
state.timestamp,
|
|
196
|
-
JSON.stringify(state.messages),
|
|
197
|
-
state.gitCommitHash || null,
|
|
198
|
-
JSON.stringify(state.fileSnapshots),
|
|
199
|
-
state.useGit ? 1 : 0
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export function popUndoState(sessionId: string): UndoRedoState | null {
|
|
204
|
-
const database = getDatabase();
|
|
205
|
-
|
|
206
|
-
database.exec('BEGIN TRANSACTION');
|
|
207
|
-
try {
|
|
208
|
-
const getStmt = database.prepare<any, [string]>(
|
|
209
|
-
`SELECT id, timestamp, messages, git_commit_hash, file_snapshots, use_git
|
|
210
|
-
FROM undo_states
|
|
211
|
-
WHERE session_id = ?
|
|
212
|
-
ORDER BY position DESC
|
|
213
|
-
LIMIT 1`
|
|
214
|
-
);
|
|
215
|
-
const row = getStmt.get(sessionId);
|
|
216
|
-
|
|
217
|
-
if (!row) {
|
|
218
|
-
database.exec('ROLLBACK');
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const deleteStmt = database.prepare(
|
|
223
|
-
'DELETE FROM undo_states WHERE id = ? AND session_id = ?'
|
|
224
|
-
);
|
|
225
|
-
deleteStmt.run(row.id, sessionId);
|
|
226
|
-
|
|
227
|
-
database.exec('COMMIT');
|
|
228
|
-
|
|
229
|
-
return {
|
|
230
|
-
id: row.id,
|
|
231
|
-
timestamp: row.timestamp,
|
|
232
|
-
messages: JSON.parse(row.messages),
|
|
233
|
-
gitCommitHash: row.git_commit_hash || undefined,
|
|
234
|
-
fileSnapshots: JSON.parse(row.file_snapshots),
|
|
235
|
-
useGit: Boolean(row.use_git)
|
|
236
|
-
};
|
|
237
|
-
} catch (error) {
|
|
238
|
-
database.exec('ROLLBACK');
|
|
239
|
-
throw error;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export function pushRedoState(sessionId: string, state: UndoRedoState): void {
|
|
244
|
-
const database = getDatabase();
|
|
245
|
-
|
|
246
|
-
const getMaxPos = database.prepare<{ maxPos: number | null }, [string]>(
|
|
247
|
-
'SELECT MAX(position) as maxPos FROM redo_states WHERE session_id = ?'
|
|
248
|
-
);
|
|
249
|
-
const maxPosResult = getMaxPos.get(sessionId);
|
|
250
|
-
const nextPosition = (maxPosResult?.maxPos ?? -1) + 1;
|
|
251
|
-
|
|
252
|
-
const stmt = database.prepare(
|
|
253
|
-
`INSERT INTO redo_states (id, session_id, position, timestamp, messages, git_commit_hash, file_snapshots, use_git)
|
|
254
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
stmt.run(
|
|
258
|
-
state.id,
|
|
259
|
-
sessionId,
|
|
260
|
-
nextPosition,
|
|
261
|
-
state.timestamp,
|
|
262
|
-
JSON.stringify(state.messages),
|
|
263
|
-
state.gitCommitHash || null,
|
|
264
|
-
JSON.stringify(state.fileSnapshots),
|
|
265
|
-
state.useGit ? 1 : 0
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export function popRedoState(sessionId: string): UndoRedoState | null {
|
|
270
|
-
const database = getDatabase();
|
|
271
|
-
|
|
272
|
-
database.exec('BEGIN TRANSACTION');
|
|
273
|
-
try {
|
|
274
|
-
const getStmt = database.prepare<any, [string]>(
|
|
275
|
-
`SELECT id, timestamp, messages, git_commit_hash, file_snapshots, use_git
|
|
276
|
-
FROM redo_states
|
|
277
|
-
WHERE session_id = ?
|
|
278
|
-
ORDER BY position DESC
|
|
279
|
-
LIMIT 1`
|
|
280
|
-
);
|
|
281
|
-
const row = getStmt.get(sessionId);
|
|
282
|
-
|
|
283
|
-
if (!row) {
|
|
284
|
-
database.exec('ROLLBACK');
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const deleteStmt = database.prepare(
|
|
289
|
-
'DELETE FROM redo_states WHERE id = ? AND session_id = ?'
|
|
290
|
-
);
|
|
291
|
-
deleteStmt.run(row.id, sessionId);
|
|
292
|
-
|
|
293
|
-
database.exec('COMMIT');
|
|
294
|
-
|
|
295
|
-
return {
|
|
296
|
-
id: row.id,
|
|
297
|
-
timestamp: row.timestamp,
|
|
298
|
-
messages: JSON.parse(row.messages),
|
|
299
|
-
gitCommitHash: row.git_commit_hash || undefined,
|
|
300
|
-
fileSnapshots: JSON.parse(row.file_snapshots),
|
|
301
|
-
useGit: Boolean(row.use_git)
|
|
302
|
-
};
|
|
303
|
-
} catch (error) {
|
|
304
|
-
database.exec('ROLLBACK');
|
|
305
|
-
throw error;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
export function clearRedoStates(sessionId: string): void {
|
|
310
|
-
const database = getDatabase();
|
|
311
|
-
const stmt = database.prepare('DELETE FROM redo_states WHERE session_id = ?');
|
|
312
|
-
stmt.run(sessionId);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
export function getUndoCount(sessionId: string): number {
|
|
316
|
-
const database = getDatabase();
|
|
317
|
-
const stmt = database.prepare<{ count: number }, [string]>(
|
|
318
|
-
'SELECT COUNT(*) as count FROM undo_states WHERE session_id = ?'
|
|
319
|
-
);
|
|
320
|
-
const result = stmt.get(sessionId);
|
|
321
|
-
return result?.count ?? 0;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
export function getRedoCount(sessionId: string): number {
|
|
325
|
-
const database = getDatabase();
|
|
326
|
-
const stmt = database.prepare<{ count: number }, [string]>(
|
|
327
|
-
'SELECT COUNT(*) as count FROM redo_states WHERE session_id = ?'
|
|
328
|
-
);
|
|
329
|
-
const result = stmt.get(sessionId);
|
|
330
|
-
return result?.count ?? 0;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
export function closeDatabase(): void {
|
|
334
|
-
if (db) {
|
|
335
|
-
db.close();
|
|
336
|
-
db = null;
|
|
337
|
-
}
|
|
338
|
-
}
|