@coderule/mcp 1.7.2 → 2.0.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/cli.cjs +224 -45
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +220 -42
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +203 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +199 -31
- package/dist/index.js.map +1 -1
- package/dist/mcp-cli.cjs +236 -46
- package/dist/mcp-cli.cjs.map +1 -1
- package/dist/mcp-cli.js +232 -43
- package/dist/mcp-cli.js.map +1 -1
- package/package.json +6 -4
package/dist/cli.cjs
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var fs5 = require('fs/promises');
|
|
5
|
+
var path2 = require('path');
|
|
6
6
|
var crypto = require('crypto');
|
|
7
7
|
var envPaths = require('env-paths');
|
|
8
8
|
var pino = require('pino');
|
|
9
|
+
var os = require('os');
|
|
9
10
|
var Database = require('better-sqlite3');
|
|
10
11
|
var qulite = require('@coderule/qulite');
|
|
11
12
|
var clients = require('@coderule/clients');
|
|
12
|
-
var
|
|
13
|
+
var fs3 = require('fs');
|
|
13
14
|
var worker_threads = require('worker_threads');
|
|
14
15
|
var chokidar = require('chokidar');
|
|
15
16
|
|
|
16
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
18
|
|
|
18
|
-
var
|
|
19
|
-
var
|
|
19
|
+
var fs5__default = /*#__PURE__*/_interopDefault(fs5);
|
|
20
|
+
var path2__default = /*#__PURE__*/_interopDefault(path2);
|
|
20
21
|
var envPaths__default = /*#__PURE__*/_interopDefault(envPaths);
|
|
21
22
|
var pino__default = /*#__PURE__*/_interopDefault(pino);
|
|
23
|
+
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
22
24
|
var Database__default = /*#__PURE__*/_interopDefault(Database);
|
|
23
|
-
var
|
|
25
|
+
var fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
24
26
|
var chokidar__default = /*#__PURE__*/_interopDefault(chokidar);
|
|
25
27
|
|
|
26
28
|
// node_modules/tsup/assets/cjs_shims.js
|
|
@@ -47,6 +49,166 @@ var DEFAULT_MAX_SNAPSHOT_ATTEMPTS = 5;
|
|
|
47
49
|
var DEFAULT_HTTP_TIMEOUT_MS = 12e4;
|
|
48
50
|
var DEFAULT_UPLOAD_CHUNK_SIZE = 1;
|
|
49
51
|
var DEFAULT_MAX_QUERY_WAIT_MS = 5e4;
|
|
52
|
+
function collectCandidateSources(options) {
|
|
53
|
+
const sources = [];
|
|
54
|
+
if (options?.cliRoot) {
|
|
55
|
+
sources.push({
|
|
56
|
+
value: options.cliRoot,
|
|
57
|
+
source: "cli-arg",
|
|
58
|
+
baseConfidence: 1
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (process.env.CODERULE_ROOT) {
|
|
62
|
+
sources.push({
|
|
63
|
+
value: process.env.CODERULE_ROOT,
|
|
64
|
+
source: "env-coderule-root",
|
|
65
|
+
baseConfidence: 0.9
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (process.env.WORKSPACE_FOLDER_PATHS) {
|
|
69
|
+
sources.push({
|
|
70
|
+
value: process.env.WORKSPACE_FOLDER_PATHS,
|
|
71
|
+
source: "env-workspace",
|
|
72
|
+
baseConfidence: 0.8
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
sources.push({
|
|
76
|
+
value: process.cwd(),
|
|
77
|
+
source: "process-cwd",
|
|
78
|
+
baseConfidence: 0.6
|
|
79
|
+
});
|
|
80
|
+
return sources;
|
|
81
|
+
}
|
|
82
|
+
async function pathExists(targetPath) {
|
|
83
|
+
try {
|
|
84
|
+
await fs5__default.default.access(targetPath);
|
|
85
|
+
return true;
|
|
86
|
+
} catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function isDirectory(targetPath) {
|
|
91
|
+
try {
|
|
92
|
+
const stat = await fs5__default.default.stat(targetPath);
|
|
93
|
+
return stat.isDirectory();
|
|
94
|
+
} catch {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function hasGitDirectory(rootPath) {
|
|
99
|
+
const gitPath = path2__default.default.join(rootPath, ".git");
|
|
100
|
+
return pathExists(gitPath);
|
|
101
|
+
}
|
|
102
|
+
function isShallowPath(absolutePath) {
|
|
103
|
+
const normalized = absolutePath.replace(/\\/g, "/");
|
|
104
|
+
const separatorCount = (normalized.match(/\//g) || []).length;
|
|
105
|
+
return separatorCount <= 1;
|
|
106
|
+
}
|
|
107
|
+
function isHomeDirectory(candidatePath) {
|
|
108
|
+
const home = os__default.default.homedir();
|
|
109
|
+
const normalizedCandidate = path2__default.default.normalize(candidatePath);
|
|
110
|
+
const normalizedHome = path2__default.default.normalize(home);
|
|
111
|
+
return normalizedCandidate === normalizedHome;
|
|
112
|
+
}
|
|
113
|
+
async function applyModifiers(candidate) {
|
|
114
|
+
const modifiers = [];
|
|
115
|
+
if (await hasGitDirectory(candidate.path)) {
|
|
116
|
+
modifiers.push({ reason: "has .git directory", delta: 0.1 });
|
|
117
|
+
}
|
|
118
|
+
if (isShallowPath(candidate.path)) {
|
|
119
|
+
modifiers.push({ reason: "shallow path (likely root)", delta: -0.2 });
|
|
120
|
+
}
|
|
121
|
+
if (isHomeDirectory(candidate.path)) {
|
|
122
|
+
modifiers.push({ reason: "is home directory", delta: -0.3 });
|
|
123
|
+
}
|
|
124
|
+
const totalModifier = modifiers.reduce((sum, m) => sum + m.delta, 0);
|
|
125
|
+
const finalConfidence = candidate.baseConfidence + totalModifier;
|
|
126
|
+
return {
|
|
127
|
+
...candidate,
|
|
128
|
+
modifiers,
|
|
129
|
+
finalConfidence
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
async function createCandidate(source) {
|
|
133
|
+
const absolutePath = path2__default.default.resolve(source.value);
|
|
134
|
+
const exists = await pathExists(absolutePath);
|
|
135
|
+
const isDir = exists ? await isDirectory(absolutePath) : false;
|
|
136
|
+
const candidate = {
|
|
137
|
+
path: absolutePath,
|
|
138
|
+
source: source.source,
|
|
139
|
+
baseConfidence: source.baseConfidence,
|
|
140
|
+
modifiers: [],
|
|
141
|
+
finalConfidence: source.baseConfidence,
|
|
142
|
+
exists,
|
|
143
|
+
isDirectory: isDir
|
|
144
|
+
};
|
|
145
|
+
if (exists && isDir) {
|
|
146
|
+
return applyModifiers(candidate);
|
|
147
|
+
}
|
|
148
|
+
return candidate;
|
|
149
|
+
}
|
|
150
|
+
async function resolveRootPath(options) {
|
|
151
|
+
const logger2 = options?.logger;
|
|
152
|
+
const sources = collectCandidateSources(options);
|
|
153
|
+
const candidates = await Promise.all(sources.map(createCandidate));
|
|
154
|
+
logger2?.debug(
|
|
155
|
+
{
|
|
156
|
+
candidates: candidates.map((c) => ({
|
|
157
|
+
path: c.path,
|
|
158
|
+
source: c.source,
|
|
159
|
+
baseConfidence: c.baseConfidence,
|
|
160
|
+
finalConfidence: c.finalConfidence,
|
|
161
|
+
exists: c.exists,
|
|
162
|
+
isDirectory: c.isDirectory,
|
|
163
|
+
modifiers: c.modifiers
|
|
164
|
+
}))
|
|
165
|
+
},
|
|
166
|
+
"Collected root path candidates"
|
|
167
|
+
);
|
|
168
|
+
const validCandidates = candidates.filter((c) => c.exists && c.isDirectory);
|
|
169
|
+
if (validCandidates.length === 0) {
|
|
170
|
+
const attempted = candidates.map((c) => c.path).join(", ");
|
|
171
|
+
throw new Error(
|
|
172
|
+
`No valid root directory found. Attempted: ${attempted}. Ensure the directory exists and is accessible.`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
const sourcePriority = {
|
|
176
|
+
"cli-arg": 1,
|
|
177
|
+
"env-coderule-root": 2,
|
|
178
|
+
"env-workspace": 3,
|
|
179
|
+
"process-cwd": 4
|
|
180
|
+
};
|
|
181
|
+
validCandidates.sort((a, b) => {
|
|
182
|
+
const confidenceDiff = b.finalConfidence - a.finalConfidence;
|
|
183
|
+
if (confidenceDiff !== 0) {
|
|
184
|
+
return confidenceDiff;
|
|
185
|
+
}
|
|
186
|
+
return sourcePriority[a.source] - sourcePriority[b.source];
|
|
187
|
+
});
|
|
188
|
+
const best = validCandidates[0];
|
|
189
|
+
if (best.finalConfidence < 0.7) {
|
|
190
|
+
logger2?.warn(
|
|
191
|
+
{
|
|
192
|
+
path: best.path,
|
|
193
|
+
source: best.source,
|
|
194
|
+
confidence: best.finalConfidence,
|
|
195
|
+
modifiers: best.modifiers
|
|
196
|
+
},
|
|
197
|
+
"Selected root path has low confidence"
|
|
198
|
+
);
|
|
199
|
+
} else {
|
|
200
|
+
logger2?.info(
|
|
201
|
+
{
|
|
202
|
+
path: best.path,
|
|
203
|
+
source: best.source,
|
|
204
|
+
confidence: best.finalConfidence,
|
|
205
|
+
modifiers: best.modifiers
|
|
206
|
+
},
|
|
207
|
+
"Resolved root path"
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
return best;
|
|
211
|
+
}
|
|
50
212
|
|
|
51
213
|
// src/config/Configurator.ts
|
|
52
214
|
var DEFAULT_RETRIEVAL_FORMATTER = "standard";
|
|
@@ -59,9 +221,9 @@ var DEFAULTS = {
|
|
|
59
221
|
maxSnapshotAttempts: DEFAULT_MAX_SNAPSHOT_ATTEMPTS
|
|
60
222
|
};
|
|
61
223
|
function normalizeRoot(root) {
|
|
62
|
-
const resolved =
|
|
63
|
-
const normalized =
|
|
64
|
-
return normalized.split(
|
|
224
|
+
const resolved = path2__default.default.resolve(root);
|
|
225
|
+
const normalized = path2__default.default.normalize(resolved);
|
|
226
|
+
return normalized.split(path2__default.default.sep).join("/");
|
|
65
227
|
}
|
|
66
228
|
function sha256(input) {
|
|
67
229
|
return crypto.createHash("sha256").update(input).digest("hex");
|
|
@@ -93,7 +255,8 @@ function parseFormatter(value) {
|
|
|
93
255
|
);
|
|
94
256
|
}
|
|
95
257
|
async function resolveConfig({
|
|
96
|
-
token
|
|
258
|
+
token,
|
|
259
|
+
rootPath: cliRoot
|
|
97
260
|
}) {
|
|
98
261
|
const resolvedToken = token ?? process.env.CODERULE_TOKEN;
|
|
99
262
|
if (!resolvedToken) {
|
|
@@ -101,14 +264,17 @@ async function resolveConfig({
|
|
|
101
264
|
"Missing token: provide params.token or CODERULE_TOKEN env"
|
|
102
265
|
);
|
|
103
266
|
}
|
|
104
|
-
const rootCandidate =
|
|
105
|
-
|
|
267
|
+
const rootCandidate = await resolveRootPath({
|
|
268
|
+
cliRoot,
|
|
269
|
+
logger: logger.child({ scope: "root-resolver" })
|
|
270
|
+
});
|
|
271
|
+
const rootPath = rootCandidate.path;
|
|
106
272
|
const normalized = normalizeRoot(rootPath);
|
|
107
273
|
const rootId = sha256(normalized);
|
|
108
274
|
const dataDir = process.env.CODERULE_DATA_DIR || envPaths__default.default("coderule").data;
|
|
109
|
-
const watchDir =
|
|
110
|
-
await
|
|
111
|
-
const dbPath =
|
|
275
|
+
const watchDir = path2__default.default.join(dataDir, "watch");
|
|
276
|
+
await fs5__default.default.mkdir(watchDir, { recursive: true });
|
|
277
|
+
const dbPath = path2__default.default.join(watchDir, `${rootId}.sqlite`);
|
|
112
278
|
const baseConfig = {
|
|
113
279
|
token: resolvedToken,
|
|
114
280
|
rootPath,
|
|
@@ -185,6 +351,9 @@ async function resolveConfig({
|
|
|
185
351
|
logger.debug(
|
|
186
352
|
{
|
|
187
353
|
rootPath,
|
|
354
|
+
rootSource: rootCandidate.source,
|
|
355
|
+
rootConfidence: rootCandidate.finalConfidence,
|
|
356
|
+
rootModifiers: rootCandidate.modifiers,
|
|
188
357
|
dbPath,
|
|
189
358
|
dataDir,
|
|
190
359
|
authBaseUrl: baseConfig.authBaseUrl,
|
|
@@ -685,7 +854,7 @@ async function fetchVisitorRules(clients, logger2) {
|
|
|
685
854
|
return rules;
|
|
686
855
|
}
|
|
687
856
|
function toPosix(input) {
|
|
688
|
-
return input.split(
|
|
857
|
+
return input.split(path2__default.default.sep).join("/");
|
|
689
858
|
}
|
|
690
859
|
function getLowerBasename(input) {
|
|
691
860
|
const base = input.split("/").pop();
|
|
@@ -704,7 +873,7 @@ function compileRulesBundle(rules) {
|
|
|
704
873
|
if (!info) {
|
|
705
874
|
logger.debug({ path: fullPath }, "Predicate fallback lstat");
|
|
706
875
|
try {
|
|
707
|
-
info =
|
|
876
|
+
info = fs3__default.default.lstatSync(fullPath);
|
|
708
877
|
} catch (error) {
|
|
709
878
|
logger.warn(
|
|
710
879
|
{ err: error, path: fullPath },
|
|
@@ -853,14 +1022,14 @@ var Hasher = class {
|
|
|
853
1022
|
await new Promise((resolve) => setImmediate(resolve));
|
|
854
1023
|
}
|
|
855
1024
|
resolveAbsolutePath(record) {
|
|
856
|
-
if (
|
|
1025
|
+
if (path2__default.default.isAbsolute(record.display_path)) {
|
|
857
1026
|
return record.display_path;
|
|
858
1027
|
}
|
|
859
|
-
return
|
|
1028
|
+
return path2__default.default.join(this.options.rootPath, record.rel_path);
|
|
860
1029
|
}
|
|
861
1030
|
async ensureExists(absPath, record) {
|
|
862
1031
|
try {
|
|
863
|
-
await
|
|
1032
|
+
await fs5__default.default.access(absPath);
|
|
864
1033
|
return true;
|
|
865
1034
|
} catch (error) {
|
|
866
1035
|
this.log.warn(
|
|
@@ -883,7 +1052,7 @@ var Hasher = class {
|
|
|
883
1052
|
const service = crypto.createHash("sha256");
|
|
884
1053
|
service.update(relPath);
|
|
885
1054
|
service.update("\n");
|
|
886
|
-
const stream =
|
|
1055
|
+
const stream = fs3__default.default.createReadStream(absPath);
|
|
887
1056
|
stream.on("data", (chunk) => {
|
|
888
1057
|
content.update(chunk);
|
|
889
1058
|
service.update(chunk);
|
|
@@ -998,13 +1167,13 @@ async function bootstrap(params) {
|
|
|
998
1167
|
return runtime;
|
|
999
1168
|
}
|
|
1000
1169
|
function toPosixRelative(root, target) {
|
|
1001
|
-
const rel =
|
|
1170
|
+
const rel = path2__default.default.relative(root, target);
|
|
1002
1171
|
if (!rel || rel === "") return "";
|
|
1003
|
-
return rel.split(
|
|
1172
|
+
return rel.split(path2__default.default.sep).join("/");
|
|
1004
1173
|
}
|
|
1005
1174
|
function isInsideRoot(root, target) {
|
|
1006
|
-
const rel =
|
|
1007
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
1175
|
+
const rel = path2__default.default.relative(root, target);
|
|
1176
|
+
return rel === "" || !rel.startsWith("..") && !path2__default.default.isAbsolute(rel);
|
|
1008
1177
|
}
|
|
1009
1178
|
|
|
1010
1179
|
// src/fs/Walker.ts
|
|
@@ -1019,7 +1188,7 @@ function cloneStats(stats) {
|
|
|
1019
1188
|
}
|
|
1020
1189
|
async function readSymlinkTarget(absPath, log) {
|
|
1021
1190
|
try {
|
|
1022
|
-
return await
|
|
1191
|
+
return await fs5__default.default.readlink(absPath);
|
|
1023
1192
|
} catch (error) {
|
|
1024
1193
|
log.warn({ err: error, path: absPath }, "Failed to read symlink target");
|
|
1025
1194
|
return null;
|
|
@@ -1029,13 +1198,13 @@ async function walkDirectory(current, opts, stats) {
|
|
|
1029
1198
|
const dirLogger = opts.logger;
|
|
1030
1199
|
let dirents;
|
|
1031
1200
|
try {
|
|
1032
|
-
dirents = await
|
|
1201
|
+
dirents = await fs5__default.default.readdir(current, { withFileTypes: true });
|
|
1033
1202
|
} catch (error) {
|
|
1034
1203
|
dirLogger.warn({ err: error, path: current }, "Failed to read directory");
|
|
1035
1204
|
return;
|
|
1036
1205
|
}
|
|
1037
1206
|
for (const dirent of dirents) {
|
|
1038
|
-
const absPath =
|
|
1207
|
+
const absPath = path2__default.default.join(current, dirent.name);
|
|
1039
1208
|
const relPath = toPosixRelative(opts.rootPath, absPath);
|
|
1040
1209
|
if (dirent.isDirectory()) {
|
|
1041
1210
|
if (shouldPruneDirectory(relPath, opts.bundle)) {
|
|
@@ -1048,7 +1217,7 @@ async function walkDirectory(current, opts, stats) {
|
|
|
1048
1217
|
if (dirent.isSymbolicLink() || dirent.isFile()) {
|
|
1049
1218
|
let stat;
|
|
1050
1219
|
try {
|
|
1051
|
-
stat = await
|
|
1220
|
+
stat = await fs5__default.default.lstat(absPath);
|
|
1052
1221
|
} catch (error) {
|
|
1053
1222
|
dirLogger.warn({ err: error, path: absPath }, "Failed to stat file");
|
|
1054
1223
|
continue;
|
|
@@ -1140,9 +1309,9 @@ async function uploadMissing(rootPath, missing, syncClient, logger2, maxAttempts
|
|
|
1140
1309
|
const list = chunks[idx];
|
|
1141
1310
|
const map = /* @__PURE__ */ new Map();
|
|
1142
1311
|
for (const missingFile of list) {
|
|
1143
|
-
const absPath =
|
|
1312
|
+
const absPath = path2__default.default.join(rootPath, missingFile.file_path);
|
|
1144
1313
|
try {
|
|
1145
|
-
const buffer = await
|
|
1314
|
+
const buffer = await fs5__default.default.readFile(absPath);
|
|
1146
1315
|
map.set(missingFile.file_hash, {
|
|
1147
1316
|
path: missingFile.file_path,
|
|
1148
1317
|
content: buffer
|
|
@@ -1422,7 +1591,7 @@ function computeBackoff(attempts) {
|
|
|
1422
1591
|
}
|
|
1423
1592
|
async function readSymlinkTarget2(absPath) {
|
|
1424
1593
|
try {
|
|
1425
|
-
return await
|
|
1594
|
+
return await fs5__default.default.readlink(absPath);
|
|
1426
1595
|
} catch {
|
|
1427
1596
|
return null;
|
|
1428
1597
|
}
|
|
@@ -1563,7 +1732,7 @@ var ServiceRunner = class {
|
|
|
1563
1732
|
async handleEvent(event, absPath, stats) {
|
|
1564
1733
|
if (!this.running) return;
|
|
1565
1734
|
const root = this.runtime.config.rootPath;
|
|
1566
|
-
const absolute =
|
|
1735
|
+
const absolute = path2__default.default.isAbsolute(absPath) ? absPath : path2__default.default.join(root, absPath);
|
|
1567
1736
|
if (!isInsideRoot(root, absolute)) {
|
|
1568
1737
|
return;
|
|
1569
1738
|
}
|
|
@@ -1583,7 +1752,7 @@ var ServiceRunner = class {
|
|
|
1583
1752
|
async handleAddChange(absPath, _stats) {
|
|
1584
1753
|
let fileStats;
|
|
1585
1754
|
try {
|
|
1586
|
-
fileStats = await
|
|
1755
|
+
fileStats = await fs5__default.default.lstat(absPath);
|
|
1587
1756
|
} catch (error) {
|
|
1588
1757
|
this.runtime.logger.warn(
|
|
1589
1758
|
{ err: error, path: absPath },
|
|
@@ -1829,7 +1998,6 @@ async function runService(params) {
|
|
|
1829
1998
|
|
|
1830
1999
|
// src/cli.ts
|
|
1831
2000
|
var ENV_FLAG_MAP = {
|
|
1832
|
-
root: "CODERULE_ROOT",
|
|
1833
2001
|
"data-dir": "CODERULE_DATA_DIR",
|
|
1834
2002
|
"auth-url": "CODERULE_AUTH_URL",
|
|
1835
2003
|
"sync-url": "CODERULE_SYNC_URL",
|
|
@@ -1876,6 +2044,7 @@ Options:
|
|
|
1876
2044
|
}
|
|
1877
2045
|
function parseArgs(argv) {
|
|
1878
2046
|
let token = process.env.CODERULE_TOKEN;
|
|
2047
|
+
let rootPath;
|
|
1879
2048
|
let mode = "service";
|
|
1880
2049
|
let clean = false;
|
|
1881
2050
|
let inlineHasher = false;
|
|
@@ -1903,6 +2072,13 @@ function parseArgs(argv) {
|
|
|
1903
2072
|
inlineHasher = true;
|
|
1904
2073
|
continue;
|
|
1905
2074
|
}
|
|
2075
|
+
if (arg === "--root") {
|
|
2076
|
+
if (args.length === 0) {
|
|
2077
|
+
throw new Error("Option --root requires a value");
|
|
2078
|
+
}
|
|
2079
|
+
rootPath = args.shift();
|
|
2080
|
+
continue;
|
|
2081
|
+
}
|
|
1906
2082
|
if (arg.startsWith("--")) {
|
|
1907
2083
|
const flag = arg.slice(2);
|
|
1908
2084
|
const envKey = ENV_FLAG_MAP[flag];
|
|
@@ -1935,22 +2111,22 @@ function parseArgs(argv) {
|
|
|
1935
2111
|
"Missing token. Provide via argument or CODERULE_TOKEN env."
|
|
1936
2112
|
);
|
|
1937
2113
|
}
|
|
1938
|
-
return { token, mode, clean, inlineHasher, env };
|
|
2114
|
+
return { token, rootPath, mode, clean, inlineHasher, env };
|
|
1939
2115
|
}
|
|
1940
|
-
async function ensureClean(configToken) {
|
|
1941
|
-
const config = await resolveConfig({ token: configToken });
|
|
2116
|
+
async function ensureClean(configToken, rootPath) {
|
|
2117
|
+
const config = await resolveConfig({ token: configToken, rootPath });
|
|
1942
2118
|
const targets = [
|
|
1943
2119
|
config.dbPath,
|
|
1944
2120
|
`${config.dbPath}-shm`,
|
|
1945
2121
|
`${config.dbPath}-wal`
|
|
1946
2122
|
];
|
|
1947
|
-
await Promise.all(targets.map((target) =>
|
|
1948
|
-
await
|
|
2123
|
+
await Promise.all(targets.map((target) => fs5__default.default.rm(target, { force: true })));
|
|
2124
|
+
await fs5__default.default.rm(path2__default.default.join(config.dataDir, "watch", `${config.rootId}.sqlite-shm`), {
|
|
1949
2125
|
force: true
|
|
1950
2126
|
}).catch(() => {
|
|
1951
2127
|
});
|
|
1952
|
-
const dir =
|
|
1953
|
-
await
|
|
2128
|
+
const dir = path2__default.default.dirname(config.dbPath);
|
|
2129
|
+
await fs5__default.default.mkdir(dir, { recursive: true });
|
|
1954
2130
|
console.log(`Removed scanner database at ${config.dbPath}`);
|
|
1955
2131
|
}
|
|
1956
2132
|
async function main() {
|
|
@@ -1967,13 +2143,16 @@ async function main() {
|
|
|
1967
2143
|
process.env[key] = value;
|
|
1968
2144
|
}
|
|
1969
2145
|
if (options.clean) {
|
|
1970
|
-
await ensureClean(options.token);
|
|
2146
|
+
await ensureClean(options.token, options.rootPath);
|
|
1971
2147
|
}
|
|
1972
2148
|
if (options.mode === "initial") {
|
|
1973
|
-
const result = await runInitialSync({
|
|
2149
|
+
const result = await runInitialSync({
|
|
2150
|
+
token: options.token,
|
|
2151
|
+
rootPath: options.rootPath
|
|
2152
|
+
});
|
|
1974
2153
|
console.log("Initial sync result:", JSON.stringify(result, null, 2));
|
|
1975
2154
|
} else {
|
|
1976
|
-
await runService({ token: options.token });
|
|
2155
|
+
await runService({ token: options.token, rootPath: options.rootPath });
|
|
1977
2156
|
}
|
|
1978
2157
|
} catch (error) {
|
|
1979
2158
|
console.error("Scanner CLI failed:", error);
|