docdex 0.2.11 → 0.2.13

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 CHANGED
@@ -1,7 +1,10 @@
1
1
  # Changelog
2
2
 
3
- ## 0.2.11
4
- - Added glama support
3
+ ## 0.2.13
4
+ - Repo memory now tags items with `repoId` and filters recalls to prevent cross-repo leakage in multi-repo daemons.
5
+ - MCP HTTP requires explicit repo selection when multiple repos are active.
6
+ - Postinstall banner now guides users to run `docdex setup`.
7
+ - Docs refreshed with memory, agent memory, code intelligence, web search, and Ollama guidance.
5
8
 
6
9
  ## 0.1.10
7
10
  - smithery deployment work to get a bettwe score. enriched server.js, added mcp.json and an icon address.
package/lib/install.js CHANGED
@@ -1899,6 +1899,55 @@ async function main() {
1899
1899
  } catch (err) {
1900
1900
  console.warn(`[docdex] postinstall setup skipped: ${err?.message || err}`);
1901
1901
  }
1902
+ printPostInstallBanner();
1903
+ }
1904
+
1905
+ function printPostInstallBanner() {
1906
+ const frame = "\x1b[35m";
1907
+ const reset = "\x1b[0m";
1908
+ const stripAnsi = (text) => text.replace(/\x1b\[[0-9;]*m/g, "");
1909
+ const writeDirect = (message) => {
1910
+ const ttyPath = process.platform === "win32" ? "CONOUT$" : "/dev/tty";
1911
+ try {
1912
+ const fd = fs.openSync(ttyPath, "w");
1913
+ fs.writeSync(fd, message);
1914
+ fs.closeSync(fd);
1915
+ return true;
1916
+ } catch {
1917
+ return false;
1918
+ }
1919
+ };
1920
+ let width = 0;
1921
+ const content = [
1922
+ "\x1b[31m _ _ \x1b[0m",
1923
+ "\x1b[31m __| | ___ ___ __| | _____ __\x1b[0m",
1924
+ "\x1b[31m / _` |/ _ \\ / __/ _` |/ _ \\ \\/ /\x1b[0m",
1925
+ "\x1b[31m | (_| | (_) | (_| (_| | __/> < \x1b[0m",
1926
+ "\x1b[31m \\__,_|\\___/ \\___\\__,_|\\___/_/\\_\\\x1b[0m",
1927
+ "",
1928
+ "\x1b[32mDocdex installed successfully!\x1b[0m",
1929
+ "\x1b[41m\x1b[97m IMPORTANT \x1b[0m \x1b[33mNext step:\x1b[0m run \x1b[32m`docdex setup`\x1b[0m to complete the installation.",
1930
+ "\x1b[33mSetup:\x1b[0m configures Ollama/models + browser.",
1931
+ "\x1b[34mTip:\x1b[0m after setup, start the daemon with \x1b[36m`docdexd serve --repo <path>`\x1b[0m"
1932
+ ];
1933
+ width = Math.max(72, content.reduce((max, line) => Math.max(max, stripAnsi(line).length), 0));
1934
+ const padLine = (text) => {
1935
+ const visible = stripAnsi(text).length;
1936
+ const padding = Math.max(0, width - visible);
1937
+ return `${text}${" ".repeat(padding)}`;
1938
+ };
1939
+
1940
+ const top = `${frame}╭${"─".repeat(width + 2)}╮${reset}`;
1941
+ const bottom = `${frame}╰${"─".repeat(width + 2)}╯${reset}`;
1942
+ const lines = [top];
1943
+ for (const line of content) {
1944
+ lines.push(`${frame}│ ${reset}${padLine(line)}${frame} │${reset}`);
1945
+ }
1946
+ lines.push(bottom);
1947
+ const banner = `\r\x1b[2K${lines.join("\n")}\n`;
1948
+ if (!writeDirect(banner)) {
1949
+ console.log(banner);
1950
+ }
1902
1951
  }
1903
1952
 
1904
1953
  function appendInstallSafetyLines(lines, err) {
@@ -157,12 +157,50 @@ function upsertMcpServerJson(pathname, url) {
157
157
  const { value } = readJson(pathname);
158
158
  if (typeof value !== "object" || value == null || Array.isArray(value)) return false;
159
159
  const root = value;
160
- if (!root.mcpServers || typeof root.mcpServers !== "object" || Array.isArray(root.mcpServers)) {
160
+ const pickSection = () => {
161
+ if (root.mcpServers && typeof root.mcpServers === "object" && !Array.isArray(root.mcpServers)) {
162
+ return { key: "mcpServers", section: root.mcpServers };
163
+ }
164
+ if (root.mcp_servers && typeof root.mcp_servers === "object" && !Array.isArray(root.mcp_servers)) {
165
+ return { key: "mcp_servers", section: root.mcp_servers };
166
+ }
167
+ return null;
168
+ };
169
+ if (Array.isArray(root.mcpServers)) {
170
+ const idx = root.mcpServers.findIndex((entry) => entry && entry.name === "docdex");
171
+ if (idx >= 0) {
172
+ if (root.mcpServers[idx].url === url) return false;
173
+ root.mcpServers[idx] = { ...root.mcpServers[idx], url };
174
+ writeJson(pathname, root);
175
+ return true;
176
+ }
177
+ root.mcpServers.push({ name: "docdex", url });
178
+ writeJson(pathname, root);
179
+ return true;
180
+ }
181
+
182
+ const picked = pickSection();
183
+ if (!picked) {
161
184
  root.mcpServers = {};
162
185
  }
163
- const current = root.mcpServers.docdex;
186
+ const section = picked ? picked.section : root.mcpServers;
187
+ const current = section.docdex;
188
+ if (current && current.url === url) return false;
189
+ section.docdex = { url };
190
+ writeJson(pathname, root);
191
+ return true;
192
+ }
193
+
194
+ function upsertZedConfig(pathname, url) {
195
+ const { value } = readJson(pathname);
196
+ if (typeof value !== "object" || value == null || Array.isArray(value)) return false;
197
+ const root = value;
198
+ if (!root.experimental_mcp_servers || typeof root.experimental_mcp_servers !== "object" || Array.isArray(root.experimental_mcp_servers)) {
199
+ root.experimental_mcp_servers = {};
200
+ }
201
+ const current = root.experimental_mcp_servers.docdex;
164
202
  if (current && current.url === url) return false;
165
- root.mcpServers.docdex = { url };
203
+ root.experimental_mcp_servers.docdex = { url };
166
204
  writeJson(pathname, root);
167
205
  return true;
168
206
  }
@@ -340,18 +378,45 @@ function clientConfigPaths() {
340
378
  return {
341
379
  claude: path.join(appData, "Claude", "claude_desktop_config.json"),
342
380
  cursor: path.join(userProfile, ".cursor", "mcp.json"),
381
+ windsurf: path.join(userProfile, ".codeium", "windsurf", "mcp_config.json"),
382
+ cline: path.join(appData, "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
383
+ roo: path.join(appData, "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
384
+ continue: path.join(userProfile, ".continue", "config.json"),
385
+ pearai: path.join(userProfile, ".kiro", "settings", "mcp.json"),
386
+ pearai_alt: path.join(userProfile, ".pearai", "mcp.json"),
387
+ void: path.join(appData, "Void", "mcp.json"),
388
+ vscode: path.join(appData, "Code", "User", "mcp.json"),
389
+ zed: path.join(appData, "Zed", "settings.json"),
343
390
  codex: path.join(userProfile, ".codex", "config.toml")
344
391
  };
345
392
  case "darwin":
346
393
  return {
347
394
  claude: path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
348
395
  cursor: path.join(home, ".cursor", "mcp.json"),
396
+ windsurf: path.join(home, ".codeium", "windsurf", "mcp_config.json"),
397
+ cline: path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
398
+ roo: path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
399
+ continue: path.join(home, ".continue", "config.json"),
400
+ pearai: path.join(home, ".kiro", "settings", "mcp.json"),
401
+ pearai_alt: path.join(home, ".config", "pearai", "mcp.json"),
402
+ void: path.join(home, "Library", "Application Support", "Void", "mcp.json"),
403
+ vscode: path.join(home, "Library", "Application Support", "Code", "User", "mcp.json"),
404
+ zed: path.join(home, ".config", "zed", "settings.json"),
349
405
  codex: path.join(home, ".codex", "config.toml")
350
406
  };
351
407
  default:
352
408
  return {
353
409
  claude: path.join(home, ".config", "Claude", "claude_desktop_config.json"),
354
410
  cursor: path.join(home, ".cursor", "mcp.json"),
411
+ windsurf: path.join(home, ".codeium", "windsurf", "mcp_config.json"),
412
+ cline: path.join(home, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
413
+ roo: path.join(home, ".config", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
414
+ continue: path.join(home, ".continue", "config.json"),
415
+ pearai: path.join(home, ".kiro", "settings", "mcp.json"),
416
+ pearai_alt: path.join(home, ".config", "pearai", "mcp.json"),
417
+ void: path.join(home, ".config", "Void", "mcp.json"),
418
+ vscode: path.join(home, ".config", "Code", "User", "mcp.json"),
419
+ zed: path.join(home, ".config", "zed", "settings.json"),
355
420
  codex: path.join(home, ".codex", "config.toml")
356
421
  };
357
422
  }
@@ -1207,8 +1272,24 @@ async function runPostInstallSetup({ binaryPath, logger } = {}) {
1207
1272
  const url = configUrlForPort(port);
1208
1273
  const codexUrl = configStreamableUrlForPort(port);
1209
1274
  const paths = clientConfigPaths();
1210
- upsertMcpServerJson(paths.claude, url);
1211
- upsertMcpServerJson(paths.cursor, url);
1275
+ const jsonPaths = [
1276
+ paths.claude,
1277
+ paths.cursor,
1278
+ paths.windsurf,
1279
+ paths.cline,
1280
+ paths.roo,
1281
+ paths.continue,
1282
+ paths.pearai,
1283
+ paths.pearai_alt,
1284
+ paths.void,
1285
+ paths.vscode
1286
+ ].filter(Boolean);
1287
+ for (const jsonPath of jsonPaths) {
1288
+ upsertMcpServerJson(jsonPath, url);
1289
+ }
1290
+ if (paths.zed) {
1291
+ upsertZedConfig(paths.zed, url);
1292
+ }
1212
1293
  upsertCodexConfig(paths.codex, codexUrl);
1213
1294
 
1214
1295
  const daemonRoot = ensureDaemonRoot();
@@ -1238,6 +1319,7 @@ module.exports = {
1238
1319
  upsertServerConfig,
1239
1320
  parseServerBind,
1240
1321
  upsertMcpServerJson,
1322
+ upsertZedConfig,
1241
1323
  upsertCodexConfig,
1242
1324
  pickAvailablePort,
1243
1325
  configUrlForPort,
package/lib/uninstall.js CHANGED
@@ -33,12 +33,14 @@ function clientConfigPaths() {
33
33
  json: [
34
34
  path.join(appData, "Claude", "claude_desktop_config.json"),
35
35
  path.join(userProfile, ".cursor", "mcp.json"),
36
- path.join(userProfile, ".cursor", "settings.json"),
37
36
  path.join(userProfile, ".codeium", "windsurf", "mcp_config.json"),
38
37
  path.join(appData, "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
39
38
  path.join(appData, "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
40
39
  path.join(userProfile, ".continue", "config.json"),
41
40
  path.join(userProfile, ".kiro", "settings", "mcp.json"),
41
+ path.join(userProfile, ".pearai", "mcp.json"),
42
+ path.join(appData, "Void", "mcp.json"),
43
+ path.join(appData, "Code", "User", "mcp.json"),
42
44
  path.join(appData, "Zed", "settings.json")
43
45
  ],
44
46
  toml: [path.join(userProfile, ".codex", "config.toml")],
@@ -49,12 +51,14 @@ function clientConfigPaths() {
49
51
  json: [
50
52
  path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
51
53
  path.join(home, ".cursor", "mcp.json"),
52
- path.join(home, ".cursor", "settings.json"),
53
54
  path.join(home, ".codeium", "windsurf", "mcp_config.json"),
54
55
  path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
55
56
  path.join(home, "Library", "Application Support", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
56
57
  path.join(home, ".continue", "config.json"),
57
58
  path.join(home, ".kiro", "settings", "mcp.json"),
59
+ path.join(home, ".config", "pearai", "mcp.json"),
60
+ path.join(home, "Library", "Application Support", "Void", "mcp.json"),
61
+ path.join(home, "Library", "Application Support", "Code", "User", "mcp.json"),
58
62
  path.join(home, ".config", "zed", "settings.json")
59
63
  ],
60
64
  toml: [path.join(home, ".codex", "config.toml")],
@@ -65,12 +69,14 @@ function clientConfigPaths() {
65
69
  json: [
66
70
  path.join(home, ".config", "Claude", "claude_desktop_config.json"),
67
71
  path.join(home, ".cursor", "mcp.json"),
68
- path.join(home, ".cursor", "settings.json"),
69
72
  path.join(home, ".codeium", "windsurf", "mcp_config.json"),
70
73
  path.join(home, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
71
74
  path.join(home, ".config", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "settings", "mcp_settings.json"),
72
75
  path.join(home, ".continue", "config.json"),
73
76
  path.join(home, ".kiro", "settings", "mcp.json"),
77
+ path.join(home, ".config", "pearai", "mcp.json"),
78
+ path.join(home, ".config", "Void", "mcp.json"),
79
+ path.join(home, ".config", "Code", "User", "mcp.json"),
74
80
  path.join(home, ".config", "zed", "settings.json")
75
81
  ],
76
82
  toml: [path.join(home, ".codex", "config.toml")],
@@ -103,11 +109,32 @@ function removeMcpServerJson(pathname, name = "docdex") {
103
109
  let changed = false;
104
110
  for (const key of keys) {
105
111
  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];
112
+ if (!section) continue;
113
+ if (Array.isArray(section)) {
114
+ const before = section.length;
115
+ root[key] = section.filter((entry) => !(entry && entry.name === name));
116
+ if (root[key].length !== before) {
117
+ changed = true;
118
+ }
119
+ if (root[key].length === 0) delete root[key];
120
+ continue;
121
+ }
122
+ if (typeof section !== "object") continue;
123
+ if (Object.prototype.hasOwnProperty.call(section, name)) {
124
+ delete section[name];
125
+ changed = true;
126
+ if (Object.keys(section).length === 0) delete root[key];
127
+ }
128
+ }
129
+ if (
130
+ root.experimental_mcp_servers &&
131
+ typeof root.experimental_mcp_servers === "object" &&
132
+ !Array.isArray(root.experimental_mcp_servers) &&
133
+ Object.prototype.hasOwnProperty.call(root.experimental_mcp_servers, name)
134
+ ) {
135
+ delete root.experimental_mcp_servers[name];
109
136
  changed = true;
110
- if (Object.keys(section).length === 0) delete root[key];
137
+ if (Object.keys(root.experimental_mcp_servers).length === 0) delete root.experimental_mcp_servers;
111
138
  }
112
139
  if (!changed) return false;
113
140
  writeJson(pathname, root);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docdex",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "mcpName": "io.github.bekirdag/docdex",
5
5
  "description": "Docdex CLI as an npm-installable binary wrapper.",
6
6
  "bin": {