@yawlabs/ctxlint 0.18.4 → 0.18.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/dist/index.js CHANGED
@@ -25432,7 +25432,7 @@ function loadSettingsSources2(projectRoot, homeDir, includeUserGlobal) {
25432
25432
  }
25433
25433
  return sources;
25434
25434
  }
25435
- function expandPath(raw, projectRoot, homeDir) {
25435
+ function expandPath(raw, projectRoot, homeDir, platform) {
25436
25436
  let s = raw;
25437
25437
  if (s === "~" || s.startsWith("~/") || s.startsWith("~\\")) {
25438
25438
  s = path10.join(homeDir, s.slice(1));
@@ -25453,6 +25453,7 @@ function expandPath(raw, projectRoot, homeDir) {
25453
25453
  });
25454
25454
  if (/\$\{?[A-Za-z_]/.test(s)) return null;
25455
25455
  if (/%[A-Za-z_][A-Za-z0-9_]*%/.test(s)) return null;
25456
+ s = translateMsysDrivePath(s, platform);
25456
25457
  if (!path10.isAbsolute(s)) s = path10.resolve(projectRoot, s);
25457
25458
  return s;
25458
25459
  }
@@ -25461,19 +25462,32 @@ function looksLikePath(token) {
25461
25462
  if (PATH_PREFIX.test(token)) return true;
25462
25463
  return hasSep && SCRIPT_EXT.test(token);
25463
25464
  }
25464
- function extractCommandPaths(command, projectRoot, homeDir) {
25465
+ function stripMatcherWildcard(token) {
25466
+ return token.replace(/:?\*+$/, "");
25467
+ }
25468
+ function isMsysFlag(token) {
25469
+ return /^\/\/[A-Za-z]+$/.test(token);
25470
+ }
25471
+ function translateMsysDrivePath(s, platform) {
25472
+ if (platform !== "win32") return s;
25473
+ const m = /^\/([A-Za-z])\/(.*)$/.exec(s);
25474
+ return m ? `${m[1]}:/${m[2]}` : s;
25475
+ }
25476
+ function extractCommandPaths(command, projectRoot, homeDir, platform) {
25465
25477
  const tokens = command.match(/"[^"]*"|'[^']*'|\S+/g) ?? [];
25466
25478
  const out = [];
25467
25479
  for (const t2 of tokens) {
25468
25480
  const token = t2.replace(/^['"]|['"]$/g, "");
25469
- if (!looksLikePath(token)) continue;
25470
- out.push({ raw: token, resolved: expandPath(token, projectRoot, homeDir) });
25481
+ const pathToken = stripMatcherWildcard(token);
25482
+ if (isMsysFlag(pathToken)) continue;
25483
+ if (!looksLikePath(pathToken)) continue;
25484
+ out.push({ raw: token, resolved: expandPath(pathToken, projectRoot, homeDir, platform) });
25471
25485
  }
25472
25486
  return out;
25473
25487
  }
25474
- function extractPermissionPaths(entry, projectRoot, homeDir) {
25488
+ function extractPermissionPaths(entry, projectRoot, homeDir, platform) {
25475
25489
  const inner = entry.replace(/^[A-Za-z]+\((.*)\)$/, "$1");
25476
- return extractCommandPaths(inner, projectRoot, homeDir);
25490
+ return extractCommandPaths(inner, projectRoot, homeDir, platform);
25477
25491
  }
25478
25492
  function lineForPath(source, jsonPath) {
25479
25493
  if (!source.tree) return 1;
@@ -25481,7 +25495,7 @@ function lineForPath(source, jsonPath) {
25481
25495
  if (!node) return 1;
25482
25496
  return offsetToPosition(source.content, node.offset).line;
25483
25497
  }
25484
- function checkSource(source, projectRoot, homeDir) {
25498
+ function checkSource(source, projectRoot, homeDir, platform) {
25485
25499
  if (!source.tree) return [];
25486
25500
  const data = getNodeValue2(source.tree);
25487
25501
  if (!data || typeof data !== "object") return [];
@@ -25508,7 +25522,7 @@ function checkSource(source, projectRoot, homeDir) {
25508
25522
  subHooks.forEach((h2, hi2) => {
25509
25523
  if (!h2 || typeof h2.command !== "string") return;
25510
25524
  const line = lineForPath(source, ["hooks", event, mi2, "hooks", hi2, "command"]);
25511
- for (const cand of extractCommandPaths(h2.command, projectRoot, homeDir)) {
25525
+ for (const cand of extractCommandPaths(h2.command, projectRoot, homeDir, platform)) {
25512
25526
  report(cand, line, `${event} hook`);
25513
25527
  }
25514
25528
  });
@@ -25521,18 +25535,18 @@ function checkSource(source, projectRoot, homeDir) {
25521
25535
  list.forEach((entry, i2) => {
25522
25536
  if (typeof entry !== "string") return;
25523
25537
  const line = lineForPath(source, ["permissions", listName, i2]);
25524
- for (const cand of extractPermissionPaths(entry, projectRoot, homeDir)) {
25538
+ for (const cand of extractPermissionPaths(entry, projectRoot, homeDir, platform)) {
25525
25539
  report(cand, line, `permissions.${listName} entry`);
25526
25540
  }
25527
25541
  });
25528
25542
  }
25529
25543
  return issues;
25530
25544
  }
25531
- async function checkHookCoverage(projectRoot, homeDir = os3.homedir(), options = {}) {
25545
+ async function checkHookCoverage(projectRoot, homeDir = os3.homedir(), options = {}, platform = process.platform) {
25532
25546
  const sources = loadSettingsSources2(projectRoot, homeDir, options.userGlobal ?? false);
25533
25547
  const issues = [];
25534
25548
  for (const source of sources) {
25535
- issues.push(...checkSource(source, projectRoot, homeDir));
25549
+ issues.push(...checkSource(source, projectRoot, homeDir, platform));
25536
25550
  }
25537
25551
  return issues;
25538
25552
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/ctxlint",
3
- "version": "0.18.4",
3
+ "version": "0.18.5",
4
4
  "mcpName": "io.github.YawLabs/ctxlint",
5
5
  "description": "Lint your AI agent context files, MCP server configs, and session data against your actual codebase",
6
6
  "bin": {