@codexguild/mcp 1.10.0 → 1.11.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.
@@ -692,7 +692,7 @@ async function findSkillDirs(root, depth = 6, out = []) {
692
692
  if (entries.some((e) => e.isFile() && /^SKILL\.md$/i.test(e.name))) out.push(root);
693
693
  if (depth > 0) {
694
694
  for (const e of entries) {
695
- if (e.isDirectory() && !SKIP_DIRS.has(e.name)) await findSkillDirs(join(root, e.name), depth - 1, out);
695
+ if (e.isDirectory() && !SKIP_DIRS.has(e.name) && !e.name.startsWith(".")) await findSkillDirs(join(root, e.name), depth - 1, out);
696
696
  }
697
697
  }
698
698
  return out;
@@ -995,7 +995,8 @@ async function stackDirs(reader, base = "") {
995
995
  const keep = (dirs) => dirs.filter((d) => !pbasename(d).startsWith(".") && !SKIP_DIRS2.has(pbasename(d)));
996
996
  const level1 = keep(await reader.subdirs(base));
997
997
  const level2 = keep((await Promise.all(level1.map((d) => reader.subdirs(d)))).flat());
998
- return [base, ...level1, ...level2].slice(0, 400);
998
+ const level3 = keep((await Promise.all(level2.slice(0, 200).map((d) => reader.subdirs(d)))).flat());
999
+ return [base, ...level1, ...level2, ...level3].slice(0, 400);
999
1000
  }
1000
1001
  async function detectStack(reader, base = "") {
1001
1002
  const dirs = await stackDirs(reader, base);
@@ -1447,6 +1448,8 @@ import { join as join5 } from "node:path";
1447
1448
  import { readdir as readdir3, readFile as readFile3, stat as stat3 } from "node:fs/promises";
1448
1449
  import { extname, join as join4, relative as relative3 } from "node:path";
1449
1450
  var SOURCE_EXT = /* @__PURE__ */ new Set([".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts", ".vue", ".svelte", ".astro", ".py", ".go", ".rs"]);
1451
+ var TEST_DIRS = /* @__PURE__ */ new Set(["test", "tests", "__tests__", "spec", "__mocks__", "fixtures", "__fixtures__", "testdata"]);
1452
+ var isTestFile = (path) => path.split(/[\\/]/).some((seg) => TEST_DIRS.has(seg)) || /\.(test|spec)\.[cm]?[jt]sx?$|_test\.(go|py)$|(^|[\\/])test_[^\\/]+\.py$/.test(path);
1450
1453
  var LIMITS = { files: 5e3, fileBytes: 1024 * 1024, hits: 60 };
1451
1454
  var escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1452
1455
  function patternsFor(apiRaw) {
@@ -1471,9 +1474,9 @@ async function sourceFiles(root) {
1471
1474
  for (const e of entries) {
1472
1475
  if (out.length >= LIMITS.files) return;
1473
1476
  if (e.isDirectory()) {
1474
- if (e.name.startsWith(".") || SKIP_DIRS2.has(e.name)) continue;
1477
+ if (e.name.startsWith(".") || SKIP_DIRS2.has(e.name) || TEST_DIRS.has(e.name)) continue;
1475
1478
  await walk(join4(dir, e.name), depth + 1);
1476
- } else if (e.isFile() && SOURCE_EXT.has(extname(e.name)) && !/\.(min|d)\.[cm]?[jt]s$/.test(e.name)) {
1479
+ } else if (e.isFile() && SOURCE_EXT.has(extname(e.name)) && !/\.(min|d)\.[cm]?[jt]s$/.test(e.name) && !isTestFile(e.name)) {
1477
1480
  out.push(join4(dir, e.name));
1478
1481
  }
1479
1482
  }
@@ -1546,7 +1549,7 @@ function formatCodeScan(hits, files, checked) {
1546
1549
  import { extname as extname2 } from "node:path";
1547
1550
  var SOURCE_EXT2 = /* @__PURE__ */ new Set([".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts", ".vue", ".svelte", ".astro", ".py", ".go", ".rs"]);
1548
1551
  function writeTexts(tool, input, existing) {
1549
- if (!input?.file_path || !SOURCE_EXT2.has(extname2(input.file_path).toLowerCase()) || /\.(min|d)\.[cm]?[jt]s$/.test(input.file_path)) return null;
1552
+ if (!input?.file_path || !SOURCE_EXT2.has(extname2(input.file_path).toLowerCase()) || /\.(min|d)\.[cm]?[jt]s$/.test(input.file_path) || isTestFile(input.file_path)) return null;
1550
1553
  if (tool === "Write" && typeof input.content === "string") return { before: existing ?? "", after: input.content };
1551
1554
  if (tool === "Edit" && typeof input.new_string === "string") return { before: input.old_string ?? "", after: input.new_string };
1552
1555
  if (tool === "MultiEdit" && Array.isArray(input.edits)) {
@@ -1835,7 +1838,7 @@ async function runHook(event, opts) {
1835
1838
  // src/index.ts
1836
1839
  var API = (process.env.CODEXGUILD_API_URL || "https://api.codexguild.com/v1").replace(/\/$/, "");
1837
1840
  var KEY = process.env.CODEXGUILD_API_KEY ?? "";
1838
- var VERSION = "1.10.0";
1841
+ var VERSION = "1.11.0";
1839
1842
  if (process.argv[2] === "guard") process.exit(await runGuard({ api: API, key: KEY || await findKey() }));
1840
1843
  if (process.argv[2] === "hook") process.exit(await runHook(process.argv[3], { api: API, key: KEY, version: VERSION }));
1841
1844
  var INSTRUCTION_FILES = ["CLAUDE.md", ".claude/CLAUDE.md", "AGENTS.md", "AGENTS.override.md", ".hermes.md", "HERMES.md", "GEMINI.md", ".cursorrules"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codexguild/mcp",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "CodexGuild MCP server (stdio) \u2014 boosts your coding agent: remote CodexGuild tools plus local stack detection from lockfiles, deprecated APIs found in your own code, and offline security audits of skills, instructions and agent workflows",
5
5
  "keywords": [
6
6
  "mcp",