docdex 0.2.4 → 0.2.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.
- package/CHANGELOG.md +1 -1
- package/lib/postinstall_setup.js +28 -5
- package/lib/uninstall.js +148 -23
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/lib/postinstall_setup.js
CHANGED
|
@@ -381,24 +381,46 @@ function hasInteractiveTty(stdin, stdout) {
|
|
|
381
381
|
return Boolean((stdin && stdin.isTTY) || (stdout && stdout.isTTY));
|
|
382
382
|
}
|
|
383
383
|
|
|
384
|
-
function
|
|
384
|
+
function canPromptWithTty(stdin, stdout) {
|
|
385
|
+
if (hasInteractiveTty(stdin, stdout)) return true;
|
|
386
|
+
const ttyPath = process.platform === "win32" ? "CONIN$" : "/dev/tty";
|
|
387
|
+
try {
|
|
388
|
+
const fd = fs.openSync(ttyPath, "r");
|
|
389
|
+
fs.closeSync(fd);
|
|
390
|
+
return true;
|
|
391
|
+
} catch {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function resolveOllamaInstallMode({
|
|
397
|
+
env = process.env,
|
|
398
|
+
stdin = process.stdin,
|
|
399
|
+
stdout = process.stdout,
|
|
400
|
+
canPrompt = canPromptWithTty
|
|
401
|
+
} = {}) {
|
|
385
402
|
const override = parseEnvBool(env.DOCDEX_OLLAMA_INSTALL);
|
|
386
403
|
if (override === true) return { mode: "install", reason: "env", interactive: false };
|
|
387
404
|
if (override === false) return { mode: "skip", reason: "env", interactive: false };
|
|
388
|
-
if (!
|
|
405
|
+
if (!canPrompt(stdin, stdout)) {
|
|
389
406
|
return { mode: "skip", reason: "non_interactive", interactive: false };
|
|
390
407
|
}
|
|
391
408
|
if (env.CI) return { mode: "skip", reason: "ci", interactive: false };
|
|
392
409
|
return { mode: "prompt", reason: "interactive", interactive: true };
|
|
393
410
|
}
|
|
394
411
|
|
|
395
|
-
function resolveOllamaModelPromptMode({
|
|
412
|
+
function resolveOllamaModelPromptMode({
|
|
413
|
+
env = process.env,
|
|
414
|
+
stdin = process.stdin,
|
|
415
|
+
stdout = process.stdout,
|
|
416
|
+
canPrompt = canPromptWithTty
|
|
417
|
+
} = {}) {
|
|
396
418
|
const override = parseEnvBool(env.DOCDEX_OLLAMA_MODEL_PROMPT);
|
|
397
419
|
if (override === true) return { mode: "prompt", reason: "env", interactive: true };
|
|
398
420
|
if (override === false) return { mode: "skip", reason: "env", interactive: false };
|
|
399
421
|
const assumeYes = parseEnvBool(env.DOCDEX_OLLAMA_MODEL_ASSUME_Y);
|
|
400
422
|
if (assumeYes === true) return { mode: "auto", reason: "env", interactive: false };
|
|
401
|
-
if (!
|
|
423
|
+
if (!canPrompt(stdin, stdout)) {
|
|
402
424
|
return { mode: "skip", reason: "non_interactive", interactive: false };
|
|
403
425
|
}
|
|
404
426
|
if (env.CI) return { mode: "skip", reason: "ci", interactive: false };
|
|
@@ -1050,5 +1072,6 @@ module.exports = {
|
|
|
1050
1072
|
upsertLlmDefaultModel,
|
|
1051
1073
|
pullOllamaModel,
|
|
1052
1074
|
listOllamaModels,
|
|
1053
|
-
hasInteractiveTty
|
|
1075
|
+
hasInteractiveTty,
|
|
1076
|
+
canPromptWithTty
|
|
1054
1077
|
};
|
package/lib/uninstall.js
CHANGED
|
@@ -18,6 +18,8 @@ function stateDir() {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function daemonLockPath() {
|
|
21
|
+
const override = process.env.DOCDEX_DAEMON_LOCK_PATH;
|
|
22
|
+
if (override && override.trim()) return override.trim();
|
|
21
23
|
return path.join(os.homedir(), ".docdex", "daemon.lock");
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -28,21 +30,51 @@ function clientConfigPaths() {
|
|
|
28
30
|
switch (process.platform) {
|
|
29
31
|
case "win32":
|
|
30
32
|
return {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
json: [
|
|
34
|
+
path.join(appData, "Claude", "claude_desktop_config.json"),
|
|
35
|
+
path.join(userProfile, ".cursor", "mcp.json"),
|
|
36
|
+
path.join(userProfile, ".cursor", "settings.json"),
|
|
37
|
+
path.join(userProfile, ".codeium", "windsurf", "mcp_config.json"),
|
|
38
|
+
path.join(appData, "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
|
|
39
|
+
path.join(appData, "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
|
|
40
|
+
path.join(userProfile, ".continue", "config.json"),
|
|
41
|
+
path.join(userProfile, ".kiro", "settings", "mcp.json"),
|
|
42
|
+
path.join(appData, "Zed", "settings.json")
|
|
43
|
+
],
|
|
44
|
+
toml: [path.join(userProfile, ".codex", "config.toml")],
|
|
45
|
+
yaml: [path.join(appData, "Aider", "config.yml")]
|
|
34
46
|
};
|
|
35
47
|
case "darwin":
|
|
36
48
|
return {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
json: [
|
|
50
|
+
path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
51
|
+
path.join(home, ".cursor", "mcp.json"),
|
|
52
|
+
path.join(home, ".cursor", "settings.json"),
|
|
53
|
+
path.join(home, ".codeium", "windsurf", "mcp_config.json"),
|
|
54
|
+
path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
|
|
55
|
+
path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
|
|
56
|
+
path.join(home, ".continue", "config.json"),
|
|
57
|
+
path.join(home, ".kiro", "settings", "mcp.json"),
|
|
58
|
+
path.join(home, ".config", "zed", "settings.json")
|
|
59
|
+
],
|
|
60
|
+
toml: [path.join(home, ".codex", "config.toml")],
|
|
61
|
+
yaml: [path.join(home, ".config", "aider", "config.yml"), path.join(home, ".aider.conf.yml")]
|
|
40
62
|
};
|
|
41
63
|
default:
|
|
42
64
|
return {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
65
|
+
json: [
|
|
66
|
+
path.join(home, ".config", "Claude", "claude_desktop_config.json"),
|
|
67
|
+
path.join(home, ".cursor", "mcp.json"),
|
|
68
|
+
path.join(home, ".cursor", "settings.json"),
|
|
69
|
+
path.join(home, ".codeium", "windsurf", "mcp_config.json"),
|
|
70
|
+
path.join(home, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
|
|
71
|
+
path.join(home, ".config", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
|
|
72
|
+
path.join(home, ".continue", "config.json"),
|
|
73
|
+
path.join(home, ".kiro", "settings", "mcp.json"),
|
|
74
|
+
path.join(home, ".config", "zed", "settings.json")
|
|
75
|
+
],
|
|
76
|
+
toml: [path.join(home, ".codex", "config.toml")],
|
|
77
|
+
yaml: [path.join(home, ".config", "aider", "config.yml"), path.join(home, ".aider.conf.yml")]
|
|
46
78
|
};
|
|
47
79
|
}
|
|
48
80
|
}
|
|
@@ -67,12 +99,17 @@ function removeMcpServerJson(pathname, name = "docdex") {
|
|
|
67
99
|
const { value, exists } = readJson(pathname);
|
|
68
100
|
if (!exists || typeof value !== "object" || value == null || Array.isArray(value)) return false;
|
|
69
101
|
const root = value;
|
|
70
|
-
|
|
71
|
-
|
|
102
|
+
const keys = ["mcpServers", "mcp_servers"];
|
|
103
|
+
let changed = false;
|
|
104
|
+
for (const key of keys) {
|
|
105
|
+
const section = root[key];
|
|
106
|
+
if (!section || typeof section !== "object" || Array.isArray(section)) continue;
|
|
107
|
+
if (!Object.prototype.hasOwnProperty.call(section, name)) continue;
|
|
108
|
+
delete section[name];
|
|
109
|
+
changed = true;
|
|
110
|
+
if (Object.keys(section).length === 0) delete root[key];
|
|
72
111
|
}
|
|
73
|
-
if (!
|
|
74
|
-
delete root.mcpServers[name];
|
|
75
|
-
if (Object.keys(root.mcpServers).length === 0) delete root.mcpServers;
|
|
112
|
+
if (!changed) return false;
|
|
76
113
|
writeJson(pathname, root);
|
|
77
114
|
return true;
|
|
78
115
|
}
|
|
@@ -180,6 +217,71 @@ function removeCodexConfig(pathname, name = "docdex") {
|
|
|
180
217
|
return false;
|
|
181
218
|
}
|
|
182
219
|
|
|
220
|
+
function removeMcpServerYaml(pathname, name = "docdex") {
|
|
221
|
+
if (!fs.existsSync(pathname)) return false;
|
|
222
|
+
const original = fs.readFileSync(pathname, "utf8");
|
|
223
|
+
const lines = original.split(/\r?\n/);
|
|
224
|
+
const output = [];
|
|
225
|
+
let inSection = false;
|
|
226
|
+
let sectionIndent = null;
|
|
227
|
+
let skipIndent = null;
|
|
228
|
+
let changed = false;
|
|
229
|
+
|
|
230
|
+
const indentSize = (line) => (line.match(/^\s*/)?.[0].length ?? 0);
|
|
231
|
+
|
|
232
|
+
for (const line of lines) {
|
|
233
|
+
if (skipIndent != null) {
|
|
234
|
+
if (line.trim() && indentSize(line) <= skipIndent) {
|
|
235
|
+
skipIndent = null;
|
|
236
|
+
} else {
|
|
237
|
+
changed = true;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!inSection) {
|
|
243
|
+
if (/^\s*mcp_servers\s*:\s*$/.test(line)) {
|
|
244
|
+
inSection = true;
|
|
245
|
+
sectionIndent = indentSize(line);
|
|
246
|
+
}
|
|
247
|
+
output.push(line);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (line.trim() && indentSize(line) <= sectionIndent) {
|
|
252
|
+
inSection = false;
|
|
253
|
+
output.push(line);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (new RegExp(`^\\s*${name}\\s*:`).test(line)) {
|
|
258
|
+
changed = true;
|
|
259
|
+
skipIndent = indentSize(line);
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const listName = line.match(/^\s*-\s*name\s*:\s*(.+)\s*$/);
|
|
264
|
+
if (listName && listName[1].replace(/["']/g, "").trim() === name) {
|
|
265
|
+
changed = true;
|
|
266
|
+
skipIndent = indentSize(line);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const listValue = line.match(/^\s*-\s*([^\s#]+)\s*$/);
|
|
271
|
+
if (listValue && listValue[1].replace(/["']/g, "").trim() === name) {
|
|
272
|
+
changed = true;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
output.push(line);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (changed) {
|
|
280
|
+
fs.writeFileSync(pathname, output.join("\n"));
|
|
281
|
+
}
|
|
282
|
+
return changed;
|
|
283
|
+
}
|
|
284
|
+
|
|
183
285
|
function killPid(pid) {
|
|
184
286
|
if (!pid) return false;
|
|
185
287
|
try {
|
|
@@ -209,6 +311,16 @@ function stopDaemonFromLock() {
|
|
|
209
311
|
}
|
|
210
312
|
}
|
|
211
313
|
|
|
314
|
+
function stopDaemonByName() {
|
|
315
|
+
if (process.platform === "win32") {
|
|
316
|
+
spawnSync("taskkill", ["/IM", "docdexd.exe", "/T", "/F"]);
|
|
317
|
+
return true;
|
|
318
|
+
}
|
|
319
|
+
spawnSync("pkill", ["-TERM", "-x", "docdexd"]);
|
|
320
|
+
spawnSync("pkill", ["-TERM", "-f", "docdexd daemon"]);
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
|
|
212
324
|
function unregisterStartup() {
|
|
213
325
|
if (process.platform === "darwin") {
|
|
214
326
|
const plistPath = path.join(os.homedir(), "Library", "LaunchAgents", "com.docdex.daemon.plist");
|
|
@@ -259,23 +371,34 @@ function clearStartupFailure() {
|
|
|
259
371
|
|
|
260
372
|
function removeDaemonRootNotice() {
|
|
261
373
|
const root = daemonRootPath();
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
374
|
+
const readmes = [path.join(root, "README.txt"), path.join(root, "README.md")];
|
|
375
|
+
for (const readme of readmes) {
|
|
376
|
+
if (fs.existsSync(readme)) {
|
|
377
|
+
try {
|
|
378
|
+
fs.unlinkSync(readme);
|
|
379
|
+
} catch {}
|
|
380
|
+
}
|
|
267
381
|
}
|
|
268
382
|
}
|
|
269
383
|
|
|
270
384
|
function removeClientConfigs() {
|
|
271
385
|
const paths = clientConfigPaths();
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
386
|
+
for (const pathname of paths.json || []) {
|
|
387
|
+
removeMcpServerJson(pathname);
|
|
388
|
+
}
|
|
389
|
+
for (const pathname of paths.toml || []) {
|
|
390
|
+
removeCodexConfig(pathname);
|
|
391
|
+
}
|
|
392
|
+
for (const pathname of paths.yaml || []) {
|
|
393
|
+
removeMcpServerYaml(pathname);
|
|
394
|
+
}
|
|
275
395
|
}
|
|
276
396
|
|
|
277
397
|
async function main() {
|
|
278
|
-
stopDaemonFromLock();
|
|
398
|
+
const stopped = stopDaemonFromLock();
|
|
399
|
+
if (!stopped) {
|
|
400
|
+
stopDaemonByName();
|
|
401
|
+
}
|
|
279
402
|
unregisterStartup();
|
|
280
403
|
removeClientConfigs();
|
|
281
404
|
clearStartupFailure();
|
|
@@ -289,7 +412,9 @@ if (require.main === module) {
|
|
|
289
412
|
module.exports = {
|
|
290
413
|
removeMcpServerJson,
|
|
291
414
|
removeCodexConfig,
|
|
415
|
+
removeMcpServerYaml,
|
|
292
416
|
stopDaemonFromLock,
|
|
417
|
+
stopDaemonByName,
|
|
293
418
|
unregisterStartup,
|
|
294
419
|
removeClientConfigs
|
|
295
420
|
};
|