@mnemonik/scanner 5.120.1 → 5.131.4
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/daemon.js +59 -17
- package/dist/daemon.js.map +1 -1
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +233 -0
- package/dist/doctor.js.map +1 -0
- package/dist/fileLog.d.ts +17 -0
- package/dist/fileLog.js +70 -0
- package/dist/fileLog.js.map +1 -0
- package/dist/index.js +30 -17
- package/dist/index.js.map +1 -1
- package/dist/pid.d.ts +1 -0
- package/dist/pid.js +37 -0
- package/dist/pid.js.map +1 -0
- package/dist/watcher.d.ts +14 -0
- package/dist/watcher.js +118 -7
- package/dist/watcher.js.map +1 -1
- package/package.json +1 -1
- package/src/daemon.ts +65 -18
- package/src/doctor.ts +239 -0
- package/src/fileLog.ts +67 -0
- package/src/index.ts +31 -19
- package/src/pid.ts +37 -0
- package/src/watcher.ts +115 -7
package/dist/index.js
CHANGED
|
@@ -4,6 +4,9 @@ import { existsSync } from 'fs';
|
|
|
4
4
|
import { join } from 'path';
|
|
5
5
|
import { homedir } from 'os';
|
|
6
6
|
import { ScannerDaemon } from './daemon.js';
|
|
7
|
+
import { installFileLogging } from './fileLog.js';
|
|
8
|
+
import { runDoctor } from './doctor.js';
|
|
9
|
+
import { pidIsScanner } from './pid.js';
|
|
7
10
|
const DEFAULT_SERVER = 'https://api.mnemonik.dev';
|
|
8
11
|
const MNEMONIK_DIR = join(homedir(), '.mnemonik');
|
|
9
12
|
const PID_FILE = join(MNEMONIK_DIR, 'daemon.pid');
|
|
@@ -13,7 +16,7 @@ const MAX_LOG_SIZE = 5 * 1024 * 1024; // 5MB
|
|
|
13
16
|
function parseCliArgs() {
|
|
14
17
|
const args = process.argv.slice(2);
|
|
15
18
|
const command = (args[0] ?? 'help');
|
|
16
|
-
if (!['start', 'stop', 'status', 'log', 'help'].includes(command)) {
|
|
19
|
+
if (!['start', 'stop', 'status', 'log', 'doctor', 'help'].includes(command)) {
|
|
17
20
|
return { command: 'help' };
|
|
18
21
|
}
|
|
19
22
|
let key;
|
|
@@ -58,18 +61,6 @@ async function checkConfigPermissions() {
|
|
|
58
61
|
// Config file doesn't exist yet
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
|
-
async function rotateLogIfNeeded() {
|
|
62
|
-
try {
|
|
63
|
-
const { rename } = await import('fs/promises');
|
|
64
|
-
const s = await stat(LOG_FILE);
|
|
65
|
-
if (s.size > MAX_LOG_SIZE) {
|
|
66
|
-
await rename(LOG_FILE, LOG_FILE + '.old');
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
// Log file doesn't exist yet
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
64
|
async function acquireLock(retried = false) {
|
|
74
65
|
try {
|
|
75
66
|
const { open: fsOpen } = await import('fs/promises');
|
|
@@ -87,7 +78,12 @@ async function acquireLock(retried = false) {
|
|
|
87
78
|
const pid = parseInt(existing.trim(), 10);
|
|
88
79
|
try {
|
|
89
80
|
process.kill(pid, 0);
|
|
90
|
-
|
|
81
|
+
// Alive is not enough — after PID reuse the number can belong to an
|
|
82
|
+
// unrelated process. Only an actual scanner holds the lock.
|
|
83
|
+
if (pidIsScanner(pid)) {
|
|
84
|
+
return false; // Process alive and is the scanner — lock is valid
|
|
85
|
+
}
|
|
86
|
+
// Live but foreign PID — treat as stale and reclaim below.
|
|
91
87
|
}
|
|
92
88
|
catch {
|
|
93
89
|
// Holder is dead — remove stale lock and retry once
|
|
@@ -111,11 +107,15 @@ async function readPid() {
|
|
|
111
107
|
// Check if process is actually alive
|
|
112
108
|
try {
|
|
113
109
|
process.kill(pid, 0);
|
|
114
|
-
return pid;
|
|
115
110
|
}
|
|
116
111
|
catch {
|
|
117
112
|
return null; // Stale PID
|
|
118
113
|
}
|
|
114
|
+
// Alive but foreign (PID reuse) is just as stale — never report it as
|
|
115
|
+
// the daemon, and never let handleStop() SIGTERM it.
|
|
116
|
+
if (!pidIsScanner(pid))
|
|
117
|
+
return null;
|
|
118
|
+
return pid;
|
|
119
119
|
}
|
|
120
120
|
catch {
|
|
121
121
|
return null;
|
|
@@ -130,6 +130,7 @@ Usage:
|
|
|
130
130
|
mnemonik-scanner stop Stop the running daemon
|
|
131
131
|
mnemonik-scanner status Show daemon status
|
|
132
132
|
mnemonik-scanner log Tail the scanner log file
|
|
133
|
+
mnemonik-scanner doctor Check install health (drift detection)
|
|
133
134
|
mnemonik-scanner help Show this help
|
|
134
135
|
|
|
135
136
|
Options (for start):
|
|
@@ -188,6 +189,12 @@ async function handleStart(cli) {
|
|
|
188
189
|
const server = cli.server || config?.server || DEFAULT_SERVER;
|
|
189
190
|
// Ensure directories exist
|
|
190
191
|
await mkdir(MNEMONIK_DIR, { recursive: true });
|
|
192
|
+
// Mirror all console output into scanner.log so `mnemonik-scanner log`
|
|
193
|
+
// reflects live activity regardless of supervisor. Under systemd, stdout is
|
|
194
|
+
// wired to the journal socket, not this file — without the tee the on-disk
|
|
195
|
+
// log goes stale and `log` shows nothing current. Install before any daemon
|
|
196
|
+
// output so the whole session is captured.
|
|
197
|
+
installFileLogging(LOG_FILE, MAX_LOG_SIZE);
|
|
191
198
|
// Save config for future runs (never save env var key to file)
|
|
192
199
|
const configToSave = {
|
|
193
200
|
roots,
|
|
@@ -203,7 +210,6 @@ async function handleStart(cli) {
|
|
|
203
210
|
}
|
|
204
211
|
await writeConfig(configToSave);
|
|
205
212
|
await checkConfigPermissions();
|
|
206
|
-
await rotateLogIfNeeded();
|
|
207
213
|
const locked = await acquireLock();
|
|
208
214
|
if (!locked) {
|
|
209
215
|
const pid = await readPid();
|
|
@@ -295,7 +301,11 @@ async function handleStatus() {
|
|
|
295
301
|
const oldPid = parseInt(content.trim(), 10);
|
|
296
302
|
try {
|
|
297
303
|
process.kill(oldPid, 0);
|
|
298
|
-
|
|
304
|
+
// Same PID-reuse guard as readPid(): only report genuinely live
|
|
305
|
+
// scanner processes, not whatever now occupies a recycled PID.
|
|
306
|
+
if (pidIsScanner(oldPid)) {
|
|
307
|
+
staleOldDaemons.push(`${f} (PID ${oldPid})`);
|
|
308
|
+
}
|
|
299
309
|
}
|
|
300
310
|
catch {
|
|
301
311
|
// Dead process, just a stale file
|
|
@@ -341,6 +351,9 @@ async function main() {
|
|
|
341
351
|
case 'log':
|
|
342
352
|
await handleLog();
|
|
343
353
|
break;
|
|
354
|
+
case 'doctor':
|
|
355
|
+
await runDoctor();
|
|
356
|
+
break;
|
|
344
357
|
case 'help':
|
|
345
358
|
default:
|
|
346
359
|
printHelp();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/pid.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function pidIsScanner(pid: number): boolean;
|
package/dist/pid.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
/**
|
|
4
|
+
* PID-reuse guard shared by the CLI lock paths (index.ts) and doctor.
|
|
5
|
+
*
|
|
6
|
+
* `process.kill(pid, 0)` only proves that *some* process is alive at that
|
|
7
|
+
* PID, not that it is ours. After a reboot or plain PID recycling the number
|
|
8
|
+
* in daemon.pid can belong to an unrelated process — SIGTERMing it from
|
|
9
|
+
* `stop`, or refusing to `start` because of it, would be wrong. So a live PID
|
|
10
|
+
* only counts as the scanner when its command line matches the daemon's
|
|
11
|
+
* signature (same pattern doctor uses to find daemon processes via `ps`).
|
|
12
|
+
*/
|
|
13
|
+
const SCANNER_CMD_PATTERN = /(mnemonik-scanner|scanner\/dist\/index\.js)/;
|
|
14
|
+
function processCmdline(pid) {
|
|
15
|
+
// Linux: /proc/<pid>/cmdline is NUL-separated argv — cheap and exact.
|
|
16
|
+
try {
|
|
17
|
+
return readFileSync(`/proc/${pid}/cmdline`, 'utf-8').replace(/\0/g, ' ');
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// /proc unavailable (macOS) or unreadable — fall back to ps below.
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return execFileSync('ps', ['-o', 'args=', '-p', String(pid)], {
|
|
24
|
+
encoding: 'utf-8',
|
|
25
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
26
|
+
timeout: 5000,
|
|
27
|
+
}).trim();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null; // No such process, or ps unavailable — cannot confirm identity.
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function pidIsScanner(pid) {
|
|
34
|
+
const cmdline = processCmdline(pid);
|
|
35
|
+
return cmdline !== null && SCANNER_CMD_PATTERN.test(cmdline);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=pid.js.map
|
package/dist/pid.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pid.js","sourceRoot":"","sources":["../src/pid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAElC;;;;;;;;;GASG;AACH,MAAM,mBAAmB,GAAG,6CAA6C,CAAC;AAE1E,SAAS,cAAc,CAAC,GAAW;IACjC,sEAAsE;IACtE,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,SAAS,GAAG,UAAU,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;IACrE,CAAC;IACD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;YAC5D,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YACnC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,gEAAgE;IAC/E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,OAAO,KAAK,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC/D,CAAC"}
|
package/dist/watcher.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare class FileWatcher {
|
|
|
4
4
|
private rootPath;
|
|
5
5
|
private onChange;
|
|
6
6
|
private watchers;
|
|
7
|
+
private watchedDirs;
|
|
8
|
+
private watchedDirInodes;
|
|
7
9
|
private pendingFiles;
|
|
8
10
|
private flushTimer;
|
|
9
11
|
private debounceMs;
|
|
@@ -13,4 +15,16 @@ export declare class FileWatcher {
|
|
|
13
15
|
stop(): void;
|
|
14
16
|
private scheduleFlush;
|
|
15
17
|
private watchDir;
|
|
18
|
+
/**
|
|
19
|
+
* Attach a watcher to a directory created after start(). Called from the
|
|
20
|
+
* per-directory change callback with every event path; stats the path and
|
|
21
|
+
* only recurses when it is a genuinely new, watchable directory.
|
|
22
|
+
*/
|
|
23
|
+
private watchNewDir;
|
|
24
|
+
/**
|
|
25
|
+
* Forget a deleted directory and everything watched beneath it. fs.watch
|
|
26
|
+
* emits no per-descendant events on a recursive delete, so the whole
|
|
27
|
+
* prefix must be purged here for a recreate to re-watch the full subtree.
|
|
28
|
+
*/
|
|
29
|
+
private unwatchSubtree;
|
|
16
30
|
}
|
package/dist/watcher.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { watch } from 'fs';
|
|
2
2
|
import { join, relative } from 'path';
|
|
3
|
-
import { readdir } from 'fs/promises';
|
|
3
|
+
import { readdir, stat } from 'fs/promises';
|
|
4
4
|
import { isGitBoundary } from '@mnemonik/shared';
|
|
5
5
|
const SKIP_DIRS = new Set([
|
|
6
6
|
'node_modules',
|
|
@@ -24,7 +24,15 @@ const SKIP_DIRS = new Set([
|
|
|
24
24
|
export class FileWatcher {
|
|
25
25
|
rootPath;
|
|
26
26
|
onChange;
|
|
27
|
-
|
|
27
|
+
// Keyed by directory so a watcher can be closed and re-attached when the
|
|
28
|
+
// directory is deleted and recreated at the same path.
|
|
29
|
+
watchers = new Map();
|
|
30
|
+
watchedDirs = new Set();
|
|
31
|
+
// Inode per watched directory: a delete+recreate faster than the delete
|
|
32
|
+
// event's stat() presents as "directory exists and is already watched",
|
|
33
|
+
// but the live watcher is bound to the OLD inode and is inert. Comparing
|
|
34
|
+
// inodes at event time detects the swap so the subtree can re-attach.
|
|
35
|
+
watchedDirInodes = new Map();
|
|
28
36
|
pendingFiles = new Set();
|
|
29
37
|
flushTimer = null;
|
|
30
38
|
debounceMs;
|
|
@@ -40,10 +48,12 @@ export class FileWatcher {
|
|
|
40
48
|
console.log(`[scanner] Watching ${this.rootPath} for changes`);
|
|
41
49
|
}
|
|
42
50
|
stop() {
|
|
43
|
-
for (const w of this.watchers) {
|
|
51
|
+
for (const w of this.watchers.values()) {
|
|
44
52
|
w.close();
|
|
45
53
|
}
|
|
46
|
-
this.watchers
|
|
54
|
+
this.watchers.clear();
|
|
55
|
+
this.watchedDirs.clear();
|
|
56
|
+
this.watchedDirInodes.clear();
|
|
47
57
|
if (this.flushTimer) {
|
|
48
58
|
clearTimeout(this.flushTimer);
|
|
49
59
|
this.flushTimer = null;
|
|
@@ -66,14 +76,30 @@ export class FileWatcher {
|
|
|
66
76
|
const dirName = dir.split('/').pop() ?? '';
|
|
67
77
|
if (SKIP_DIRS.has(dirName))
|
|
68
78
|
return;
|
|
79
|
+
// Dedup guard — the change callback re-enters watchDir for new
|
|
80
|
+
// subdirectories, and a rapid create/rename burst can resolve the same
|
|
81
|
+
// path twice before the first watch is registered.
|
|
82
|
+
if (this.watchedDirs.has(dir))
|
|
83
|
+
return;
|
|
84
|
+
this.watchedDirs.add(dir);
|
|
69
85
|
try {
|
|
70
|
-
|
|
86
|
+
// Record the inode BEFORE attaching so watchNewDir can distinguish a
|
|
87
|
+
// benign event on this directory from a recreate-at-same-path.
|
|
88
|
+
this.watchedDirInodes.set(dir, (await stat(dir)).ino);
|
|
89
|
+
const watcher = watch(dir, { persistent: true }, (event, filename) => {
|
|
71
90
|
if (!filename)
|
|
72
91
|
return;
|
|
73
92
|
const fullPath = join(dir, filename);
|
|
74
93
|
const relPath = relative(this.rootPath, fullPath);
|
|
75
94
|
this.pendingFiles.add(relPath);
|
|
76
95
|
this.scheduleFlush();
|
|
96
|
+
// fs.watch is non-recursive: the initial recursion below only covers
|
|
97
|
+
// directories that existed at start(). When this event is a newly
|
|
98
|
+
// created directory, attach a watcher to it too — otherwise the
|
|
99
|
+
// subtree is a permanent blind spot until restart. Fire-and-forget;
|
|
100
|
+
// watchNewDir no-ops for plain files, skip dirs, git boundaries, and
|
|
101
|
+
// already-watched paths.
|
|
102
|
+
void this.watchNewDir(fullPath, event);
|
|
77
103
|
});
|
|
78
104
|
watcher.on('error', (err) => {
|
|
79
105
|
console.warn(`[scanner] Watcher error for ${dir}:`, err.message);
|
|
@@ -81,7 +107,7 @@ export class FileWatcher {
|
|
|
81
107
|
this.onError(err);
|
|
82
108
|
}
|
|
83
109
|
});
|
|
84
|
-
this.watchers.
|
|
110
|
+
this.watchers.set(dir, watcher);
|
|
85
111
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
86
112
|
for (const entry of entries) {
|
|
87
113
|
if (entry.isDirectory() && !SKIP_DIRS.has(entry.name)) {
|
|
@@ -95,8 +121,93 @@ export class FileWatcher {
|
|
|
95
121
|
}
|
|
96
122
|
}
|
|
97
123
|
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
// Watch registration failed. Never fatal for the subtree's parent, but
|
|
126
|
+
// the *reason* matters: inotify/fd limit exhaustion means silently
|
|
127
|
+
// growing blind spots, while permission-denied is a benign property of
|
|
128
|
+
// the directory itself. Drop the bookkeeping (and any watcher that did
|
|
129
|
+
// attach before the failure) so a later retry can re-enter cleanly.
|
|
130
|
+
this.watchedDirs.delete(dir);
|
|
131
|
+
this.watchedDirInodes.delete(dir);
|
|
132
|
+
const stale = this.watchers.get(dir);
|
|
133
|
+
if (stale) {
|
|
134
|
+
stale.close();
|
|
135
|
+
this.watchers.delete(dir);
|
|
136
|
+
}
|
|
137
|
+
const code = err.code;
|
|
138
|
+
if (code === 'ENOSPC' || code === 'EMFILE' || code === 'ENFILE') {
|
|
139
|
+
console.warn(`[scanner] Watch limit reached (${code}) — subtree unwatched: ${dir}. ` +
|
|
140
|
+
'Raise fs.inotify.max_user_watches or trim scanner roots.');
|
|
141
|
+
// Surface to the daemon only for the root — losing the root means the
|
|
142
|
+
// whole project is blind; a subtree gap must not tear the project down
|
|
143
|
+
// (the daemon's onError removes the project entirely).
|
|
144
|
+
if (dir === this.rootPath && this.onError) {
|
|
145
|
+
this.onError(err);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// Permission denied or inaccessible directory
|
|
150
|
+
console.warn(`[scanner] Cannot watch ${dir}: ${err.message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Attach a watcher to a directory created after start(). Called from the
|
|
156
|
+
* per-directory change callback with every event path; stats the path and
|
|
157
|
+
* only recurses when it is a genuinely new, watchable directory.
|
|
158
|
+
*/
|
|
159
|
+
async watchNewDir(fullPath, eventType) {
|
|
160
|
+
try {
|
|
161
|
+
// Stat before the dedup check: a delete event arrives with the same
|
|
162
|
+
// path as the original create, and the stale watchedDirs entry must
|
|
163
|
+
// not short-circuit the vanish detection below.
|
|
164
|
+
const s = await stat(fullPath);
|
|
165
|
+
if (!s.isDirectory())
|
|
166
|
+
return;
|
|
167
|
+
if (this.watchedDirs.has(fullPath)) {
|
|
168
|
+
// Already watched — but a delete+recreate faster than this stat
|
|
169
|
+
// presents exactly like this, with the live watcher bound to the
|
|
170
|
+
// OLD (dead) inode and inert. A 'rename' event means the entry's
|
|
171
|
+
// identity changed (created / deleted / moved), so re-attach
|
|
172
|
+
// unconditionally — comparing inodes is NOT sufficient there
|
|
173
|
+
// because ext4 routinely hands the freed inode straight back to
|
|
174
|
+
// the recreated directory. 'change' events are attrib noise (a
|
|
175
|
+
// write inside the child bumps its mtime, which fires on the
|
|
176
|
+
// parent), so the cheap inode check keeps those churn-free.
|
|
177
|
+
if (eventType !== 'rename' && this.watchedDirInodes.get(fullPath) === s.ino)
|
|
178
|
+
return;
|
|
179
|
+
this.unwatchSubtree(fullPath);
|
|
180
|
+
}
|
|
181
|
+
if (await isGitBoundary(fullPath))
|
|
182
|
+
return;
|
|
183
|
+
await this.watchDir(fullPath);
|
|
184
|
+
}
|
|
98
185
|
catch {
|
|
99
|
-
//
|
|
186
|
+
// Path vanished between event and stat. If it (or anything under it)
|
|
187
|
+
// was a watched directory, drop the bookkeeping and close the dead
|
|
188
|
+
// watchers — otherwise the dedup guards in watchDir/watchNewDir block
|
|
189
|
+
// re-attachment forever when the path is recreated (build-output
|
|
190
|
+
// wipes, codegen, rm -rf && mkdir).
|
|
191
|
+
this.unwatchSubtree(fullPath);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Forget a deleted directory and everything watched beneath it. fs.watch
|
|
196
|
+
* emits no per-descendant events on a recursive delete, so the whole
|
|
197
|
+
* prefix must be purged here for a recreate to re-watch the full subtree.
|
|
198
|
+
*/
|
|
199
|
+
unwatchSubtree(root) {
|
|
200
|
+
const prefix = root + '/';
|
|
201
|
+
for (const dir of this.watchedDirs) {
|
|
202
|
+
if (dir !== root && !dir.startsWith(prefix))
|
|
203
|
+
continue;
|
|
204
|
+
this.watchedDirs.delete(dir);
|
|
205
|
+
this.watchedDirInodes.delete(dir);
|
|
206
|
+
const w = this.watchers.get(dir);
|
|
207
|
+
if (w) {
|
|
208
|
+
w.close();
|
|
209
|
+
this.watchers.delete(dir);
|
|
210
|
+
}
|
|
100
211
|
}
|
|
101
212
|
}
|
|
102
213
|
}
|
package/dist/watcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,IAAI,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/daemon.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
2
|
import { readFile } from 'fs/promises';
|
|
3
3
|
import { join } from 'path';
|
|
4
|
-
import { CodeScanner, type CodeChunk } from '@mnemonik/shared';
|
|
4
|
+
import { CodeScanner, scrubSecrets, type CodeChunk } from '@mnemonik/shared';
|
|
5
5
|
|
|
6
6
|
/** Maximum raw content bytes accepted by the server's scanFileSchema. */
|
|
7
7
|
const MAX_PUSH_CONTENT_BYTES = 5_000_000;
|
|
@@ -218,10 +218,21 @@ export class ScannerDaemon {
|
|
|
218
218
|
continue;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
const scanned = await this.scanner.
|
|
221
|
+
const scanned = await this.scanner.listFilesWithStatus(project.path);
|
|
222
222
|
// I1: include authority file paths so they are never treated as removed
|
|
223
|
-
const authority = await this.scanner.
|
|
224
|
-
|
|
223
|
+
const authority = await this.scanner.collectAuthorityFilesWithStatus(project.path);
|
|
224
|
+
// A partial walk (fs error swallowed mid-traversal) reads as mass
|
|
225
|
+
// deletion: files that still exist on disk vanish from currentSet
|
|
226
|
+
// and would be deprecated server-side. Withhold the diff AND keep
|
|
227
|
+
// lastInventory untouched so the next clean tick diffs against the
|
|
228
|
+
// trusted baseline.
|
|
229
|
+
if (!scanned.complete || !authority.complete) {
|
|
230
|
+
console.warn(
|
|
231
|
+
`[scanner] [${project.projectId.slice(0, 8)}] incomplete file walk; withholding removed-files diff this tick`
|
|
232
|
+
);
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
const currentSet = new Set([...scanned.paths, ...authority.files.map((a) => a.path)]);
|
|
225
236
|
const removedFiles = [...project.lastInventory].filter((p) => !currentSet.has(p));
|
|
226
237
|
await this.sendRemovedFiles(project.projectId, removedFiles);
|
|
227
238
|
project.lastInventory = currentSet;
|
|
@@ -334,15 +345,16 @@ export class ScannerDaemon {
|
|
|
334
345
|
}> {
|
|
335
346
|
const startTime = Date.now();
|
|
336
347
|
|
|
337
|
-
const
|
|
348
|
+
const scan = await this.scanner.scanDirectoryWithStatus(projectRoot);
|
|
349
|
+
const chunks = scan.chunks;
|
|
338
350
|
const status = await this.client.getStatus(projectId);
|
|
339
351
|
|
|
340
352
|
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
341
|
-
const
|
|
353
|
+
const authority = await this.collectAuthorityPushFiles(projectRoot);
|
|
342
354
|
// C1: dedupe — chunk-scanned entries win over authority duplicates
|
|
343
355
|
// (e.g. setup.py matches both .py includeExtensions and AUTHORITY_FILE_MATCHERS)
|
|
344
356
|
const seen = new Set(files.map((f) => f.path));
|
|
345
|
-
const allFiles = [...files, ...
|
|
357
|
+
const allFiles = [...files, ...authority.files.filter((a) => !seen.has(a.path))];
|
|
346
358
|
const filesToPush = allFiles.filter((f) => {
|
|
347
359
|
const serverHash = status.fileHashes.get(f.path);
|
|
348
360
|
return !serverHash || serverHash !== f.hash;
|
|
@@ -385,14 +397,26 @@ export class ScannerDaemon {
|
|
|
385
397
|
// currently has for this project). Anything the server knows that
|
|
386
398
|
// the daemon doesn't see on disk now = removed. Closes the
|
|
387
399
|
// daemon-was-offline case and the newly-added-ignore-pattern case.
|
|
400
|
+
// Gated on walk completeness: adds/changes above are not
|
|
401
|
+
// completeness-sensitive (a missing file just isn't pushed this
|
|
402
|
+
// pass), but deriving removals from a partial walk deprecates
|
|
403
|
+
// memories for files that still exist. Skip the diff entirely when
|
|
404
|
+
// either walk was truncated.
|
|
388
405
|
const currentPaths = allFiles.map((f) => f.path);
|
|
389
406
|
const currentPathSet = new Set(currentPaths);
|
|
390
|
-
|
|
391
|
-
|
|
407
|
+
let removedFiles: string[] = [];
|
|
408
|
+
if (scan.complete && authority.complete) {
|
|
409
|
+
removedFiles = [...status.fileHashes.keys()].filter((p) => !currentPathSet.has(p));
|
|
410
|
+
await this.sendRemovedFiles(projectId, removedFiles).catch((err) => {
|
|
411
|
+
console.warn(
|
|
412
|
+
`[scanner] [${projectId.slice(0, 8)}] removedFiles report failed (non-blocking): ${(err as Error).message}`
|
|
413
|
+
);
|
|
414
|
+
});
|
|
415
|
+
} else {
|
|
392
416
|
console.warn(
|
|
393
|
-
`[scanner] [${projectId.slice(0, 8)}]
|
|
417
|
+
`[scanner] [${projectId.slice(0, 8)}] incomplete file walk; withholding removed-files diff for this scan`
|
|
394
418
|
);
|
|
395
|
-
}
|
|
419
|
+
}
|
|
396
420
|
|
|
397
421
|
const duration = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
398
422
|
console.log(
|
|
@@ -467,10 +491,10 @@ export class ScannerDaemon {
|
|
|
467
491
|
if (chunks.length === 0) return;
|
|
468
492
|
|
|
469
493
|
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
470
|
-
const
|
|
494
|
+
const authority = await this.collectAuthorityPushFiles(projectRoot);
|
|
471
495
|
// C1: dedupe — chunk-scanned entries win over authority duplicates
|
|
472
496
|
const seen = new Set(files.map((f) => f.path));
|
|
473
|
-
const allFiles = [...files, ...
|
|
497
|
+
const allFiles = [...files, ...authority.files.filter((a) => !seen.has(a.path))];
|
|
474
498
|
|
|
475
499
|
// Skip files whose content hash matches what the server already has —
|
|
476
500
|
// fs.watch fires on no-op events (editor flush, chmod, mtime touch) that
|
|
@@ -564,9 +588,24 @@ export class ScannerDaemon {
|
|
|
564
588
|
project.retryTimer.unref();
|
|
565
589
|
}
|
|
566
590
|
|
|
567
|
-
private async collectAuthorityPushFiles(
|
|
568
|
-
|
|
569
|
-
|
|
591
|
+
private async collectAuthorityPushFiles(
|
|
592
|
+
projectRoot: string
|
|
593
|
+
): Promise<{ files: ScanPushFile[]; complete: boolean }> {
|
|
594
|
+
const authority = await this.scanner.collectAuthorityFilesWithStatus(projectRoot);
|
|
595
|
+
return {
|
|
596
|
+
// Whole-file `content` must honor the same daemon-side redaction
|
|
597
|
+
// invariant as chunk content: no credential leaves this process.
|
|
598
|
+
// `hash` stays computed over the RAW bytes so change detection
|
|
599
|
+
// against the server's known-hash map is unaffected; the server
|
|
600
|
+
// recomputes its own stored content_hash from what arrives.
|
|
601
|
+
files: authority.files.map((f) => ({
|
|
602
|
+
path: f.path,
|
|
603
|
+
hash: f.hash,
|
|
604
|
+
chunks: [],
|
|
605
|
+
content: f.content === undefined ? undefined : scrubSecrets(f.content),
|
|
606
|
+
})),
|
|
607
|
+
complete: authority.complete,
|
|
608
|
+
};
|
|
570
609
|
}
|
|
571
610
|
|
|
572
611
|
private async groupChunksByFile(
|
|
@@ -596,17 +635,25 @@ export class ScannerDaemon {
|
|
|
596
635
|
try {
|
|
597
636
|
const absPath = join(projectRoot, file.path);
|
|
598
637
|
const raw = await readFile(absPath, 'utf-8');
|
|
638
|
+
// Hash the RAW bytes (change detection against the server's
|
|
639
|
+
// known-hash map keys on what's on disk), but never ship them:
|
|
640
|
+
// whole-file `content` honors the same daemon-side redaction
|
|
641
|
+
// invariant as chunk content. The server recomputes its stored
|
|
642
|
+
// content_hash from the scrubbed bytes it receives.
|
|
599
643
|
file.hash = createHash('sha256').update(raw).digest('hex');
|
|
600
644
|
// C2: drop content if it would exceed the server schema cap (5MB)
|
|
601
|
-
file.content = raw.length <= MAX_PUSH_CONTENT_BYTES ? raw : undefined;
|
|
645
|
+
file.content = raw.length <= MAX_PUSH_CONTENT_BYTES ? scrubSecrets(raw) : undefined;
|
|
602
646
|
} catch (err) {
|
|
603
647
|
console.warn(`[scanner] Cannot read ${file.path} for hashing, using chunk-based fallback`, {
|
|
604
648
|
error: err instanceof Error ? err.message : String(err),
|
|
605
649
|
});
|
|
650
|
+
// Chunk content is already scrubbed by CodeScanner; scrubSecrets is
|
|
651
|
+
// idempotent so re-applying keeps the invariant explicit.
|
|
606
652
|
const allContent = file.chunks.map((c) => c.content).join('\n');
|
|
607
653
|
file.hash = createHash('sha256').update(allContent).digest('hex');
|
|
608
654
|
// C2: drop content if it would exceed the server schema cap (5MB)
|
|
609
|
-
file.content =
|
|
655
|
+
file.content =
|
|
656
|
+
allContent.length <= MAX_PUSH_CONTENT_BYTES ? scrubSecrets(allContent) : undefined;
|
|
610
657
|
}
|
|
611
658
|
}
|
|
612
659
|
|