@mnemonik/scanner 5.151.0 → 5.151.3
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/client.d.ts +99 -0
- package/dist/client.js +140 -0
- package/dist/client.js.map +1 -0
- package/dist/daemon.d.ts +51 -0
- package/dist/daemon.js +550 -0
- package/dist/daemon.js.map +1 -0
- package/dist/discovery.d.ts +21 -0
- package/dist/discovery.js +107 -0
- package/dist/discovery.js.map +1 -0
- 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/git.d.ts +31 -0
- package/dist/git.js +111 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +399 -0
- package/dist/index.js.map +1 -0
- 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 +30 -0
- package/dist/watcher.js +214 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +7 -3
- package/src/client.ts +0 -216
- package/src/daemon.ts +0 -679
- package/src/discovery.ts +0 -124
- package/src/doctor.ts +0 -239
- package/src/fileLog.ts +0 -67
- package/src/git.ts +0 -122
- package/src/index.ts +0 -446
- package/src/pid.ts +0 -37
- package/src/watcher.ts +0 -219
- package/tests/validateServerUrl.test.ts +0 -41
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -13
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export interface ScanPushFile {
|
|
2
|
+
path: string;
|
|
3
|
+
hash: string;
|
|
4
|
+
chunks: Array<{
|
|
5
|
+
content: string;
|
|
6
|
+
startLine: number;
|
|
7
|
+
endLine: number;
|
|
8
|
+
chunkType: string;
|
|
9
|
+
language: string;
|
|
10
|
+
contentHash: string;
|
|
11
|
+
metadata: {
|
|
12
|
+
fileName: string;
|
|
13
|
+
extension: string;
|
|
14
|
+
size: number;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Optional raw file content. Sent by the scanner daemon for ALL files
|
|
19
|
+
* (code and authority/manifest alike) so the doc-truth worker can run
|
|
20
|
+
* claim extraction against whole documents without filesystem access.
|
|
21
|
+
* Omitted when the file exceeds the server's 5 MB schema cap or when
|
|
22
|
+
* the raw content could not be read (chunk-based fallback path).
|
|
23
|
+
*/
|
|
24
|
+
content?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ScanPushCommit {
|
|
27
|
+
sha: string;
|
|
28
|
+
author: string;
|
|
29
|
+
date: string;
|
|
30
|
+
message: string;
|
|
31
|
+
files: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface ScanPushPayload {
|
|
34
|
+
projectId: string;
|
|
35
|
+
files: ScanPushFile[];
|
|
36
|
+
commits?: ScanPushCommit[];
|
|
37
|
+
}
|
|
38
|
+
export interface ScanStatusResponse {
|
|
39
|
+
files: Array<{
|
|
40
|
+
path: string;
|
|
41
|
+
hash: string;
|
|
42
|
+
}>;
|
|
43
|
+
gitMining?: {
|
|
44
|
+
enabled: boolean;
|
|
45
|
+
lastMinedCommit: string | null;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export interface GitMiningMeta {
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
lastMinedCommit: string | null;
|
|
51
|
+
}
|
|
52
|
+
export declare class MnemonikClient {
|
|
53
|
+
private serverUrl;
|
|
54
|
+
private apiKey;
|
|
55
|
+
constructor(serverUrl: string, apiKey: string);
|
|
56
|
+
private request;
|
|
57
|
+
/**
|
|
58
|
+
* Fetch per-file hashes for dedup, plus git-mining metadata.
|
|
59
|
+
* The daemon uses `gitMining.enabled` to decide whether to collect commits
|
|
60
|
+
* this cycle, and `lastMinedCommit` as the lower bound of `git log`.
|
|
61
|
+
*/
|
|
62
|
+
getStatus(projectId: string): Promise<{
|
|
63
|
+
fileHashes: Map<string, string>;
|
|
64
|
+
gitMining: GitMiningMeta;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* Push file chunks in batches. When `commits` is supplied (non-empty) it is
|
|
68
|
+
* attached to the first batch only — BullMQ's idempotent jobId means a
|
|
69
|
+
* duplicate would collapse anyway, but one payload saves bandwidth.
|
|
70
|
+
*
|
|
71
|
+
* When `files` is empty and `commits` is non-empty, a single commit-only
|
|
72
|
+
* push is made — the server accepts `files=[]` since If both are
|
|
73
|
+
* empty, no request is sent.
|
|
74
|
+
*/
|
|
75
|
+
pushFiles(projectId: string, files: ScanPushFile[], commits?: ScanPushCommit[]): Promise<{
|
|
76
|
+
success: boolean;
|
|
77
|
+
}>;
|
|
78
|
+
sendHeartbeat(projectId: string, scanner: {
|
|
79
|
+
scope: 'global';
|
|
80
|
+
version?: string;
|
|
81
|
+
}): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Notify the server of files that have been removed since the daemon's
|
|
84
|
+
* previous scan of this project. Server deprecates exactly those code
|
|
85
|
+
* memories. Empty arrays are accepted as no-ops so the daemon can call
|
|
86
|
+
* this every tick regardless of whether anything was removed.
|
|
87
|
+
*
|
|
88
|
+
* The caller is responsible for computing the removal set locally — the
|
|
89
|
+
* old inventory-diff shape that asked the server to derive removals from
|
|
90
|
+
* a "known files" list has been removed because a small/malformed list
|
|
91
|
+
* would mass-deprecate. The narrow `removedFiles` shape cannot exhibit
|
|
92
|
+
* that failure mode by construction.
|
|
93
|
+
*/
|
|
94
|
+
reportRemovedFiles(projectId: string, removedFiles: string[]): Promise<{
|
|
95
|
+
deprecated: number;
|
|
96
|
+
couplingsRemoved: number;
|
|
97
|
+
}>;
|
|
98
|
+
healthCheck(): Promise<boolean>;
|
|
99
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const SCAN_PUSH_BATCH_DELAY_MS = 500;
|
|
2
|
+
/**
|
|
3
|
+
* Exponential backoff (base 2000ms × attempt) with ±25% jitter, to avoid a
|
|
4
|
+
* fleet of scanners retrying in lockstep after a shared 5xx/network blip
|
|
5
|
+
* (thundering herd). Base values unchanged from the pre-jitter constants.
|
|
6
|
+
*/
|
|
7
|
+
function backoffWithJitter(attempt) {
|
|
8
|
+
const base = 2000 * (attempt + 1);
|
|
9
|
+
return Math.round(base * (0.75 + Math.random() * 0.5));
|
|
10
|
+
}
|
|
11
|
+
export class MnemonikClient {
|
|
12
|
+
serverUrl;
|
|
13
|
+
apiKey;
|
|
14
|
+
constructor(serverUrl, apiKey) {
|
|
15
|
+
this.serverUrl = serverUrl;
|
|
16
|
+
this.apiKey = apiKey;
|
|
17
|
+
}
|
|
18
|
+
async request(path, body, retries = 3) {
|
|
19
|
+
const url = `${this.serverUrl}${path}`;
|
|
20
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
21
|
+
try {
|
|
22
|
+
const res = await fetch(url, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
27
|
+
},
|
|
28
|
+
body: JSON.stringify(body),
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
const text = await res.text().catch(() => 'Unknown error');
|
|
32
|
+
if (res.status === 401 || res.status === 403) {
|
|
33
|
+
throw new Error(`Auth failed (${res.status}). Check your API key.`);
|
|
34
|
+
}
|
|
35
|
+
if (res.status === 503 && attempt < retries) {
|
|
36
|
+
const retryAfter = parseInt(res.headers.get('Retry-After') || '5', 10);
|
|
37
|
+
await new Promise((r) => setTimeout(r, retryAfter * 1000));
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (res.status >= 500 && attempt < retries) {
|
|
41
|
+
await new Promise((r) => setTimeout(r, backoffWithJitter(attempt)));
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`${res.status} ${res.statusText}: ${text}`);
|
|
45
|
+
}
|
|
46
|
+
return res.json();
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (attempt < retries && err.message?.includes('fetch failed')) {
|
|
50
|
+
await new Promise((r) => setTimeout(r, backoffWithJitter(attempt)));
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
throw new Error(`Request to ${path} failed after ${retries} retries`);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Fetch per-file hashes for dedup, plus git-mining metadata.
|
|
60
|
+
* The daemon uses `gitMining.enabled` to decide whether to collect commits
|
|
61
|
+
* this cycle, and `lastMinedCommit` as the lower bound of `git log`.
|
|
62
|
+
*/
|
|
63
|
+
async getStatus(projectId) {
|
|
64
|
+
const result = await this.request('/api/v1/scan/status', { projectId });
|
|
65
|
+
return {
|
|
66
|
+
fileHashes: new Map(result.files.map((f) => [f.path, f.hash])),
|
|
67
|
+
gitMining: result.gitMining ?? { enabled: false, lastMinedCommit: null },
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Push file chunks in batches. When `commits` is supplied (non-empty) it is
|
|
72
|
+
* attached to the first batch only — BullMQ's idempotent jobId means a
|
|
73
|
+
* duplicate would collapse anyway, but one payload saves bandwidth.
|
|
74
|
+
*
|
|
75
|
+
* When `files` is empty and `commits` is non-empty, a single commit-only
|
|
76
|
+
* push is made — the server accepts `files=[]` since If both are
|
|
77
|
+
* empty, no request is sent.
|
|
78
|
+
*/
|
|
79
|
+
async pushFiles(projectId, files, commits) {
|
|
80
|
+
const hasCommits = !!commits && commits.length > 0;
|
|
81
|
+
if (files.length === 0) {
|
|
82
|
+
if (hasCommits) {
|
|
83
|
+
await this.request('/api/v1/scan/push', { projectId, files: [], commits });
|
|
84
|
+
}
|
|
85
|
+
return { success: true };
|
|
86
|
+
}
|
|
87
|
+
const batchSize = 25;
|
|
88
|
+
let attachedCommits = false;
|
|
89
|
+
for (let i = 0; i < files.length; i += batchSize) {
|
|
90
|
+
const batch = files.slice(i, i + batchSize);
|
|
91
|
+
const body = { projectId, files: batch };
|
|
92
|
+
if (!attachedCommits && hasCommits) {
|
|
93
|
+
body.commits = commits;
|
|
94
|
+
attachedCommits = true;
|
|
95
|
+
}
|
|
96
|
+
await this.request('/api/v1/scan/push', body);
|
|
97
|
+
if (i + batchSize < files.length) {
|
|
98
|
+
await sleep(SCAN_PUSH_BATCH_DELAY_MS);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { success: true };
|
|
102
|
+
}
|
|
103
|
+
async sendHeartbeat(projectId, scanner) {
|
|
104
|
+
await this.request('/api/v1/scan/heartbeat', { projectId, scanner });
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Notify the server of files that have been removed since the daemon's
|
|
108
|
+
* previous scan of this project. Server deprecates exactly those code
|
|
109
|
+
* memories. Empty arrays are accepted as no-ops so the daemon can call
|
|
110
|
+
* this every tick regardless of whether anything was removed.
|
|
111
|
+
*
|
|
112
|
+
* The caller is responsible for computing the removal set locally — the
|
|
113
|
+
* old inventory-diff shape that asked the server to derive removals from
|
|
114
|
+
* a "known files" list has been removed because a small/malformed list
|
|
115
|
+
* would mass-deprecate. The narrow `removedFiles` shape cannot exhibit
|
|
116
|
+
* that failure mode by construction.
|
|
117
|
+
*/
|
|
118
|
+
async reportRemovedFiles(projectId, removedFiles) {
|
|
119
|
+
const result = await this.request('/api/v1/scan/reconcile', { projectId, removedFiles });
|
|
120
|
+
return {
|
|
121
|
+
deprecated: result.deprecated ?? 0,
|
|
122
|
+
couplingsRemoved: result.couplingsRemoved ?? 0,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async healthCheck() {
|
|
126
|
+
try {
|
|
127
|
+
const res = await fetch(`${this.serverUrl}/api/v1/health`, {
|
|
128
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
129
|
+
});
|
|
130
|
+
return res.ok;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function sleep(ms) {
|
|
138
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface DaemonConfig {
|
|
2
|
+
serverUrl: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
roots: string[];
|
|
5
|
+
refreshIntervalMs?: number;
|
|
6
|
+
maxConcurrentScans?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class ScannerDaemon {
|
|
9
|
+
private config;
|
|
10
|
+
private client;
|
|
11
|
+
private scanner;
|
|
12
|
+
private projects;
|
|
13
|
+
private refreshTimer;
|
|
14
|
+
private heartbeatTimer;
|
|
15
|
+
private discovery;
|
|
16
|
+
private refreshIntervalMs;
|
|
17
|
+
private maxConcurrentScans;
|
|
18
|
+
private scannerVersion;
|
|
19
|
+
constructor(config: DaemonConfig);
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
stop(): Promise<void>;
|
|
22
|
+
private sendHeartbeats;
|
|
23
|
+
private getScannerVersion;
|
|
24
|
+
getWatchedProjects(): Array<{
|
|
25
|
+
projectId: string;
|
|
26
|
+
path: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Discover projects from configured roots and reconcile with current watch list.
|
|
31
|
+
*/
|
|
32
|
+
refreshProjects(): Promise<void>;
|
|
33
|
+
private addProject;
|
|
34
|
+
private waitForServer;
|
|
35
|
+
private initialScan;
|
|
36
|
+
/**
|
|
37
|
+
* Send the explicit list of paths that vanished since the previous scan.
|
|
38
|
+
* Empty lists short-circuit so we don't pay an HTTP round-trip when
|
|
39
|
+
* nothing was removed this tick.
|
|
40
|
+
*/
|
|
41
|
+
private sendRemovedFiles;
|
|
42
|
+
/**
|
|
43
|
+
* Fetch commits since the last mine. Swallows errors — a git failure must
|
|
44
|
+
* not block the file scan push.
|
|
45
|
+
*/
|
|
46
|
+
private collectCommits;
|
|
47
|
+
private handleChanges;
|
|
48
|
+
private startRetryLoop;
|
|
49
|
+
private collectAuthorityPushFiles;
|
|
50
|
+
private groupChunksByFile;
|
|
51
|
+
}
|