@mnemonik/scanner 2.0.1 → 2.1.0
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 +37 -2
- package/dist/client.js +22 -3
- package/dist/client.js.map +1 -1
- package/dist/daemon.d.ts +5 -0
- package/dist/daemon.js +55 -7
- package/dist/daemon.js.map +1 -1
- package/dist/git.d.ts +31 -0
- package/dist/git.js +111 -0
- package/dist/git.js.map +1 -0
- package/package.json +1 -1
- package/src/client.ts +52 -8
- package/src/daemon.ts +76 -9
- package/src/git.ts +122 -0
package/dist/client.d.ts
CHANGED
|
@@ -15,17 +15,52 @@ export interface ScanPushFile {
|
|
|
15
15
|
};
|
|
16
16
|
}>;
|
|
17
17
|
}
|
|
18
|
+
export interface ScanPushCommit {
|
|
19
|
+
sha: string;
|
|
20
|
+
author: string;
|
|
21
|
+
date: string;
|
|
22
|
+
message: string;
|
|
23
|
+
files: string[];
|
|
24
|
+
}
|
|
18
25
|
export interface ScanPushPayload {
|
|
19
26
|
projectId: string;
|
|
20
27
|
files: ScanPushFile[];
|
|
28
|
+
commits?: ScanPushCommit[];
|
|
29
|
+
}
|
|
30
|
+
export interface ScanStatusResponse {
|
|
31
|
+
files: Array<{
|
|
32
|
+
path: string;
|
|
33
|
+
hash: string;
|
|
34
|
+
}>;
|
|
35
|
+
gitMining?: {
|
|
36
|
+
enabled: boolean;
|
|
37
|
+
lastMinedCommit: string | null;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export interface GitMiningMeta {
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
lastMinedCommit: string | null;
|
|
21
43
|
}
|
|
22
44
|
export declare class MnemonikClient {
|
|
23
45
|
private serverUrl;
|
|
24
46
|
private apiKey;
|
|
25
47
|
constructor(serverUrl: string, apiKey: string);
|
|
26
48
|
private request;
|
|
27
|
-
|
|
28
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Fetch per-file hashes for dedup, plus git-mining metadata (v3.68).
|
|
51
|
+
* The daemon uses `gitMining.enabled` to decide whether to collect commits
|
|
52
|
+
* this cycle, and `lastMinedCommit` as the lower bound of `git log`.
|
|
53
|
+
*/
|
|
54
|
+
getStatus(projectId: string): Promise<{
|
|
55
|
+
fileHashes: Map<string, string>;
|
|
56
|
+
gitMining: GitMiningMeta;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* Push file chunks in batches. When `commits` is supplied (non-empty) it is
|
|
60
|
+
* attached to the first batch only — BullMQ's idempotent jobId means a
|
|
61
|
+
* duplicate would collapse anyway, but one payload saves bandwidth.
|
|
62
|
+
*/
|
|
63
|
+
pushFiles(projectId: string, files: ScanPushFile[], commits?: ScanPushCommit[]): Promise<{
|
|
29
64
|
success: boolean;
|
|
30
65
|
}>;
|
|
31
66
|
sendHeartbeat(projectId: string): Promise<void>;
|
package/dist/client.js
CHANGED
|
@@ -45,15 +45,34 @@ export class MnemonikClient {
|
|
|
45
45
|
}
|
|
46
46
|
throw new Error(`Request to ${path} failed after ${retries} retries`);
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Fetch per-file hashes for dedup, plus git-mining metadata (v3.68).
|
|
50
|
+
* The daemon uses `gitMining.enabled` to decide whether to collect commits
|
|
51
|
+
* this cycle, and `lastMinedCommit` as the lower bound of `git log`.
|
|
52
|
+
*/
|
|
48
53
|
async getStatus(projectId) {
|
|
49
54
|
const result = await this.request('/api/v1/scan/status', { projectId });
|
|
50
|
-
return
|
|
55
|
+
return {
|
|
56
|
+
fileHashes: new Map(result.files.map((f) => [f.path, f.hash])),
|
|
57
|
+
gitMining: result.gitMining ?? { enabled: false, lastMinedCommit: null },
|
|
58
|
+
};
|
|
51
59
|
}
|
|
52
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Push file chunks in batches. When `commits` is supplied (non-empty) it is
|
|
62
|
+
* attached to the first batch only — BullMQ's idempotent jobId means a
|
|
63
|
+
* duplicate would collapse anyway, but one payload saves bandwidth.
|
|
64
|
+
*/
|
|
65
|
+
async pushFiles(projectId, files, commits) {
|
|
53
66
|
const batchSize = 25;
|
|
67
|
+
let attachedCommits = false;
|
|
54
68
|
for (let i = 0; i < files.length; i += batchSize) {
|
|
55
69
|
const batch = files.slice(i, i + batchSize);
|
|
56
|
-
|
|
70
|
+
const body = { projectId, files: batch };
|
|
71
|
+
if (!attachedCommits && commits && commits.length > 0) {
|
|
72
|
+
body.commits = commits;
|
|
73
|
+
attachedCommits = true;
|
|
74
|
+
}
|
|
75
|
+
await this.request('/api/v1/scan/push', body);
|
|
57
76
|
}
|
|
58
77
|
return { success: true };
|
|
59
78
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AA6CA,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;;;;OAIG;IACH,KAAK,CAAC,SAAS,CACb,SAAiB;QAEjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAqB,qBAAqB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5F,OAAO;YACL,UAAU,EAAE,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;YAC9D,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE;SACzE,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS,CACb,SAAiB,EACjB,KAAqB,EACrB,OAA0B;QAE1B,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,IAAI,eAAe,GAAG,KAAK,CAAC;QAC5B,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,GAAoB,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAC1D,IAAI,CAAC,eAAe,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACvB,eAAe,GAAG,IAAI,CAAC;YACzB,CAAC;YACD,MAAM,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;QAChD,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
|
@@ -31,6 +31,11 @@ export declare class ScannerDaemon {
|
|
|
31
31
|
private addProject;
|
|
32
32
|
private waitForServer;
|
|
33
33
|
private initialScan;
|
|
34
|
+
/**
|
|
35
|
+
* Fetch commits since the last mine. Swallows errors — a git failure must
|
|
36
|
+
* not block the file scan push.
|
|
37
|
+
*/
|
|
38
|
+
private collectCommits;
|
|
34
39
|
private handleChanges;
|
|
35
40
|
private startRetryLoop;
|
|
36
41
|
private groupChunksByFile;
|
package/dist/daemon.js
CHANGED
|
@@ -5,6 +5,7 @@ import { CodeScanner } from '@mnemonik/shared';
|
|
|
5
5
|
import { MnemonikClient } from './client.js';
|
|
6
6
|
import { FileWatcher } from './watcher.js';
|
|
7
7
|
import { ProjectDiscovery } from './discovery.js';
|
|
8
|
+
import { probeGit, fetchCommits } from './git.js';
|
|
8
9
|
export class ScannerDaemon {
|
|
9
10
|
config;
|
|
10
11
|
client;
|
|
@@ -116,8 +117,13 @@ export class ScannerDaemon {
|
|
|
116
117
|
async addProject(discovered) {
|
|
117
118
|
const label = discovered.projectName ?? discovered.projectId.slice(0, 8);
|
|
118
119
|
console.log(`[scanner] Adding project: ${label} (${discovered.path})`);
|
|
120
|
+
let gitState = {
|
|
121
|
+
isGitRepo: false,
|
|
122
|
+
gitMiningEnabled: false,
|
|
123
|
+
lastMinedCommit: null,
|
|
124
|
+
};
|
|
119
125
|
try {
|
|
120
|
-
await this.initialScan(discovered.projectId, discovered.path);
|
|
126
|
+
gitState = await this.initialScan(discovered.projectId, discovered.path);
|
|
121
127
|
}
|
|
122
128
|
catch (err) {
|
|
123
129
|
console.warn(`[scanner] Initial scan failed for ${label}:`, err.message);
|
|
@@ -146,6 +152,9 @@ export class ScannerDaemon {
|
|
|
146
152
|
watcher,
|
|
147
153
|
pendingRetries: new Set(),
|
|
148
154
|
retryTimer: null,
|
|
155
|
+
isGitRepo: gitState.isGitRepo,
|
|
156
|
+
gitMiningEnabled: gitState.gitMiningEnabled,
|
|
157
|
+
lastMinedCommit: gitState.lastMinedCommit,
|
|
149
158
|
});
|
|
150
159
|
}
|
|
151
160
|
async waitForServer() {
|
|
@@ -174,19 +183,46 @@ export class ScannerDaemon {
|
|
|
174
183
|
async initialScan(projectId, projectRoot) {
|
|
175
184
|
const startTime = Date.now();
|
|
176
185
|
const chunks = await this.scanner.scanDirectory(projectRoot);
|
|
177
|
-
const
|
|
186
|
+
const status = await this.client.getStatus(projectId);
|
|
178
187
|
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
179
188
|
const filesToPush = files.filter((f) => {
|
|
180
|
-
const serverHash =
|
|
189
|
+
const serverHash = status.fileHashes.get(f.path);
|
|
181
190
|
return !serverHash || serverHash !== f.hash;
|
|
182
191
|
});
|
|
192
|
+
// v3.68: collect new commits since last mine when this is a git repo and
|
|
193
|
+
// the server has mining enabled for this project (Pro+ tier + not opted out).
|
|
194
|
+
const isGitRepo = await probeGit(projectRoot);
|
|
195
|
+
const commits = isGitRepo && status.gitMining.enabled
|
|
196
|
+
? await this.collectCommits(projectRoot, status.gitMining.lastMinedCommit)
|
|
197
|
+
: [];
|
|
183
198
|
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);
|
|
199
|
+
console.log(`[scanner] Pushing ${filesToPush.length} changed files + ${commits.length} commits for ${projectId.slice(0, 8)}...`);
|
|
200
|
+
await this.client.pushFiles(projectId, filesToPush, commits);
|
|
186
201
|
}
|
|
187
202
|
const duration = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
188
203
|
console.log(`[scanner] Scan complete for ${projectId.slice(0, 8)}: ` +
|
|
189
|
-
`${chunks.length} chunks, ${filesToPush.length} pushed (${duration}s)`);
|
|
204
|
+
`${chunks.length} chunks, ${filesToPush.length} pushed, ${commits.length} commits (${duration}s)`);
|
|
205
|
+
return {
|
|
206
|
+
isGitRepo,
|
|
207
|
+
gitMiningEnabled: status.gitMining.enabled,
|
|
208
|
+
// Cache the newest SHA we just pushed; if no new commits, keep the
|
|
209
|
+
// server's watermark.
|
|
210
|
+
lastMinedCommit: commits[0]?.sha ?? status.gitMining.lastMinedCommit,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Fetch commits since the last mine. Swallows errors — a git failure must
|
|
215
|
+
* not block the file scan push.
|
|
216
|
+
*/
|
|
217
|
+
async collectCommits(projectRoot, lastMinedCommit) {
|
|
218
|
+
try {
|
|
219
|
+
const commits = await fetchCommits(projectRoot, lastMinedCommit);
|
|
220
|
+
return commits;
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
console.warn(`[scanner] git log failed in ${projectRoot}:`, err.message);
|
|
224
|
+
return [];
|
|
225
|
+
}
|
|
190
226
|
}
|
|
191
227
|
async handleChanges(projectId, projectRoot, changedFiles) {
|
|
192
228
|
const project = this.projects.get(projectId);
|
|
@@ -198,13 +234,20 @@ export class ScannerDaemon {
|
|
|
198
234
|
if (chunks.length === 0)
|
|
199
235
|
return;
|
|
200
236
|
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
237
|
+
// v3.68: attach any new commits since our cached watermark. Only the
|
|
238
|
+
// first batch carries them (idempotent jobId on the server collapses
|
|
239
|
+
// duplicates anyway, but one payload saves bandwidth).
|
|
240
|
+
const commits = project.isGitRepo && project.gitMiningEnabled
|
|
241
|
+
? await this.collectCommits(projectRoot, project.lastMinedCommit)
|
|
242
|
+
: [];
|
|
201
243
|
const batchSize = 25;
|
|
202
244
|
const succeededPaths = new Set();
|
|
203
245
|
let hadFailure = false;
|
|
204
246
|
for (let i = 0; i < files.length; i += batchSize) {
|
|
205
247
|
const batch = files.slice(i, i + batchSize);
|
|
206
248
|
try {
|
|
207
|
-
|
|
249
|
+
// Only attach commits to the first batch.
|
|
250
|
+
await this.client.pushFiles(projectId, batch, i === 0 ? commits : undefined);
|
|
208
251
|
for (const f of batch)
|
|
209
252
|
succeededPaths.add(f.path);
|
|
210
253
|
}
|
|
@@ -214,6 +257,11 @@ export class ScannerDaemon {
|
|
|
214
257
|
project.pendingRetries.add(f.path);
|
|
215
258
|
}
|
|
216
259
|
}
|
|
260
|
+
// Advance the cached watermark only if the first batch succeeded (so we
|
|
261
|
+
// don't skip commits on a retry).
|
|
262
|
+
if (commits.length > 0 && !hadFailure) {
|
|
263
|
+
project.lastMinedCommit = commits[0]?.sha ?? project.lastMinedCommit;
|
|
264
|
+
}
|
|
217
265
|
if (succeededPaths.size > 0) {
|
|
218
266
|
console.log(`[scanner] [${projectId.slice(0, 8)}] Pushed ${succeededPaths.size} file(s): ${[...succeededPaths].join(', ')}`);
|
|
219
267
|
}
|
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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"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git commit extraction on the scanner daemon side.
|
|
3
|
+
*
|
|
4
|
+
* The production server runs in ECS and cannot `git log` the user's repo —
|
|
5
|
+
* the repo lives on the user's machine, next to the daemon. We run `git log`
|
|
6
|
+
* here and push the parsed commits alongside scan results. Server-side
|
|
7
|
+
* `GitMiner.mineCommits` consumes them without touching the filesystem.
|
|
8
|
+
*/
|
|
9
|
+
export interface ParsedCommit {
|
|
10
|
+
sha: string;
|
|
11
|
+
author: string;
|
|
12
|
+
date: string;
|
|
13
|
+
message: string;
|
|
14
|
+
files: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* True when `repoRoot/.git` exists and `git log -1` returns a commit.
|
|
18
|
+
* Non-git projects, `git init` with no commits, and corrupted repos all
|
|
19
|
+
* return false without throwing.
|
|
20
|
+
*/
|
|
21
|
+
export declare function probeGit(repoRoot: string): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetch commits between `sinceCommit` and HEAD (or the last MAX_COMMITS on
|
|
24
|
+
* first run). Returns [] on failure — caller omits the field from the push.
|
|
25
|
+
*
|
|
26
|
+
* Uses `-z` NUL-separated output so `--name-only` file entries cannot collide
|
|
27
|
+
* with commit metadata. Parser mirrors the server-side token-walking parser
|
|
28
|
+
* in GitMiner.parseLogOutput.
|
|
29
|
+
*/
|
|
30
|
+
export declare function fetchCommits(repoRoot: string, sinceCommit: string | null): Promise<ParsedCommit[]>;
|
|
31
|
+
export declare function parseLogOutput(raw: string): ParsedCommit[];
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git commit extraction on the scanner daemon side.
|
|
3
|
+
*
|
|
4
|
+
* The production server runs in ECS and cannot `git log` the user's repo —
|
|
5
|
+
* the repo lives on the user's machine, next to the daemon. We run `git log`
|
|
6
|
+
* here and push the parsed commits alongside scan results. Server-side
|
|
7
|
+
* `GitMiner.mineCommits` consumes them without touching the filesystem.
|
|
8
|
+
*/
|
|
9
|
+
import { execFile } from 'child_process';
|
|
10
|
+
import { promisify } from 'util';
|
|
11
|
+
import { access } from 'fs/promises';
|
|
12
|
+
import { join } from 'path';
|
|
13
|
+
const execFileAsync = promisify(execFile);
|
|
14
|
+
// Keep in sync with server-side MAX_COMMITS_PER_RUN in GitMiner.ts and the
|
|
15
|
+
// `commits` array cap in scanPushSchema.
|
|
16
|
+
const MAX_COMMITS = 100;
|
|
17
|
+
const GIT_TIMEOUT_MS = 20_000;
|
|
18
|
+
/**
|
|
19
|
+
* True when `repoRoot/.git` exists and `git log -1` returns a commit.
|
|
20
|
+
* Non-git projects, `git init` with no commits, and corrupted repos all
|
|
21
|
+
* return false without throwing.
|
|
22
|
+
*/
|
|
23
|
+
export async function probeGit(repoRoot) {
|
|
24
|
+
try {
|
|
25
|
+
await access(join(repoRoot, '.git'));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const { stdout } = await execFileAsync('git', ['log', '-1', '--format=%H'], {
|
|
32
|
+
cwd: repoRoot,
|
|
33
|
+
encoding: 'utf-8',
|
|
34
|
+
timeout: GIT_TIMEOUT_MS,
|
|
35
|
+
});
|
|
36
|
+
return /^[0-9a-f]{40}/m.test(stdout);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Fetch commits between `sinceCommit` and HEAD (or the last MAX_COMMITS on
|
|
44
|
+
* first run). Returns [] on failure — caller omits the field from the push.
|
|
45
|
+
*
|
|
46
|
+
* Uses `-z` NUL-separated output so `--name-only` file entries cannot collide
|
|
47
|
+
* with commit metadata. Parser mirrors the server-side token-walking parser
|
|
48
|
+
* in GitMiner.parseLogOutput.
|
|
49
|
+
*/
|
|
50
|
+
export async function fetchCommits(repoRoot, sinceCommit) {
|
|
51
|
+
const args = [
|
|
52
|
+
'log',
|
|
53
|
+
'-z',
|
|
54
|
+
'--format=%H%n%an%n%aI%n%B',
|
|
55
|
+
'--name-only',
|
|
56
|
+
`--max-count=${MAX_COMMITS}`,
|
|
57
|
+
];
|
|
58
|
+
if (sinceCommit)
|
|
59
|
+
args.push(`${sinceCommit}..HEAD`);
|
|
60
|
+
let raw;
|
|
61
|
+
try {
|
|
62
|
+
const result = await execFileAsync('git', args, {
|
|
63
|
+
cwd: repoRoot,
|
|
64
|
+
encoding: 'utf-8',
|
|
65
|
+
timeout: GIT_TIMEOUT_MS,
|
|
66
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
67
|
+
});
|
|
68
|
+
raw = result.stdout;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
const msg = err.message;
|
|
72
|
+
// "fatal: Invalid revision range <sha>..HEAD" — the daemon's cached
|
|
73
|
+
// last_mined_commit is stale (e.g. history was rewritten or the server
|
|
74
|
+
// was reseeded). Fall back to a fresh full-history scan.
|
|
75
|
+
if (sinceCommit && /Invalid (?:revision range|symmetric difference expression)/i.test(msg)) {
|
|
76
|
+
return fetchCommits(repoRoot, null);
|
|
77
|
+
}
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
return parseLogOutput(raw);
|
|
81
|
+
}
|
|
82
|
+
export function parseLogOutput(raw) {
|
|
83
|
+
const commits = [];
|
|
84
|
+
const tokens = raw.split('\0').filter((t) => t.length > 0);
|
|
85
|
+
let current = null;
|
|
86
|
+
for (const token of tokens) {
|
|
87
|
+
if (token.includes('\n')) {
|
|
88
|
+
if (current)
|
|
89
|
+
commits.push(current);
|
|
90
|
+
const lines = token.split('\n');
|
|
91
|
+
const sha = lines[0]?.trim() ?? '';
|
|
92
|
+
const author = lines[1]?.trim() ?? '';
|
|
93
|
+
const date = lines[2]?.trim() ?? '';
|
|
94
|
+
const message = lines.slice(3).join('\n').trim();
|
|
95
|
+
if (!sha || !author || !date || !message) {
|
|
96
|
+
current = null;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
current = { sha, author, date, message, files: [] };
|
|
100
|
+
}
|
|
101
|
+
else if (current) {
|
|
102
|
+
const file = token.trim();
|
|
103
|
+
if (file.length > 0)
|
|
104
|
+
current.files.push(file);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (current)
|
|
108
|
+
commits.push(current);
|
|
109
|
+
return commits;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -16,9 +16,31 @@ export interface ScanPushFile {
|
|
|
16
16
|
}>;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
export interface ScanPushCommit {
|
|
20
|
+
sha: string;
|
|
21
|
+
author: string;
|
|
22
|
+
date: string;
|
|
23
|
+
message: string;
|
|
24
|
+
files: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
19
27
|
export interface ScanPushPayload {
|
|
20
28
|
projectId: string;
|
|
21
29
|
files: ScanPushFile[];
|
|
30
|
+
commits?: ScanPushCommit[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ScanStatusResponse {
|
|
34
|
+
files: Array<{ path: string; hash: string }>;
|
|
35
|
+
gitMining?: {
|
|
36
|
+
enabled: boolean;
|
|
37
|
+
lastMinedCommit: string | null;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface GitMiningMeta {
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
lastMinedCommit: string | null;
|
|
22
44
|
}
|
|
23
45
|
|
|
24
46
|
export class MnemonikClient {
|
|
@@ -69,19 +91,41 @@ export class MnemonikClient {
|
|
|
69
91
|
throw new Error(`Request to ${path} failed after ${retries} retries`);
|
|
70
92
|
}
|
|
71
93
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Fetch per-file hashes for dedup, plus git-mining metadata (v3.68).
|
|
96
|
+
* The daemon uses `gitMining.enabled` to decide whether to collect commits
|
|
97
|
+
* this cycle, and `lastMinedCommit` as the lower bound of `git log`.
|
|
98
|
+
*/
|
|
99
|
+
async getStatus(
|
|
100
|
+
projectId: string
|
|
101
|
+
): Promise<{ fileHashes: Map<string, string>; gitMining: GitMiningMeta }> {
|
|
102
|
+
const result = await this.request<ScanStatusResponse>('/api/v1/scan/status', { projectId });
|
|
103
|
+
return {
|
|
104
|
+
fileHashes: new Map(result.files.map((f) => [f.path, f.hash])),
|
|
105
|
+
gitMining: result.gitMining ?? { enabled: false, lastMinedCommit: null },
|
|
106
|
+
};
|
|
78
107
|
}
|
|
79
108
|
|
|
80
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Push file chunks in batches. When `commits` is supplied (non-empty) it is
|
|
111
|
+
* attached to the first batch only — BullMQ's idempotent jobId means a
|
|
112
|
+
* duplicate would collapse anyway, but one payload saves bandwidth.
|
|
113
|
+
*/
|
|
114
|
+
async pushFiles(
|
|
115
|
+
projectId: string,
|
|
116
|
+
files: ScanPushFile[],
|
|
117
|
+
commits?: ScanPushCommit[]
|
|
118
|
+
): Promise<{ success: boolean }> {
|
|
81
119
|
const batchSize = 25;
|
|
120
|
+
let attachedCommits = false;
|
|
82
121
|
for (let i = 0; i < files.length; i += batchSize) {
|
|
83
122
|
const batch = files.slice(i, i + batchSize);
|
|
84
|
-
|
|
123
|
+
const body: ScanPushPayload = { projectId, files: batch };
|
|
124
|
+
if (!attachedCommits && commits && commits.length > 0) {
|
|
125
|
+
body.commits = commits;
|
|
126
|
+
attachedCommits = true;
|
|
127
|
+
}
|
|
128
|
+
await this.request('/api/v1/scan/push', body);
|
|
85
129
|
}
|
|
86
130
|
return { success: true };
|
|
87
131
|
}
|
package/src/daemon.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { createHash } from 'crypto';
|
|
|
2
2
|
import { readFile } from 'fs/promises';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { CodeScanner, type CodeChunk } from '@mnemonik/shared';
|
|
5
|
-
import { MnemonikClient, type ScanPushFile } from './client.js';
|
|
5
|
+
import { MnemonikClient, type ScanPushCommit, type ScanPushFile } from './client.js';
|
|
6
6
|
import { FileWatcher } from './watcher.js';
|
|
7
7
|
import { ProjectDiscovery, type DiscoveredProject } from './discovery.js';
|
|
8
|
+
import { probeGit, fetchCommits } from './git.js';
|
|
8
9
|
|
|
9
10
|
export interface DaemonConfig {
|
|
10
11
|
serverUrl: string;
|
|
@@ -21,6 +22,13 @@ interface WatchedProject {
|
|
|
21
22
|
watcher: FileWatcher;
|
|
22
23
|
pendingRetries: Set<string>;
|
|
23
24
|
retryTimer: ReturnType<typeof setInterval> | null;
|
|
25
|
+
// v3.68: git-mining state cached across scans. `isGitRepo` is set once at
|
|
26
|
+
// project add time (false for non-git projects, skips git calls entirely).
|
|
27
|
+
// `gitMiningEnabled` reflects server-side Pro+ tier + feature flag +
|
|
28
|
+
// per-project opt-out. `lastMinedCommit` bounds `git log` from below.
|
|
29
|
+
isGitRepo: boolean;
|
|
30
|
+
gitMiningEnabled: boolean;
|
|
31
|
+
lastMinedCommit: string | null;
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
export class ScannerDaemon {
|
|
@@ -147,8 +155,13 @@ export class ScannerDaemon {
|
|
|
147
155
|
const label = discovered.projectName ?? discovered.projectId.slice(0, 8);
|
|
148
156
|
console.log(`[scanner] Adding project: ${label} (${discovered.path})`);
|
|
149
157
|
|
|
158
|
+
let gitState = {
|
|
159
|
+
isGitRepo: false,
|
|
160
|
+
gitMiningEnabled: false,
|
|
161
|
+
lastMinedCommit: null as string | null,
|
|
162
|
+
};
|
|
150
163
|
try {
|
|
151
|
-
await this.initialScan(discovered.projectId, discovered.path);
|
|
164
|
+
gitState = await this.initialScan(discovered.projectId, discovered.path);
|
|
152
165
|
} catch (err) {
|
|
153
166
|
console.warn(`[scanner] Initial scan failed for ${label}:`, (err as Error).message);
|
|
154
167
|
}
|
|
@@ -184,6 +197,9 @@ export class ScannerDaemon {
|
|
|
184
197
|
watcher,
|
|
185
198
|
pendingRetries: new Set(),
|
|
186
199
|
retryTimer: null,
|
|
200
|
+
isGitRepo: gitState.isGitRepo,
|
|
201
|
+
gitMiningEnabled: gitState.gitMiningEnabled,
|
|
202
|
+
lastMinedCommit: gitState.lastMinedCommit,
|
|
187
203
|
});
|
|
188
204
|
}
|
|
189
205
|
|
|
@@ -211,30 +227,66 @@ export class ScannerDaemon {
|
|
|
211
227
|
throw new Error(`Server unreachable after ${maxRetries} attempts`);
|
|
212
228
|
}
|
|
213
229
|
|
|
214
|
-
private async initialScan(
|
|
230
|
+
private async initialScan(
|
|
231
|
+
projectId: string,
|
|
232
|
+
projectRoot: string
|
|
233
|
+
): Promise<{ isGitRepo: boolean; gitMiningEnabled: boolean; lastMinedCommit: string | null }> {
|
|
215
234
|
const startTime = Date.now();
|
|
216
235
|
|
|
217
236
|
const chunks = await this.scanner.scanDirectory(projectRoot);
|
|
218
|
-
const
|
|
237
|
+
const status = await this.client.getStatus(projectId);
|
|
219
238
|
|
|
220
239
|
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
221
240
|
const filesToPush = files.filter((f) => {
|
|
222
|
-
const serverHash =
|
|
241
|
+
const serverHash = status.fileHashes.get(f.path);
|
|
223
242
|
return !serverHash || serverHash !== f.hash;
|
|
224
243
|
});
|
|
225
244
|
|
|
245
|
+
// v3.68: collect new commits since last mine when this is a git repo and
|
|
246
|
+
// the server has mining enabled for this project (Pro+ tier + not opted out).
|
|
247
|
+
const isGitRepo = await probeGit(projectRoot);
|
|
248
|
+
const commits =
|
|
249
|
+
isGitRepo && status.gitMining.enabled
|
|
250
|
+
? await this.collectCommits(projectRoot, status.gitMining.lastMinedCommit)
|
|
251
|
+
: [];
|
|
252
|
+
|
|
226
253
|
if (filesToPush.length > 0) {
|
|
227
254
|
console.log(
|
|
228
|
-
`[scanner] Pushing ${filesToPush.length} changed files for ${projectId.slice(0, 8)}...`
|
|
255
|
+
`[scanner] Pushing ${filesToPush.length} changed files + ${commits.length} commits for ${projectId.slice(0, 8)}...`
|
|
229
256
|
);
|
|
230
|
-
await this.client.pushFiles(projectId, filesToPush);
|
|
257
|
+
await this.client.pushFiles(projectId, filesToPush, commits);
|
|
231
258
|
}
|
|
232
259
|
|
|
233
260
|
const duration = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
234
261
|
console.log(
|
|
235
262
|
`[scanner] Scan complete for ${projectId.slice(0, 8)}: ` +
|
|
236
|
-
`${chunks.length} chunks, ${filesToPush.length} pushed (${duration}s)`
|
|
263
|
+
`${chunks.length} chunks, ${filesToPush.length} pushed, ${commits.length} commits (${duration}s)`
|
|
237
264
|
);
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
isGitRepo,
|
|
268
|
+
gitMiningEnabled: status.gitMining.enabled,
|
|
269
|
+
// Cache the newest SHA we just pushed; if no new commits, keep the
|
|
270
|
+
// server's watermark.
|
|
271
|
+
lastMinedCommit: commits[0]?.sha ?? status.gitMining.lastMinedCommit,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Fetch commits since the last mine. Swallows errors — a git failure must
|
|
277
|
+
* not block the file scan push.
|
|
278
|
+
*/
|
|
279
|
+
private async collectCommits(
|
|
280
|
+
projectRoot: string,
|
|
281
|
+
lastMinedCommit: string | null
|
|
282
|
+
): Promise<ScanPushCommit[]> {
|
|
283
|
+
try {
|
|
284
|
+
const commits = await fetchCommits(projectRoot, lastMinedCommit);
|
|
285
|
+
return commits;
|
|
286
|
+
} catch (err) {
|
|
287
|
+
console.warn(`[scanner] git log failed in ${projectRoot}:`, (err as Error).message);
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
238
290
|
}
|
|
239
291
|
|
|
240
292
|
private async handleChanges(
|
|
@@ -253,6 +305,14 @@ export class ScannerDaemon {
|
|
|
253
305
|
|
|
254
306
|
const files = await this.groupChunksByFile(chunks, projectRoot);
|
|
255
307
|
|
|
308
|
+
// v3.68: attach any new commits since our cached watermark. Only the
|
|
309
|
+
// first batch carries them (idempotent jobId on the server collapses
|
|
310
|
+
// duplicates anyway, but one payload saves bandwidth).
|
|
311
|
+
const commits =
|
|
312
|
+
project.isGitRepo && project.gitMiningEnabled
|
|
313
|
+
? await this.collectCommits(projectRoot, project.lastMinedCommit)
|
|
314
|
+
: [];
|
|
315
|
+
|
|
256
316
|
const batchSize = 25;
|
|
257
317
|
const succeededPaths = new Set<string>();
|
|
258
318
|
let hadFailure = false;
|
|
@@ -260,7 +320,8 @@ export class ScannerDaemon {
|
|
|
260
320
|
for (let i = 0; i < files.length; i += batchSize) {
|
|
261
321
|
const batch = files.slice(i, i + batchSize);
|
|
262
322
|
try {
|
|
263
|
-
|
|
323
|
+
// Only attach commits to the first batch.
|
|
324
|
+
await this.client.pushFiles(projectId, batch, i === 0 ? commits : undefined);
|
|
264
325
|
for (const f of batch) succeededPaths.add(f.path);
|
|
265
326
|
} catch {
|
|
266
327
|
hadFailure = true;
|
|
@@ -268,6 +329,12 @@ export class ScannerDaemon {
|
|
|
268
329
|
}
|
|
269
330
|
}
|
|
270
331
|
|
|
332
|
+
// Advance the cached watermark only if the first batch succeeded (so we
|
|
333
|
+
// don't skip commits on a retry).
|
|
334
|
+
if (commits.length > 0 && !hadFailure) {
|
|
335
|
+
project.lastMinedCommit = commits[0]?.sha ?? project.lastMinedCommit;
|
|
336
|
+
}
|
|
337
|
+
|
|
271
338
|
if (succeededPaths.size > 0) {
|
|
272
339
|
console.log(
|
|
273
340
|
`[scanner] [${projectId.slice(0, 8)}] Pushed ${succeededPaths.size} file(s): ${[...succeededPaths].join(', ')}`
|
package/src/git.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git commit extraction on the scanner daemon side.
|
|
3
|
+
*
|
|
4
|
+
* The production server runs in ECS and cannot `git log` the user's repo —
|
|
5
|
+
* the repo lives on the user's machine, next to the daemon. We run `git log`
|
|
6
|
+
* here and push the parsed commits alongside scan results. Server-side
|
|
7
|
+
* `GitMiner.mineCommits` consumes them without touching the filesystem.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execFile } from 'child_process';
|
|
11
|
+
import { promisify } from 'util';
|
|
12
|
+
import { access } from 'fs/promises';
|
|
13
|
+
import { join } from 'path';
|
|
14
|
+
|
|
15
|
+
const execFileAsync = promisify(execFile);
|
|
16
|
+
|
|
17
|
+
export interface ParsedCommit {
|
|
18
|
+
sha: string;
|
|
19
|
+
author: string;
|
|
20
|
+
date: string;
|
|
21
|
+
message: string;
|
|
22
|
+
files: string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Keep in sync with server-side MAX_COMMITS_PER_RUN in GitMiner.ts and the
|
|
26
|
+
// `commits` array cap in scanPushSchema.
|
|
27
|
+
const MAX_COMMITS = 100;
|
|
28
|
+
const GIT_TIMEOUT_MS = 20_000;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* True when `repoRoot/.git` exists and `git log -1` returns a commit.
|
|
32
|
+
* Non-git projects, `git init` with no commits, and corrupted repos all
|
|
33
|
+
* return false without throwing.
|
|
34
|
+
*/
|
|
35
|
+
export async function probeGit(repoRoot: string): Promise<boolean> {
|
|
36
|
+
try {
|
|
37
|
+
await access(join(repoRoot, '.git'));
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const { stdout } = await execFileAsync('git', ['log', '-1', '--format=%H'], {
|
|
43
|
+
cwd: repoRoot,
|
|
44
|
+
encoding: 'utf-8',
|
|
45
|
+
timeout: GIT_TIMEOUT_MS,
|
|
46
|
+
});
|
|
47
|
+
return /^[0-9a-f]{40}/m.test(stdout);
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Fetch commits between `sinceCommit` and HEAD (or the last MAX_COMMITS on
|
|
55
|
+
* first run). Returns [] on failure — caller omits the field from the push.
|
|
56
|
+
*
|
|
57
|
+
* Uses `-z` NUL-separated output so `--name-only` file entries cannot collide
|
|
58
|
+
* with commit metadata. Parser mirrors the server-side token-walking parser
|
|
59
|
+
* in GitMiner.parseLogOutput.
|
|
60
|
+
*/
|
|
61
|
+
export async function fetchCommits(
|
|
62
|
+
repoRoot: string,
|
|
63
|
+
sinceCommit: string | null
|
|
64
|
+
): Promise<ParsedCommit[]> {
|
|
65
|
+
const args = [
|
|
66
|
+
'log',
|
|
67
|
+
'-z',
|
|
68
|
+
'--format=%H%n%an%n%aI%n%B',
|
|
69
|
+
'--name-only',
|
|
70
|
+
`--max-count=${MAX_COMMITS}`,
|
|
71
|
+
];
|
|
72
|
+
if (sinceCommit) args.push(`${sinceCommit}..HEAD`);
|
|
73
|
+
|
|
74
|
+
let raw: string;
|
|
75
|
+
try {
|
|
76
|
+
const result = await execFileAsync('git', args, {
|
|
77
|
+
cwd: repoRoot,
|
|
78
|
+
encoding: 'utf-8',
|
|
79
|
+
timeout: GIT_TIMEOUT_MS,
|
|
80
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
81
|
+
});
|
|
82
|
+
raw = result.stdout;
|
|
83
|
+
} catch (err) {
|
|
84
|
+
const msg = (err as Error).message;
|
|
85
|
+
// "fatal: Invalid revision range <sha>..HEAD" — the daemon's cached
|
|
86
|
+
// last_mined_commit is stale (e.g. history was rewritten or the server
|
|
87
|
+
// was reseeded). Fall back to a fresh full-history scan.
|
|
88
|
+
if (sinceCommit && /Invalid (?:revision range|symmetric difference expression)/i.test(msg)) {
|
|
89
|
+
return fetchCommits(repoRoot, null);
|
|
90
|
+
}
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return parseLogOutput(raw);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function parseLogOutput(raw: string): ParsedCommit[] {
|
|
98
|
+
const commits: ParsedCommit[] = [];
|
|
99
|
+
const tokens = raw.split('\0').filter((t) => t.length > 0);
|
|
100
|
+
let current: ParsedCommit | null = null;
|
|
101
|
+
|
|
102
|
+
for (const token of tokens) {
|
|
103
|
+
if (token.includes('\n')) {
|
|
104
|
+
if (current) commits.push(current);
|
|
105
|
+
const lines = token.split('\n');
|
|
106
|
+
const sha = lines[0]?.trim() ?? '';
|
|
107
|
+
const author = lines[1]?.trim() ?? '';
|
|
108
|
+
const date = lines[2]?.trim() ?? '';
|
|
109
|
+
const message = lines.slice(3).join('\n').trim();
|
|
110
|
+
if (!sha || !author || !date || !message) {
|
|
111
|
+
current = null;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
current = { sha, author, date, message, files: [] };
|
|
115
|
+
} else if (current) {
|
|
116
|
+
const file = token.trim();
|
|
117
|
+
if (file.length > 0) current.files.push(file);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (current) commits.push(current);
|
|
121
|
+
return commits;
|
|
122
|
+
}
|