@saiteja1123/mcp-server 1.1.4 → 1.1.5

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.
@@ -0,0 +1,57 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { assertSourceSafePayload, cloneSourceSafe } from './sourceSafe.js';
4
+ import { validateDeepScanState, validateRunIdSegment } from './contracts.js';
5
+
6
+ export class LocalDeepScanStore {
7
+ constructor({ rootPath, directory = '.vibesecur/deep-scans' }) {
8
+ if (!rootPath || typeof rootPath !== 'string') throw new Error('LocalDeepScanStore requires rootPath');
9
+ if (!directory || typeof directory !== 'string') throw new Error('LocalDeepScanStore requires directory');
10
+ const normalizedDirectory = path.normalize(directory);
11
+ if (
12
+ path.isAbsolute(normalizedDirectory)
13
+ || normalizedDirectory === '..'
14
+ || normalizedDirectory.startsWith(`..${path.sep}`)
15
+ ) {
16
+ throw new Error('LocalDeepScanStore directory must stay inside rootPath');
17
+ }
18
+ this.rootPath = path.resolve(rootPath);
19
+ this.directory = normalizedDirectory;
20
+ }
21
+
22
+ get baseDir() {
23
+ return path.join(this.rootPath, this.directory);
24
+ }
25
+
26
+ runPath(runId) {
27
+ return path.join(this.baseDir, `${validateRunIdSegment(runId, 'runId')}.json`);
28
+ }
29
+
30
+ async saveRun(state) {
31
+ const safeState = validateDeepScanState(cloneSourceSafe(state, 'deepScanState'));
32
+ assertSourceSafePayload(safeState, 'deepScanState');
33
+ await fs.mkdir(this.baseDir, { recursive: true });
34
+ const target = this.runPath(safeState.runId);
35
+ const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;
36
+ await fs.writeFile(tmp, `${JSON.stringify(safeState, null, 2)}\n`, 'utf8');
37
+ await fs.rename(tmp, target);
38
+ return safeState;
39
+ }
40
+
41
+ async getRun(runId) {
42
+ const raw = await fs.readFile(this.runPath(runId), 'utf8');
43
+ return validateDeepScanState(JSON.parse(raw));
44
+ }
45
+
46
+ async listRuns() {
47
+ await fs.mkdir(this.baseDir, { recursive: true });
48
+ const entries = await fs.readdir(this.baseDir);
49
+ const runs = [];
50
+ for (const entry of entries) {
51
+ if (!entry.endsWith('.json')) continue;
52
+ const runId = entry.slice(0, -5);
53
+ runs.push(await this.getRun(runId));
54
+ }
55
+ return runs.sort((a, b) => String(b.updatedAt).localeCompare(String(a.updatedAt)));
56
+ }
57
+ }