@kafca/agentdock 0.1.7

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 (79) hide show
  1. package/README.md +70 -0
  2. package/bin/agentdock.mjs +275 -0
  3. package/build/icon.png +0 -0
  4. package/dist/renderer/assets/index-BaNpzC6d.js +482 -0
  5. package/dist/renderer/assets/index-CLWJyO0E.css +11 -0
  6. package/dist/renderer/favicon.svg +19 -0
  7. package/dist/renderer/index.html +14 -0
  8. package/dist/renderer/logo-options.svg +153 -0
  9. package/dist-electron/electron/knowledge-skill-script.test.js +125 -0
  10. package/dist-electron/electron/lac-cli.test.js +221 -0
  11. package/dist-electron/electron/local-core-refactor.test.js +1075 -0
  12. package/dist-electron/electron/main.js +163 -0
  13. package/dist-electron/electron/plugin-kernel.test.js +534 -0
  14. package/dist-electron/electron/preload.js +2 -0
  15. package/dist-electron/package.json +3 -0
  16. package/dist-electron/packages/contracts/src/index.js +18 -0
  17. package/dist-electron/packages/contracts/src/local-core.js +2 -0
  18. package/dist-electron/packages/core-sdk/src/index.js +406 -0
  19. package/dist-electron/packages/knowledge-api/src/ai-vector-provider.js +388 -0
  20. package/dist-electron/packages/knowledge-api/src/index.js +146 -0
  21. package/dist-electron/packages/knowledge-api/src/sqlite-store.js +467 -0
  22. package/dist-electron/packages/knowledge-api/src/thread-knowledge-store.js +21 -0
  23. package/dist-electron/packages/knowledge-api/test/ai-vector-provider.test.js +412 -0
  24. package/dist-electron/packages/plugin-sdk/src/index.js +2 -0
  25. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +369 -0
  26. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-response-processor.js +110 -0
  27. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +171 -0
  28. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +635 -0
  29. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +190 -0
  30. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +244 -0
  31. package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +52 -0
  32. package/dist-electron/services/local-ai-core/src/cli/lac.js +290 -0
  33. package/dist-electron/services/local-ai-core/src/gateway/local-core-lark-gateway.js +976 -0
  34. package/dist-electron/services/local-ai-core/src/gateway/local-core-weixin-gateway.js +1143 -0
  35. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +291 -0
  36. package/dist-electron/services/local-ai-core/src/kernel/capability-registry.js +67 -0
  37. package/dist-electron/services/local-ai-core/src/kernel/diagnostics.js +27 -0
  38. package/dist-electron/services/local-ai-core/src/kernel/event-bus.js +27 -0
  39. package/dist-electron/services/local-ai-core/src/kernel/lifecycle-manager.js +85 -0
  40. package/dist-electron/services/local-ai-core/src/kernel/plugin-registry.js +60 -0
  41. package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +114 -0
  42. package/dist-electron/services/local-ai-core/src/plugins/builtin/channel-lark-plugin.js +59 -0
  43. package/dist-electron/services/local-ai-core/src/plugins/builtin/channel-weixin-plugin.js +56 -0
  44. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-ai-vector-plugin.js +7 -0
  45. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-noop-plugin.js +7 -0
  46. package/dist-electron/services/local-ai-core/src/plugins/builtin/runtime-capabilities-plugin.js +62 -0
  47. package/dist-electron/services/local-ai-core/src/plugins/builtin/scheduler-cron-plugin.js +49 -0
  48. package/dist-electron/services/local-ai-core/src/plugins/builtin/scheduler-lark-plugin.js +38 -0
  49. package/dist-electron/services/local-ai-core/src/plugins/builtin/scheduler-weixin-plugin.js +38 -0
  50. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +230 -0
  51. package/dist-electron/services/local-ai-core/src/router/workspace-router-types.js +2 -0
  52. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +389 -0
  53. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +315 -0
  54. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +282 -0
  55. package/dist-electron/services/local-ai-core/src/runtime/server.js +465 -0
  56. package/dist-electron/services/local-ai-core/src/runtime/standalone.js +38 -0
  57. package/dist-electron/services/local-ai-core/src/scheduler/adapters.js +2 -0
  58. package/dist-electron/services/local-ai-core/src/scheduler/cron-command-detector.js +70 -0
  59. package/dist-electron/services/local-ai-core/src/scheduler/cron.js +53 -0
  60. package/dist-electron/services/local-ai-core/src/scheduler/execution-policy.js +2 -0
  61. package/dist-electron/services/local-ai-core/src/scheduler/lark-execution-policies.js +66 -0
  62. package/dist-electron/services/local-ai-core/src/scheduler/lark-schedule-adapter.js +77 -0
  63. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-conversation-executor.js +46 -0
  64. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-run-lifecycle.js +64 -0
  65. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +133 -0
  66. package/dist-electron/services/local-ai-core/src/scheduler/weixin-execution-policies.js +66 -0
  67. package/dist-electron/services/local-ai-core/src/scheduler/weixin-schedule-adapter.js +78 -0
  68. package/dist-electron/services/local-ai-core/src/thread/workspace-thread-id.js +17 -0
  69. package/dist-electron/services/local-ai-core/src/thread/workspace-thread-mappers.js +43 -0
  70. package/dist-electron/shared/desktop.js +195 -0
  71. package/dist-electron/src/api/client.js +73 -0
  72. package/dist-electron/src/api/sessions.js +21 -0
  73. package/dist-electron/src/lib/session-utils.js +51 -0
  74. package/dist-electron/src/pages/Threads/thread-chat-model.js +246 -0
  75. package/dist-electron/src/pages/Threads/thread-chat-model.test.js +76 -0
  76. package/dist-electron/src/pages/Threads/thread-chat-permission.js +26 -0
  77. package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +102 -0
  78. package/dist-electron/src/pages/Threads/thread-chat-task-state.js +65 -0
  79. package/package.json +146 -0
@@ -0,0 +1,467 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KnowledgeSqliteStore = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const node_sqlite_1 = require("node:sqlite");
7
+ const SCHEMA_VERSION = '2';
8
+ function clone(value) {
9
+ return JSON.parse(JSON.stringify(value));
10
+ }
11
+ function parseMetadata(raw) {
12
+ if (!raw) {
13
+ return null;
14
+ }
15
+ try {
16
+ const parsed = JSON.parse(raw);
17
+ return parsed && typeof parsed === 'object' ? parsed : null;
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ function cleanupDatabaseFiles(dbPath) {
24
+ (0, node_fs_1.rmSync)(dbPath, { force: true });
25
+ (0, node_fs_1.rmSync)(`${dbPath}-shm`, { force: true });
26
+ (0, node_fs_1.rmSync)(`${dbPath}-wal`, { force: true });
27
+ }
28
+ class KnowledgeSqliteStore {
29
+ dbPath;
30
+ legacyStorePath;
31
+ legacyBackupPath;
32
+ db;
33
+ constructor(options) {
34
+ this.dbPath = (0, node_path_1.join)(options.userDataPath, 'runtime', 'knowledge.db');
35
+ this.legacyStorePath = (0, node_path_1.join)(options.userDataPath, 'runtime', 'knowledge-store.json');
36
+ this.legacyBackupPath = `${this.legacyStorePath}.bak`;
37
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.dbPath), { recursive: true });
38
+ const shouldMigrate = !(0, node_fs_1.existsSync)(this.dbPath) && (0, node_fs_1.existsSync)(this.legacyStorePath);
39
+ this.db = new node_sqlite_1.DatabaseSync(this.dbPath);
40
+ try {
41
+ this.initializeSchema();
42
+ if (shouldMigrate) {
43
+ this.migrateLegacyJson();
44
+ }
45
+ }
46
+ catch (error) {
47
+ this.db.close();
48
+ if (shouldMigrate) {
49
+ cleanupDatabaseFiles(this.dbPath);
50
+ }
51
+ throw error;
52
+ }
53
+ }
54
+ close() {
55
+ this.db.close();
56
+ }
57
+ listFolders() {
58
+ const rows = this.db.prepare(`
59
+ SELECT id, name, parent_id, path, sort_order, created_at, updated_at
60
+ FROM knowledge_folders
61
+ ORDER BY path ASC, sort_order ASC
62
+ `).all();
63
+ return rows.map((row) => this.mapFolder(row));
64
+ }
65
+ getFolder(id) {
66
+ const row = this.db.prepare(`
67
+ SELECT id, name, parent_id, path, sort_order, created_at, updated_at
68
+ FROM knowledge_folders
69
+ WHERE id = ?
70
+ LIMIT 1
71
+ `).get(id);
72
+ return row ? this.mapFolder(row) : null;
73
+ }
74
+ insertFolder(folder) {
75
+ this.db.prepare(`
76
+ INSERT INTO knowledge_folders (
77
+ id, name, parent_id, path, sort_order, created_at, updated_at
78
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
79
+ `).run(folder.id, folder.name, folder.parentId, folder.path, folder.sortOrder, folder.createdAt, folder.updatedAt);
80
+ return clone(folder);
81
+ }
82
+ renameFolder(id, input) {
83
+ this.transaction(() => {
84
+ const updateResult = this.db.prepare(`
85
+ UPDATE knowledge_folders
86
+ SET name = ?, path = ?, updated_at = ?
87
+ WHERE id = ?
88
+ `).run(input.name, input.nextPath, input.updatedAt, id);
89
+ if (Number(updateResult.changes || 0) === 0) {
90
+ throw new Error('Folder does not exist.');
91
+ }
92
+ this.db.prepare(`
93
+ UPDATE knowledge_folders
94
+ SET path = replace(path, ?, ?), updated_at = ?
95
+ WHERE id <> ? AND path LIKE ?
96
+ `).run(input.previousPath, input.nextPath, input.updatedAt, id, `${input.previousPath}/%`);
97
+ });
98
+ const folder = this.getFolder(id);
99
+ if (!folder) {
100
+ throw new Error('Folder does not exist.');
101
+ }
102
+ return folder;
103
+ }
104
+ deleteFolder(id) {
105
+ this.db.prepare('DELETE FROM knowledge_folders WHERE id = ?').run(id);
106
+ }
107
+ listKnowledgeBases() {
108
+ const rows = this.db.prepare(`
109
+ SELECT
110
+ bases.id,
111
+ bases.name,
112
+ bases.description,
113
+ bases.folder_id,
114
+ bases.creator_name,
115
+ bases.icon,
116
+ bases.created_at,
117
+ bases.updated_at,
118
+ COALESCE(stats.file_count, 0) AS file_count,
119
+ COALESCE(stats.word_count, 0) AS word_count
120
+ FROM knowledge_bases AS bases
121
+ LEFT JOIN (
122
+ SELECT
123
+ knowledgebase_id,
124
+ COUNT(*) AS file_count,
125
+ COALESCE(SUM(COALESCE(word_count, 0)), 0) AS word_count
126
+ FROM knowledge_files
127
+ GROUP BY knowledgebase_id
128
+ ) AS stats ON stats.knowledgebase_id = bases.id
129
+ ORDER BY bases.updated_at DESC
130
+ `).all();
131
+ return rows.map((row) => this.mapKnowledgeBase(row));
132
+ }
133
+ getKnowledgeBase(id) {
134
+ const row = this.db.prepare(`
135
+ SELECT
136
+ bases.id,
137
+ bases.name,
138
+ bases.description,
139
+ bases.folder_id,
140
+ bases.creator_name,
141
+ bases.icon,
142
+ bases.created_at,
143
+ bases.updated_at,
144
+ COALESCE(stats.file_count, 0) AS file_count,
145
+ COALESCE(stats.word_count, 0) AS word_count
146
+ FROM knowledge_bases AS bases
147
+ LEFT JOIN (
148
+ SELECT
149
+ knowledgebase_id,
150
+ COUNT(*) AS file_count,
151
+ COALESCE(SUM(COALESCE(word_count, 0)), 0) AS word_count
152
+ FROM knowledge_files
153
+ GROUP BY knowledgebase_id
154
+ ) AS stats ON stats.knowledgebase_id = bases.id
155
+ WHERE bases.id = ?
156
+ LIMIT 1
157
+ `).get(id);
158
+ return row ? this.mapKnowledgeBase(row) : null;
159
+ }
160
+ insertKnowledgeBase(base) {
161
+ this.db.prepare(`
162
+ INSERT INTO knowledge_bases (
163
+ id, name, description, folder_id, creator_name, icon, created_at, updated_at
164
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
165
+ `).run(base.id, base.name, base.description, base.folderId, base.creatorName, base.icon, base.createdAt, base.updatedAt);
166
+ return clone(base);
167
+ }
168
+ updateKnowledgeBase(base) {
169
+ const result = this.db.prepare(`
170
+ UPDATE knowledge_bases
171
+ SET name = ?, description = ?, folder_id = ?, creator_name = ?, icon = ?, updated_at = ?
172
+ WHERE id = ?
173
+ `).run(base.name, base.description, base.folderId, base.creatorName, base.icon, base.updatedAt, base.id);
174
+ if (Number(result.changes || 0) === 0) {
175
+ throw new Error('Knowledge base does not exist.');
176
+ }
177
+ return this.getKnowledgeBase(base.id) || clone(base);
178
+ }
179
+ touchKnowledgeBase(id, updatedAt) {
180
+ this.db.prepare('UPDATE knowledge_bases SET updated_at = ? WHERE id = ?').run(updatedAt, id);
181
+ }
182
+ deleteKnowledgeBase(id) {
183
+ this.transaction(() => {
184
+ this.db.prepare('DELETE FROM thread_knowledge_bases WHERE knowledge_base_id = ?').run(id);
185
+ this.db.prepare('DELETE FROM knowledge_files WHERE knowledgebase_id = ?').run(id);
186
+ this.db.prepare('DELETE FROM knowledge_bases WHERE id = ?').run(id);
187
+ });
188
+ }
189
+ listKnowledgeBaseFiles(knowledgeBaseId) {
190
+ const rows = this.db.prepare(`
191
+ SELECT
192
+ knowledgebase_id,
193
+ file_id,
194
+ file_name,
195
+ file_type,
196
+ file_size,
197
+ folder,
198
+ create_time,
199
+ word_count,
200
+ metadata_json,
201
+ abstract,
202
+ full_content,
203
+ updated_at
204
+ FROM knowledge_files
205
+ WHERE knowledgebase_id = ?
206
+ ORDER BY create_time DESC, file_name COLLATE NOCASE ASC
207
+ `).all(knowledgeBaseId);
208
+ return rows.map((row) => this.mapKnowledgeFile(row));
209
+ }
210
+ upsertKnowledgeBaseFiles(files) {
211
+ if (files.length === 0) {
212
+ return;
213
+ }
214
+ const statement = this.db.prepare(`
215
+ INSERT INTO knowledge_files (
216
+ knowledgebase_id,
217
+ file_id,
218
+ file_name,
219
+ file_type,
220
+ file_size,
221
+ folder,
222
+ create_time,
223
+ word_count,
224
+ metadata_json,
225
+ abstract,
226
+ full_content,
227
+ updated_at
228
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
229
+ ON CONFLICT(file_id) DO UPDATE SET
230
+ knowledgebase_id = excluded.knowledgebase_id,
231
+ file_name = excluded.file_name,
232
+ file_type = excluded.file_type,
233
+ file_size = excluded.file_size,
234
+ folder = excluded.folder,
235
+ create_time = excluded.create_time,
236
+ word_count = excluded.word_count,
237
+ metadata_json = excluded.metadata_json,
238
+ abstract = excluded.abstract,
239
+ full_content = excluded.full_content,
240
+ updated_at = excluded.updated_at
241
+ `);
242
+ this.transaction(() => {
243
+ files.forEach((file) => {
244
+ statement.run(file.knowledgebaseId || null, file.fileId, file.fileName, file.fileType, file.fileSize, file.folder || null, file.createTime, file.wordCount ?? null, file.metadata ? JSON.stringify(file.metadata) : null, file.abstract || null, file.fullContent || null, new Date().toISOString());
245
+ });
246
+ });
247
+ }
248
+ deleteKnowledgeBaseFile(fileId) {
249
+ this.db.prepare('DELETE FROM knowledge_files WHERE file_id = ?').run(fileId);
250
+ }
251
+ listThreadKnowledgeBaseIds(threadId) {
252
+ const rows = this.db.prepare(`
253
+ SELECT thread_id, knowledge_base_id, created_at
254
+ FROM thread_knowledge_bases
255
+ WHERE thread_id = ?
256
+ ORDER BY created_at ASC, rowid ASC
257
+ `).all(threadId);
258
+ return rows.map((row) => row.knowledge_base_id);
259
+ }
260
+ replaceThreadKnowledgeBaseIds(threadId, knowledgeBaseIds) {
261
+ const uniqueIds = Array.from(new Set(knowledgeBaseIds.map((id) => String(id || '').trim()).filter(Boolean)));
262
+ const missingId = uniqueIds.find((knowledgeBaseId) => !this.getKnowledgeBase(knowledgeBaseId));
263
+ if (missingId) {
264
+ throw new Error(`Knowledge base does not exist: ${missingId}`);
265
+ }
266
+ this.transaction(() => {
267
+ this.db.prepare('DELETE FROM thread_knowledge_bases WHERE thread_id = ?').run(threadId);
268
+ if (uniqueIds.length === 0) {
269
+ return;
270
+ }
271
+ const insertStatement = this.db.prepare(`
272
+ INSERT INTO thread_knowledge_bases (
273
+ thread_id,
274
+ knowledge_base_id,
275
+ created_at
276
+ ) VALUES (?, ?, ?)
277
+ `);
278
+ uniqueIds.forEach((knowledgeBaseId) => {
279
+ insertStatement.run(threadId, knowledgeBaseId, new Date().toISOString());
280
+ });
281
+ });
282
+ return uniqueIds;
283
+ }
284
+ deleteThreadKnowledgeBaseLinks(threadId) {
285
+ this.db.prepare('DELETE FROM thread_knowledge_bases WHERE thread_id = ?').run(threadId);
286
+ }
287
+ hasFolderChildren(id) {
288
+ const row = this.db.prepare(`
289
+ SELECT 1 AS value
290
+ FROM knowledge_folders
291
+ WHERE parent_id = ?
292
+ LIMIT 1
293
+ `).get(id);
294
+ return Boolean(row?.value);
295
+ }
296
+ hasKnowledgeBasesInFolder(id) {
297
+ const row = this.db.prepare(`
298
+ SELECT 1 AS value
299
+ FROM knowledge_bases
300
+ WHERE folder_id = ?
301
+ LIMIT 1
302
+ `).get(id);
303
+ return Boolean(row?.value);
304
+ }
305
+ runInTransaction(callback) {
306
+ return this.transaction(callback);
307
+ }
308
+ initializeSchema() {
309
+ this.db.exec('PRAGMA foreign_keys = ON;');
310
+ this.db.exec(`
311
+ CREATE TABLE IF NOT EXISTS meta (
312
+ key TEXT PRIMARY KEY,
313
+ value TEXT NOT NULL
314
+ );
315
+
316
+ CREATE TABLE IF NOT EXISTS knowledge_folders (
317
+ id TEXT PRIMARY KEY,
318
+ name TEXT NOT NULL,
319
+ parent_id TEXT,
320
+ path TEXT NOT NULL,
321
+ sort_order INTEGER NOT NULL DEFAULT 0,
322
+ created_at TEXT NOT NULL,
323
+ updated_at TEXT NOT NULL
324
+ );
325
+
326
+ CREATE TABLE IF NOT EXISTS knowledge_bases (
327
+ id TEXT PRIMARY KEY,
328
+ name TEXT NOT NULL,
329
+ description TEXT NOT NULL DEFAULT '',
330
+ folder_id TEXT,
331
+ creator_name TEXT NOT NULL,
332
+ icon TEXT NOT NULL,
333
+ created_at TEXT NOT NULL,
334
+ updated_at TEXT NOT NULL
335
+ );
336
+
337
+ CREATE TABLE IF NOT EXISTS knowledge_files (
338
+ file_id TEXT PRIMARY KEY,
339
+ knowledgebase_id TEXT,
340
+ file_name TEXT NOT NULL,
341
+ file_type TEXT NOT NULL,
342
+ file_size INTEGER NOT NULL DEFAULT 0,
343
+ folder TEXT,
344
+ create_time TEXT NOT NULL,
345
+ word_count INTEGER,
346
+ metadata_json TEXT,
347
+ abstract TEXT,
348
+ full_content TEXT,
349
+ updated_at TEXT NOT NULL
350
+ );
351
+
352
+ CREATE TABLE IF NOT EXISTS thread_knowledge_bases (
353
+ thread_id TEXT NOT NULL,
354
+ knowledge_base_id TEXT NOT NULL,
355
+ created_at TEXT NOT NULL,
356
+ PRIMARY KEY (thread_id, knowledge_base_id)
357
+ );
358
+
359
+ CREATE INDEX IF NOT EXISTS idx_knowledge_folders_parent_id
360
+ ON knowledge_folders (parent_id);
361
+ CREATE INDEX IF NOT EXISTS idx_knowledge_bases_folder_id
362
+ ON knowledge_bases (folder_id);
363
+ CREATE INDEX IF NOT EXISTS idx_knowledge_files_knowledgebase_id
364
+ ON knowledge_files (knowledgebase_id);
365
+ CREATE INDEX IF NOT EXISTS idx_knowledge_files_create_time
366
+ ON knowledge_files (create_time DESC);
367
+ CREATE INDEX IF NOT EXISTS idx_thread_knowledge_bases_thread_id
368
+ ON thread_knowledge_bases (thread_id);
369
+ `);
370
+ this.db.prepare(`
371
+ INSERT INTO meta (key, value)
372
+ VALUES ('schema_version', ?)
373
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value
374
+ `).run(SCHEMA_VERSION);
375
+ }
376
+ migrateLegacyJson() {
377
+ if (!(0, node_fs_1.existsSync)(this.legacyStorePath)) {
378
+ return;
379
+ }
380
+ if ((0, node_fs_1.existsSync)(this.legacyBackupPath)) {
381
+ (0, node_fs_1.unlinkSync)(this.legacyBackupPath);
382
+ }
383
+ (0, node_fs_1.renameSync)(this.legacyStorePath, this.legacyBackupPath);
384
+ try {
385
+ const raw = JSON.parse((0, node_fs_1.readFileSync)(this.legacyBackupPath, 'utf8'));
386
+ const folders = Array.isArray(raw.folders) ? raw.folders : [];
387
+ const knowledgeBases = Array.isArray(raw.knowledgeBases) ? raw.knowledgeBases : [];
388
+ this.transaction(() => {
389
+ const insertFolder = this.db.prepare(`
390
+ INSERT INTO knowledge_folders (
391
+ id, name, parent_id, path, sort_order, created_at, updated_at
392
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
393
+ `);
394
+ const insertKnowledgeBase = this.db.prepare(`
395
+ INSERT INTO knowledge_bases (
396
+ id, name, description, folder_id, creator_name, icon, created_at, updated_at
397
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
398
+ `);
399
+ folders.forEach((folder) => {
400
+ insertFolder.run(folder.id, folder.name, folder.parentId || null, folder.path, folder.sortOrder, folder.createdAt, folder.updatedAt);
401
+ });
402
+ knowledgeBases.forEach((base) => {
403
+ insertKnowledgeBase.run(base.id, base.name, base.description, base.folderId || null, base.creatorName, base.icon, base.createdAt, base.updatedAt);
404
+ });
405
+ });
406
+ }
407
+ catch (error) {
408
+ if ((0, node_fs_1.existsSync)(this.legacyBackupPath) && !(0, node_fs_1.existsSync)(this.legacyStorePath)) {
409
+ (0, node_fs_1.renameSync)(this.legacyBackupPath, this.legacyStorePath);
410
+ }
411
+ throw error;
412
+ }
413
+ }
414
+ transaction(callback) {
415
+ this.db.exec('BEGIN IMMEDIATE');
416
+ try {
417
+ const result = callback();
418
+ this.db.exec('COMMIT');
419
+ return result;
420
+ }
421
+ catch (error) {
422
+ this.db.exec('ROLLBACK');
423
+ throw error;
424
+ }
425
+ }
426
+ mapFolder(row) {
427
+ return {
428
+ id: row.id,
429
+ name: row.name,
430
+ parentId: row.parent_id,
431
+ path: row.path,
432
+ sortOrder: Number(row.sort_order || 0),
433
+ createdAt: row.created_at,
434
+ updatedAt: row.updated_at,
435
+ };
436
+ }
437
+ mapKnowledgeBase(row) {
438
+ return {
439
+ id: row.id,
440
+ name: row.name,
441
+ description: row.description,
442
+ folderId: row.folder_id,
443
+ creatorName: row.creator_name,
444
+ icon: row.icon,
445
+ fileCount: Number(row.file_count || 0),
446
+ wordCount: Number(row.word_count || 0),
447
+ createdAt: row.created_at,
448
+ updatedAt: row.updated_at,
449
+ };
450
+ }
451
+ mapKnowledgeFile(row) {
452
+ return {
453
+ knowledgebaseId: row.knowledgebase_id,
454
+ fileId: row.file_id,
455
+ fileName: row.file_name,
456
+ fileType: row.file_type,
457
+ fileSize: Number(row.file_size || 0),
458
+ folder: row.folder,
459
+ createTime: row.create_time,
460
+ wordCount: typeof row.word_count === 'number' ? row.word_count : null,
461
+ metadata: parseMetadata(row.metadata_json),
462
+ abstract: row.abstract,
463
+ fullContent: row.full_content,
464
+ };
465
+ }
466
+ }
467
+ exports.KnowledgeSqliteStore = KnowledgeSqliteStore;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqliteThreadKnowledgeAttachmentStore = void 0;
4
+ const sqlite_store_js_1 = require("./sqlite-store.js");
5
+ class SqliteThreadKnowledgeAttachmentStore {
6
+ store;
7
+ constructor(options) {
8
+ this.store = new sqlite_store_js_1.KnowledgeSqliteStore({ userDataPath: options.userDataPath });
9
+ }
10
+ async listThreadKnowledgeBaseIds(threadId) {
11
+ return this.store.listThreadKnowledgeBaseIds(threadId);
12
+ }
13
+ async updateThreadKnowledgeBaseIds(threadId, knowledgeBaseIds) {
14
+ return this.store.replaceThreadKnowledgeBaseIds(threadId, knowledgeBaseIds);
15
+ }
16
+ async deleteThreadKnowledgeBaseLinks(threadId) {
17
+ this.store.deleteThreadKnowledgeBaseLinks(threadId);
18
+ return { deleted: true };
19
+ }
20
+ }
21
+ exports.SqliteThreadKnowledgeAttachmentStore = SqliteThreadKnowledgeAttachmentStore;