grepmax 0.12.0 → 0.12.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/dist/commands/watch.js
CHANGED
|
@@ -44,6 +44,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.watch = void 0;
|
|
46
46
|
const node_child_process_1 = require("node:child_process");
|
|
47
|
+
const fs = __importStar(require("node:fs"));
|
|
47
48
|
const path = __importStar(require("node:path"));
|
|
48
49
|
const commander_1 = require("commander");
|
|
49
50
|
const config_1 = require("../config");
|
|
@@ -79,6 +80,16 @@ exports.watch = new commander_1.Command("watch")
|
|
|
79
80
|
if (options.background) {
|
|
80
81
|
// Skip spawn if daemon already running — prevents process accumulation
|
|
81
82
|
// when SessionStart hook fires on every session/clear/resume
|
|
83
|
+
const pidFile = config_1.PATHS.daemonPidFile;
|
|
84
|
+
try {
|
|
85
|
+
const existingPid = Number.parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
|
|
86
|
+
if (existingPid) {
|
|
87
|
+
process.kill(existingPid, 0); // throws if dead
|
|
88
|
+
process.exit(0); // alive — skip
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (_c) { }
|
|
92
|
+
// Also check socket as fallback
|
|
82
93
|
const { isDaemonRunning } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/daemon-client")));
|
|
83
94
|
if (yield isDaemonRunning()) {
|
|
84
95
|
process.exit(0);
|
package/dist/config.js
CHANGED
|
@@ -95,6 +95,7 @@ exports.PATHS = {
|
|
|
95
95
|
grammars: path.join(GLOBAL_ROOT, "grammars"),
|
|
96
96
|
logsDir: path.join(GLOBAL_ROOT, "logs"),
|
|
97
97
|
daemonSocket: path.join(GLOBAL_ROOT, "daemon.sock"),
|
|
98
|
+
daemonPidFile: path.join(GLOBAL_ROOT, "daemon.pid"),
|
|
98
99
|
// Centralized index storage — one database for all indexed directories
|
|
99
100
|
lancedbDir: path.join(GLOBAL_ROOT, "lancedb"),
|
|
100
101
|
cacheDir: path.join(GLOBAL_ROOT, "cache"),
|
|
@@ -81,11 +81,27 @@ class Daemon {
|
|
|
81
81
|
yield (0, process_1.killProcess)(w.pid);
|
|
82
82
|
(0, watcher_store_1.unregisterWatcher)(w.pid);
|
|
83
83
|
}
|
|
84
|
-
// 2.
|
|
84
|
+
// 2. PID file — atomic dedup guard
|
|
85
|
+
const pidFile = config_1.PATHS.daemonPidFile;
|
|
86
|
+
try {
|
|
87
|
+
// Check if another daemon is alive
|
|
88
|
+
const existingPid = Number.parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
|
|
89
|
+
if (existingPid && existingPid !== process.pid) {
|
|
90
|
+
try {
|
|
91
|
+
process.kill(existingPid, 0); // throws if dead
|
|
92
|
+
console.error("[daemon] Another daemon is already running (PID:", existingPid + ")");
|
|
93
|
+
process.exit(0);
|
|
94
|
+
}
|
|
95
|
+
catch (_a) { }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (_b) { }
|
|
99
|
+
fs.writeFileSync(pidFile, String(process.pid));
|
|
100
|
+
// 3. Stale socket cleanup
|
|
85
101
|
try {
|
|
86
102
|
fs.unlinkSync(config_1.PATHS.daemonSocket);
|
|
87
103
|
}
|
|
88
|
-
catch (
|
|
104
|
+
catch (_c) { }
|
|
89
105
|
// 3. Open shared resources
|
|
90
106
|
try {
|
|
91
107
|
fs.mkdirSync(config_1.PATHS.cacheDir, { recursive: true });
|
|
@@ -99,10 +115,19 @@ class Daemon {
|
|
|
99
115
|
}
|
|
100
116
|
// 4. Register daemon (only after resources are open)
|
|
101
117
|
(0, watcher_store_1.registerDaemon)(process.pid);
|
|
102
|
-
// 5. Subscribe to all registered projects
|
|
118
|
+
// 5. Subscribe to all registered projects (skip missing directories)
|
|
103
119
|
const projects = (0, project_registry_1.listProjects)().filter((p) => p.status === "indexed");
|
|
104
120
|
for (const p of projects) {
|
|
105
|
-
|
|
121
|
+
if (!fs.existsSync(p.root)) {
|
|
122
|
+
console.log(`[daemon] Skipping ${path.basename(p.root)} — directory not found`);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
yield this.watchProject(p.root);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
console.error(`[daemon] Failed to watch ${path.basename(p.root)}:`, err);
|
|
130
|
+
}
|
|
106
131
|
}
|
|
107
132
|
// 6. Heartbeat
|
|
108
133
|
this.heartbeatInterval = setInterval(() => {
|
|
@@ -253,12 +278,16 @@ class Daemon {
|
|
|
253
278
|
catch (_d) { }
|
|
254
279
|
}
|
|
255
280
|
this.subscriptions.clear();
|
|
256
|
-
// Close server + socket
|
|
281
|
+
// Close server + socket + PID file
|
|
257
282
|
(_a = this.server) === null || _a === void 0 ? void 0 : _a.close();
|
|
258
283
|
try {
|
|
259
284
|
fs.unlinkSync(config_1.PATHS.daemonSocket);
|
|
260
285
|
}
|
|
261
286
|
catch (_e) { }
|
|
287
|
+
try {
|
|
288
|
+
fs.unlinkSync(config_1.PATHS.daemonPidFile);
|
|
289
|
+
}
|
|
290
|
+
catch (_f) { }
|
|
262
291
|
// Unregister all
|
|
263
292
|
for (const root of this.processors.keys()) {
|
|
264
293
|
(0, watcher_store_1.unregisterWatcherByRoot)(root);
|
|
@@ -269,11 +298,11 @@ class Daemon {
|
|
|
269
298
|
try {
|
|
270
299
|
yield ((_b = this.metaCache) === null || _b === void 0 ? void 0 : _b.close());
|
|
271
300
|
}
|
|
272
|
-
catch (
|
|
301
|
+
catch (_g) { }
|
|
273
302
|
try {
|
|
274
303
|
yield ((_c = this.vectorDb) === null || _c === void 0 ? void 0 : _c.close());
|
|
275
304
|
}
|
|
276
|
-
catch (
|
|
305
|
+
catch (_h) { }
|
|
277
306
|
console.log("[daemon] Shutdown complete");
|
|
278
307
|
});
|
|
279
308
|
}
|
package/package.json
CHANGED