@sylphx/flow 1.7.0 → 1.8.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.
Files changed (131) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/assets/agents/coder.md +72 -119
  3. package/assets/agents/orchestrator.md +26 -90
  4. package/assets/agents/reviewer.md +76 -47
  5. package/assets/agents/writer.md +82 -63
  6. package/assets/output-styles/silent.md +141 -8
  7. package/assets/rules/code-standards.md +9 -33
  8. package/assets/rules/core.md +67 -59
  9. package/package.json +2 -12
  10. package/src/commands/flow/execute.ts +470 -0
  11. package/src/commands/flow/index.ts +11 -0
  12. package/src/commands/flow/prompt.ts +35 -0
  13. package/src/commands/flow/setup.ts +312 -0
  14. package/src/commands/flow/targets.ts +18 -0
  15. package/src/commands/flow/types.ts +47 -0
  16. package/src/commands/flow-command.ts +18 -967
  17. package/src/commands/flow-orchestrator.ts +14 -5
  18. package/src/commands/hook-command.ts +1 -1
  19. package/src/commands/init-core.ts +12 -3
  20. package/src/commands/run-command.ts +1 -1
  21. package/src/config/rules.ts +1 -1
  22. package/src/core/error-handling.ts +1 -1
  23. package/src/core/loop-controller.ts +1 -1
  24. package/src/core/state-detector.ts +1 -1
  25. package/src/core/target-manager.ts +1 -1
  26. package/src/index.ts +1 -1
  27. package/src/shared/files/index.ts +1 -1
  28. package/src/shared/processing/index.ts +1 -1
  29. package/src/targets/claude-code.ts +3 -3
  30. package/src/targets/opencode.ts +3 -3
  31. package/src/utils/agent-enhancer.ts +2 -2
  32. package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
  33. package/src/utils/{paths.ts → config/paths.ts} +1 -1
  34. package/src/utils/{settings.ts → config/settings.ts} +1 -1
  35. package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
  36. package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
  37. package/src/utils/display/banner.ts +25 -0
  38. package/src/utils/display/status.ts +55 -0
  39. package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
  40. package/src/utils/files/jsonc.ts +36 -0
  41. package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
  42. package/src/utils/index.ts +42 -61
  43. package/src/utils/version.ts +47 -0
  44. package/src/components/benchmark-monitor.tsx +0 -331
  45. package/src/components/reindex-progress.tsx +0 -261
  46. package/src/composables/functional/index.ts +0 -14
  47. package/src/composables/functional/useEnvironment.ts +0 -171
  48. package/src/composables/functional/useFileSystem.ts +0 -139
  49. package/src/composables/index.ts +0 -4
  50. package/src/composables/useEnv.ts +0 -13
  51. package/src/composables/useRuntimeConfig.ts +0 -27
  52. package/src/core/ai-sdk.ts +0 -603
  53. package/src/core/app-factory.ts +0 -381
  54. package/src/core/builtin-agents.ts +0 -9
  55. package/src/core/command-system.ts +0 -550
  56. package/src/core/config-system.ts +0 -550
  57. package/src/core/connection-pool.ts +0 -390
  58. package/src/core/di-container.ts +0 -155
  59. package/src/core/headless-display.ts +0 -96
  60. package/src/core/interfaces/index.ts +0 -22
  61. package/src/core/interfaces/repository.interface.ts +0 -91
  62. package/src/core/interfaces/service.interface.ts +0 -133
  63. package/src/core/interfaces.ts +0 -96
  64. package/src/core/result.ts +0 -351
  65. package/src/core/service-config.ts +0 -252
  66. package/src/core/session-service.ts +0 -121
  67. package/src/core/storage-factory.ts +0 -115
  68. package/src/core/stream-handler.ts +0 -288
  69. package/src/core/type-utils.ts +0 -427
  70. package/src/core/unified-storage.ts +0 -456
  71. package/src/core/validation/limit.ts +0 -46
  72. package/src/core/validation/query.ts +0 -20
  73. package/src/db/auto-migrate.ts +0 -322
  74. package/src/db/base-database-client.ts +0 -144
  75. package/src/db/cache-db.ts +0 -218
  76. package/src/db/cache-schema.ts +0 -75
  77. package/src/db/database.ts +0 -70
  78. package/src/db/index.ts +0 -252
  79. package/src/db/memory-db.ts +0 -153
  80. package/src/db/memory-schema.ts +0 -29
  81. package/src/db/schema.ts +0 -289
  82. package/src/db/session-repository.ts +0 -733
  83. package/src/domains/index.ts +0 -6
  84. package/src/domains/utilities/index.ts +0 -6
  85. package/src/domains/utilities/time/index.ts +0 -5
  86. package/src/domains/utilities/time/tools.ts +0 -291
  87. package/src/services/agent-service.ts +0 -273
  88. package/src/services/evaluation-service.ts +0 -271
  89. package/src/services/functional/evaluation-logic.ts +0 -296
  90. package/src/services/functional/file-processor.ts +0 -273
  91. package/src/services/functional/index.ts +0 -12
  92. package/src/services/memory.service.ts +0 -476
  93. package/src/types/api/batch.ts +0 -108
  94. package/src/types/api/errors.ts +0 -118
  95. package/src/types/api/index.ts +0 -55
  96. package/src/types/api/requests.ts +0 -76
  97. package/src/types/api/responses.ts +0 -180
  98. package/src/types/api/websockets.ts +0 -85
  99. package/src/types/benchmark.ts +0 -49
  100. package/src/types/database.types.ts +0 -510
  101. package/src/types/memory-types.ts +0 -63
  102. package/src/utils/advanced-tokenizer.ts +0 -191
  103. package/src/utils/ai-model-fetcher.ts +0 -19
  104. package/src/utils/async-file-operations.ts +0 -516
  105. package/src/utils/audio-player.ts +0 -345
  106. package/src/utils/codebase-helpers.ts +0 -211
  107. package/src/utils/console-ui.ts +0 -79
  108. package/src/utils/database-errors.ts +0 -140
  109. package/src/utils/debug-logger.ts +0 -49
  110. package/src/utils/file-scanner.ts +0 -259
  111. package/src/utils/help.ts +0 -20
  112. package/src/utils/immutable-cache.ts +0 -106
  113. package/src/utils/jsonc.ts +0 -158
  114. package/src/utils/memory-tui.ts +0 -414
  115. package/src/utils/models-dev.ts +0 -91
  116. package/src/utils/parallel-operations.ts +0 -487
  117. package/src/utils/process-manager.ts +0 -155
  118. package/src/utils/prompts.ts +0 -120
  119. package/src/utils/search-tool-builder.ts +0 -214
  120. package/src/utils/session-manager.ts +0 -168
  121. package/src/utils/session-title.ts +0 -87
  122. package/src/utils/simplified-errors.ts +0 -410
  123. package/src/utils/template-engine.ts +0 -94
  124. package/src/utils/test-audio.ts +0 -71
  125. package/src/utils/todo-context.ts +0 -46
  126. package/src/utils/token-counter.ts +0 -288
  127. /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
  128. /package/src/utils/{logger.ts → display/logger.ts} +0 -0
  129. /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
  130. /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
  131. /package/src/utils/{security.ts → security/security.ts} +0 -0
@@ -1,75 +0,0 @@
1
- /**
2
- * Cache database schema - 臨時索引數據 (不應該上 Git)
3
- * 包含代碼庫索引、搜索詞彙等可以重新生成的數據
4
- */
5
-
6
- import { index, integer, primaryKey, real, sqliteTable, text } from 'drizzle-orm/sqlite-core';
7
-
8
- // Codebase files table (代碼庫檔案索引)
9
- export const codebaseFiles = sqliteTable(
10
- 'codebase_files_table',
11
- {
12
- path: text('path').primaryKey(),
13
- mtime: integer('mtime').notNull(),
14
- hash: text('hash').notNull(),
15
- content: text('content'), // Optional full content
16
- language: text('language'), // Detected programming language
17
- size: integer('size'), // File size in bytes
18
- indexedAt: text('indexed_at').notNull(),
19
- },
20
- (table) => [
21
- index('idx_codebase_files_mtime').on(table.mtime),
22
- index('idx_codebase_files_hash').on(table.hash),
23
- ]
24
- );
25
-
26
- // Codebase metadata table (代碼庫元數據)
27
- export const codebaseMetadata = sqliteTable('codebase_metadata_table', {
28
- key: text('key').primaryKey(),
29
- value: text('value').notNull(),
30
- });
31
-
32
- // TF-IDF terms table (搜索詞彙)
33
- export const tfidfTerms = sqliteTable(
34
- 'tfidf_terms_table',
35
- {
36
- filePath: text('file_path')
37
- .notNull()
38
- .references(() => codebaseFiles.path, { onDelete: 'cascade' }),
39
- term: text('term').notNull(),
40
- frequency: real('frequency').notNull(),
41
- },
42
- (table) => [
43
- primaryKey({ columns: [table.filePath, table.term] }),
44
- index('idx_tfidf_terms_term').on(table.term),
45
- index('idx_tfidf_terms_file').on(table.filePath),
46
- ]
47
- );
48
-
49
- // TF-IDF documents table (文檔向量)
50
- export const tfidfDocuments = sqliteTable('tfidf_documents_table', {
51
- filePath: text('file_path')
52
- .primaryKey()
53
- .references(() => codebaseFiles.path, { onDelete: 'cascade' }),
54
- magnitude: real('magnitude').notNull(),
55
- termCount: integer('term_count').notNull(),
56
- rawTerms: text('raw_terms').notNull(), // JSON string
57
- });
58
-
59
- // TF-IDF IDF values table (IDF 計算結果)
60
- export const tfidfIdf = sqliteTable('tfidf_idf_table', {
61
- term: text('term').primaryKey(),
62
- idfValue: real('idf_value').notNull(),
63
- });
64
-
65
- // Types for cache database
66
- export type CodebaseFile = typeof codebaseFiles.$inferSelect;
67
- export type NewCodebaseFile = typeof codebaseFiles.$inferInsert;
68
- export type CodebaseMetadata = typeof codebaseMetadata.$inferSelect;
69
- export type NewCodebaseMetadata = typeof codebaseMetadata.$inferInsert;
70
- export type TfidfTerm = typeof tfidfTerms.$inferSelect;
71
- export type NewTfidfTerm = typeof tfidfTerms.$inferInsert;
72
- export type TfidfDocument = typeof tfidfDocuments.$inferSelect;
73
- export type NewTfidfDocument = typeof tfidfDocuments.$inferInsert;
74
- export type TfidfIdf = typeof tfidfIdf.$inferSelect;
75
- export type NewTfidfIdf = typeof tfidfIdf.$inferInsert;
@@ -1,70 +0,0 @@
1
- /**
2
- * Database Singleton
3
- * Global database instance and repository access
4
- */
5
-
6
- import { createClient } from '@libsql/client';
7
- import { drizzle } from 'drizzle-orm/libsql';
8
- import { join } from 'node:path';
9
- import { homedir } from 'node:os';
10
- import { SessionRepository } from './session-repository.js';
11
- import { initializeDatabase } from './auto-migrate.js';
12
-
13
- const DB_PATH = join(homedir(), '.sylphx-flow', 'memory.db');
14
- const DATABASE_URL = process.env.DATABASE_URL || `file:${DB_PATH}`;
15
-
16
- // Global database instance
17
- let dbInstance: any = null;
18
- let repositoryInstance: SessionRepository | null = null;
19
- let initPromise: Promise<any> | null = null;
20
-
21
- /**
22
- * Get database instance (lazy initialization with auto-migration)
23
- * Ensures database is initialized only once
24
- */
25
- export async function getDatabase(): Promise<any> {
26
- if (dbInstance) {
27
- return dbInstance;
28
- }
29
-
30
- // If initialization in progress, wait for it
31
- if (initPromise) {
32
- return initPromise;
33
- }
34
-
35
- // Start initialization
36
- initPromise = initializeDatabase((progress) => {
37
- if (process.env.DEBUG) {
38
- console.log(`[DB] ${progress.current}/${progress.total}: ${progress.status}`);
39
- }
40
- });
41
-
42
- dbInstance = await initPromise;
43
- initPromise = null;
44
-
45
- return dbInstance;
46
- }
47
-
48
- /**
49
- * Get session repository instance
50
- * Ensures repository uses initialized database
51
- */
52
- export async function getSessionRepository(): Promise<SessionRepository> {
53
- if (repositoryInstance) {
54
- return repositoryInstance;
55
- }
56
-
57
- const db = await getDatabase();
58
- repositoryInstance = new SessionRepository(db);
59
-
60
- return repositoryInstance;
61
- }
62
-
63
- /**
64
- * Reset database instance (for testing)
65
- */
66
- export function resetDatabase(): void {
67
- dbInstance = null;
68
- repositoryInstance = null;
69
- initPromise = null;
70
- }
package/src/db/index.ts DELETED
@@ -1,252 +0,0 @@
1
- /**
2
- * Drizzle ORM database client for Sylphx Flow
3
- * Type-safe database operations with proper migrations
4
- */
5
-
6
- import * as fs from 'node:fs';
7
- import * as os from 'node:os';
8
- import * as path from 'node:path';
9
- import { createClient } from '@libsql/client';
10
- import { drizzle } from 'drizzle-orm/libsql';
11
- import { migrate } from 'drizzle-orm/libsql/migrator';
12
- import { ConnectionError, DatabaseError } from '../utils/database-errors.js';
13
- import * as schema from './schema.js';
14
- import { findPackageRoot } from '../utils/paths.js';
15
-
16
- export type Database = ReturnType<typeof drizzle<typeof schema>>;
17
-
18
- export class DrizzleDatabase {
19
- private client: ReturnType<typeof createClient>;
20
- public db: Database;
21
- private useHomeDir: boolean;
22
-
23
- constructor(options?: { useHomeDir?: boolean }) {
24
- // Default to project directory if not specified
25
- this.useHomeDir = options?.useHomeDir ?? false;
26
-
27
- try {
28
- // Create both home directory and current directory .sylphx-flow folders
29
- const homeDir = path.join(os.homedir(), '.sylphx-flow');
30
- const projectDir = path.join(process.cwd(), '.sylphx-flow');
31
-
32
- // Ensure both directories exist with proper error handling
33
- try {
34
- if (!fs.existsSync(homeDir)) {
35
- fs.mkdirSync(homeDir, { recursive: true });
36
- }
37
- if (!fs.existsSync(projectDir)) {
38
- fs.mkdirSync(projectDir, { recursive: true });
39
- }
40
- } catch (dirError) {
41
- throw new Error(
42
- `Failed to create database directories: ${homeDir}, ${projectDir}. ` +
43
- `Error: ${(dirError as Error).message}`
44
- );
45
- }
46
-
47
- // Determine database location
48
- // code command uses home directory, init/run commands use project directory
49
- const memoryDir = this.useHomeDir ? homeDir : projectDir;
50
- const dbPath = path.join(memoryDir, 'memory.db');
51
-
52
- // Use local path directly without file: URL scheme
53
- // libSQL will automatically create the file if it doesn't exist
54
- this.client = createClient({
55
- url: dbPath,
56
- });
57
-
58
- this.db = drizzle(this.client, { schema });
59
- } catch (error) {
60
- const dbPath = path.join(process.cwd(), '.sylphx-flow', 'memory.db');
61
-
62
- throw new ConnectionError(
63
- 'Failed to initialize database connection',
64
- {
65
- url: dbPath,
66
- dbPath,
67
- cwd: process.cwd(),
68
- platform: process.platform,
69
- },
70
- error as Error
71
- );
72
- }
73
- }
74
-
75
- /**
76
- * Initialize database schema using Drizzle migrations
77
- */
78
- async initialize(): Promise<void> {
79
- try {
80
- // Check if tables already exist from previous implementation
81
- const migrationStatus = await this.getMigrationStatus();
82
-
83
- if (migrationStatus.isMigrated) {
84
- console.error('[INFO] Database tables already exist, checking migration state');
85
-
86
- // Check if __drizzle_migrations table exists
87
- const drizzleMigrationResult = await this.client.execute(`
88
- SELECT name FROM sqlite_master
89
- WHERE type='table' AND name='__drizzle_migrations'
90
- `);
91
-
92
- if (drizzleMigrationResult.rows.length === 0) {
93
- // Tables exist but no Drizzle migration tracking
94
- // Create the migration tracking table and mark as migrated
95
- await this.client.execute(`
96
- CREATE TABLE IF NOT EXISTS __drizzle_migrations (
97
- id INTEGER PRIMARY KEY AUTOINCREMENT,
98
- hash text NOT NULL UNIQUE,
99
- created_at numeric NOT NULL DEFAULT (strftime('%s', 'now'))
100
- )
101
- `);
102
-
103
- // Insert our migration as already applied
104
- await this.client.execute(`
105
- INSERT OR IGNORE INTO __drizzle_migrations (hash, created_at)
106
- VALUES ('0000_wooden_lady_bullseye', strftime('%s', 'now'))
107
- `);
108
-
109
- console.error('[INFO] Migration tracking initialized for existing tables');
110
- }
111
-
112
- return;
113
- }
114
-
115
- // Run migrations using Drizzle migrator
116
- // Use package root to find migrations folder (works with npm install)
117
- const packageRoot = findPackageRoot('drizzle migrations');
118
- const migrationsPath = path.join(packageRoot, 'drizzle');
119
-
120
- if (fs.existsSync(migrationsPath)) {
121
- await migrate(this.db, { migrationsFolder: migrationsPath });
122
- console.error('[INFO] Database migrations completed');
123
- } else {
124
- console.error('[WARN] No migrations folder found, using fallback table creation');
125
- await this.createTablesFallback();
126
- }
127
- } catch (error) {
128
- const errorMessage = `Migration failed: ${(error as Error).message}`;
129
- console.error('[ERROR]', errorMessage);
130
-
131
- // Try fallback as last resort
132
- try {
133
- await this.createTablesFallback();
134
- console.error('[WARN] Fallback table creation completed');
135
- } catch (fallbackError) {
136
- throw new DatabaseError(
137
- 'Both migration and fallback failed',
138
- 'initialize',
139
- fallbackError as Error,
140
- { originalError: (error as Error).message }
141
- );
142
- }
143
- }
144
- }
145
-
146
- /**
147
- * Fallback table creation for development
148
- * Only used if migrations fail
149
- */
150
- private async createTablesFallback(): Promise<void> {
151
- // This is a minimal fallback - in production we should always use migrations
152
- console.error('[INFO] Using fallback table creation');
153
-
154
- // Create tables using the existing database connection
155
- // The tables should already exist from previous runs
156
- // This is just a safety net
157
- }
158
-
159
- /**
160
- * Close database connection
161
- */
162
- async close(): Promise<void> {
163
- // libSQL client doesn't have explicit close for file-based databases
164
- }
165
-
166
- /**
167
- * Get database path for debugging
168
- */
169
- getDatabasePath(): string {
170
- const homeDir = path.join(os.homedir(), '.sylphx-flow');
171
- const projectDir = path.join(process.cwd(), '.sylphx-flow');
172
- const memoryDir = this.useHomeDir ? homeDir : projectDir;
173
- return path.join(memoryDir, 'memory.db');
174
- }
175
-
176
- /**
177
- * Get migration status
178
- */
179
- async getMigrationStatus(): Promise<{
180
- isMigrated: boolean;
181
- migrationCount: number;
182
- }> {
183
- try {
184
- // Check if our main tables exist
185
- const result = await this.client.execute(`
186
- SELECT name FROM sqlite_master
187
- WHERE type='table' AND name IN ('memory', 'codebase_files', 'tfidf_terms')
188
- `);
189
-
190
- return {
191
- isMigrated: result.rows.length >= 2, // At least memory and codebase_files
192
- migrationCount: result.rows.length,
193
- };
194
- } catch (error) {
195
- throw new DatabaseError(
196
- 'Failed to check migration status',
197
- 'getMigrationStatus',
198
- error as Error
199
- );
200
- }
201
- }
202
-
203
- /**
204
- * Perform database health check
205
- */
206
- async healthCheck(): Promise<{
207
- healthy: boolean;
208
- error?: string;
209
- details?: Record<string, unknown>;
210
- }> {
211
- try {
212
- // Test basic connectivity
213
- await this.client.execute('SELECT 1');
214
-
215
- // Check if critical tables exist
216
- const migrationStatus = await this.getMigrationStatus();
217
-
218
- // Test basic read/write operation
219
- const testResult = await this.client.execute(`
220
- SELECT count(*) as count FROM memory
221
- `);
222
-
223
- return {
224
- healthy: true,
225
- details: {
226
- tablesExist: migrationStatus.isMigrated,
227
- tableCount: migrationStatus.migrationCount,
228
- memoryEntries: testResult.rows[0]?.count || 0,
229
- },
230
- };
231
- } catch (error) {
232
- return {
233
- healthy: false,
234
- error: (error as Error).message,
235
- };
236
- }
237
- }
238
- }
239
-
240
- // Export schema and types
241
- export * from './schema.js';
242
- export { schema };
243
-
244
- // Re-export commonly used database functions (these will be added when memory-db is fully implemented)
245
- // export {
246
- // storeMemory,
247
- // retrieveMemory,
248
- // searchMemory,
249
- // clearMemory,
250
- // } from './memory-db';
251
-
252
- export { isDatabaseError } from '../utils/database-errors';
@@ -1,153 +0,0 @@
1
- /**
2
- * Memory database client - 永久記憶數據庫
3
- * 負責管理需要持久化和版本控制的記憶數據
4
- */
5
-
6
- import * as path from 'node:path';
7
- import type { drizzle } from 'drizzle-orm/libsql';
8
- import { DatabaseError } from '../utils/database-errors.js';
9
- import { BaseDatabaseClient } from './base-database-client.js';
10
- import * as schema from './memory-schema.js';
11
-
12
- export type MemoryDatabase = ReturnType<typeof drizzle<typeof schema>>;
13
-
14
- export class MemoryDatabaseClient extends BaseDatabaseClient<typeof schema> {
15
- constructor() {
16
- super('memory', schema);
17
- }
18
-
19
- /**
20
- * Initialize memory database schema
21
- */
22
- async initialize(): Promise<void> {
23
- try {
24
- // Check if tables already exist
25
- const migrationStatus = await this.getMigrationStatus();
26
-
27
- if (migrationStatus.isMigrated) {
28
- // Tables already exist, skip logging to reduce noise
29
- return;
30
- }
31
-
32
- // Run migrations
33
- const _migrationsPath = path.join(process.cwd(), 'drizzle', 'memory');
34
-
35
- // For now, create tables directly since we don't have migration files yet
36
- await this.createTables();
37
- console.error('[INFO] Memory database tables created');
38
- } catch (error) {
39
- throw new DatabaseError(
40
- 'Failed to initialize memory database',
41
- 'memory.initialize',
42
- error as Error
43
- );
44
- }
45
- }
46
-
47
- /**
48
- * Create tables directly (fallback)
49
- */
50
- private async createTables(): Promise<void> {
51
- // Create memory table
52
- await this.createTable(`
53
- CREATE TABLE IF NOT EXISTS memory_table (
54
- key TEXT NOT NULL,
55
- namespace TEXT NOT NULL DEFAULT 'default',
56
- value TEXT NOT NULL,
57
- timestamp INTEGER NOT NULL,
58
- created_at TEXT NOT NULL,
59
- updated_at TEXT NOT NULL,
60
- PRIMARY KEY (key, namespace)
61
- )
62
- `);
63
-
64
- // Create indexes
65
- await this.createIndex(`
66
- CREATE INDEX IF NOT EXISTS idx_memory_namespace ON memory_table (namespace)
67
- `);
68
-
69
- await this.createIndex(`
70
- CREATE INDEX IF NOT EXISTS idx_memory_timestamp ON memory_table (timestamp)
71
- `);
72
-
73
- await this.createIndex(`
74
- CREATE INDEX IF NOT EXISTS idx_memory_key ON memory_table (key)
75
- `);
76
- }
77
-
78
- /**
79
- * Get migration status
80
- */
81
- async getMigrationStatus(): Promise<{
82
- isMigrated: boolean;
83
- migrationCount: number;
84
- }> {
85
- try {
86
- const exists = await this.tableExists('memory_table');
87
- return {
88
- isMigrated: exists,
89
- migrationCount: exists ? 1 : 0,
90
- };
91
- } catch (error) {
92
- throw new DatabaseError(
93
- 'Failed to check memory database migration status',
94
- 'memory.getMigrationStatus',
95
- error as Error
96
- );
97
- }
98
- }
99
-
100
- /**
101
- * Perform database health check
102
- */
103
- async healthCheck(): Promise<{
104
- healthy: boolean;
105
- error?: string;
106
- details?: Record<string, unknown>;
107
- }> {
108
- try {
109
- // Test basic connectivity
110
- await this.client.execute('SELECT 1');
111
-
112
- // Check if memory table exists
113
- const migrationStatus = await this.getMigrationStatus();
114
-
115
- // Test basic read/write operation
116
- const testResult = await this.client.execute(`
117
- SELECT count(*) as count FROM memory_table
118
- `);
119
-
120
- return {
121
- healthy: true,
122
- details: {
123
- tablesExist: migrationStatus.isMigrated,
124
- memoryEntries: testResult.rows[0]?.count || 0,
125
- },
126
- };
127
- } catch (error) {
128
- return {
129
- healthy: false,
130
- error: (error as Error).message,
131
- };
132
- }
133
- }
134
-
135
- /**
136
- * Close database connection
137
- */
138
- async close(): Promise<void> {
139
- // libSQL client doesn't have explicit close for file-based databases
140
- }
141
-
142
- /**
143
- * Get database path for debugging
144
- */
145
- getDatabasePath(): string {
146
- const memoryDir = path.join(process.cwd(), '.sylphx-flow');
147
- return path.join(memoryDir, 'memory.db');
148
- }
149
- }
150
-
151
- // Export schema and types
152
- export * from './memory-schema.js';
153
- export { schema };
@@ -1,29 +0,0 @@
1
- /**
2
- * Memory database schema - 永久記憶數據 (應該上 Git)
3
- * 包含用戶記憶、協調數據等需要持久化的信息
4
- */
5
-
6
- import { index, integer, primaryKey, sqliteTable, text } from 'drizzle-orm/sqlite-core';
7
-
8
- // Memory table for persistent storage (永久記憶)
9
- export const memory = sqliteTable(
10
- 'memory_table',
11
- {
12
- key: text('key').notNull(),
13
- namespace: text('namespace').notNull().default('default'),
14
- value: text('value').notNull(),
15
- timestamp: integer('timestamp').notNull(),
16
- created_at: text('created_at').notNull(),
17
- updated_at: text('updated_at').notNull(),
18
- },
19
- (table) => [
20
- primaryKey({ columns: [table.key, table.namespace] }),
21
- index('idx_memory_namespace').on(table.namespace),
22
- index('idx_memory_timestamp').on(table.timestamp),
23
- index('idx_memory_key').on(table.key),
24
- ]
25
- );
26
-
27
- // Types for memory database
28
- export type Memory = typeof memory.$inferSelect;
29
- export type NewMemory = typeof memory.$inferInsert;