@stackmemoryai/stackmemory 0.6.3 → 0.8.0
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/dist/src/cli/commands/clear.js +10 -15
- package/dist/src/cli/commands/clear.js.map +2 -2
- package/dist/src/cli/commands/daemon.js +31 -0
- package/dist/src/cli/commands/daemon.js.map +2 -2
- package/dist/src/core/context/refactored-frame-manager.js +7 -0
- package/dist/src/core/context/refactored-frame-manager.js.map +2 -2
- package/dist/src/core/database/database-adapter.js +45 -0
- package/dist/src/core/database/database-adapter.js.map +2 -2
- package/dist/src/core/database/embedding-provider-factory.js +73 -0
- package/dist/src/core/database/embedding-provider-factory.js.map +7 -0
- package/dist/src/core/database/ollama-embedding-provider.js +31 -0
- package/dist/src/core/database/ollama-embedding-provider.js.map +7 -0
- package/dist/src/core/database/openai-embedding-provider.js +44 -0
- package/dist/src/core/database/openai-embedding-provider.js.map +7 -0
- package/dist/src/core/database/sqlite-adapter.js +419 -21
- package/dist/src/core/database/sqlite-adapter.js.map +3 -3
- package/dist/src/core/retrieval/context-retriever.js +20 -3
- package/dist/src/core/retrieval/context-retriever.js.map +2 -2
- package/dist/src/core/session/enhanced-handoff.js +1 -1
- package/dist/src/core/session/enhanced-handoff.js.map +2 -2
- package/dist/src/core/storage/project-registry.js +61 -0
- package/dist/src/core/storage/project-registry.js.map +7 -0
- package/dist/src/core/storage/storage-tier-manager.js +214 -0
- package/dist/src/core/storage/storage-tier-manager.js.map +7 -0
- package/dist/src/daemon/daemon-config.js +11 -0
- package/dist/src/daemon/daemon-config.js.map +2 -2
- package/dist/src/daemon/services/maintenance-service.js +110 -3
- package/dist/src/daemon/services/maintenance-service.js.map +2 -2
- package/dist/src/daemon/services/memory-service.js +190 -0
- package/dist/src/daemon/services/memory-service.js.map +7 -0
- package/dist/src/daemon/unified-daemon.js +39 -5
- package/dist/src/daemon/unified-daemon.js.map +2 -2
- package/package.json +1 -1
|
@@ -18,12 +18,14 @@ import {
|
|
|
18
18
|
import { DaemonContextService } from "./services/context-service.js";
|
|
19
19
|
import { DaemonLinearService } from "./services/linear-service.js";
|
|
20
20
|
import { DaemonMaintenanceService } from "./services/maintenance-service.js";
|
|
21
|
+
import { DaemonMemoryService } from "./services/memory-service.js";
|
|
21
22
|
class UnifiedDaemon {
|
|
22
23
|
config;
|
|
23
24
|
paths;
|
|
24
25
|
contextService;
|
|
25
26
|
linearService;
|
|
26
27
|
maintenanceService;
|
|
28
|
+
memoryService;
|
|
27
29
|
heartbeatInterval;
|
|
28
30
|
isShuttingDown = false;
|
|
29
31
|
startTime = 0;
|
|
@@ -42,6 +44,10 @@ class UnifiedDaemon {
|
|
|
42
44
|
this.config.maintenance,
|
|
43
45
|
(level, msg, data) => this.log(level, "maintenance", msg, data)
|
|
44
46
|
);
|
|
47
|
+
this.memoryService = new DaemonMemoryService(
|
|
48
|
+
this.config.memory,
|
|
49
|
+
(level, msg, data) => this.log(level, "memory", msg, data)
|
|
50
|
+
);
|
|
45
51
|
}
|
|
46
52
|
log(level, service, message, data) {
|
|
47
53
|
const logLevel = level.toUpperCase();
|
|
@@ -95,6 +101,7 @@ class UnifiedDaemon {
|
|
|
95
101
|
}
|
|
96
102
|
updateStatus() {
|
|
97
103
|
const maintenanceState = this.maintenanceService.getState();
|
|
104
|
+
const memoryState = this.memoryService.getState();
|
|
98
105
|
const status = {
|
|
99
106
|
running: true,
|
|
100
107
|
pid: process.pid,
|
|
@@ -116,7 +123,15 @@ class UnifiedDaemon {
|
|
|
116
123
|
lastRun: maintenanceState.lastRunTime || void 0,
|
|
117
124
|
staleFramesCleaned: maintenanceState.staleFramesCleaned,
|
|
118
125
|
ftsRebuilds: maintenanceState.ftsRebuilds,
|
|
119
|
-
embeddingsGenerated: maintenanceState.embeddingsGenerated
|
|
126
|
+
embeddingsGenerated: maintenanceState.embeddingsGenerated,
|
|
127
|
+
embeddingsTotal: maintenanceState.embeddingsTotal,
|
|
128
|
+
embeddingsRemaining: maintenanceState.embeddingsRemaining
|
|
129
|
+
},
|
|
130
|
+
memory: {
|
|
131
|
+
enabled: this.config.memory.enabled,
|
|
132
|
+
lastTrigger: memoryState.lastTriggerTime || void 0,
|
|
133
|
+
triggerCount: memoryState.triggerCount,
|
|
134
|
+
currentRamPercent: memoryState.currentRamPercent
|
|
120
135
|
},
|
|
121
136
|
fileWatch: {
|
|
122
137
|
enabled: this.config.fileWatch.enabled
|
|
@@ -125,7 +140,8 @@ class UnifiedDaemon {
|
|
|
125
140
|
errors: [
|
|
126
141
|
...this.contextService.getState().errors.slice(-5),
|
|
127
142
|
...this.linearService.getState().errors.slice(-5),
|
|
128
|
-
...maintenanceState.errors.slice(-5)
|
|
143
|
+
...maintenanceState.errors.slice(-5),
|
|
144
|
+
...memoryState.errors.slice(-5)
|
|
129
145
|
]
|
|
130
146
|
};
|
|
131
147
|
writeDaemonStatus(status);
|
|
@@ -180,6 +196,10 @@ class UnifiedDaemon {
|
|
|
180
196
|
staleFramesCleaned: this.maintenanceService.getState().staleFramesCleaned,
|
|
181
197
|
ftsRebuilds: this.maintenanceService.getState().ftsRebuilds
|
|
182
198
|
},
|
|
199
|
+
memory: {
|
|
200
|
+
enabled: false,
|
|
201
|
+
triggerCount: this.memoryService.getState().triggerCount
|
|
202
|
+
},
|
|
183
203
|
fileWatch: { enabled: false }
|
|
184
204
|
},
|
|
185
205
|
errors: []
|
|
@@ -194,7 +214,8 @@ class UnifiedDaemon {
|
|
|
194
214
|
uptime: Date.now() - this.startTime,
|
|
195
215
|
contextSaves: this.contextService.getState().saveCount,
|
|
196
216
|
linearSyncs: this.linearService.getState().syncCount,
|
|
197
|
-
maintenanceRuns: this.maintenanceService.getState().ftsRebuilds
|
|
217
|
+
maintenanceRuns: this.maintenanceService.getState().ftsRebuilds,
|
|
218
|
+
memoryTriggers: this.memoryService.getState().triggerCount
|
|
198
219
|
});
|
|
199
220
|
if (this.heartbeatInterval) {
|
|
200
221
|
clearInterval(this.heartbeatInterval);
|
|
@@ -203,6 +224,7 @@ class UnifiedDaemon {
|
|
|
203
224
|
this.contextService.stop();
|
|
204
225
|
this.linearService.stop();
|
|
205
226
|
this.maintenanceService.stop();
|
|
227
|
+
this.memoryService.stop();
|
|
206
228
|
this.cleanup();
|
|
207
229
|
const exitCode = reason === "sigterm" || reason === "sigint" || reason === "sighup" ? 0 : 1;
|
|
208
230
|
process.exit(exitCode);
|
|
@@ -221,12 +243,14 @@ class UnifiedDaemon {
|
|
|
221
243
|
context: this.config.context.enabled,
|
|
222
244
|
linear: this.config.linear.enabled,
|
|
223
245
|
maintenance: this.config.maintenance.enabled,
|
|
246
|
+
memory: this.config.memory.enabled,
|
|
224
247
|
fileWatch: this.config.fileWatch.enabled
|
|
225
248
|
}
|
|
226
249
|
});
|
|
227
250
|
this.contextService.start();
|
|
228
251
|
await this.linearService.start();
|
|
229
252
|
this.maintenanceService.start();
|
|
253
|
+
this.memoryService.start();
|
|
230
254
|
this.heartbeatInterval = setInterval(() => {
|
|
231
255
|
this.updateStatus();
|
|
232
256
|
}, this.config.heartbeatInterval * 1e3);
|
|
@@ -234,6 +258,7 @@ class UnifiedDaemon {
|
|
|
234
258
|
}
|
|
235
259
|
getStatus() {
|
|
236
260
|
const maintenanceState = this.maintenanceService.getState();
|
|
261
|
+
const memoryState = this.memoryService.getState();
|
|
237
262
|
return {
|
|
238
263
|
running: !this.isShuttingDown,
|
|
239
264
|
pid: process.pid,
|
|
@@ -255,7 +280,15 @@ class UnifiedDaemon {
|
|
|
255
280
|
lastRun: maintenanceState.lastRunTime || void 0,
|
|
256
281
|
staleFramesCleaned: maintenanceState.staleFramesCleaned,
|
|
257
282
|
ftsRebuilds: maintenanceState.ftsRebuilds,
|
|
258
|
-
embeddingsGenerated: maintenanceState.embeddingsGenerated
|
|
283
|
+
embeddingsGenerated: maintenanceState.embeddingsGenerated,
|
|
284
|
+
embeddingsTotal: maintenanceState.embeddingsTotal,
|
|
285
|
+
embeddingsRemaining: maintenanceState.embeddingsRemaining
|
|
286
|
+
},
|
|
287
|
+
memory: {
|
|
288
|
+
enabled: this.config.memory.enabled,
|
|
289
|
+
lastTrigger: memoryState.lastTriggerTime || void 0,
|
|
290
|
+
triggerCount: memoryState.triggerCount,
|
|
291
|
+
currentRamPercent: memoryState.currentRamPercent
|
|
259
292
|
},
|
|
260
293
|
fileWatch: {
|
|
261
294
|
enabled: this.config.fileWatch.enabled
|
|
@@ -264,7 +297,8 @@ class UnifiedDaemon {
|
|
|
264
297
|
errors: [
|
|
265
298
|
...this.contextService.getState().errors,
|
|
266
299
|
...this.linearService.getState().errors,
|
|
267
|
-
...maintenanceState.errors
|
|
300
|
+
...maintenanceState.errors,
|
|
301
|
+
...memoryState.errors
|
|
268
302
|
]
|
|
269
303
|
};
|
|
270
304
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/daemon/unified-daemon.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\n/**\n * Unified Daemon for StackMemory\n *\n * Single background process managing multiple services:\n * - Context auto-save\n * - Linear sync\n * - File watch (future)\n */\n\nimport {\n existsSync,\n writeFileSync,\n unlinkSync,\n appendFileSync,\n readFileSync,\n} from 'fs';\nimport {\n loadDaemonConfig,\n getDaemonPaths,\n writeDaemonStatus,\n type DaemonConfig,\n type DaemonStatus,\n} from './daemon-config.js';\nimport { DaemonContextService } from './services/context-service.js';\nimport { DaemonLinearService } from './services/linear-service.js';\nimport { DaemonMaintenanceService } from './services/maintenance-service.js';\n\ninterface LogEntry {\n timestamp: string;\n level: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';\n service: string;\n message: string;\n data?: unknown;\n}\n\nexport class UnifiedDaemon {\n private config: DaemonConfig;\n private paths: ReturnType<typeof getDaemonPaths>;\n private contextService: DaemonContextService;\n private linearService: DaemonLinearService;\n private maintenanceService: DaemonMaintenanceService;\n private heartbeatInterval?: NodeJS.Timeout;\n private isShuttingDown = false;\n private startTime: number = 0;\n\n constructor(config?: Partial<DaemonConfig>) {\n this.paths = getDaemonPaths();\n this.config = { ...loadDaemonConfig(), ...config };\n\n // Initialize services\n this.contextService = new DaemonContextService(\n this.config.context,\n (level, msg, data) => this.log(level, 'context', msg, data)\n );\n\n this.linearService = new DaemonLinearService(\n this.config.linear,\n (level, msg, data) => this.log(level, 'linear', msg, data)\n );\n\n this.maintenanceService = new DaemonMaintenanceService(\n this.config.maintenance,\n (level, msg, data) => this.log(level, 'maintenance', msg, data)\n );\n }\n\n private log(\n level: string,\n service: string,\n message: string,\n data?: unknown\n ): void {\n const logLevel = level.toUpperCase() as LogEntry['level'];\n\n // Check log level\n const levels = ['DEBUG', 'INFO', 'WARN', 'ERROR'];\n const configLevel = this.config.logLevel.toUpperCase();\n if (levels.indexOf(logLevel) < levels.indexOf(configLevel)) {\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level: logLevel,\n service,\n message,\n data,\n };\n\n const logLine = JSON.stringify(entry) + '\\n';\n\n try {\n appendFileSync(this.paths.logFile, logLine);\n } catch {\n console.error(`[${entry.timestamp}] ${level} [${service}]: ${message}`);\n }\n }\n\n private checkIdempotency(): boolean {\n if (existsSync(this.paths.pidFile)) {\n try {\n const existingPid = readFileSync(this.paths.pidFile, 'utf8').trim();\n const pid = parseInt(existingPid, 10);\n\n // Check if process is running\n try {\n process.kill(pid, 0);\n this.log('WARN', 'daemon', 'Daemon already running', { pid });\n return false;\n } catch {\n // Process not running, stale PID\n this.log('INFO', 'daemon', 'Cleaning stale PID file', { pid });\n unlinkSync(this.paths.pidFile);\n }\n } catch {\n try {\n unlinkSync(this.paths.pidFile);\n } catch {\n // Ignore\n }\n }\n }\n return true;\n }\n\n private writePidFile(): void {\n writeFileSync(this.paths.pidFile, process.pid.toString());\n this.log('INFO', 'daemon', 'PID file created', {\n pid: process.pid,\n file: this.paths.pidFile,\n });\n }\n\n private updateStatus(): void {\n const maintenanceState = this.maintenanceService.getState();\n const status: DaemonStatus = {\n running: true,\n pid: process.pid,\n startTime: this.startTime,\n uptime: Date.now() - this.startTime,\n services: {\n context: {\n enabled: this.config.context.enabled,\n lastRun: this.contextService.getState().lastSaveTime || undefined,\n saveCount: this.contextService.getState().saveCount,\n },\n linear: {\n enabled: this.config.linear.enabled,\n lastRun: this.linearService.getState().lastSyncTime || undefined,\n syncCount: this.linearService.getState().syncCount,\n },\n maintenance: {\n enabled: this.config.maintenance.enabled,\n lastRun: maintenanceState.lastRunTime || undefined,\n staleFramesCleaned: maintenanceState.staleFramesCleaned,\n ftsRebuilds: maintenanceState.ftsRebuilds,\n embeddingsGenerated: maintenanceState.embeddingsGenerated,\n },\n fileWatch: {\n enabled: this.config.fileWatch.enabled,\n },\n },\n errors: [\n ...this.contextService.getState().errors.slice(-5),\n ...this.linearService.getState().errors.slice(-5),\n ...maintenanceState.errors.slice(-5),\n ],\n };\n\n writeDaemonStatus(status);\n }\n\n private setupSignalHandlers(): void {\n const handleSignal = (signal: string) => {\n this.log('INFO', 'daemon', `Received ${signal}, shutting down`);\n this.shutdown(signal.toLowerCase());\n };\n\n process.on('SIGTERM', () => handleSignal('SIGTERM'));\n process.on('SIGINT', () => handleSignal('SIGINT'));\n process.on('SIGHUP', () => handleSignal('SIGHUP'));\n\n process.on('uncaughtException', (err) => {\n this.log('ERROR', 'daemon', 'Uncaught exception', {\n error: err.message,\n stack: err.stack,\n });\n this.shutdown('uncaught_exception');\n });\n\n process.on('unhandledRejection', (reason) => {\n this.log('ERROR', 'daemon', 'Unhandled rejection', {\n reason: String(reason),\n });\n });\n }\n\n private cleanup(): void {\n // Remove PID file\n try {\n if (existsSync(this.paths.pidFile)) {\n unlinkSync(this.paths.pidFile);\n this.log('INFO', 'daemon', 'PID file removed');\n }\n } catch (e) {\n this.log('WARN', 'daemon', 'Failed to remove PID file', {\n error: String(e),\n });\n }\n\n // Update status\n const finalStatus: DaemonStatus = {\n running: false,\n startTime: this.startTime,\n uptime: Date.now() - this.startTime,\n services: {\n context: {\n enabled: false,\n saveCount: this.contextService.getState().saveCount,\n },\n linear: {\n enabled: false,\n syncCount: this.linearService.getState().syncCount,\n },\n maintenance: {\n enabled: false,\n staleFramesCleaned:\n this.maintenanceService.getState().staleFramesCleaned,\n ftsRebuilds: this.maintenanceService.getState().ftsRebuilds,\n },\n fileWatch: { enabled: false },\n },\n errors: [],\n };\n writeDaemonStatus(finalStatus);\n }\n\n private shutdown(reason: string): void {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n\n this.log('INFO', 'daemon', 'Daemon shutting down', {\n reason,\n uptime: Date.now() - this.startTime,\n contextSaves: this.contextService.getState().saveCount,\n linearSyncs: this.linearService.getState().syncCount,\n maintenanceRuns: this.maintenanceService.getState().ftsRebuilds,\n });\n\n // Stop heartbeat\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = undefined;\n }\n\n // Stop services\n this.contextService.stop();\n this.linearService.stop();\n this.maintenanceService.stop();\n\n // Cleanup\n this.cleanup();\n\n const exitCode =\n reason === 'sigterm' || reason === 'sigint' || reason === 'sighup'\n ? 0\n : 1;\n process.exit(exitCode);\n }\n\n async start(): Promise<void> {\n // Check idempotency\n if (!this.checkIdempotency()) {\n this.log('INFO', 'daemon', 'Exiting - daemon already running');\n process.exit(0);\n }\n\n this.startTime = Date.now();\n\n // Write PID file\n this.writePidFile();\n\n // Setup signal handlers\n this.setupSignalHandlers();\n\n this.log('INFO', 'daemon', 'Unified daemon started', {\n pid: process.pid,\n config: {\n context: this.config.context.enabled,\n linear: this.config.linear.enabled,\n maintenance: this.config.maintenance.enabled,\n fileWatch: this.config.fileWatch.enabled,\n },\n });\n\n // Start services\n this.contextService.start();\n await this.linearService.start();\n this.maintenanceService.start();\n\n // Start heartbeat\n this.heartbeatInterval = setInterval(() => {\n this.updateStatus();\n }, this.config.heartbeatInterval * 1000);\n\n // Initial status update\n this.updateStatus();\n }\n\n getStatus(): DaemonStatus {\n const maintenanceState = this.maintenanceService.getState();\n return {\n running: !this.isShuttingDown,\n pid: process.pid,\n startTime: this.startTime,\n uptime: Date.now() - this.startTime,\n services: {\n context: {\n enabled: this.config.context.enabled,\n lastRun: this.contextService.getState().lastSaveTime || undefined,\n saveCount: this.contextService.getState().saveCount,\n },\n linear: {\n enabled: this.config.linear.enabled,\n lastRun: this.linearService.getState().lastSyncTime || undefined,\n syncCount: this.linearService.getState().syncCount,\n },\n maintenance: {\n enabled: this.config.maintenance.enabled,\n lastRun: maintenanceState.lastRunTime || undefined,\n staleFramesCleaned: maintenanceState.staleFramesCleaned,\n ftsRebuilds: maintenanceState.ftsRebuilds,\n embeddingsGenerated: maintenanceState.embeddingsGenerated,\n },\n fileWatch: {\n enabled: this.config.fileWatch.enabled,\n },\n },\n errors: [\n ...this.contextService.getState().errors,\n ...this.linearService.getState().errors,\n ...maintenanceState.errors,\n ],\n };\n }\n}\n\n// CLI entry point\nif (\n import.meta.url === `file://${process.argv[1]}` ||\n process.argv[1]?.endsWith('unified-daemon.js')\n) {\n const args = process.argv.slice(2);\n const config: Partial<DaemonConfig> = {};\n\n // Parse command line args\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--save-interval' && args[i + 1]) {\n config.context = { enabled: true, interval: parseInt(args[i + 1], 10) };\n i++;\n } else if (arg === '--linear-interval' && args[i + 1]) {\n config.linear = {\n enabled: true,\n interval: parseInt(args[i + 1], 10),\n retryAttempts: 3,\n retryDelay: 30000,\n };\n i++;\n } else if (arg === '--no-linear') {\n config.linear = {\n enabled: false,\n interval: 60,\n retryAttempts: 3,\n retryDelay: 30000,\n };\n } else if (arg === '--log-level' && args[i + 1]) {\n config.logLevel = args[i + 1] as DaemonConfig['logLevel'];\n i++;\n }\n }\n\n const daemon = new UnifiedDaemon(config);\n daemon.start().catch((err) => {\n console.error('Failed to start daemon:', err);\n process.exit(1);\n });\n}\n"],
|
|
5
|
-
"mappings": ";;;;;AAWA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,SAAS,gCAAgC;
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\n/**\n * Unified Daemon for StackMemory\n *\n * Single background process managing multiple services:\n * - Context auto-save\n * - Linear sync\n * - File watch (future)\n */\n\nimport {\n existsSync,\n writeFileSync,\n unlinkSync,\n appendFileSync,\n readFileSync,\n} from 'fs';\nimport {\n loadDaemonConfig,\n getDaemonPaths,\n writeDaemonStatus,\n type DaemonConfig,\n type DaemonStatus,\n} from './daemon-config.js';\nimport { DaemonContextService } from './services/context-service.js';\nimport { DaemonLinearService } from './services/linear-service.js';\nimport { DaemonMaintenanceService } from './services/maintenance-service.js';\nimport { DaemonMemoryService } from './services/memory-service.js';\n\ninterface LogEntry {\n timestamp: string;\n level: 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';\n service: string;\n message: string;\n data?: unknown;\n}\n\nexport class UnifiedDaemon {\n private config: DaemonConfig;\n private paths: ReturnType<typeof getDaemonPaths>;\n private contextService: DaemonContextService;\n private linearService: DaemonLinearService;\n private maintenanceService: DaemonMaintenanceService;\n private memoryService: DaemonMemoryService;\n private heartbeatInterval?: NodeJS.Timeout;\n private isShuttingDown = false;\n private startTime: number = 0;\n\n constructor(config?: Partial<DaemonConfig>) {\n this.paths = getDaemonPaths();\n this.config = { ...loadDaemonConfig(), ...config };\n\n // Initialize services\n this.contextService = new DaemonContextService(\n this.config.context,\n (level, msg, data) => this.log(level, 'context', msg, data)\n );\n\n this.linearService = new DaemonLinearService(\n this.config.linear,\n (level, msg, data) => this.log(level, 'linear', msg, data)\n );\n\n this.maintenanceService = new DaemonMaintenanceService(\n this.config.maintenance,\n (level, msg, data) => this.log(level, 'maintenance', msg, data)\n );\n\n this.memoryService = new DaemonMemoryService(\n this.config.memory,\n (level, msg, data) => this.log(level, 'memory', msg, data)\n );\n }\n\n private log(\n level: string,\n service: string,\n message: string,\n data?: unknown\n ): void {\n const logLevel = level.toUpperCase() as LogEntry['level'];\n\n // Check log level\n const levels = ['DEBUG', 'INFO', 'WARN', 'ERROR'];\n const configLevel = this.config.logLevel.toUpperCase();\n if (levels.indexOf(logLevel) < levels.indexOf(configLevel)) {\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level: logLevel,\n service,\n message,\n data,\n };\n\n const logLine = JSON.stringify(entry) + '\\n';\n\n try {\n appendFileSync(this.paths.logFile, logLine);\n } catch {\n console.error(`[${entry.timestamp}] ${level} [${service}]: ${message}`);\n }\n }\n\n private checkIdempotency(): boolean {\n if (existsSync(this.paths.pidFile)) {\n try {\n const existingPid = readFileSync(this.paths.pidFile, 'utf8').trim();\n const pid = parseInt(existingPid, 10);\n\n // Check if process is running\n try {\n process.kill(pid, 0);\n this.log('WARN', 'daemon', 'Daemon already running', { pid });\n return false;\n } catch {\n // Process not running, stale PID\n this.log('INFO', 'daemon', 'Cleaning stale PID file', { pid });\n unlinkSync(this.paths.pidFile);\n }\n } catch {\n try {\n unlinkSync(this.paths.pidFile);\n } catch {\n // Ignore\n }\n }\n }\n return true;\n }\n\n private writePidFile(): void {\n writeFileSync(this.paths.pidFile, process.pid.toString());\n this.log('INFO', 'daemon', 'PID file created', {\n pid: process.pid,\n file: this.paths.pidFile,\n });\n }\n\n private updateStatus(): void {\n const maintenanceState = this.maintenanceService.getState();\n const memoryState = this.memoryService.getState();\n const status: DaemonStatus = {\n running: true,\n pid: process.pid,\n startTime: this.startTime,\n uptime: Date.now() - this.startTime,\n services: {\n context: {\n enabled: this.config.context.enabled,\n lastRun: this.contextService.getState().lastSaveTime || undefined,\n saveCount: this.contextService.getState().saveCount,\n },\n linear: {\n enabled: this.config.linear.enabled,\n lastRun: this.linearService.getState().lastSyncTime || undefined,\n syncCount: this.linearService.getState().syncCount,\n },\n maintenance: {\n enabled: this.config.maintenance.enabled,\n lastRun: maintenanceState.lastRunTime || undefined,\n staleFramesCleaned: maintenanceState.staleFramesCleaned,\n ftsRebuilds: maintenanceState.ftsRebuilds,\n embeddingsGenerated: maintenanceState.embeddingsGenerated,\n embeddingsTotal: maintenanceState.embeddingsTotal,\n embeddingsRemaining: maintenanceState.embeddingsRemaining,\n },\n memory: {\n enabled: this.config.memory.enabled,\n lastTrigger: memoryState.lastTriggerTime || undefined,\n triggerCount: memoryState.triggerCount,\n currentRamPercent: memoryState.currentRamPercent,\n },\n fileWatch: {\n enabled: this.config.fileWatch.enabled,\n },\n },\n errors: [\n ...this.contextService.getState().errors.slice(-5),\n ...this.linearService.getState().errors.slice(-5),\n ...maintenanceState.errors.slice(-5),\n ...memoryState.errors.slice(-5),\n ],\n };\n\n writeDaemonStatus(status);\n }\n\n private setupSignalHandlers(): void {\n const handleSignal = (signal: string) => {\n this.log('INFO', 'daemon', `Received ${signal}, shutting down`);\n this.shutdown(signal.toLowerCase());\n };\n\n process.on('SIGTERM', () => handleSignal('SIGTERM'));\n process.on('SIGINT', () => handleSignal('SIGINT'));\n process.on('SIGHUP', () => handleSignal('SIGHUP'));\n\n process.on('uncaughtException', (err) => {\n this.log('ERROR', 'daemon', 'Uncaught exception', {\n error: err.message,\n stack: err.stack,\n });\n this.shutdown('uncaught_exception');\n });\n\n process.on('unhandledRejection', (reason) => {\n this.log('ERROR', 'daemon', 'Unhandled rejection', {\n reason: String(reason),\n });\n });\n }\n\n private cleanup(): void {\n // Remove PID file\n try {\n if (existsSync(this.paths.pidFile)) {\n unlinkSync(this.paths.pidFile);\n this.log('INFO', 'daemon', 'PID file removed');\n }\n } catch (e) {\n this.log('WARN', 'daemon', 'Failed to remove PID file', {\n error: String(e),\n });\n }\n\n // Update status\n const finalStatus: DaemonStatus = {\n running: false,\n startTime: this.startTime,\n uptime: Date.now() - this.startTime,\n services: {\n context: {\n enabled: false,\n saveCount: this.contextService.getState().saveCount,\n },\n linear: {\n enabled: false,\n syncCount: this.linearService.getState().syncCount,\n },\n maintenance: {\n enabled: false,\n staleFramesCleaned:\n this.maintenanceService.getState().staleFramesCleaned,\n ftsRebuilds: this.maintenanceService.getState().ftsRebuilds,\n },\n memory: {\n enabled: false,\n triggerCount: this.memoryService.getState().triggerCount,\n },\n fileWatch: { enabled: false },\n },\n errors: [],\n };\n writeDaemonStatus(finalStatus);\n }\n\n private shutdown(reason: string): void {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n\n this.log('INFO', 'daemon', 'Daemon shutting down', {\n reason,\n uptime: Date.now() - this.startTime,\n contextSaves: this.contextService.getState().saveCount,\n linearSyncs: this.linearService.getState().syncCount,\n maintenanceRuns: this.maintenanceService.getState().ftsRebuilds,\n memoryTriggers: this.memoryService.getState().triggerCount,\n });\n\n // Stop heartbeat\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = undefined;\n }\n\n // Stop services\n this.contextService.stop();\n this.linearService.stop();\n this.maintenanceService.stop();\n this.memoryService.stop();\n\n // Cleanup\n this.cleanup();\n\n const exitCode =\n reason === 'sigterm' || reason === 'sigint' || reason === 'sighup'\n ? 0\n : 1;\n process.exit(exitCode);\n }\n\n async start(): Promise<void> {\n // Check idempotency\n if (!this.checkIdempotency()) {\n this.log('INFO', 'daemon', 'Exiting - daemon already running');\n process.exit(0);\n }\n\n this.startTime = Date.now();\n\n // Write PID file\n this.writePidFile();\n\n // Setup signal handlers\n this.setupSignalHandlers();\n\n this.log('INFO', 'daemon', 'Unified daemon started', {\n pid: process.pid,\n config: {\n context: this.config.context.enabled,\n linear: this.config.linear.enabled,\n maintenance: this.config.maintenance.enabled,\n memory: this.config.memory.enabled,\n fileWatch: this.config.fileWatch.enabled,\n },\n });\n\n // Start services\n this.contextService.start();\n await this.linearService.start();\n this.maintenanceService.start();\n this.memoryService.start();\n\n // Start heartbeat\n this.heartbeatInterval = setInterval(() => {\n this.updateStatus();\n }, this.config.heartbeatInterval * 1000);\n\n // Initial status update\n this.updateStatus();\n }\n\n getStatus(): DaemonStatus {\n const maintenanceState = this.maintenanceService.getState();\n const memoryState = this.memoryService.getState();\n return {\n running: !this.isShuttingDown,\n pid: process.pid,\n startTime: this.startTime,\n uptime: Date.now() - this.startTime,\n services: {\n context: {\n enabled: this.config.context.enabled,\n lastRun: this.contextService.getState().lastSaveTime || undefined,\n saveCount: this.contextService.getState().saveCount,\n },\n linear: {\n enabled: this.config.linear.enabled,\n lastRun: this.linearService.getState().lastSyncTime || undefined,\n syncCount: this.linearService.getState().syncCount,\n },\n maintenance: {\n enabled: this.config.maintenance.enabled,\n lastRun: maintenanceState.lastRunTime || undefined,\n staleFramesCleaned: maintenanceState.staleFramesCleaned,\n ftsRebuilds: maintenanceState.ftsRebuilds,\n embeddingsGenerated: maintenanceState.embeddingsGenerated,\n embeddingsTotal: maintenanceState.embeddingsTotal,\n embeddingsRemaining: maintenanceState.embeddingsRemaining,\n },\n memory: {\n enabled: this.config.memory.enabled,\n lastTrigger: memoryState.lastTriggerTime || undefined,\n triggerCount: memoryState.triggerCount,\n currentRamPercent: memoryState.currentRamPercent,\n },\n fileWatch: {\n enabled: this.config.fileWatch.enabled,\n },\n },\n errors: [\n ...this.contextService.getState().errors,\n ...this.linearService.getState().errors,\n ...maintenanceState.errors,\n ...memoryState.errors,\n ],\n };\n }\n}\n\n// CLI entry point\nif (\n import.meta.url === `file://${process.argv[1]}` ||\n process.argv[1]?.endsWith('unified-daemon.js')\n) {\n const args = process.argv.slice(2);\n const config: Partial<DaemonConfig> = {};\n\n // Parse command line args\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === '--save-interval' && args[i + 1]) {\n config.context = { enabled: true, interval: parseInt(args[i + 1], 10) };\n i++;\n } else if (arg === '--linear-interval' && args[i + 1]) {\n config.linear = {\n enabled: true,\n interval: parseInt(args[i + 1], 10),\n retryAttempts: 3,\n retryDelay: 30000,\n };\n i++;\n } else if (arg === '--no-linear') {\n config.linear = {\n enabled: false,\n interval: 60,\n retryAttempts: 3,\n retryDelay: 30000,\n };\n } else if (arg === '--log-level' && args[i + 1]) {\n config.logLevel = args[i + 1] as DaemonConfig['logLevel'];\n i++;\n }\n }\n\n const daemon = new UnifiedDaemon(config);\n daemon.start().catch((err) => {\n console.error('Failed to start daemon:', err);\n process.exit(1);\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackmemoryai/stackmemory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Project-scoped memory for AI coding tools. Durable context across sessions with MCP integration, frames, smart retrieval, Claude Code skills, and automatic hooks.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.0.0",
|