@mnemonik/scanner 1.0.0 → 2.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 +90 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +3 -0
- package/dist/client.js.map +1 -1
- package/dist/daemon.d.ts +22 -10
- package/dist/daemon.js +172 -73
- package/dist/daemon.js.map +1 -1
- package/dist/discovery.d.ts +21 -0
- package/dist/discovery.js +107 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.js +248 -56
- package/dist/index.js.map +1 -1
- package/dist/watcher.d.ts +3 -1
- package/dist/watcher.js +9 -1
- package/dist/watcher.js.map +1 -1
- package/package.json +3 -3
- package/src/client.ts +4 -0
- package/src/daemon.ts +214 -80
- package/src/discovery.ts +124 -0
- package/src/index.ts +273 -58
- package/src/watcher.ts +13 -2
package/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# @mnemonik/scanner
|
|
2
|
+
|
|
3
|
+
Automatic codebase indexing daemon for [Mnemonik](https://mnemonik.dev) — persistent memory for AI coding assistants.
|
|
4
|
+
|
|
5
|
+
The scanner watches your project directories for code changes and indexes them so your AI assistant can find relevant files, functions, and patterns when you need them.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @mnemonik/scanner
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
mnemonik-scanner start --key <your-api-key> --roots ~/Projects
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Your API key is available on the [Mnemonik dashboard](https://app.mnemonik.dev). The `--roots` flag specifies which directories to scan for projects (comma-separated).
|
|
20
|
+
|
|
21
|
+
Configuration is saved to `~/.mnemonik/scanner.json` after first run. Subsequent starts need no arguments:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
mnemonik-scanner start
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## How It Works
|
|
28
|
+
|
|
29
|
+
1. The daemon walks your `--roots` directories looking for `.mnemonik.json` files (created automatically by your IDE's Mnemonik integration)
|
|
30
|
+
2. For each discovered project, it scans source files and pushes code chunks to the Mnemonik API
|
|
31
|
+
3. It watches for file changes and incrementally updates the index
|
|
32
|
+
4. Every 5 minutes, it re-scans roots to discover new projects, handle folder renames, and drop deleted projects
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
| Command | Description |
|
|
37
|
+
|---------|-------------|
|
|
38
|
+
| `mnemonik-scanner start [options]` | Start the daemon |
|
|
39
|
+
| `mnemonik-scanner stop` | Stop the running daemon |
|
|
40
|
+
| `mnemonik-scanner status` | Show daemon status and watched projects |
|
|
41
|
+
| `mnemonik-scanner log` | Show recent log output |
|
|
42
|
+
| `mnemonik-scanner help` | Show usage information |
|
|
43
|
+
|
|
44
|
+
### Start Options
|
|
45
|
+
|
|
46
|
+
| Option | Description |
|
|
47
|
+
|--------|-------------|
|
|
48
|
+
| `--key <api-key>` | Mnemonik API key (or set `MNEMONIK_API_KEY` env var) |
|
|
49
|
+
| `--server <url>` | Server URL (default: `https://api.mnemonik.dev`) |
|
|
50
|
+
| `--roots <dirs>` | Comma-separated directories to scan for projects |
|
|
51
|
+
|
|
52
|
+
## Configuration
|
|
53
|
+
|
|
54
|
+
The daemon saves its configuration to `~/.mnemonik/scanner.json` with `0600` permissions (owner read/write only).
|
|
55
|
+
|
|
56
|
+
You can also set the API key via the `MNEMONIK_API_KEY` environment variable, which takes precedence over the config file and is never written to disk.
|
|
57
|
+
|
|
58
|
+
### Files
|
|
59
|
+
|
|
60
|
+
| Path | Purpose |
|
|
61
|
+
|------|---------|
|
|
62
|
+
| `~/.mnemonik/scanner.json` | Persistent configuration |
|
|
63
|
+
| `~/.mnemonik/daemon.pid` | PID file for the running daemon |
|
|
64
|
+
| `~/.mnemonik/scanner.log` | Log file (rotated at 5MB) |
|
|
65
|
+
|
|
66
|
+
## What Gets Indexed
|
|
67
|
+
|
|
68
|
+
The scanner indexes code chunks (functions, classes, modules) from these file types:
|
|
69
|
+
|
|
70
|
+
`.ts` `.tsx` `.js` `.jsx` `.py` `.rs` `.go` `.java` `.c` `.cpp` `.h` `.cs` `.rb` `.php` `.swift` `.kt` `.md`
|
|
71
|
+
|
|
72
|
+
It respects `.gitignore` and skips common directories (`node_modules`, `.git`, `dist`, `build`, etc.). Only code structure is indexed — binary files and non-code assets are ignored.
|
|
73
|
+
|
|
74
|
+
## Resource Usage
|
|
75
|
+
|
|
76
|
+
The daemon is designed to run continuously with minimal impact:
|
|
77
|
+
|
|
78
|
+
- **Memory**: Capped at 256MB
|
|
79
|
+
- **CPU**: Event-driven (idle when no files change)
|
|
80
|
+
- **Disk**: Log rotation at 5MB
|
|
81
|
+
- **Network**: Only changed files are pushed (hash-based diffing)
|
|
82
|
+
|
|
83
|
+
## Requirements
|
|
84
|
+
|
|
85
|
+
- Node.js 20 or later
|
|
86
|
+
- A Mnemonik account and API key ([sign up](https://mnemonik.dev))
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
Proprietary. See [mnemonik.dev/terms](https://mnemonik.dev/terms) for details.
|
package/dist/client.d.ts
CHANGED
package/dist/client.js
CHANGED
|
@@ -57,6 +57,9 @@ export class MnemonikClient {
|
|
|
57
57
|
}
|
|
58
58
|
return { success: true };
|
|
59
59
|
}
|
|
60
|
+
async sendHeartbeat(projectId) {
|
|
61
|
+
await this.request('/api/v1/scan/heartbeat', { projectId });
|
|
62
|
+
}
|
|
60
63
|
async healthCheck() {
|
|
61
64
|
try {
|
|
62
65
|
const res = await fetch(`${this.serverUrl}/api/v1/health`, {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAuBA,MAAM,OAAO,cAAc;IAEf;IACA;IAFV,YACU,SAAiB,EACjB,MAAc;QADd,cAAS,GAAT,SAAS,CAAQ;QACjB,WAAM,GAAN,MAAM,CAAQ;IACrB,CAAC;IAEI,KAAK,CAAC,OAAO,CAAI,IAAY,EAAE,IAAa,EAAE,OAAO,GAAG,CAAC;QAC/D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,EAAE,CAAC;QACvC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBAC3B,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;qBACvC;oBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;iBAC3B,CAAC,CAAC;gBAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;oBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC;oBAC3D,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;wBAC7C,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,MAAM,wBAAwB,CAAC,CAAC;oBACtE,CAAC;oBACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;wBAC5C,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;wBACvE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;wBAC3D,SAAS;oBACX,CAAC;oBACD,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;wBAC3C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC9D,SAAS;oBACX,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC,CAAC;gBAC9D,CAAC;gBAED,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;YAClC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,OAAO,GAAG,OAAO,IAAK,GAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;oBAC1E,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9D,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,iBAAiB,OAAO,UAAU,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,SAAiB;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAC/B,qBAAqB,EACrB,EAAE,SAAS,EAAE,CACd,CAAC;QACF,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,KAAqB;QACtD,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;YAC5C,MAAM,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAAiB;QACnC,MAAM,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,gBAAgB,EAAE;gBACzD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE;aACpD,CAAC,CAAC;YACH,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF"}
|
package/dist/daemon.d.ts
CHANGED
|
@@ -1,25 +1,37 @@
|
|
|
1
1
|
export interface DaemonConfig {
|
|
2
|
-
projectId: string;
|
|
3
|
-
projectRoot: string;
|
|
4
2
|
serverUrl: string;
|
|
5
3
|
apiKey: string;
|
|
4
|
+
roots: string[];
|
|
5
|
+
refreshIntervalMs?: number;
|
|
6
|
+
maxConcurrentScans?: number;
|
|
6
7
|
}
|
|
7
8
|
export declare class ScannerDaemon {
|
|
8
9
|
private config;
|
|
9
10
|
private client;
|
|
10
11
|
private scanner;
|
|
11
|
-
private
|
|
12
|
-
private
|
|
13
|
-
private
|
|
12
|
+
private projects;
|
|
13
|
+
private refreshTimer;
|
|
14
|
+
private heartbeatTimer;
|
|
15
|
+
private discovery;
|
|
16
|
+
private refreshIntervalMs;
|
|
17
|
+
private maxConcurrentScans;
|
|
14
18
|
constructor(config: DaemonConfig);
|
|
15
19
|
start(): Promise<void>;
|
|
16
|
-
private waitForServer;
|
|
17
|
-
getProjectRoot(): string;
|
|
18
|
-
getProjectId(): string;
|
|
19
20
|
stop(): Promise<void>;
|
|
20
|
-
private
|
|
21
|
+
private sendHeartbeats;
|
|
22
|
+
getWatchedProjects(): Array<{
|
|
23
|
+
projectId: string;
|
|
24
|
+
path: string;
|
|
25
|
+
name?: string;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Discover projects from configured roots and reconcile with current watch list.
|
|
29
|
+
*/
|
|
30
|
+
refreshProjects(): Promise<void>;
|
|
31
|
+
private addProject;
|
|
32
|
+
private waitForServer;
|
|
21
33
|
private initialScan;
|
|
22
|
-
private startWatching;
|
|
23
34
|
private handleChanges;
|
|
35
|
+
private startRetryLoop;
|
|
24
36
|
private groupChunksByFile;
|
|
25
37
|
}
|
package/dist/daemon.js
CHANGED
|
@@ -4,25 +4,149 @@ import { join } from 'path';
|
|
|
4
4
|
import { CodeScanner } from '@mnemonik/shared';
|
|
5
5
|
import { MnemonikClient } from './client.js';
|
|
6
6
|
import { FileWatcher } from './watcher.js';
|
|
7
|
+
import { ProjectDiscovery } from './discovery.js';
|
|
7
8
|
export class ScannerDaemon {
|
|
8
9
|
config;
|
|
9
10
|
client;
|
|
10
11
|
scanner;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
projects = new Map();
|
|
13
|
+
refreshTimer = null;
|
|
14
|
+
heartbeatTimer = null;
|
|
15
|
+
discovery;
|
|
16
|
+
refreshIntervalMs;
|
|
17
|
+
maxConcurrentScans;
|
|
14
18
|
constructor(config) {
|
|
15
19
|
this.config = config;
|
|
16
20
|
this.client = new MnemonikClient(config.serverUrl, config.apiKey);
|
|
17
21
|
this.scanner = new CodeScanner();
|
|
22
|
+
this.discovery = new ProjectDiscovery(config.roots);
|
|
23
|
+
this.refreshIntervalMs = config.refreshIntervalMs ?? 300_000; // 5 min
|
|
24
|
+
this.maxConcurrentScans = config.maxConcurrentScans ?? 5;
|
|
18
25
|
}
|
|
19
26
|
async start() {
|
|
20
|
-
console.log(`[scanner] Starting daemon
|
|
27
|
+
console.log(`[scanner] Starting daemon`);
|
|
21
28
|
console.log(`[scanner] Server: ${this.config.serverUrl}`);
|
|
22
|
-
console.log(`[scanner]
|
|
29
|
+
console.log(`[scanner] Roots: ${this.config.roots.join(', ')}`);
|
|
23
30
|
await this.waitForServer();
|
|
24
|
-
await this.
|
|
25
|
-
|
|
31
|
+
await this.refreshProjects();
|
|
32
|
+
this.refreshTimer = setInterval(() => {
|
|
33
|
+
this.refreshProjects().catch((err) => {
|
|
34
|
+
console.warn('[scanner] Refresh failed:', err.message);
|
|
35
|
+
});
|
|
36
|
+
}, this.refreshIntervalMs);
|
|
37
|
+
this.refreshTimer.unref();
|
|
38
|
+
// Send heartbeat immediately, then every 60s so session_bootstrap
|
|
39
|
+
// can reliably detect daemon liveness without waiting for a file scan.
|
|
40
|
+
await this.sendHeartbeats();
|
|
41
|
+
this.heartbeatTimer = setInterval(() => {
|
|
42
|
+
this.sendHeartbeats().catch((err) => {
|
|
43
|
+
console.warn('[scanner] Heartbeat failed:', err.message);
|
|
44
|
+
});
|
|
45
|
+
}, 60_000);
|
|
46
|
+
this.heartbeatTimer.unref();
|
|
47
|
+
console.log('[scanner] Watching for changes.');
|
|
48
|
+
}
|
|
49
|
+
async stop() {
|
|
50
|
+
if (this.refreshTimer) {
|
|
51
|
+
clearInterval(this.refreshTimer);
|
|
52
|
+
this.refreshTimer = null;
|
|
53
|
+
}
|
|
54
|
+
if (this.heartbeatTimer) {
|
|
55
|
+
clearInterval(this.heartbeatTimer);
|
|
56
|
+
this.heartbeatTimer = null;
|
|
57
|
+
}
|
|
58
|
+
for (const project of this.projects.values()) {
|
|
59
|
+
project.watcher.stop();
|
|
60
|
+
if (project.retryTimer)
|
|
61
|
+
clearInterval(project.retryTimer);
|
|
62
|
+
}
|
|
63
|
+
this.projects.clear();
|
|
64
|
+
console.log('[scanner] Daemon stopped');
|
|
65
|
+
}
|
|
66
|
+
async sendHeartbeats() {
|
|
67
|
+
for (const { projectId } of this.projects.values()) {
|
|
68
|
+
await this.client.sendHeartbeat(projectId).catch((err) => {
|
|
69
|
+
console.warn(`[scanner] Heartbeat failed for ${projectId}:`, err.message);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
getWatchedProjects() {
|
|
74
|
+
return Array.from(this.projects.values()).map((p) => ({
|
|
75
|
+
projectId: p.projectId,
|
|
76
|
+
path: p.path,
|
|
77
|
+
name: p.name,
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Discover projects from configured roots and reconcile with current watch list.
|
|
82
|
+
*/
|
|
83
|
+
async refreshProjects() {
|
|
84
|
+
const discovered = await this.discovery.discover();
|
|
85
|
+
const discoveredMap = new Map(discovered.map((d) => [d.projectId, d]));
|
|
86
|
+
// Remove projects no longer discovered
|
|
87
|
+
for (const [projectId, project] of this.projects) {
|
|
88
|
+
if (!discoveredMap.has(projectId)) {
|
|
89
|
+
console.log(`[scanner] Project removed: ${project.name ?? projectId} (${project.path})`);
|
|
90
|
+
project.watcher.stop();
|
|
91
|
+
if (project.retryTimer)
|
|
92
|
+
clearInterval(project.retryTimer);
|
|
93
|
+
this.projects.delete(projectId);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Add new projects or handle path changes
|
|
97
|
+
for (const discovered_project of discoveredMap.values()) {
|
|
98
|
+
const existing = this.projects.get(discovered_project.projectId);
|
|
99
|
+
if (!existing) {
|
|
100
|
+
// New project
|
|
101
|
+
await this.addProject(discovered_project);
|
|
102
|
+
}
|
|
103
|
+
else if (existing.path !== discovered_project.path) {
|
|
104
|
+
// Path changed (folder renamed/moved)
|
|
105
|
+
console.log(`[scanner] Project moved: ${existing.name ?? existing.projectId} ` +
|
|
106
|
+
`${existing.path} → ${discovered_project.path}`);
|
|
107
|
+
existing.watcher.stop();
|
|
108
|
+
if (existing.retryTimer)
|
|
109
|
+
clearInterval(existing.retryTimer);
|
|
110
|
+
this.projects.delete(discovered_project.projectId);
|
|
111
|
+
await this.addProject(discovered_project);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
console.log(`[scanner] Watching ${this.projects.size} project(s)`);
|
|
115
|
+
}
|
|
116
|
+
async addProject(discovered) {
|
|
117
|
+
const label = discovered.projectName ?? discovered.projectId.slice(0, 8);
|
|
118
|
+
console.log(`[scanner] Adding project: ${label} (${discovered.path})`);
|
|
119
|
+
try {
|
|
120
|
+
await this.initialScan(discovered.projectId, discovered.path);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
console.warn(`[scanner] Initial scan failed for ${label}:`, err.message);
|
|
124
|
+
}
|
|
125
|
+
const watcher = new FileWatcher(discovered.path, (changedFiles) => this.handleChanges(discovered.projectId, discovered.path, changedFiles), 500, (err) => {
|
|
126
|
+
console.warn(`[scanner] Root watcher error for ${label}: ${err.message}. Removing project.`);
|
|
127
|
+
const project = this.projects.get(discovered.projectId);
|
|
128
|
+
if (project) {
|
|
129
|
+
project.watcher.stop();
|
|
130
|
+
if (project.retryTimer)
|
|
131
|
+
clearInterval(project.retryTimer);
|
|
132
|
+
this.projects.delete(discovered.projectId);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
try {
|
|
136
|
+
await watcher.start();
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
console.warn(`[scanner] Failed to start watcher for ${label}:`, err.message);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
this.projects.set(discovered.projectId, {
|
|
143
|
+
projectId: discovered.projectId,
|
|
144
|
+
path: discovered.path,
|
|
145
|
+
name: discovered.projectName,
|
|
146
|
+
watcher,
|
|
147
|
+
pendingRetries: new Set(),
|
|
148
|
+
retryTimer: null,
|
|
149
|
+
});
|
|
26
150
|
}
|
|
27
151
|
async waitForServer() {
|
|
28
152
|
let logged = false;
|
|
@@ -47,108 +171,83 @@ export class ScannerDaemon {
|
|
|
47
171
|
}
|
|
48
172
|
throw new Error(`Server unreachable after ${maxRetries} attempts`);
|
|
49
173
|
}
|
|
50
|
-
|
|
51
|
-
return this.config.projectRoot;
|
|
52
|
-
}
|
|
53
|
-
getProjectId() {
|
|
54
|
-
return this.config.projectId;
|
|
55
|
-
}
|
|
56
|
-
async stop() {
|
|
57
|
-
this.watcher?.stop();
|
|
58
|
-
if (this.retryTimer)
|
|
59
|
-
clearInterval(this.retryTimer);
|
|
60
|
-
console.log('[scanner] Daemon stopped');
|
|
61
|
-
}
|
|
62
|
-
startRetryLoop() {
|
|
63
|
-
if (this.retryTimer)
|
|
64
|
-
return;
|
|
65
|
-
console.log(`[scanner] ${this.pendingRetries.size} file(s) queued for retry`);
|
|
66
|
-
this.retryTimer = setInterval(async () => {
|
|
67
|
-
if (this.pendingRetries.size === 0) {
|
|
68
|
-
if (this.retryTimer)
|
|
69
|
-
clearInterval(this.retryTimer);
|
|
70
|
-
this.retryTimer = null;
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
const files = [...this.pendingRetries];
|
|
74
|
-
this.pendingRetries.clear();
|
|
75
|
-
await this.handleChanges(files);
|
|
76
|
-
}, 10_000);
|
|
77
|
-
this.retryTimer.unref();
|
|
78
|
-
}
|
|
79
|
-
async initialScan() {
|
|
80
|
-
console.log('[scanner] Starting initial scan...');
|
|
174
|
+
async initialScan(projectId, projectRoot) {
|
|
81
175
|
const startTime = Date.now();
|
|
82
|
-
const chunks = await this.scanner.scanDirectory(
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
console.log(`[scanner] Server knows ${serverHashes.size} files`);
|
|
86
|
-
const files = await this.groupChunksByFile(chunks);
|
|
176
|
+
const chunks = await this.scanner.scanDirectory(projectRoot);
|
|
177
|
+
const serverHashes = await this.client.getStatus(projectId);
|
|
178
|
+
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
87
179
|
const filesToPush = files.filter((f) => {
|
|
88
180
|
const serverHash = serverHashes.get(f.path);
|
|
89
181
|
return !serverHash || serverHash !== f.hash;
|
|
90
182
|
});
|
|
91
|
-
if (filesToPush.length
|
|
92
|
-
console.log(
|
|
93
|
-
|
|
94
|
-
else {
|
|
95
|
-
console.log(`[scanner] Pushing ${filesToPush.length} changed files...`);
|
|
96
|
-
await this.client.pushFiles(this.config.projectId, filesToPush);
|
|
97
|
-
console.log(`[scanner] Push complete`);
|
|
183
|
+
if (filesToPush.length > 0) {
|
|
184
|
+
console.log(`[scanner] Pushing ${filesToPush.length} changed files for ${projectId.slice(0, 8)}...`);
|
|
185
|
+
await this.client.pushFiles(projectId, filesToPush);
|
|
98
186
|
}
|
|
99
187
|
const duration = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
100
|
-
console.log(`[scanner]
|
|
101
|
-
|
|
102
|
-
async startWatching() {
|
|
103
|
-
this.watcher = new FileWatcher(this.config.projectRoot, (changedFiles) => this.handleChanges(changedFiles), 500);
|
|
104
|
-
await this.watcher.start();
|
|
188
|
+
console.log(`[scanner] Scan complete for ${projectId.slice(0, 8)}: ` +
|
|
189
|
+
`${chunks.length} chunks, ${filesToPush.length} pushed (${duration}s)`);
|
|
105
190
|
}
|
|
106
|
-
async handleChanges(changedFiles) {
|
|
191
|
+
async handleChanges(projectId, projectRoot, changedFiles) {
|
|
192
|
+
const project = this.projects.get(projectId);
|
|
193
|
+
if (!project)
|
|
194
|
+
return;
|
|
107
195
|
try {
|
|
108
|
-
const absPaths = changedFiles.map((rel) => join(
|
|
109
|
-
const chunks = await this.scanner.scanFiles(absPaths,
|
|
196
|
+
const absPaths = changedFiles.map((rel) => join(projectRoot, rel));
|
|
197
|
+
const chunks = await this.scanner.scanFiles(absPaths, projectRoot);
|
|
110
198
|
if (chunks.length === 0)
|
|
111
199
|
return;
|
|
112
|
-
const files = await this.groupChunksByFile(chunks);
|
|
113
|
-
// Push in batches, only retrying files from failed batches
|
|
200
|
+
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
114
201
|
const batchSize = 25;
|
|
115
202
|
const succeededPaths = new Set();
|
|
116
203
|
let hadFailure = false;
|
|
117
204
|
for (let i = 0; i < files.length; i += batchSize) {
|
|
118
205
|
const batch = files.slice(i, i + batchSize);
|
|
119
206
|
try {
|
|
120
|
-
await this.client.pushFiles(
|
|
207
|
+
await this.client.pushFiles(projectId, batch);
|
|
121
208
|
for (const f of batch)
|
|
122
209
|
succeededPaths.add(f.path);
|
|
123
210
|
}
|
|
124
211
|
catch {
|
|
125
212
|
hadFailure = true;
|
|
126
213
|
for (const f of batch)
|
|
127
|
-
|
|
214
|
+
project.pendingRetries.add(f.path);
|
|
128
215
|
}
|
|
129
216
|
}
|
|
130
217
|
if (succeededPaths.size > 0) {
|
|
131
|
-
console.log(`[scanner] Pushed ${succeededPaths.size}
|
|
218
|
+
console.log(`[scanner] [${projectId.slice(0, 8)}] Pushed ${succeededPaths.size} file(s): ${[...succeededPaths].join(', ')}`);
|
|
132
219
|
}
|
|
133
220
|
if (hadFailure) {
|
|
134
|
-
console.warn(`[scanner] ${
|
|
135
|
-
this.startRetryLoop();
|
|
221
|
+
console.warn(`[scanner] [${projectId.slice(0, 8)}] ${project.pendingRetries.size} file(s) failed, queued for retry`);
|
|
222
|
+
this.startRetryLoop(project);
|
|
136
223
|
}
|
|
137
224
|
}
|
|
138
225
|
catch (err) {
|
|
139
|
-
console.error(
|
|
226
|
+
console.error(`[scanner] [${projectId.slice(0, 8)}] Error handling changes:`, err);
|
|
140
227
|
}
|
|
141
228
|
}
|
|
142
|
-
|
|
229
|
+
startRetryLoop(project) {
|
|
230
|
+
if (project.retryTimer)
|
|
231
|
+
return;
|
|
232
|
+
project.retryTimer = setInterval(async () => {
|
|
233
|
+
if (project.pendingRetries.size === 0) {
|
|
234
|
+
if (project.retryTimer)
|
|
235
|
+
clearInterval(project.retryTimer);
|
|
236
|
+
project.retryTimer = null;
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const files = [...project.pendingRetries];
|
|
240
|
+
project.pendingRetries.clear();
|
|
241
|
+
await this.handleChanges(project.projectId, project.path, files);
|
|
242
|
+
}, 10_000);
|
|
243
|
+
project.retryTimer.unref();
|
|
244
|
+
}
|
|
245
|
+
async groupChunksByFile(chunks, projectRoot) {
|
|
143
246
|
const fileMap = new Map();
|
|
144
247
|
for (const chunk of chunks) {
|
|
145
248
|
const key = chunk.filePath;
|
|
146
249
|
if (!fileMap.has(key)) {
|
|
147
|
-
fileMap.set(key, {
|
|
148
|
-
path: key,
|
|
149
|
-
hash: '',
|
|
150
|
-
chunks: [],
|
|
151
|
-
});
|
|
250
|
+
fileMap.set(key, { path: key, hash: '', chunks: [] });
|
|
152
251
|
}
|
|
153
252
|
const file = fileMap.get(key);
|
|
154
253
|
file.chunks.push({
|
|
@@ -163,7 +262,7 @@ export class ScannerDaemon {
|
|
|
163
262
|
}
|
|
164
263
|
for (const file of fileMap.values()) {
|
|
165
264
|
try {
|
|
166
|
-
const absPath = join(
|
|
265
|
+
const absPath = join(projectRoot, file.path);
|
|
167
266
|
const raw = await readFile(absPath, 'utf-8');
|
|
168
267
|
file.hash = createHash('sha256').update(raw).digest('hex');
|
|
169
268
|
}
|
package/dist/daemon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface DiscoveredProject {
|
|
2
|
+
projectId: string;
|
|
3
|
+
path: string;
|
|
4
|
+
projectName?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class ProjectDiscovery {
|
|
7
|
+
private roots;
|
|
8
|
+
private maxDepth;
|
|
9
|
+
private timeoutMs;
|
|
10
|
+
constructor(roots: string[], options?: {
|
|
11
|
+
maxDepth?: number;
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Discover all projects with .mnemonik.json files under the configured roots.
|
|
16
|
+
* Deduplicates by projectId (same project found at multiple paths = first wins).
|
|
17
|
+
*/
|
|
18
|
+
discover(): Promise<DiscoveredProject[]>;
|
|
19
|
+
private walkWithTimeout;
|
|
20
|
+
private walk;
|
|
21
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { readFile, readdir } from 'fs/promises';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
/** Directories to skip during discovery walk */
|
|
4
|
+
const SKIP_DIRS = new Set([
|
|
5
|
+
'node_modules',
|
|
6
|
+
'.git',
|
|
7
|
+
'dist',
|
|
8
|
+
'build',
|
|
9
|
+
'.next',
|
|
10
|
+
'.nuxt',
|
|
11
|
+
'.output',
|
|
12
|
+
'__pycache__',
|
|
13
|
+
'.venv',
|
|
14
|
+
'venv',
|
|
15
|
+
'.tox',
|
|
16
|
+
'target',
|
|
17
|
+
'.cache',
|
|
18
|
+
'coverage',
|
|
19
|
+
'.turbo',
|
|
20
|
+
'.vercel',
|
|
21
|
+
'.svelte-kit',
|
|
22
|
+
]);
|
|
23
|
+
export class ProjectDiscovery {
|
|
24
|
+
roots;
|
|
25
|
+
maxDepth;
|
|
26
|
+
timeoutMs;
|
|
27
|
+
constructor(roots, options) {
|
|
28
|
+
this.roots = roots;
|
|
29
|
+
this.maxDepth = options?.maxDepth ?? 3;
|
|
30
|
+
this.timeoutMs = options?.timeoutMs ?? 30_000;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Discover all projects with .mnemonik.json files under the configured roots.
|
|
34
|
+
* Deduplicates by projectId (same project found at multiple paths = first wins).
|
|
35
|
+
*/
|
|
36
|
+
async discover() {
|
|
37
|
+
const seen = new Map();
|
|
38
|
+
for (const root of this.roots) {
|
|
39
|
+
const absRoot = resolve(root.replace(/^~/, process.env.HOME || ''));
|
|
40
|
+
try {
|
|
41
|
+
await this.walkWithTimeout(absRoot, 0, seen);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
if (err instanceof DiscoveryTimeoutError) {
|
|
45
|
+
console.warn(`[scanner] Discovery timeout for root: ${absRoot} (>${this.timeoutMs}ms)`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.warn(`[scanner] Error scanning root ${absRoot}:`, err.message);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Array.from(seen.values());
|
|
53
|
+
}
|
|
54
|
+
async walkWithTimeout(dir, depth, seen) {
|
|
55
|
+
const deadline = Date.now() + this.timeoutMs;
|
|
56
|
+
await this.walk(dir, depth, seen, deadline);
|
|
57
|
+
}
|
|
58
|
+
async walk(dir, depth, seen, deadline) {
|
|
59
|
+
if (depth > this.maxDepth)
|
|
60
|
+
return;
|
|
61
|
+
if (Date.now() > deadline)
|
|
62
|
+
throw new DiscoveryTimeoutError();
|
|
63
|
+
// Check for .mnemonik.json in this directory
|
|
64
|
+
const configPath = join(dir, '.mnemonik.json');
|
|
65
|
+
try {
|
|
66
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
67
|
+
const parsed = JSON.parse(raw);
|
|
68
|
+
if (typeof parsed.projectId === 'string' && parsed.projectId.length > 0) {
|
|
69
|
+
if (!seen.has(parsed.projectId)) {
|
|
70
|
+
seen.set(parsed.projectId, {
|
|
71
|
+
projectId: parsed.projectId,
|
|
72
|
+
path: dir,
|
|
73
|
+
projectName: typeof parsed.projectName === 'string' ? parsed.projectName : undefined,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Don't recurse into subdirectories of a project — the project owns this tree
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// No .mnemonik.json here, continue walking
|
|
82
|
+
}
|
|
83
|
+
// Recurse into subdirectories
|
|
84
|
+
try {
|
|
85
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
86
|
+
for (const entry of entries) {
|
|
87
|
+
if (!entry.isDirectory())
|
|
88
|
+
continue;
|
|
89
|
+
if (SKIP_DIRS.has(entry.name))
|
|
90
|
+
continue;
|
|
91
|
+
if (entry.name.startsWith('.') && entry.name !== '.mnemonik')
|
|
92
|
+
continue;
|
|
93
|
+
await this.walk(join(dir, entry.name), depth + 1, seen, deadline);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Permission denied or inaccessible directory
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
class DiscoveryTimeoutError extends Error {
|
|
102
|
+
constructor() {
|
|
103
|
+
super('Discovery walk timed out');
|
|
104
|
+
this.name = 'DiscoveryTimeoutError';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=discovery.js.map
|