@minhpnq1807/contextos 0.5.2 → 0.5.3

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,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.3
4
+
5
+ - Skips project MCP imports whose command is an absolute path that does not exist, preventing placeholder paths such as `/home/user/.cargo/bin/mcp-rtk` from reaching Antigravity.
6
+ - Sanitizes Antigravity MCP config files during `ctx sync --rules` by removing existing MCP entries with missing absolute command paths.
7
+
3
8
  ## 0.5.2
4
9
 
5
10
  - Recovers automatically from malformed `embeddings.db` files by moving the corrupt cache aside and recreating it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minhpnq1807/contextos",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Task-aware AGENTS.md context injection and compliance reporting for Codex, Claude Code, and Antigravity.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -196,6 +196,7 @@ export function readProjectMcpJsonServers({ cwd = process.cwd(), configPath = pa
196
196
  const mcpServers = config.mcpServers && typeof config.mcpServers === "object" ? config.mcpServers : {};
197
197
  return Object.entries(mcpServers)
198
198
  .filter(([, server]) => server && typeof server.command === "string")
199
+ .filter(([, server]) => isRunnableMcpCommand(server.command))
199
200
  .map(([name, server]) => ({
200
201
  name,
201
202
  command: server.command,
@@ -203,6 +204,11 @@ export function readProjectMcpJsonServers({ cwd = process.cwd(), configPath = pa
203
204
  }));
204
205
  }
205
206
 
207
+ function isRunnableMcpCommand(command) {
208
+ if (!path.isAbsolute(command)) return true;
209
+ return fs.existsSync(command);
210
+ }
211
+
206
212
  function mergeMcpServers(...groups) {
207
213
  const merged = new Map();
208
214
  for (const group of groups) {
@@ -253,12 +259,21 @@ function writeJsonFile(filePath, value) {
253
259
  }
254
260
 
255
261
  export function syncAntigravityMcpFromRuler({ tomlPath, configPaths = antigravityMcpConfigPaths(), dryRun = false } = {}) {
256
- const servers = readRulerMcpServers({ tomlPath });
257
- if (!servers.length) return { changed: false, servers: [], configPaths };
262
+ const allServers = readRulerMcpServers({ tomlPath });
263
+ const servers = allServers.filter((server) => isRunnableMcpCommand(server.command));
264
+ const skipped = allServers.filter((server) => !isRunnableMcpCommand(server.command)).map((server) => server.name);
265
+ if (!servers.length && !skipped.length) return { changed: false, servers: [], skipped, removed: [], configPaths };
258
266
 
267
+ const removed = [];
259
268
  for (const configPath of configPaths) {
260
269
  const config = readJsonFile(configPath, {});
261
270
  if (!config.mcpServers || typeof config.mcpServers !== "object") config.mcpServers = {};
271
+ for (const [name, server] of Object.entries(config.mcpServers)) {
272
+ if (server?.command && !isRunnableMcpCommand(server.command)) {
273
+ delete config.mcpServers[name];
274
+ removed.push(name);
275
+ }
276
+ }
262
277
  for (const server of servers) {
263
278
  config.mcpServers[server.name] = {
264
279
  command: server.command,
@@ -268,7 +283,7 @@ export function syncAntigravityMcpFromRuler({ tomlPath, configPaths = antigravit
268
283
  if (!dryRun) writeJsonFile(configPath, config);
269
284
  }
270
285
 
271
- return { changed: true, servers: servers.map((server) => server.name), configPaths };
286
+ return { changed: true, servers: servers.map((server) => server.name), skipped, removed: [...new Set(removed)], configPaths };
272
287
  }
273
288
 
274
289
  export function buildCtxMcpToml({ mcpServerPath, agents = DEFAULT_AGENTS } = {}) {