@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.
- package/CHANGELOG.md +78 -0
- package/assets/agents/coder.md +72 -119
- package/assets/agents/orchestrator.md +26 -90
- package/assets/agents/reviewer.md +76 -47
- package/assets/agents/writer.md +82 -63
- package/assets/output-styles/silent.md +141 -8
- package/assets/rules/code-standards.md +9 -33
- package/assets/rules/core.md +67 -59
- package/package.json +2 -12
- package/src/commands/flow/execute.ts +470 -0
- package/src/commands/flow/index.ts +11 -0
- package/src/commands/flow/prompt.ts +35 -0
- package/src/commands/flow/setup.ts +312 -0
- package/src/commands/flow/targets.ts +18 -0
- package/src/commands/flow/types.ts +47 -0
- package/src/commands/flow-command.ts +18 -967
- package/src/commands/flow-orchestrator.ts +14 -5
- package/src/commands/hook-command.ts +1 -1
- package/src/commands/init-core.ts +12 -3
- package/src/commands/run-command.ts +1 -1
- package/src/config/rules.ts +1 -1
- package/src/core/error-handling.ts +1 -1
- package/src/core/loop-controller.ts +1 -1
- package/src/core/state-detector.ts +1 -1
- package/src/core/target-manager.ts +1 -1
- package/src/index.ts +1 -1
- package/src/shared/files/index.ts +1 -1
- package/src/shared/processing/index.ts +1 -1
- package/src/targets/claude-code.ts +3 -3
- package/src/targets/opencode.ts +3 -3
- package/src/utils/agent-enhancer.ts +2 -2
- package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
- package/src/utils/{paths.ts → config/paths.ts} +1 -1
- package/src/utils/{settings.ts → config/settings.ts} +1 -1
- package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
- package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
- package/src/utils/display/banner.ts +25 -0
- package/src/utils/display/status.ts +55 -0
- package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
- package/src/utils/files/jsonc.ts +36 -0
- package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
- package/src/utils/index.ts +42 -61
- package/src/utils/version.ts +47 -0
- package/src/components/benchmark-monitor.tsx +0 -331
- package/src/components/reindex-progress.tsx +0 -261
- package/src/composables/functional/index.ts +0 -14
- package/src/composables/functional/useEnvironment.ts +0 -171
- package/src/composables/functional/useFileSystem.ts +0 -139
- package/src/composables/index.ts +0 -4
- package/src/composables/useEnv.ts +0 -13
- package/src/composables/useRuntimeConfig.ts +0 -27
- package/src/core/ai-sdk.ts +0 -603
- package/src/core/app-factory.ts +0 -381
- package/src/core/builtin-agents.ts +0 -9
- package/src/core/command-system.ts +0 -550
- package/src/core/config-system.ts +0 -550
- package/src/core/connection-pool.ts +0 -390
- package/src/core/di-container.ts +0 -155
- package/src/core/headless-display.ts +0 -96
- package/src/core/interfaces/index.ts +0 -22
- package/src/core/interfaces/repository.interface.ts +0 -91
- package/src/core/interfaces/service.interface.ts +0 -133
- package/src/core/interfaces.ts +0 -96
- package/src/core/result.ts +0 -351
- package/src/core/service-config.ts +0 -252
- package/src/core/session-service.ts +0 -121
- package/src/core/storage-factory.ts +0 -115
- package/src/core/stream-handler.ts +0 -288
- package/src/core/type-utils.ts +0 -427
- package/src/core/unified-storage.ts +0 -456
- package/src/core/validation/limit.ts +0 -46
- package/src/core/validation/query.ts +0 -20
- package/src/db/auto-migrate.ts +0 -322
- package/src/db/base-database-client.ts +0 -144
- package/src/db/cache-db.ts +0 -218
- package/src/db/cache-schema.ts +0 -75
- package/src/db/database.ts +0 -70
- package/src/db/index.ts +0 -252
- package/src/db/memory-db.ts +0 -153
- package/src/db/memory-schema.ts +0 -29
- package/src/db/schema.ts +0 -289
- package/src/db/session-repository.ts +0 -733
- package/src/domains/index.ts +0 -6
- package/src/domains/utilities/index.ts +0 -6
- package/src/domains/utilities/time/index.ts +0 -5
- package/src/domains/utilities/time/tools.ts +0 -291
- package/src/services/agent-service.ts +0 -273
- package/src/services/evaluation-service.ts +0 -271
- package/src/services/functional/evaluation-logic.ts +0 -296
- package/src/services/functional/file-processor.ts +0 -273
- package/src/services/functional/index.ts +0 -12
- package/src/services/memory.service.ts +0 -476
- package/src/types/api/batch.ts +0 -108
- package/src/types/api/errors.ts +0 -118
- package/src/types/api/index.ts +0 -55
- package/src/types/api/requests.ts +0 -76
- package/src/types/api/responses.ts +0 -180
- package/src/types/api/websockets.ts +0 -85
- package/src/types/benchmark.ts +0 -49
- package/src/types/database.types.ts +0 -510
- package/src/types/memory-types.ts +0 -63
- package/src/utils/advanced-tokenizer.ts +0 -191
- package/src/utils/ai-model-fetcher.ts +0 -19
- package/src/utils/async-file-operations.ts +0 -516
- package/src/utils/audio-player.ts +0 -345
- package/src/utils/codebase-helpers.ts +0 -211
- package/src/utils/console-ui.ts +0 -79
- package/src/utils/database-errors.ts +0 -140
- package/src/utils/debug-logger.ts +0 -49
- package/src/utils/file-scanner.ts +0 -259
- package/src/utils/help.ts +0 -20
- package/src/utils/immutable-cache.ts +0 -106
- package/src/utils/jsonc.ts +0 -158
- package/src/utils/memory-tui.ts +0 -414
- package/src/utils/models-dev.ts +0 -91
- package/src/utils/parallel-operations.ts +0 -487
- package/src/utils/process-manager.ts +0 -155
- package/src/utils/prompts.ts +0 -120
- package/src/utils/search-tool-builder.ts +0 -214
- package/src/utils/session-manager.ts +0 -168
- package/src/utils/session-title.ts +0 -87
- package/src/utils/simplified-errors.ts +0 -410
- package/src/utils/template-engine.ts +0 -94
- package/src/utils/test-audio.ts +0 -71
- package/src/utils/todo-context.ts +0 -46
- package/src/utils/token-counter.ts +0 -288
- /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
- /package/src/utils/{logger.ts → display/logger.ts} +0 -0
- /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
- /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
- /package/src/utils/{security.ts → security/security.ts} +0 -0
package/src/db/cache-schema.ts
DELETED
|
@@ -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;
|
package/src/db/database.ts
DELETED
|
@@ -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';
|
package/src/db/memory-db.ts
DELETED
|
@@ -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 };
|
package/src/db/memory-schema.ts
DELETED
|
@@ -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;
|