@jungjaehoon/mama-core 1.0.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/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # @jungjaehoon/mama-core
2
+
3
+ Shared core modules for MAMA (Memory-Augmented MCP Assistant).
4
+
5
+ ## What is MAMA Core?
6
+
7
+ MAMA Core is a shared package containing the fundamental modules used by all MAMA packages:
8
+
9
+ - **mcp-server**: MCP protocol server
10
+ - **claude-code-plugin**: Claude Code plugin
11
+ - **standalone**: Standalone HTTP server
12
+
13
+ This package provides embedding generation, database management, decision tracking, and other core functionality without the transport layer (MCP/HTTP).
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @jungjaehoon/mama-core
19
+ # or
20
+ pnpm add @jungjaehoon/mama-core
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### Import Everything
26
+
27
+ ```javascript
28
+ const mama = require('@jungjaehoon/mama-core');
29
+
30
+ // Access all exported functions
31
+ const embedding = await mama.generateEmbedding('your text');
32
+ await mama.initDB();
33
+ ```
34
+
35
+ ### Import Specific Modules
36
+
37
+ ```javascript
38
+ const { generateEmbedding } = require('@jungjaehoon/mama-core/embeddings');
39
+ const { initDB, getDB } = require('@jungjaehoon/mama-core/db-manager');
40
+ const mamaApi = require('@jungjaehoon/mama-core/mama-api');
41
+ ```
42
+
43
+ ## Available Modules
44
+
45
+ ### Embedding Modules
46
+
47
+ - **embeddings** - Generate embeddings using Transformers.js
48
+ - `generateEmbedding(text)` - Single text embedding
49
+ - `generateBatchEmbeddings(texts)` - Batch embedding generation
50
+ - `cosineSimilarity(a, b)` - Similarity calculation
51
+
52
+ - **embedding-cache** - In-memory embedding cache
53
+ - `embeddingCache.get(key)` - Retrieve cached embedding
54
+ - `embeddingCache.set(key, value)` - Store embedding
55
+ - `embeddingCache.clear()` - Clear cache
56
+
57
+ - **embedding-client** - HTTP client for embedding server
58
+ - `isServerRunning()` - Check server availability
59
+ - `getEmbeddingFromServer(text)` - Get embedding via HTTP
60
+ - `getServerStatus()` - Server health check
61
+
62
+ ### Database Modules
63
+
64
+ - **db-manager** - SQLite database initialization
65
+ - `initDB()` - Initialize database with migrations
66
+ - `getDB()` - Get database connection
67
+ - `closeDB()` - Close connection
68
+
69
+ - **db-adapter** - Database adapter interface
70
+ - `createAdapter(type)` - Create SQLite adapter
71
+ - Supports prepared statements and transactions
72
+
73
+ - **memory-store** - Decision storage operations
74
+ - CRUD operations for decisions
75
+ - Vector similarity search
76
+
77
+ ### Core API
78
+
79
+ - **mama-api** - High-level API interface
80
+ - `save(decision)` - Save decision
81
+ - `recall(topic)` - Retrieve decision history
82
+ - `suggest(query)` - Semantic search
83
+ - `updateOutcome(id, outcome)` - Update decision outcome
84
+
85
+ - **decision-tracker** - Decision graph management
86
+ - `learnDecision(decision)` - Learn from decision
87
+ - `createEdgesFromReasoning(reasoning)` - Parse decision links
88
+
89
+ - **relevance-scorer** - Semantic similarity scoring
90
+ - `scoreRelevance(query, decisions)` - Score decision relevance
91
+ - Combines vector, graph, and recency signals
92
+
93
+ ### Configuration
94
+
95
+ - **config-loader** - Configuration management
96
+ - `loadConfig()` - Load MAMA configuration
97
+ - `getModelName()` - Get embedding model name
98
+ - `getEmbeddingDim()` - Get embedding dimensions
99
+ - `updateConfig(config)` - Update configuration
100
+
101
+ ## Environment Variables
102
+
103
+ - `MAMA_DB_PATH` - Database file path (default: `~/.claude/mama-memory.db`)
104
+ - `MAMA_HTTP_PORT` - Embedding server port (default: `3847`)
105
+
106
+ ## Dependencies
107
+
108
+ - **@huggingface/transformers** - Local embedding generation
109
+ - **better-sqlite3** - SQLite database
110
+ - **sqlite-vec** - Vector similarity extension
111
+
112
+ ## Development
113
+
114
+ ```bash
115
+ # Install dependencies
116
+ pnpm install
117
+
118
+ # Run tests
119
+ pnpm test
120
+
121
+ # Watch mode
122
+ pnpm test:watch
123
+ ```
124
+
125
+ ## Test Coverage
126
+
127
+ - 35 unit tests
128
+ - 100% passing
129
+ - Tests cover:
130
+ - Config loader
131
+ - Database initialization
132
+ - Module exports
133
+
134
+ ## Architecture
135
+
136
+ MAMA Core uses CommonJS modules and is designed to be shared across multiple packages:
137
+
138
+ ```
139
+ packages/mama-core/
140
+ ├── src/
141
+ │ ├── index.js # Main exports
142
+ │ ├── embeddings.js # Embedding generation
143
+ │ ├── db-manager.js # Database management
144
+ │ ├── mama-api.js # High-level API
145
+ │ └── db-adapter/ # Database adapter
146
+ ├── db/migrations/ # SQLite migrations
147
+ └── tests/ # Unit tests
148
+ ```
149
+
150
+ ## Migration Files
151
+
152
+ Database migrations are included in `db/migrations/`:
153
+
154
+ - 001-initial-decision-graph.sql
155
+ - 002-add-error-patterns.sql
156
+ - 003-add-validation-fields.sql
157
+ - (and more...)
158
+
159
+ ## License
160
+
161
+ MIT - see LICENSE file for details
162
+
163
+ ## Links
164
+
165
+ - [GitHub Repository](https://github.com/jungjaehoon-lifegamez/MAMA)
166
+ - [Documentation](https://github.com/jungjaehoon-lifegamez/MAMA/tree/main/docs)
167
+ - [Issues](https://github.com/jungjaehoon-lifegamez/MAMA/issues)
168
+
169
+ ---
170
+
171
+ **Part of the MAMA monorepo** - Memory-Augmented MCP Assistant
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@jungjaehoon/mama-core",
3
+ "version": "1.0.1",
4
+ "description": "MAMA Core - Shared modules for Memory-Augmented MCP Assistant",
5
+ "main": "src/index.js",
6
+ "exports": {
7
+ ".": "./src/index.js",
8
+ "./embeddings": "./src/embeddings.js",
9
+ "./embedding-cache": "./src/embedding-cache.js",
10
+ "./embedding-client": "./src/embedding-client.js",
11
+ "./embedding-server": "./src/embedding-server/index.js",
12
+ "./memory-store": "./src/memory-store.js",
13
+ "./db-manager": "./src/db-manager.js",
14
+ "./db-adapter": "./src/db-adapter/index.js",
15
+ "./mama-api": "./src/mama-api.js",
16
+ "./config-loader": "./src/config-loader.js",
17
+ "./relevance-scorer": "./src/relevance-scorer.js",
18
+ "./decision-tracker": "./src/decision-tracker.js",
19
+ "./debug-logger": "./src/debug-logger.js",
20
+ "./decision-formatter": "./src/decision-formatter.js",
21
+ "./memory-inject": "./src/memory-inject.js",
22
+ "./ollama-client": "./src/ollama-client.js"
23
+ },
24
+ "scripts": {
25
+ "test": "vitest run",
26
+ "test:watch": "vitest watch",
27
+ "clean": "rm -rf node_modules"
28
+ },
29
+ "keywords": [
30
+ "mama",
31
+ "memory-assistant",
32
+ "decision-tracking",
33
+ "semantic-search",
34
+ "embeddings",
35
+ "sqlite",
36
+ "mcp"
37
+ ],
38
+ "author": "SpineLift Team",
39
+ "license": "MIT",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/jungjaehoon-lifegamez/MAMA.git",
43
+ "directory": "packages/mama-core"
44
+ },
45
+ "bugs": {
46
+ "url": "https://github.com/jungjaehoon-lifegamez/MAMA/issues"
47
+ },
48
+ "homepage": "https://github.com/jungjaehoon-lifegamez/MAMA#readme",
49
+ "engines": {
50
+ "node": ">=18.0.0"
51
+ },
52
+ "dependencies": {
53
+ "@anthropic-ai/sdk": "^0.72.1",
54
+ "@huggingface/transformers": "^3.8.1",
55
+ "better-sqlite3": "^11.0.0",
56
+ "sqlite-vec": "^0.1.0",
57
+ "ws": "^8.19.0"
58
+ },
59
+ "devDependencies": {
60
+ "@types/better-sqlite3": "^7.6.0",
61
+ "vitest": "^1.0.0"
62
+ },
63
+ "files": [
64
+ "src/**/*.js",
65
+ "README.md",
66
+ "LICENSE"
67
+ ]
68
+ }
@@ -0,0 +1,218 @@
1
+ /**
2
+ * MAMA Configuration Loader
3
+ *
4
+ * Story M1.4: Configurable embedding model selection
5
+ * Priority: P1 (Core Feature)
6
+ *
7
+ * Loads user configuration from ~/.mama/config.json with sensible defaults.
8
+ * Supports:
9
+ * - Model selection (default: multilingual-e5-small)
10
+ * - Embedding dimensions
11
+ * - Cache directory configuration
12
+ *
13
+ * @module config-loader
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+ const os = require('os');
19
+ const { info, warn, error: logError } = require('./debug-logger');
20
+
21
+ // Default configuration
22
+ const DEFAULT_CONFIG = {
23
+ modelName: 'Xenova/multilingual-e5-small',
24
+ embeddingDim: 384,
25
+ cacheDir: path.join(os.homedir(), '.cache', 'huggingface', 'transformers'),
26
+ };
27
+
28
+ // Config file path
29
+ const CONFIG_DIR = path.join(os.homedir(), '.mama');
30
+ const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
31
+
32
+ // Cached configuration
33
+ let cachedConfig = null;
34
+
35
+ /**
36
+ * Ensure config directory exists
37
+ * @returns {void}
38
+ */
39
+ function ensureConfigDir() {
40
+ if (!fs.existsSync(CONFIG_DIR)) {
41
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
42
+ info(`[config] Created config directory: ${CONFIG_DIR}`);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Create default config file if it doesn't exist
48
+ * @returns {void}
49
+ */
50
+ function ensureConfigFile() {
51
+ if (!fs.existsSync(CONFIG_PATH)) {
52
+ ensureConfigDir();
53
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(DEFAULT_CONFIG, null, 2), 'utf8');
54
+ info(`[config] Created default config file: ${CONFIG_PATH}`);
55
+ info(`[config] Model: ${DEFAULT_CONFIG.modelName} (${DEFAULT_CONFIG.embeddingDim}-dim)`);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Load MAMA configuration from ~/.mama/config.json
61
+ *
62
+ * Story M1.4 AC #1: Config parser loads ~/.mama/config.json
63
+ *
64
+ * @param {boolean} reload - Force reload from disk (default: false)
65
+ * @returns {Object} Configuration object with modelName, embeddingDim, cacheDir
66
+ */
67
+ function loadConfig(reload = false) {
68
+ // Return cached config if available and not forcing reload
69
+ if (cachedConfig && !reload) {
70
+ return cachedConfig;
71
+ }
72
+
73
+ try {
74
+ // Ensure config file exists
75
+ ensureConfigFile();
76
+
77
+ // Read and parse config file
78
+ const configData = fs.readFileSync(CONFIG_PATH, 'utf8');
79
+ const userConfig = JSON.parse(configData);
80
+
81
+ // Merge with defaults (user config overrides)
82
+ const config = {
83
+ ...DEFAULT_CONFIG,
84
+ ...userConfig,
85
+ };
86
+
87
+ // Validate configuration
88
+ if (!config.modelName || typeof config.modelName !== 'string') {
89
+ warn('[config] Invalid modelName, using default:', DEFAULT_CONFIG.modelName);
90
+ config.modelName = DEFAULT_CONFIG.modelName;
91
+ }
92
+
93
+ if (!Number.isInteger(config.embeddingDim) || config.embeddingDim <= 0) {
94
+ warn('[config] Invalid embeddingDim, using default:', DEFAULT_CONFIG.embeddingDim);
95
+ config.embeddingDim = DEFAULT_CONFIG.embeddingDim;
96
+ }
97
+
98
+ if (!config.cacheDir || typeof config.cacheDir !== 'string') {
99
+ warn('[config] Invalid cacheDir, using default:', DEFAULT_CONFIG.cacheDir);
100
+ config.cacheDir = DEFAULT_CONFIG.cacheDir;
101
+ }
102
+
103
+ // Cache the loaded config
104
+ cachedConfig = config;
105
+
106
+ // Log loaded configuration
107
+ if (reload) {
108
+ info(`[config] Configuration reloaded from ${CONFIG_PATH}`);
109
+ info(`[config] Model: ${config.modelName} (${config.embeddingDim}-dim)`);
110
+ info(`[config] Cache: ${config.cacheDir}`);
111
+ }
112
+
113
+ return config;
114
+ } catch (error) {
115
+ logError(`[config] Failed to load config file: ${error.message}`);
116
+ logError('[config] Using default configuration');
117
+
118
+ // Cache defaults on error
119
+ cachedConfig = { ...DEFAULT_CONFIG };
120
+ return cachedConfig;
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Get current model name
126
+ * @returns {string} Current model name
127
+ */
128
+ function getModelName() {
129
+ const config = loadConfig();
130
+ return config.modelName;
131
+ }
132
+
133
+ /**
134
+ * Get current embedding dimension
135
+ * @returns {number} Current embedding dimension
136
+ */
137
+ function getEmbeddingDim() {
138
+ const config = loadConfig();
139
+ return config.embeddingDim;
140
+ }
141
+
142
+ /**
143
+ * Get current cache directory
144
+ * @returns {string} Current cache directory
145
+ */
146
+ function getCacheDir() {
147
+ const config = loadConfig();
148
+ return config.cacheDir;
149
+ }
150
+
151
+ /**
152
+ * Update configuration and save to file
153
+ *
154
+ * Story M1.4 AC #3: Changing model via config triggers informative log + resets caches
155
+ *
156
+ * @param {Object} updates - Configuration updates
157
+ * @param {string} updates.modelName - New model name
158
+ * @param {number} updates.embeddingDim - New embedding dimension
159
+ * @param {string} updates.cacheDir - New cache directory
160
+ * @returns {boolean} Success status
161
+ */
162
+ function updateConfig(updates) {
163
+ try {
164
+ ensureConfigFile();
165
+
166
+ // Load current config
167
+ const currentConfig = loadConfig();
168
+
169
+ // Check if model is changing
170
+ const modelChanged = updates.modelName && updates.modelName !== currentConfig.modelName;
171
+ const dimChanged = updates.embeddingDim && updates.embeddingDim !== currentConfig.embeddingDim;
172
+
173
+ // Merge updates
174
+ const newConfig = {
175
+ ...currentConfig,
176
+ ...updates,
177
+ };
178
+
179
+ // Save to file
180
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(newConfig, null, 2), 'utf8');
181
+
182
+ // Update cache
183
+ cachedConfig = newConfig;
184
+
185
+ // Story M1.4 AC #3: Informative log when model changes
186
+ if (modelChanged || dimChanged) {
187
+ info('[config] ⚠️ Embedding model configuration changed');
188
+ info(`[config] Old: ${currentConfig.modelName} (${currentConfig.embeddingDim}-dim)`);
189
+ info(`[config] New: ${newConfig.modelName} (${newConfig.embeddingDim}-dim)`);
190
+ info('[config] ⚡ Model cache will be reset on next embedding generation');
191
+ info('[config] ⚡ Existing embeddings in database remain unchanged');
192
+ }
193
+
194
+ info(`[config] Configuration saved to ${CONFIG_PATH}`);
195
+ return true;
196
+ } catch (error) {
197
+ logError(`[config] Failed to update config: ${error.message}`);
198
+ return false;
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Get config file path
204
+ * @returns {string} Config file path
205
+ */
206
+ function getConfigPath() {
207
+ return CONFIG_PATH;
208
+ }
209
+
210
+ module.exports = {
211
+ loadConfig,
212
+ getModelName,
213
+ getEmbeddingDim,
214
+ getCacheDir,
215
+ updateConfig,
216
+ getConfigPath,
217
+ DEFAULT_CONFIG,
218
+ };
@@ -0,0 +1,110 @@
1
+ # Database Adapter Layer
2
+
3
+ ## Overview
4
+
5
+ Abstraction layer for MAMA database to support both SQLite (development/testing) and PostgreSQL (production on Railway).
6
+
7
+ ## Architecture
8
+
9
+ ```
10
+ mama-api.js
11
+
12
+ memory-store.js (business logic)
13
+
14
+ DatabaseAdapter (interface)
15
+
16
+ ├── SQLiteAdapter (better-sqlite3 + sqlite-vss)
17
+ └── PostgreSQLAdapter (pg + pgvector)
18
+ ```
19
+
20
+ ## Decision Rationale
21
+
22
+ **Topic**: mama_db_adapter_pattern
23
+ **Decision**: Abstract database layer with driver-specific implementations
24
+ **Reasoning**:
25
+
26
+ 1. **Environment Flexibility**: SQLite for local/testing, PostgreSQL for production
27
+ 2. **Zero Breaking Changes**: Existing memory-store.js API remains unchanged
28
+ 3. **Vector Search Portability**: sqlite-vss → pgvector migration path
29
+ 4. **Testing Simplicity**: Fast SQLite tests, production PostgreSQL validation
30
+
31
+ ## Adapter Interface
32
+
33
+ All adapters must implement:
34
+
35
+ ```javascript
36
+ class DatabaseAdapter {
37
+ // Connection
38
+ connect(config) → db
39
+ disconnect()
40
+ isConnected() → boolean
41
+
42
+ // Prepared Statements
43
+ prepare(sql) → Statement
44
+ exec(sql)
45
+ transaction(fn) → result
46
+
47
+ // Vector Search
48
+ vectorSearch(embedding, limit) → results
49
+ insertEmbedding(rowid, embedding)
50
+
51
+ // Utility
52
+ getLastInsertRowid() → number
53
+ }
54
+ ```
55
+
56
+ ## Implementation Files
57
+
58
+ - `index.js` - Factory + environment detection
59
+ - `sqlite-adapter.js` - SQLite implementation (current behavior)
60
+ - `postgresql-adapter.js` - PostgreSQL implementation
61
+ - `statement.js` - Statement wrapper (unified interface)
62
+
63
+ ## Environment Variable
64
+
65
+ ```bash
66
+ # Default: SQLite
67
+ MAMA_DB_PATH=~/.mama/memories.db
68
+
69
+ # PostgreSQL (Railway)
70
+ MAMA_DATABASE_URL=postgresql://user:pass@host:5432/mama_db
71
+ ```
72
+
73
+ **Detection Logic**:
74
+
75
+ - If `MAMA_DATABASE_URL` set → PostgreSQL
76
+ - Else → SQLite with `MAMA_DB_PATH`
77
+
78
+ ## Migration Strategy
79
+
80
+ ### Phase 1: Adapter Layer (Current)
81
+
82
+ 1. Create adapter interface
83
+ 2. Extract SQLite logic to SQLiteAdapter
84
+ 3. Update memory-store.js to use adapter
85
+
86
+ ### Phase 2: PostgreSQL Support
87
+
88
+ 1. Implement PostgreSQLAdapter
89
+ 2. Convert migration SQL files
90
+ 3. Add pgvector support
91
+
92
+ ### Phase 3: Testing
93
+
94
+ 1. Run existing tests with SQLite
95
+ 2. Add PostgreSQL integration tests
96
+ 3. Validate on Railway
97
+
98
+ ## Performance Requirements
99
+
100
+ - Prepared statement caching
101
+ - Connection pooling (PostgreSQL only)
102
+ - Transaction batching support
103
+ - Vector search < 100ms (p95)
104
+
105
+ ## Backward Compatibility
106
+
107
+ ✅ Existing code works without changes
108
+ ✅ SQLite remains default for development
109
+ ✅ Environment variable controls database type
110
+ ✅ No API changes to memory-store.js
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Base Database Adapter Interface
3
+ * All adapters must implement these methods
4
+ */
5
+ class DatabaseAdapter {
6
+ /**
7
+ * Connect to database
8
+ * @returns {Object} Database connection
9
+ */
10
+ connect() {
11
+ throw new Error('connect() must be implemented by subclass');
12
+ }
13
+
14
+ /**
15
+ * Disconnect from database
16
+ */
17
+ disconnect() {
18
+ throw new Error('disconnect() must be implemented by subclass');
19
+ }
20
+
21
+ /**
22
+ * Check if connected
23
+ * @returns {boolean} Connection status
24
+ */
25
+ isConnected() {
26
+ throw new Error('isConnected() must be implemented by subclass');
27
+ }
28
+
29
+ /**
30
+ * Prepare a SQL statement
31
+ * @param {string} _sql - SQL query
32
+ * @returns {Statement} Prepared statement
33
+ */
34
+ prepare(_sql) {
35
+ throw new Error('prepare() must be implemented by subclass');
36
+ }
37
+
38
+ /**
39
+ * Execute raw SQL
40
+ * @param {string} _sql - SQL to execute
41
+ */
42
+ exec(_sql) {
43
+ throw new Error('exec() must be implemented by subclass');
44
+ }
45
+
46
+ /**
47
+ * Execute function in transaction
48
+ * @param {Function} _fn - Function to execute
49
+ * @returns {*} Function return value
50
+ */
51
+ transaction(_fn) {
52
+ throw new Error('transaction() must be implemented by subclass');
53
+ }
54
+
55
+ /**
56
+ * Vector similarity search
57
+ * @param {number[]} _embedding - Query embedding (384-dim)
58
+ * @param {number} _limit - Max results
59
+ * @returns {Array<Object>} Search results with distance
60
+ */
61
+ vectorSearch(_embedding, _limit) {
62
+ throw new Error('vectorSearch() must be implemented by subclass');
63
+ }
64
+
65
+ /**
66
+ * Insert vector embedding
67
+ * @param {number} _rowid - Decision rowid
68
+ * @param {number[]} _embedding - Embedding vector
69
+ */
70
+ insertEmbedding(_rowid, _embedding) {
71
+ throw new Error('insertEmbedding() must be implemented by subclass');
72
+ }
73
+
74
+ /**
75
+ * Get last inserted row ID
76
+ * @returns {number} Last rowid
77
+ */
78
+ getLastInsertRowid() {
79
+ throw new Error('getLastInsertRowid() must be implemented by subclass');
80
+ }
81
+
82
+ /**
83
+ * Run migrations
84
+ * @param {string} _migrationsDir - Path to migrations directory
85
+ */
86
+ runMigrations(_migrationsDir) {
87
+ throw new Error('runMigrations() must be implemented by subclass');
88
+ }
89
+ }
90
+
91
+ module.exports = { DatabaseAdapter };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Database Adapter Factory (SQLite-only)
3
+ *
4
+ * MAMA Plugin uses SQLite exclusively for local storage.
5
+ * PostgreSQL support is only available in the legacy mcp-server.
6
+ *
7
+ * @module db-adapter
8
+ */
9
+
10
+ const { info } = require('../debug-logger');
11
+ const SQLiteAdapter = require('./sqlite-adapter');
12
+
13
+ /**
14
+ * Create SQLite database adapter
15
+ *
16
+ * @param {Object} config - Database configuration
17
+ * @param {string} [config.dbPath] - SQLite file path (overrides env)
18
+ * @returns {DatabaseAdapter} Configured SQLite adapter instance
19
+ */
20
+ function createAdapter(config = {}) {
21
+ info('[db-adapter] Using SQLite adapter (plugin mode)');
22
+ const dbPath = config.dbPath || process.env.MAMA_DB_PATH;
23
+ return new SQLiteAdapter({ dbPath });
24
+ }
25
+
26
+ const { DatabaseAdapter } = require('./base-adapter');
27
+
28
+ module.exports = {
29
+ createAdapter,
30
+ DatabaseAdapter,
31
+ };