claude-flow 2.0.0-alpha.62 → 2.0.0-alpha.64
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/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +54 -0
- package/.claude/commands/analysis/token-efficiency.md +2 -1
- package/.claude/commands/automation/self-healing.md +47 -2
- package/.claude/commands/automation/session-memory.md +39 -10
- package/.claude/commands/automation/smart-agents.md +36 -8
- package/.claude/commands/github/code-review-swarm.md +80 -15
- package/.claude/commands/github/github-modes.md +14 -14
- package/.claude/commands/github/issue-tracker.md +19 -16
- package/.claude/commands/github/multi-repo-swarm.md +114 -16
- package/.claude/commands/github/pr-manager.md +5 -4
- package/.claude/commands/github/project-board-sync.md +38 -5
- package/.claude/commands/github/release-manager.md +19 -19
- package/.claude/commands/github/release-swarm.md +102 -13
- package/.claude/commands/github/repo-architect.md +6 -6
- package/.claude/commands/github/swarm-issue.md +139 -17
- package/.claude/commands/github/swarm-pr.md +49 -15
- package/.claude/commands/github/sync-coordinator.md +33 -33
- package/.claude/commands/github/workflow-automation.md +37 -10
- package/.claude/commands/hooks/overview.md +2 -2
- package/.claude/commands/hooks/setup.md +7 -7
- package/.claude/commands/memory/neural.md +10 -5
- package/.claude/commands/memory/usage.md +9 -5
- package/.claude/commands/monitoring/agents.md +7 -5
- package/.claude/commands/monitoring/status.md +8 -5
- package/.claude/commands/optimization/auto-topology.md +13 -1
- package/.claude/commands/optimization/parallel-execution.md +7 -1
- package/.claude/commands/sparc/analyzer.md +28 -2
- package/.claude/commands/sparc/architect.md +27 -1
- package/.claude/commands/sparc/batch-executor.md +27 -1
- package/.claude/commands/sparc/coder.md +27 -1
- package/.claude/commands/sparc/debugger.md +27 -1
- package/.claude/commands/sparc/designer.md +27 -1
- package/.claude/commands/sparc/documenter.md +27 -1
- package/.claude/commands/sparc/innovator.md +27 -1
- package/.claude/commands/sparc/memory-manager.md +27 -1
- package/.claude/commands/sparc/optimizer.md +27 -1
- package/.claude/commands/sparc/orchestrator.md +106 -2
- package/.claude/commands/sparc/researcher.md +27 -1
- package/.claude/commands/sparc/reviewer.md +27 -1
- package/.claude/commands/sparc/sparc-modes.md +137 -5
- package/.claude/commands/sparc/swarm-coordinator.md +27 -1
- package/.claude/commands/sparc/tdd.md +27 -1
- package/.claude/commands/sparc/tester.md +27 -1
- package/.claude/commands/sparc/workflow-manager.md +27 -1
- package/.claude/commands/swarm/analysis.md +82 -5
- package/.claude/commands/swarm/development.md +83 -6
- package/.claude/commands/swarm/examples.md +141 -3
- package/.claude/commands/swarm/maintenance.md +92 -8
- package/.claude/commands/swarm/optimization.md +107 -9
- package/.claude/commands/swarm/research.md +126 -8
- package/.claude/commands/swarm/testing.md +121 -9
- package/.claude/commands/training/neural-patterns.md +27 -2
- package/.claude/commands/training/specialization.md +13 -3
- package/.claude/commands/workflows/development.md +43 -4
- package/.claude/commands/workflows/research.md +26 -2
- package/CHANGELOG.md +34 -0
- package/README.md +8 -0
- package/bin/claude-flow +1 -1
- package/dist/cli/simple-commands/hive-mind/mcp-wrapper.d.ts +66 -0
- package/dist/cli/simple-commands/hive-mind/mcp-wrapper.d.ts.map +1 -1
- package/dist/cli/simple-commands/hive-mind/mcp-wrapper.js +220 -2
- package/dist/cli/simple-commands/hive-mind/mcp-wrapper.js.map +1 -1
- package/dist/cli/simple-commands/hive-mind.d.ts.map +1 -1
- package/dist/cli/simple-commands/hive-mind.js +83 -5
- package/dist/cli/simple-commands/hive-mind.js.map +1 -1
- package/dist/memory/fallback-store.d.ts +1 -0
- package/dist/memory/fallback-store.d.ts.map +1 -1
- package/dist/memory/fallback-store.js +25 -3
- package/dist/memory/fallback-store.js.map +1 -1
- package/dist/memory/sqlite-store.d.ts +34 -0
- package/dist/memory/sqlite-store.d.ts.map +1 -0
- package/dist/memory/sqlite-store.js +2 -3
- package/dist/memory/sqlite-store.js.map +1 -1
- package/dist/memory/sqlite-wrapper.d.ts +38 -0
- package/dist/memory/sqlite-wrapper.d.ts.map +1 -0
- package/dist/memory/sqlite-wrapper.js +157 -0
- package/dist/memory/sqlite-wrapper.js.map +1 -0
- package/package.json +1 -1
- package/src/api/claude-api-errors.ts +248 -0
- package/src/api/claude-client-enhanced.ts +616 -0
- package/src/api/claude-client.ts +282 -14
- package/src/cli/help-text.js +4 -3
- package/src/cli/simple-cli.js +1 -1
- package/src/cli/simple-commands/coordination.js +73 -49
- package/src/cli/simple-commands/hive-mind/auto-save-middleware.js +6 -6
- package/src/cli/simple-commands/hive-mind/mcp-wrapper.js +327 -8
- package/src/cli/simple-commands/hive-mind/session-manager.js +330 -108
- package/src/cli/simple-commands/hive-mind.js +192 -11
- package/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +53 -28
- package/src/cli/simple-commands/init/claude-commands/slash-commands.js +36 -14
- package/src/cli/simple-commands/init/claude-commands/sparc-commands.js +107 -30
- package/src/cli/simple-commands/init/copy-revised-templates.js +175 -0
- package/src/cli/simple-commands/init/index.js +156 -235
- package/src/cli/simple-commands/init/template-copier.js +583 -0
- package/src/cli/simple-commands/init/templates/claude-flow-universal +1 -1
- package/src/cli/simple-commands/init/templates/coordination.md +16 -0
- package/src/cli/simple-commands/init/templates/memory-bank.md +16 -0
- package/src/cli/simple-commands/init/templates/settings.json.enhanced +35 -0
- package/src/cli/simple-commands/init/templates/sparc-modes.js +634 -23
- package/src/hive-mind/core/DatabaseManager.ts +75 -16
- package/src/memory/backends/sqlite.ts +21 -3
- package/src/memory/fallback-store.js +35 -3
- package/src/memory/sqlite-store.js +2 -3
- package/src/memory/sqlite-wrapper.js +173 -0
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
* using SQLite as the persistence layer.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import Database from 'better-sqlite3';
|
|
9
8
|
import path from 'path';
|
|
10
9
|
import fs from 'fs/promises';
|
|
11
10
|
import { EventEmitter } from 'events';
|
|
@@ -15,11 +14,25 @@ import { fileURLToPath } from 'url';
|
|
|
15
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
16
15
|
const __dirname = path.dirname(__filename);
|
|
17
16
|
|
|
17
|
+
// Dynamic import for SQLite wrapper
|
|
18
|
+
let createDatabase: any;
|
|
19
|
+
let isSQLiteAvailable: any;
|
|
20
|
+
let isWindows: any;
|
|
21
|
+
|
|
22
|
+
async function loadSQLiteWrapper() {
|
|
23
|
+
const module = await import('../../memory/sqlite-wrapper.js');
|
|
24
|
+
createDatabase = module.createDatabase;
|
|
25
|
+
isSQLiteAvailable = module.isSQLiteAvailable;
|
|
26
|
+
isWindows = module.isWindows;
|
|
27
|
+
}
|
|
28
|
+
|
|
18
29
|
export class DatabaseManager extends EventEmitter {
|
|
19
30
|
private static instance: DatabaseManager;
|
|
20
|
-
private db: Database
|
|
21
|
-
private statements: Map<string,
|
|
31
|
+
private db: any; // Database instance or in-memory fallback
|
|
32
|
+
private statements: Map<string, any>;
|
|
22
33
|
private dbPath: string;
|
|
34
|
+
private isInMemory: boolean = false;
|
|
35
|
+
private memoryStore: any = null;
|
|
23
36
|
|
|
24
37
|
private constructor() {
|
|
25
38
|
super();
|
|
@@ -41,24 +54,70 @@ export class DatabaseManager extends EventEmitter {
|
|
|
41
54
|
* Initialize database
|
|
42
55
|
*/
|
|
43
56
|
async initialize(): Promise<void> {
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
// Load SQLite wrapper functions
|
|
58
|
+
await loadSQLiteWrapper();
|
|
59
|
+
|
|
60
|
+
// Check if SQLite is available
|
|
61
|
+
const sqliteAvailable = await isSQLiteAvailable();
|
|
62
|
+
|
|
63
|
+
if (!sqliteAvailable) {
|
|
64
|
+
console.warn('SQLite not available, using in-memory storage for Hive Mind');
|
|
65
|
+
this.initializeInMemoryFallback();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
try {
|
|
70
|
+
// Ensure data directory exists
|
|
71
|
+
const dataDir = path.join(process.cwd(), 'data');
|
|
72
|
+
await fs.mkdir(dataDir, { recursive: true });
|
|
50
73
|
|
|
51
|
-
|
|
52
|
-
|
|
74
|
+
// Set database path
|
|
75
|
+
this.dbPath = path.join(dataDir, 'hive-mind.db');
|
|
53
76
|
|
|
54
|
-
|
|
55
|
-
|
|
77
|
+
// Open database
|
|
78
|
+
this.db = await createDatabase(this.dbPath);
|
|
56
79
|
|
|
57
|
-
|
|
58
|
-
|
|
80
|
+
// Enable foreign keys
|
|
81
|
+
this.db.pragma('foreign_keys = ON');
|
|
59
82
|
|
|
60
|
-
|
|
61
|
-
|
|
83
|
+
// Load schema
|
|
84
|
+
await this.loadSchema();
|
|
85
|
+
|
|
86
|
+
// Prepare statements
|
|
87
|
+
this.prepareStatements();
|
|
88
|
+
|
|
89
|
+
this.emit('initialized');
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error('Failed to initialize SQLite database:', error);
|
|
92
|
+
console.warn('Falling back to in-memory storage');
|
|
93
|
+
this.initializeInMemoryFallback();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Initialize in-memory fallback
|
|
99
|
+
*/
|
|
100
|
+
private initializeInMemoryFallback(): void {
|
|
101
|
+
this.isInMemory = true;
|
|
102
|
+
this.memoryStore = {
|
|
103
|
+
swarms: new Map(),
|
|
104
|
+
agents: new Map(),
|
|
105
|
+
tasks: new Map(),
|
|
106
|
+
memory: new Map(),
|
|
107
|
+
communications: new Map(),
|
|
108
|
+
performance_metrics: new Map(),
|
|
109
|
+
consensus: new Map()
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Create mock statement methods
|
|
113
|
+
this.statements = new Map();
|
|
114
|
+
|
|
115
|
+
if (isWindows && isWindows()) {
|
|
116
|
+
console.info(`
|
|
117
|
+
Note: Hive Mind data will not persist between runs on Windows without SQLite.
|
|
118
|
+
For persistent storage options, see: https://github.com/ruvnet/claude-code-flow/docs/windows-installation.md
|
|
119
|
+
`);
|
|
120
|
+
}
|
|
62
121
|
|
|
63
122
|
this.emit('initialized');
|
|
64
123
|
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* SQLite backend implementation for memory storage
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import Database from 'better-sqlite3';
|
|
6
5
|
import { promises as fs } from 'fs';
|
|
7
6
|
import path from 'path';
|
|
8
7
|
import type { IMemoryBackend } from './base.js';
|
|
@@ -10,11 +9,16 @@ import type { MemoryEntry, MemoryQuery } from '../../utils/types.js';
|
|
|
10
9
|
import type { ILogger } from '../../core/logger.js';
|
|
11
10
|
import { MemoryBackendError } from '../../utils/errors.js';
|
|
12
11
|
|
|
12
|
+
// Dynamic imports for SQLite
|
|
13
|
+
let createDatabase: any;
|
|
14
|
+
let isSQLiteAvailable: any;
|
|
15
|
+
|
|
13
16
|
/**
|
|
14
17
|
* SQLite-based memory backend
|
|
15
18
|
*/
|
|
16
19
|
export class SQLiteBackend implements IMemoryBackend {
|
|
17
|
-
private db?:
|
|
20
|
+
private db?: any;
|
|
21
|
+
private sqliteLoaded: boolean = false;
|
|
18
22
|
|
|
19
23
|
constructor(
|
|
20
24
|
private dbPath: string,
|
|
@@ -25,12 +29,26 @@ export class SQLiteBackend implements IMemoryBackend {
|
|
|
25
29
|
this.logger.info('Initializing SQLite backend', { dbPath: this.dbPath });
|
|
26
30
|
|
|
27
31
|
try {
|
|
32
|
+
// Load SQLite wrapper if not loaded
|
|
33
|
+
if (!this.sqliteLoaded) {
|
|
34
|
+
const module = await import('../sqlite-wrapper.js');
|
|
35
|
+
createDatabase = module.createDatabase;
|
|
36
|
+
isSQLiteAvailable = module.isSQLiteAvailable;
|
|
37
|
+
this.sqliteLoaded = true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check if SQLite is available
|
|
41
|
+
const sqliteAvailable = await isSQLiteAvailable();
|
|
42
|
+
if (!sqliteAvailable) {
|
|
43
|
+
throw new Error('SQLite module not available');
|
|
44
|
+
}
|
|
45
|
+
|
|
28
46
|
// Ensure directory exists
|
|
29
47
|
const dir = path.dirname(this.dbPath);
|
|
30
48
|
await fs.mkdir(dir, { recursive: true });
|
|
31
49
|
|
|
32
50
|
// Open SQLite connection
|
|
33
|
-
this.db =
|
|
51
|
+
this.db = await createDatabase(this.dbPath);
|
|
34
52
|
|
|
35
53
|
// Enable WAL mode for better performance
|
|
36
54
|
this.db.pragma('journal_mode = WAL');
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { SqliteMemoryStore } from './sqlite-store.js';
|
|
7
7
|
import { InMemoryStore } from './in-memory-store.js';
|
|
8
|
+
import { isSQLiteAvailable, getLoadError, isWindows } from './sqlite-wrapper.js';
|
|
8
9
|
|
|
9
10
|
class FallbackMemoryStore {
|
|
10
11
|
constructor(options = {}) {
|
|
@@ -19,7 +20,27 @@ class FallbackMemoryStore {
|
|
|
19
20
|
if (this.initializationAttempted) return;
|
|
20
21
|
this.initializationAttempted = true;
|
|
21
22
|
|
|
22
|
-
//
|
|
23
|
+
// Check if SQLite is available before attempting initialization
|
|
24
|
+
const sqliteAvailable = await isSQLiteAvailable();
|
|
25
|
+
|
|
26
|
+
if (!sqliteAvailable) {
|
|
27
|
+
// Skip SQLite initialization if module can't be loaded
|
|
28
|
+
const loadError = getLoadError();
|
|
29
|
+
console.error(
|
|
30
|
+
`[${new Date().toISOString()}] WARN [fallback-store] SQLite module not available:`,
|
|
31
|
+
loadError?.message || 'Unknown error',
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Use in-memory store directly
|
|
35
|
+
this.fallbackStore = new InMemoryStore(this.options);
|
|
36
|
+
await this.fallbackStore.initialize();
|
|
37
|
+
this.useFallback = true;
|
|
38
|
+
|
|
39
|
+
this._logFallbackUsage();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Try to initialize SQLite store
|
|
23
44
|
try {
|
|
24
45
|
this.primaryStore = new SqliteMemoryStore(this.options);
|
|
25
46
|
await this.primaryStore.initialize();
|
|
@@ -29,7 +50,7 @@ class FallbackMemoryStore {
|
|
|
29
50
|
this.useFallback = false;
|
|
30
51
|
} catch (error) {
|
|
31
52
|
console.error(
|
|
32
|
-
`[${new Date().toISOString()}] WARN [fallback-store] SQLite initialization failed
|
|
53
|
+
`[${new Date().toISOString()}] WARN [fallback-store] SQLite initialization failed:`,
|
|
33
54
|
error.message,
|
|
34
55
|
);
|
|
35
56
|
|
|
@@ -38,9 +59,20 @@ class FallbackMemoryStore {
|
|
|
38
59
|
await this.fallbackStore.initialize();
|
|
39
60
|
this.useFallback = true;
|
|
40
61
|
|
|
62
|
+
this._logFallbackUsage();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_logFallbackUsage() {
|
|
67
|
+
console.error(
|
|
68
|
+
`[${new Date().toISOString()}] INFO [fallback-store] Using in-memory store (data will not persist across sessions)`,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (isWindows()) {
|
|
41
72
|
console.error(
|
|
42
|
-
`[${new Date().toISOString()}] INFO [fallback-store]
|
|
73
|
+
`[${new Date().toISOString()}] INFO [fallback-store] Windows detected. For persistent storage options, see: https://github.com/ruvnet/claude-code-flow/docs/windows-installation.md`,
|
|
43
74
|
);
|
|
75
|
+
} else {
|
|
44
76
|
console.error(
|
|
45
77
|
`[${new Date().toISOString()}] INFO [fallback-store] To enable persistent storage, install the package locally: npm install claude-flow@alpha`,
|
|
46
78
|
);
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
* Provides persistent storage that works with both local and remote npx execution
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
// @ts-ignore
|
|
7
|
-
import Database from 'better-sqlite3';
|
|
8
6
|
import path from 'path';
|
|
9
7
|
import { promises as fs } from 'fs';
|
|
10
8
|
import { fileURLToPath } from 'url';
|
|
11
9
|
import os from 'os';
|
|
10
|
+
import { createDatabase } from './sqlite-wrapper.js';
|
|
12
11
|
|
|
13
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
13
|
const __dirname = path.dirname(__filename);
|
|
@@ -54,7 +53,7 @@ class SqliteMemoryStore {
|
|
|
54
53
|
|
|
55
54
|
// Open database
|
|
56
55
|
const dbPath = path.join(this.options.directory, this.options.dbName);
|
|
57
|
-
this.db =
|
|
56
|
+
this.db = await createDatabase(dbPath);
|
|
58
57
|
|
|
59
58
|
// Enable WAL mode for better concurrency
|
|
60
59
|
this.db.pragma('journal_mode = WAL');
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Wrapper with Windows Fallback Support
|
|
3
|
+
* Provides graceful fallback when better-sqlite3 fails to load
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createRequire } from 'module';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
let Database = null;
|
|
14
|
+
let sqliteAvailable = false;
|
|
15
|
+
let loadError = null;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Try to load better-sqlite3 with comprehensive error handling
|
|
19
|
+
*/
|
|
20
|
+
function tryLoadSQLite() {
|
|
21
|
+
try {
|
|
22
|
+
// Try ES module import
|
|
23
|
+
const module = import('better-sqlite3');
|
|
24
|
+
return module.then(m => {
|
|
25
|
+
Database = m.default;
|
|
26
|
+
sqliteAvailable = true;
|
|
27
|
+
return true;
|
|
28
|
+
}).catch(err => {
|
|
29
|
+
loadError = err;
|
|
30
|
+
return false;
|
|
31
|
+
});
|
|
32
|
+
} catch (err) {
|
|
33
|
+
// Fallback to CommonJS require
|
|
34
|
+
try {
|
|
35
|
+
const require = createRequire(import.meta.url);
|
|
36
|
+
Database = require('better-sqlite3');
|
|
37
|
+
sqliteAvailable = true;
|
|
38
|
+
return Promise.resolve(true);
|
|
39
|
+
} catch (requireErr) {
|
|
40
|
+
loadError = requireErr;
|
|
41
|
+
|
|
42
|
+
// Check for specific Windows errors
|
|
43
|
+
if (requireErr.message.includes('was compiled against a different Node.js version') ||
|
|
44
|
+
requireErr.message.includes('Could not locate the bindings file') ||
|
|
45
|
+
requireErr.message.includes('The specified module could not be found') ||
|
|
46
|
+
requireErr.code === 'MODULE_NOT_FOUND') {
|
|
47
|
+
|
|
48
|
+
console.warn(`
|
|
49
|
+
╔══════════════════════════════════════════════════════════════════════════════╗
|
|
50
|
+
║ Windows SQLite Installation Issue ║
|
|
51
|
+
╠══════════════════════════════════════════════════════════════════════════════╣
|
|
52
|
+
║ ║
|
|
53
|
+
║ The native SQLite module failed to load. This is common on Windows when ║
|
|
54
|
+
║ using 'npx' or when node-gyp build tools are not available. ║
|
|
55
|
+
║ ║
|
|
56
|
+
║ Claude Flow will continue with in-memory storage (non-persistent). ║
|
|
57
|
+
║ ║
|
|
58
|
+
║ To enable persistent storage on Windows: ║
|
|
59
|
+
║ ║
|
|
60
|
+
║ Option 1 - Install Windows Build Tools: ║
|
|
61
|
+
║ > npm install --global windows-build-tools ║
|
|
62
|
+
║ > npm install claude-flow@alpha ║
|
|
63
|
+
║ ║
|
|
64
|
+
║ Option 2 - Use Pre-built Binaries: ║
|
|
65
|
+
║ > npm config set python python3 ║
|
|
66
|
+
║ > npm install claude-flow@alpha --build-from-source=false ║
|
|
67
|
+
║ ║
|
|
68
|
+
║ Option 3 - Use WSL (Windows Subsystem for Linux): ║
|
|
69
|
+
║ Install WSL and run Claude Flow inside a Linux environment ║
|
|
70
|
+
║ ║
|
|
71
|
+
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
72
|
+
`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return Promise.resolve(false);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if SQLite is available
|
|
82
|
+
*/
|
|
83
|
+
export async function isSQLiteAvailable() {
|
|
84
|
+
if (sqliteAvailable !== null) {
|
|
85
|
+
return sqliteAvailable;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
await tryLoadSQLite();
|
|
89
|
+
return sqliteAvailable;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get SQLite Database constructor or null
|
|
94
|
+
*/
|
|
95
|
+
export async function getSQLiteDatabase() {
|
|
96
|
+
if (!sqliteAvailable && loadError === null) {
|
|
97
|
+
await tryLoadSQLite();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return Database;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get the load error if any
|
|
105
|
+
*/
|
|
106
|
+
export function getLoadError() {
|
|
107
|
+
return loadError;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Create a SQLite database instance with fallback
|
|
112
|
+
*/
|
|
113
|
+
export async function createDatabase(dbPath) {
|
|
114
|
+
const DB = await getSQLiteDatabase();
|
|
115
|
+
|
|
116
|
+
if (!DB) {
|
|
117
|
+
throw new Error('SQLite is not available. Use fallback storage instead.');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
return new DB(dbPath);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
// Additional Windows-specific error handling
|
|
124
|
+
if (err.message.includes('EPERM') || err.message.includes('access denied')) {
|
|
125
|
+
throw new Error(`Cannot create database at ${dbPath}. Permission denied. Try using a different directory or running with administrator privileges.`);
|
|
126
|
+
}
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Check if running on Windows
|
|
133
|
+
*/
|
|
134
|
+
export function isWindows() {
|
|
135
|
+
return process.platform === 'win32';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get platform-specific storage recommendations
|
|
140
|
+
*/
|
|
141
|
+
export function getStorageRecommendations() {
|
|
142
|
+
if (isWindows()) {
|
|
143
|
+
return {
|
|
144
|
+
recommended: 'in-memory',
|
|
145
|
+
reason: 'Windows native module compatibility',
|
|
146
|
+
alternatives: [
|
|
147
|
+
'Install Windows build tools for SQLite support',
|
|
148
|
+
'Use WSL (Windows Subsystem for Linux)',
|
|
149
|
+
'Use Docker container with Linux'
|
|
150
|
+
]
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
recommended: 'sqlite',
|
|
156
|
+
reason: 'Best performance and persistence',
|
|
157
|
+
alternatives: ['in-memory for testing']
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Pre-load SQLite on module import
|
|
162
|
+
tryLoadSQLite().catch(() => {
|
|
163
|
+
// Silently handle initial load failure
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
export default {
|
|
167
|
+
isSQLiteAvailable,
|
|
168
|
+
getSQLiteDatabase,
|
|
169
|
+
getLoadError,
|
|
170
|
+
createDatabase,
|
|
171
|
+
isWindows,
|
|
172
|
+
getStorageRecommendations
|
|
173
|
+
};
|