@stackmemoryai/stackmemory 0.5.46 → 0.5.48
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 +26 -40
- package/dist/cli/commands/daemon.js +392 -0
- package/dist/cli/commands/daemon.js.map +7 -0
- package/dist/cli/commands/service.js +55 -1
- package/dist/cli/commands/service.js.map +2 -2
- package/dist/cli/index.js +37 -22
- package/dist/cli/index.js.map +2 -2
- package/dist/core/config/feature-flags.js +7 -1
- package/dist/core/config/feature-flags.js.map +2 -2
- package/dist/daemon/daemon-config.js +149 -0
- package/dist/daemon/daemon-config.js.map +7 -0
- package/dist/daemon/services/context-service.js +122 -0
- package/dist/daemon/services/context-service.js.map +7 -0
- package/dist/daemon/services/linear-service.js +136 -0
- package/dist/daemon/services/linear-service.js.map +7 -0
- package/dist/daemon/unified-daemon.js +276 -0
- package/dist/daemon/unified-daemon.js.map +7 -0
- package/package.json +4 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
3
|
+
import { dirname as __pathDirname } from 'path';
|
|
4
|
+
const __filename = __fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = __pathDirname(__filename);
|
|
6
|
+
import {
|
|
7
|
+
existsSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
unlinkSync,
|
|
10
|
+
appendFileSync,
|
|
11
|
+
readFileSync
|
|
12
|
+
} from "fs";
|
|
13
|
+
import {
|
|
14
|
+
loadDaemonConfig,
|
|
15
|
+
getDaemonPaths,
|
|
16
|
+
writeDaemonStatus
|
|
17
|
+
} from "./daemon-config.js";
|
|
18
|
+
import { DaemonContextService } from "./services/context-service.js";
|
|
19
|
+
import { DaemonLinearService } from "./services/linear-service.js";
|
|
20
|
+
class UnifiedDaemon {
|
|
21
|
+
config;
|
|
22
|
+
paths;
|
|
23
|
+
contextService;
|
|
24
|
+
linearService;
|
|
25
|
+
heartbeatInterval;
|
|
26
|
+
isShuttingDown = false;
|
|
27
|
+
startTime = 0;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.paths = getDaemonPaths();
|
|
30
|
+
this.config = { ...loadDaemonConfig(), ...config };
|
|
31
|
+
this.contextService = new DaemonContextService(
|
|
32
|
+
this.config.context,
|
|
33
|
+
(level, msg, data) => this.log(level, "context", msg, data)
|
|
34
|
+
);
|
|
35
|
+
this.linearService = new DaemonLinearService(
|
|
36
|
+
this.config.linear,
|
|
37
|
+
(level, msg, data) => this.log(level, "linear", msg, data)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
log(level, service, message, data) {
|
|
41
|
+
const logLevel = level.toUpperCase();
|
|
42
|
+
const levels = ["DEBUG", "INFO", "WARN", "ERROR"];
|
|
43
|
+
const configLevel = this.config.logLevel.toUpperCase();
|
|
44
|
+
if (levels.indexOf(logLevel) < levels.indexOf(configLevel)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const entry = {
|
|
48
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
49
|
+
level: logLevel,
|
|
50
|
+
service,
|
|
51
|
+
message,
|
|
52
|
+
data
|
|
53
|
+
};
|
|
54
|
+
const logLine = JSON.stringify(entry) + "\n";
|
|
55
|
+
try {
|
|
56
|
+
appendFileSync(this.paths.logFile, logLine);
|
|
57
|
+
} catch {
|
|
58
|
+
console.error(`[${entry.timestamp}] ${level} [${service}]: ${message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
checkIdempotency() {
|
|
62
|
+
if (existsSync(this.paths.pidFile)) {
|
|
63
|
+
try {
|
|
64
|
+
const existingPid = readFileSync(this.paths.pidFile, "utf8").trim();
|
|
65
|
+
const pid = parseInt(existingPid, 10);
|
|
66
|
+
try {
|
|
67
|
+
process.kill(pid, 0);
|
|
68
|
+
this.log("WARN", "daemon", "Daemon already running", { pid });
|
|
69
|
+
return false;
|
|
70
|
+
} catch {
|
|
71
|
+
this.log("INFO", "daemon", "Cleaning stale PID file", { pid });
|
|
72
|
+
unlinkSync(this.paths.pidFile);
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
try {
|
|
76
|
+
unlinkSync(this.paths.pidFile);
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
writePidFile() {
|
|
84
|
+
writeFileSync(this.paths.pidFile, process.pid.toString());
|
|
85
|
+
this.log("INFO", "daemon", "PID file created", {
|
|
86
|
+
pid: process.pid,
|
|
87
|
+
file: this.paths.pidFile
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
updateStatus() {
|
|
91
|
+
const status = {
|
|
92
|
+
running: true,
|
|
93
|
+
pid: process.pid,
|
|
94
|
+
startTime: this.startTime,
|
|
95
|
+
uptime: Date.now() - this.startTime,
|
|
96
|
+
services: {
|
|
97
|
+
context: {
|
|
98
|
+
enabled: this.config.context.enabled,
|
|
99
|
+
lastRun: this.contextService.getState().lastSaveTime || void 0,
|
|
100
|
+
saveCount: this.contextService.getState().saveCount
|
|
101
|
+
},
|
|
102
|
+
linear: {
|
|
103
|
+
enabled: this.config.linear.enabled,
|
|
104
|
+
lastRun: this.linearService.getState().lastSyncTime || void 0,
|
|
105
|
+
syncCount: this.linearService.getState().syncCount
|
|
106
|
+
},
|
|
107
|
+
fileWatch: {
|
|
108
|
+
enabled: this.config.fileWatch.enabled
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
errors: [
|
|
112
|
+
...this.contextService.getState().errors.slice(-5),
|
|
113
|
+
...this.linearService.getState().errors.slice(-5)
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
writeDaemonStatus(status);
|
|
117
|
+
}
|
|
118
|
+
setupSignalHandlers() {
|
|
119
|
+
const handleSignal = (signal) => {
|
|
120
|
+
this.log("INFO", "daemon", `Received ${signal}, shutting down`);
|
|
121
|
+
this.shutdown(signal.toLowerCase());
|
|
122
|
+
};
|
|
123
|
+
process.on("SIGTERM", () => handleSignal("SIGTERM"));
|
|
124
|
+
process.on("SIGINT", () => handleSignal("SIGINT"));
|
|
125
|
+
process.on("SIGHUP", () => handleSignal("SIGHUP"));
|
|
126
|
+
process.on("uncaughtException", (err) => {
|
|
127
|
+
this.log("ERROR", "daemon", "Uncaught exception", {
|
|
128
|
+
error: err.message,
|
|
129
|
+
stack: err.stack
|
|
130
|
+
});
|
|
131
|
+
this.shutdown("uncaught_exception");
|
|
132
|
+
});
|
|
133
|
+
process.on("unhandledRejection", (reason) => {
|
|
134
|
+
this.log("ERROR", "daemon", "Unhandled rejection", {
|
|
135
|
+
reason: String(reason)
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
cleanup() {
|
|
140
|
+
try {
|
|
141
|
+
if (existsSync(this.paths.pidFile)) {
|
|
142
|
+
unlinkSync(this.paths.pidFile);
|
|
143
|
+
this.log("INFO", "daemon", "PID file removed");
|
|
144
|
+
}
|
|
145
|
+
} catch (e) {
|
|
146
|
+
this.log("WARN", "daemon", "Failed to remove PID file", {
|
|
147
|
+
error: String(e)
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const finalStatus = {
|
|
151
|
+
running: false,
|
|
152
|
+
startTime: this.startTime,
|
|
153
|
+
uptime: Date.now() - this.startTime,
|
|
154
|
+
services: {
|
|
155
|
+
context: {
|
|
156
|
+
enabled: false,
|
|
157
|
+
saveCount: this.contextService.getState().saveCount
|
|
158
|
+
},
|
|
159
|
+
linear: {
|
|
160
|
+
enabled: false,
|
|
161
|
+
syncCount: this.linearService.getState().syncCount
|
|
162
|
+
},
|
|
163
|
+
fileWatch: { enabled: false }
|
|
164
|
+
},
|
|
165
|
+
errors: []
|
|
166
|
+
};
|
|
167
|
+
writeDaemonStatus(finalStatus);
|
|
168
|
+
}
|
|
169
|
+
shutdown(reason) {
|
|
170
|
+
if (this.isShuttingDown) return;
|
|
171
|
+
this.isShuttingDown = true;
|
|
172
|
+
this.log("INFO", "daemon", "Daemon shutting down", {
|
|
173
|
+
reason,
|
|
174
|
+
uptime: Date.now() - this.startTime,
|
|
175
|
+
contextSaves: this.contextService.getState().saveCount,
|
|
176
|
+
linearSyncs: this.linearService.getState().syncCount
|
|
177
|
+
});
|
|
178
|
+
if (this.heartbeatInterval) {
|
|
179
|
+
clearInterval(this.heartbeatInterval);
|
|
180
|
+
this.heartbeatInterval = void 0;
|
|
181
|
+
}
|
|
182
|
+
this.contextService.stop();
|
|
183
|
+
this.linearService.stop();
|
|
184
|
+
this.cleanup();
|
|
185
|
+
const exitCode = reason === "sigterm" || reason === "sigint" || reason === "sighup" ? 0 : 1;
|
|
186
|
+
process.exit(exitCode);
|
|
187
|
+
}
|
|
188
|
+
async start() {
|
|
189
|
+
if (!this.checkIdempotency()) {
|
|
190
|
+
this.log("INFO", "daemon", "Exiting - daemon already running");
|
|
191
|
+
process.exit(0);
|
|
192
|
+
}
|
|
193
|
+
this.startTime = Date.now();
|
|
194
|
+
this.writePidFile();
|
|
195
|
+
this.setupSignalHandlers();
|
|
196
|
+
this.log("INFO", "daemon", "Unified daemon started", {
|
|
197
|
+
pid: process.pid,
|
|
198
|
+
config: {
|
|
199
|
+
context: this.config.context.enabled,
|
|
200
|
+
linear: this.config.linear.enabled,
|
|
201
|
+
fileWatch: this.config.fileWatch.enabled
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
this.contextService.start();
|
|
205
|
+
await this.linearService.start();
|
|
206
|
+
this.heartbeatInterval = setInterval(() => {
|
|
207
|
+
this.updateStatus();
|
|
208
|
+
}, this.config.heartbeatInterval * 1e3);
|
|
209
|
+
this.updateStatus();
|
|
210
|
+
}
|
|
211
|
+
getStatus() {
|
|
212
|
+
return {
|
|
213
|
+
running: !this.isShuttingDown,
|
|
214
|
+
pid: process.pid,
|
|
215
|
+
startTime: this.startTime,
|
|
216
|
+
uptime: Date.now() - this.startTime,
|
|
217
|
+
services: {
|
|
218
|
+
context: {
|
|
219
|
+
enabled: this.config.context.enabled,
|
|
220
|
+
lastRun: this.contextService.getState().lastSaveTime || void 0,
|
|
221
|
+
saveCount: this.contextService.getState().saveCount
|
|
222
|
+
},
|
|
223
|
+
linear: {
|
|
224
|
+
enabled: this.config.linear.enabled,
|
|
225
|
+
lastRun: this.linearService.getState().lastSyncTime || void 0,
|
|
226
|
+
syncCount: this.linearService.getState().syncCount
|
|
227
|
+
},
|
|
228
|
+
fileWatch: {
|
|
229
|
+
enabled: this.config.fileWatch.enabled
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
errors: [
|
|
233
|
+
...this.contextService.getState().errors,
|
|
234
|
+
...this.linearService.getState().errors
|
|
235
|
+
]
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("unified-daemon.js")) {
|
|
240
|
+
const args = process.argv.slice(2);
|
|
241
|
+
const config = {};
|
|
242
|
+
for (let i = 0; i < args.length; i++) {
|
|
243
|
+
const arg = args[i];
|
|
244
|
+
if (arg === "--save-interval" && args[i + 1]) {
|
|
245
|
+
config.context = { enabled: true, interval: parseInt(args[i + 1], 10) };
|
|
246
|
+
i++;
|
|
247
|
+
} else if (arg === "--linear-interval" && args[i + 1]) {
|
|
248
|
+
config.linear = {
|
|
249
|
+
enabled: true,
|
|
250
|
+
interval: parseInt(args[i + 1], 10),
|
|
251
|
+
retryAttempts: 3,
|
|
252
|
+
retryDelay: 3e4
|
|
253
|
+
};
|
|
254
|
+
i++;
|
|
255
|
+
} else if (arg === "--no-linear") {
|
|
256
|
+
config.linear = {
|
|
257
|
+
enabled: false,
|
|
258
|
+
interval: 60,
|
|
259
|
+
retryAttempts: 3,
|
|
260
|
+
retryDelay: 3e4
|
|
261
|
+
};
|
|
262
|
+
} else if (arg === "--log-level" && args[i + 1]) {
|
|
263
|
+
config.logLevel = args[i + 1];
|
|
264
|
+
i++;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const daemon = new UnifiedDaemon(config);
|
|
268
|
+
daemon.start().catch((err) => {
|
|
269
|
+
console.error("Failed to start daemon:", err);
|
|
270
|
+
process.exit(1);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
export {
|
|
274
|
+
UnifiedDaemon
|
|
275
|
+
};
|
|
276
|
+
//# sourceMappingURL=unified-daemon.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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';\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 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\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 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 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 ],\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 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 });\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\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 fileWatch: this.config.fileWatch.enabled,\n },\n });\n\n // Start services\n this.contextService.start();\n await this.linearService.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 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 fileWatch: {\n enabled: this.config.fileWatch.enabled,\n },\n },\n errors: [\n ...this.contextService.getState().errors,\n ...this.linearService.getState().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
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackmemoryai/stackmemory",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.48",
|
|
4
4
|
"description": "Lossless memory runtime for AI coding tools - organizes context as a call stack instead of linear chat logs, with team collaboration and infinite retention",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.0.0",
|
|
@@ -74,6 +74,9 @@
|
|
|
74
74
|
"daemons:stop": "node scripts/claude-sm-autostart.js stop",
|
|
75
75
|
"daemon:session": "node dist/daemon/session-daemon.js",
|
|
76
76
|
"daemon:session:start": "node dist/daemon/session-daemon.js --session-id",
|
|
77
|
+
"daemon:start": "node dist/daemon/unified-daemon.js",
|
|
78
|
+
"daemon:stop": "node dist/cli/index.js daemon stop",
|
|
79
|
+
"daemon:status": "node dist/cli/index.js daemon status",
|
|
77
80
|
"sync:start": "node scripts/background-sync-manager.js",
|
|
78
81
|
"sync:setup": "./scripts/setup-background-sync.sh",
|
|
79
82
|
"prepare": "echo 'Prepare step completed'"
|