@wrongstack/plugins 0.287.0 → 0.289.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.
Files changed (40) hide show
  1. package/dist/accessibility-auditor/index.d.ts.map +1 -1
  2. package/dist/accessibility-auditor.js +45 -42
  3. package/dist/auto-i18n-extractor.js +1 -1
  4. package/dist/code-metrics/index.d.ts.map +1 -1
  5. package/dist/code-metrics.js +46 -42
  6. package/dist/cost-tracker/index.d.ts.map +1 -1
  7. package/dist/cost-tracker.js +4 -2
  8. package/dist/dead-code-detector.js +3 -3
  9. package/dist/diff-summary.js +1 -1
  10. package/dist/doc-sync-guard.js +3 -3
  11. package/dist/duplicate-code-detector/index.d.ts.map +1 -1
  12. package/dist/duplicate-code-detector.js +47 -43
  13. package/dist/feature-flag-tracker/index.d.ts.map +1 -1
  14. package/dist/feature-flag-tracker.js +46 -42
  15. package/dist/file-watcher/index.d.ts.map +1 -1
  16. package/dist/file-watcher.js +6 -2
  17. package/dist/format-on-save.js +1 -1
  18. package/dist/import-organizer.js +1 -1
  19. package/dist/index.js +396 -539
  20. package/dist/interface-contract-guard/index.d.ts.map +1 -1
  21. package/dist/interface-contract-guard.js +46 -42
  22. package/dist/lint-gate/index.d.ts.map +1 -1
  23. package/dist/lint-gate.js +61 -30
  24. package/dist/migration-planner.js +1 -1
  25. package/dist/prompt-firewall/index.d.ts +14 -6
  26. package/dist/prompt-firewall/index.d.ts.map +1 -1
  27. package/dist/prompt-firewall.js +7 -6
  28. package/dist/refactor-suggester/index.d.ts.map +1 -1
  29. package/dist/refactor-suggester.js +46 -42
  30. package/dist/runtime/index.d.ts +24 -0
  31. package/dist/runtime/index.d.ts.map +1 -1
  32. package/dist/runtime.js +63 -24
  33. package/dist/schema-evolution-guard.js +1 -1
  34. package/dist/secret-scanner/index.d.ts.map +1 -1
  35. package/dist/secret-scanner.js +17 -6
  36. package/dist/security-hotspot-scanner.js +1 -1
  37. package/dist/spec-linker.js +396 -539
  38. package/dist/test-runner-gate.js +1 -1
  39. package/dist/type-gate.js +19 -23
  40. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/accessibility-auditor/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS/C,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,qBAAqB,GACrB,0BAA0B,GAC1B,qBAAqB,GACrB,cAAc,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AA+RD,QAAA,MAAM,MAAM,EAAE,MA0Nb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/accessibility-auditor/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS/C,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,qBAAqB,GACrB,0BAA0B,GAC1B,qBAAqB,GACrB,cAAc,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAoPD,QAAA,MAAM,MAAM,EAAE,MA0Nb,CAAC;eAEa,MAAM"}
@@ -1,9 +1,10 @@
1
1
  // src/accessibility-auditor/index.ts
2
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
2
+ import { readFileSync } from "node:fs";
3
3
  import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
4
4
 
5
5
  // src/runtime/index.ts
6
- import { basename, isAbsolute, relative, resolve } from "node:path";
6
+ import { existsSync, readdirSync, statSync } from "node:fs";
7
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
8
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
8
9
  function hasLeadingDash(arg) {
9
10
  return arg.length > 0 && arg.startsWith("-");
@@ -18,6 +19,47 @@ function withinProjectPath(projectRoot, candidate) {
18
19
  function withinProject(p) {
19
20
  return withinProjectPath(process.cwd(), p) || relative(process.cwd(), p) === ".";
20
21
  }
22
+ var DEFAULT_EXCLUDE_DIRS = ["node_modules", "dist", ".git", "coverage"];
23
+ function collectSourceFiles(root, opts) {
24
+ const files = [];
25
+ if (!existsSync(root)) return files;
26
+ const s = statSync(root);
27
+ if (s.isFile()) {
28
+ if (matchesExtension(root, opts.extensions)) files.push(root);
29
+ return files;
30
+ }
31
+ if (!s.isDirectory()) return files;
32
+ const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
33
+ function walk(dir, depth) {
34
+ if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
35
+ let entries;
36
+ try {
37
+ entries = readdirSync(dir);
38
+ } catch {
39
+ return;
40
+ }
41
+ for (const entry of entries) {
42
+ if (exclude.includes(entry)) continue;
43
+ const full = resolve(dir, entry);
44
+ let st;
45
+ try {
46
+ st = statSync(full);
47
+ } catch {
48
+ continue;
49
+ }
50
+ if (st.isDirectory()) {
51
+ walk(full, depth + 1);
52
+ } else if (st.isFile() && matchesExtension(full, opts.extensions)) {
53
+ files.push(full);
54
+ }
55
+ }
56
+ }
57
+ walk(root, 0);
58
+ return files;
59
+ }
60
+ function matchesExtension(p, exts) {
61
+ return exts.includes(extname(p).toLowerCase());
62
+ }
21
63
 
22
64
  // src/accessibility-auditor/index.ts
23
65
  var API_VERSION = "^0.1.10";
@@ -50,45 +92,6 @@ function readConfig(raw) {
50
92
  function normalizeExtensions(exts) {
51
93
  return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
52
94
  }
53
- function matchesExtension(p, exts) {
54
- const dot = p.lastIndexOf(".");
55
- if (dot === -1) return false;
56
- return exts.includes(p.slice(dot).toLowerCase());
57
- }
58
- function collectUiFiles(root, exts) {
59
- const files = [];
60
- if (!existsSync(root)) return files;
61
- const s = statSync(root);
62
- if (s.isFile()) {
63
- if (matchesExtension(root, exts)) files.push(root);
64
- return files;
65
- }
66
- if (!s.isDirectory()) return files;
67
- function walk(dir) {
68
- let entries;
69
- try {
70
- entries = readdirSync(dir);
71
- } catch {
72
- return;
73
- }
74
- for (const entry of entries) {
75
- const full = resolve2(dir, entry);
76
- let st;
77
- try {
78
- st = statSync(full);
79
- } catch {
80
- continue;
81
- }
82
- if (st.isDirectory()) {
83
- walk(full);
84
- } else if (st.isFile() && matchesExtension(full, exts)) {
85
- files.push(full);
86
- }
87
- }
88
- }
89
- walk(root);
90
- return files;
91
- }
92
95
  var TAG_IMG = /<img\b[^>]*>/gi;
93
96
  var TAG_INPUT = /<input\b[^>]*\/?>/gi;
94
97
  var TAG_BUTTON = /<button\b[^>]*>([\s\S]*?)<\/button>/gi;
@@ -199,7 +202,7 @@ function auditPath(rawPath, cfg) {
199
202
  const root = process.cwd();
200
203
  const resolved = isAbsolute2(rawPath) ? resolve2(rawPath) : resolve2(root, rawPath);
201
204
  const exts = normalizeExtensions(cfg.includeExtensions);
202
- const files = collectUiFiles(resolved, exts);
205
+ const files = collectSourceFiles(resolved, { extensions: exts });
203
206
  const findings = [];
204
207
  for (const file of files) {
205
208
  const fileFindings = auditFile(file, root);
@@ -2,7 +2,7 @@
2
2
  import { readFileSync } from "node:fs";
3
3
 
4
4
  // src/runtime/index.ts
5
- import { basename, isAbsolute, relative, resolve } from "node:path";
5
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
6
6
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
7
7
  function hasLeadingDash(arg) {
8
8
  return arg.length > 0 && arg.startsWith("-");
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code-metrics/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAoP/C,QAAA,MAAM,MAAM,EAAE,MAgMb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code-metrics/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AA0M/C,QAAA,MAAM,MAAM,EAAE,MAgMb,CAAC;eAEa,MAAM"}
@@ -1,9 +1,10 @@
1
1
  // src/code-metrics/index.ts
2
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
3
- import { extname, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
2
+ import { readFileSync } from "node:fs";
3
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
4
4
 
5
5
  // src/runtime/index.ts
6
- import { basename, isAbsolute, relative, resolve } from "node:path";
6
+ import { existsSync, readdirSync, statSync } from "node:fs";
7
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
8
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
8
9
  function hasLeadingDash(arg) {
9
10
  return arg.length > 0 && arg.startsWith("-");
@@ -18,46 +19,19 @@ function withinProjectPath(projectRoot, candidate) {
18
19
  function withinProject(p) {
19
20
  return withinProjectPath(process.cwd(), p) || relative(process.cwd(), p) === ".";
20
21
  }
21
-
22
- // src/code-metrics/index.ts
23
- var API_VERSION = "^0.1.10";
24
- var state = {
25
- measureCount: 0,
26
- fileCount: 0,
27
- hookInvocationCount: 0,
28
- errorCount: 0,
29
- hookUnregister: null
30
- };
31
- var DEFAULTS = {
32
- enabled: false,
33
- extensions: [".ts", ".tsx", ".js", ".jsx"],
34
- maxFiles: 50
35
- };
36
- function readConfig(raw) {
37
- if (!raw || typeof raw !== "object") return { ...DEFAULTS };
38
- const r = raw;
39
- return {
40
- enabled: r["enabled"] !== false,
41
- extensions: Array.isArray(r["extensions"]) ? r["extensions"].filter((x) => typeof x === "string") : DEFAULTS.extensions,
42
- maxFiles: typeof r["maxFiles"] === "number" && r["maxFiles"] >= 1 && r["maxFiles"] <= 500 ? r["maxFiles"] : DEFAULTS.maxFiles
43
- };
44
- }
45
- function normalizeExtensions(exts) {
46
- return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
47
- }
48
- function matchesExtension(p, exts) {
49
- return exts.includes(extname(p).toLowerCase());
50
- }
51
- function collectSourceFiles(root, exts) {
22
+ var DEFAULT_EXCLUDE_DIRS = ["node_modules", "dist", ".git", "coverage"];
23
+ function collectSourceFiles(root, opts) {
52
24
  const files = [];
53
25
  if (!existsSync(root)) return files;
54
26
  const s = statSync(root);
55
27
  if (s.isFile()) {
56
- if (matchesExtension(root, exts)) files.push(root);
28
+ if (matchesExtension(root, opts.extensions)) files.push(root);
57
29
  return files;
58
30
  }
59
31
  if (!s.isDirectory()) return files;
60
- function walk(dir) {
32
+ const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
33
+ function walk(dir, depth) {
34
+ if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
61
35
  let entries;
62
36
  try {
63
37
  entries = readdirSync(dir);
@@ -65,8 +39,8 @@ function collectSourceFiles(root, exts) {
65
39
  return;
66
40
  }
67
41
  for (const entry of entries) {
68
- if (entry === "node_modules" || entry === "dist" || entry === ".git" || entry === "coverage") continue;
69
- const full = resolve2(dir, entry);
42
+ if (exclude.includes(entry)) continue;
43
+ const full = resolve(dir, entry);
70
44
  let st;
71
45
  try {
72
46
  st = statSync(full);
@@ -74,15 +48,45 @@ function collectSourceFiles(root, exts) {
74
48
  continue;
75
49
  }
76
50
  if (st.isDirectory()) {
77
- walk(full);
78
- } else if (st.isFile() && matchesExtension(full, exts)) {
51
+ walk(full, depth + 1);
52
+ } else if (st.isFile() && matchesExtension(full, opts.extensions)) {
79
53
  files.push(full);
80
54
  }
81
55
  }
82
56
  }
83
- walk(root);
57
+ walk(root, 0);
84
58
  return files;
85
59
  }
60
+ function matchesExtension(p, exts) {
61
+ return exts.includes(extname(p).toLowerCase());
62
+ }
63
+
64
+ // src/code-metrics/index.ts
65
+ var API_VERSION = "^0.1.10";
66
+ var state = {
67
+ measureCount: 0,
68
+ fileCount: 0,
69
+ hookInvocationCount: 0,
70
+ errorCount: 0,
71
+ hookUnregister: null
72
+ };
73
+ var DEFAULTS = {
74
+ enabled: false,
75
+ extensions: [".ts", ".tsx", ".js", ".jsx"],
76
+ maxFiles: 50
77
+ };
78
+ function readConfig(raw) {
79
+ if (!raw || typeof raw !== "object") return { ...DEFAULTS };
80
+ const r = raw;
81
+ return {
82
+ enabled: r["enabled"] !== false,
83
+ extensions: Array.isArray(r["extensions"]) ? r["extensions"].filter((x) => typeof x === "string") : DEFAULTS.extensions,
84
+ maxFiles: typeof r["maxFiles"] === "number" && r["maxFiles"] >= 1 && r["maxFiles"] <= 500 ? r["maxFiles"] : DEFAULTS.maxFiles
85
+ };
86
+ }
87
+ function normalizeExtensions(exts) {
88
+ return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
89
+ }
86
90
  function toPosix(p) {
87
91
  return p.replace(/\\/g, "/");
88
92
  }
@@ -166,7 +170,7 @@ function measurePath(rawPath, cfg) {
166
170
  const root = process.cwd();
167
171
  const resolved = isAbsolute2(rawPath) ? resolve2(rawPath) : resolve2(root, rawPath);
168
172
  const exts = normalizeExtensions(cfg.extensions);
169
- const allFiles = collectSourceFiles(resolved, exts);
173
+ const allFiles = collectSourceFiles(resolved, { extensions: exts });
170
174
  const files = allFiles.slice(0, cfg.maxFiles);
171
175
  const metrics = [];
172
176
  for (const p of files) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cost-tracker/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAK/C;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;CAChB;AA8KD,QAAA,MAAM,MAAM,EAAE,MA8Zb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cost-tracker/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAK/C;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;CAChB;AAyKD,QAAA,MAAM,MAAM,EAAE,MA8Zb,CAAC;eAEa,MAAM"}
@@ -19,11 +19,13 @@ var digestCounters = {
19
19
  mailboxDigestErrors: 0
20
20
  };
21
21
  function readCostTrackerConfig(raw) {
22
+ const digestEveryN = raw?.["mailboxDigestEveryN"];
23
+ const digestTo = raw?.["mailboxDigestTo"];
22
24
  return {
23
25
  budgetLimit: typeof raw?.["budgetLimit"] === "number" ? raw["budgetLimit"] : 0,
24
26
  warningThreshold: typeof raw?.["warningThreshold"] === "number" ? raw["warningThreshold"] : 80,
25
- mailboxDigestEveryN: typeof raw?.["mailboxDigestEveryN"] === "number" && raw?.["mailboxDigestEveryN"] >= 0 ? Math.floor(raw?.["mailboxDigestEveryN"]) : 0,
26
- mailboxDigestTo: typeof raw?.["mailboxDigestTo"] === "string" && (raw?.["mailboxDigestTo"]).length > 0 ? raw?.["mailboxDigestTo"] : "cost-tracker"
27
+ mailboxDigestEveryN: typeof digestEveryN === "number" && digestEveryN >= 0 ? Math.floor(digestEveryN) : 0,
28
+ mailboxDigestTo: typeof digestTo === "string" && digestTo.length > 0 ? digestTo : "cost-tracker"
27
29
  };
28
30
  }
29
31
  function estimateCost(model, promptTokens, completionTokens) {
@@ -1,9 +1,9 @@
1
1
  // src/dead-code-detector/index.ts
2
2
  import { readdirSync, readFileSync, statSync } from "node:fs";
3
- import { extname, join, relative as relative2, resolve as resolve2 } from "node:path";
3
+ import { extname as extname2, join, relative as relative2, resolve as resolve2 } from "node:path";
4
4
 
5
5
  // src/runtime/index.ts
6
- import { basename, isAbsolute, relative, resolve } from "node:path";
6
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
7
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
8
8
  function hasLeadingDash(arg) {
9
9
  return arg.length > 0 && arg.startsWith("-");
@@ -63,7 +63,7 @@ function gatherFiles(root, depth, cfg) {
63
63
  walk(join(dir, entry.name), remaining - 1);
64
64
  }
65
65
  } else if (entry.isFile()) {
66
- const ext = extname(entry.name).toLowerCase();
66
+ const ext = extname2(entry.name).toLowerCase();
67
67
  if (cfg.extensions.includes(ext)) {
68
68
  files.push(join(dir, entry.name));
69
69
  }
@@ -2,7 +2,7 @@
2
2
  import { execFileSync } from "node:child_process";
3
3
 
4
4
  // src/runtime/index.ts
5
- import { basename, isAbsolute, relative, resolve } from "node:path";
5
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
6
6
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
7
7
  function hasLeadingDash(arg) {
8
8
  return arg.length > 0 && arg.startsWith("-");
@@ -1,8 +1,8 @@
1
1
  // src/doc-sync-guard/index.ts
2
- import { basename as basename2, extname } from "node:path";
2
+ import { basename as basename2, extname as extname2 } from "node:path";
3
3
 
4
4
  // src/runtime/index.ts
5
- import { basename, isAbsolute, relative, resolve } from "node:path";
5
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
6
6
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
7
7
  function hasLeadingDash(arg) {
8
8
  return arg.length > 0 && arg.startsWith("-");
@@ -47,7 +47,7 @@ function normalizeSlashes(p) {
47
47
  return p.replace(/\\/g, "/");
48
48
  }
49
49
  function isSourceFile(p, extensions) {
50
- const ext = extname(p).toLowerCase();
50
+ const ext = extname2(p).toLowerCase();
51
51
  return extensions.includes(ext);
52
52
  }
53
53
  function isPublicSource(p, extensions) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/duplicate-code-detector/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AA8O/C,QAAA,MAAM,MAAM,EAAE,MA8Qb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/duplicate-code-detector/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAoM/C,QAAA,MAAM,MAAM,EAAE,MA8Qb,CAAC;eAEa,MAAM"}
@@ -1,9 +1,10 @@
1
1
  // src/duplicate-code-detector/index.ts
2
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
3
- import { extname, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
2
+ import { readFileSync } from "node:fs";
3
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
4
4
 
5
5
  // src/runtime/index.ts
6
- import { basename, isAbsolute, relative, resolve } from "node:path";
6
+ import { existsSync, readdirSync, statSync } from "node:fs";
7
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
8
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
8
9
  function hasLeadingDash(arg) {
9
10
  return arg.length > 0 && arg.startsWith("-");
@@ -18,6 +19,47 @@ function withinProjectPath(projectRoot, candidate) {
18
19
  function withinProject(p) {
19
20
  return withinProjectPath(process.cwd(), p) || relative(process.cwd(), p) === ".";
20
21
  }
22
+ var DEFAULT_EXCLUDE_DIRS = ["node_modules", "dist", ".git", "coverage"];
23
+ function collectSourceFiles(root, opts) {
24
+ const files = [];
25
+ if (!existsSync(root)) return files;
26
+ const s = statSync(root);
27
+ if (s.isFile()) {
28
+ if (matchesExtension(root, opts.extensions)) files.push(root);
29
+ return files;
30
+ }
31
+ if (!s.isDirectory()) return files;
32
+ const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
33
+ function walk(dir, depth) {
34
+ if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
35
+ let entries;
36
+ try {
37
+ entries = readdirSync(dir);
38
+ } catch {
39
+ return;
40
+ }
41
+ for (const entry of entries) {
42
+ if (exclude.includes(entry)) continue;
43
+ const full = resolve(dir, entry);
44
+ let st;
45
+ try {
46
+ st = statSync(full);
47
+ } catch {
48
+ continue;
49
+ }
50
+ if (st.isDirectory()) {
51
+ walk(full, depth + 1);
52
+ } else if (st.isFile() && matchesExtension(full, opts.extensions)) {
53
+ files.push(full);
54
+ }
55
+ }
56
+ }
57
+ walk(root, 0);
58
+ return files;
59
+ }
60
+ function matchesExtension(p, exts) {
61
+ return exts.includes(extname(p).toLowerCase());
62
+ }
21
63
 
22
64
  // src/duplicate-code-detector/index.ts
23
65
  var API_VERSION = "^0.1.10";
@@ -50,44 +92,6 @@ function readConfig(raw) {
50
92
  maxFindings: typeof r["maxFindings"] === "number" && r["maxFindings"] >= 1 && r["maxFindings"] <= 500 ? r["maxFindings"] : DEFAULTS.maxFindings
51
93
  };
52
94
  }
53
- function matchesExtension(p, exts) {
54
- const ext = extname(p).toLowerCase();
55
- return exts.includes(ext);
56
- }
57
- function collectSourceFiles(root, cfg) {
58
- const files = [];
59
- if (!existsSync(root)) return files;
60
- const s = statSync(root);
61
- if (s.isFile()) {
62
- if (matchesExtension(root, cfg.extensions)) files.push(root);
63
- return files;
64
- }
65
- if (!s.isDirectory()) return files;
66
- function walk(dir) {
67
- let entries;
68
- try {
69
- entries = readdirSync(dir);
70
- } catch {
71
- return;
72
- }
73
- for (const entry of entries) {
74
- const full = resolve2(dir, entry);
75
- let st;
76
- try {
77
- st = statSync(full);
78
- } catch {
79
- continue;
80
- }
81
- if (st.isDirectory()) {
82
- if (!cfg.excludeDirs.includes(entry)) walk(full);
83
- } else if (st.isFile() && matchesExtension(full, cfg.extensions)) {
84
- files.push(full);
85
- }
86
- }
87
- }
88
- walk(root);
89
- return files;
90
- }
91
95
  function toPosix(p) {
92
96
  return p.replace(/\\/g, "/");
93
97
  }
@@ -151,7 +155,7 @@ function findDuplicates(files, minLines, maxFindings) {
151
155
  function scanPath(rawPath, cfg) {
152
156
  const root = process.cwd();
153
157
  const resolved = isAbsolute2(rawPath) ? resolve2(rawPath) : resolve2(root, rawPath);
154
- const filePaths = collectSourceFiles(resolved, cfg);
158
+ const filePaths = collectSourceFiles(resolved, { extensions: cfg.extensions, excludeDirs: cfg.excludeDirs });
155
159
  const files = /* @__PURE__ */ new Map();
156
160
  for (const p of filePaths) {
157
161
  try {
@@ -248,7 +252,7 @@ var plugin = {
248
252
  const projectRoot = resolve2(process.cwd());
249
253
  let otherFiles;
250
254
  try {
251
- const filePaths = collectSourceFiles(projectRoot, cfg).filter((p) => p !== changedFile);
255
+ const filePaths = collectSourceFiles(projectRoot, { extensions: cfg.extensions, excludeDirs: cfg.excludeDirs }).filter((p) => p !== changedFile);
252
256
  otherFiles = /* @__PURE__ */ new Map();
253
257
  for (const p of filePaths) {
254
258
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/feature-flag-tracker/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS/C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAoLD,QAAA,MAAM,MAAM,EAAE,MA+Mb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/feature-flag-tracker/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS/C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AA0ID,QAAA,MAAM,MAAM,EAAE,MA+Mb,CAAC;eAEa,MAAM"}
@@ -1,9 +1,10 @@
1
1
  // src/feature-flag-tracker/index.ts
2
- import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
3
- import { extname, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
2
+ import { readFileSync } from "node:fs";
3
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
4
4
 
5
5
  // src/runtime/index.ts
6
- import { basename, isAbsolute, relative, resolve } from "node:path";
6
+ import { existsSync, readdirSync, statSync } from "node:fs";
7
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
8
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
8
9
  function hasLeadingDash(arg) {
9
10
  return arg.length > 0 && arg.startsWith("-");
@@ -18,6 +19,47 @@ function withinProjectPath(projectRoot, candidate) {
18
19
  function withinProject(p) {
19
20
  return withinProjectPath(process.cwd(), p) || relative(process.cwd(), p) === ".";
20
21
  }
22
+ var DEFAULT_EXCLUDE_DIRS = ["node_modules", "dist", ".git", "coverage"];
23
+ function collectSourceFiles(root, opts) {
24
+ const files = [];
25
+ if (!existsSync(root)) return files;
26
+ const s = statSync(root);
27
+ if (s.isFile()) {
28
+ if (matchesExtension(root, opts.extensions)) files.push(root);
29
+ return files;
30
+ }
31
+ if (!s.isDirectory()) return files;
32
+ const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
33
+ function walk(dir, depth) {
34
+ if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
35
+ let entries;
36
+ try {
37
+ entries = readdirSync(dir);
38
+ } catch {
39
+ return;
40
+ }
41
+ for (const entry of entries) {
42
+ if (exclude.includes(entry)) continue;
43
+ const full = resolve(dir, entry);
44
+ let st;
45
+ try {
46
+ st = statSync(full);
47
+ } catch {
48
+ continue;
49
+ }
50
+ if (st.isDirectory()) {
51
+ walk(full, depth + 1);
52
+ } else if (st.isFile() && matchesExtension(full, opts.extensions)) {
53
+ files.push(full);
54
+ }
55
+ }
56
+ }
57
+ walk(root, 0);
58
+ return files;
59
+ }
60
+ function matchesExtension(p, exts) {
61
+ return exts.includes(extname(p).toLowerCase());
62
+ }
21
63
 
22
64
  // src/feature-flag-tracker/index.ts
23
65
  var API_VERSION = "^0.1.10";
@@ -54,44 +96,6 @@ function readConfig(raw) {
54
96
  function normalizeExtensions(exts) {
55
97
  return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
56
98
  }
57
- function matchesExtension(p, exts) {
58
- return exts.includes(extname(p).toLowerCase());
59
- }
60
- function collectSourceFiles(root, exts) {
61
- const files = [];
62
- if (!existsSync(root)) return files;
63
- const s = statSync(root);
64
- if (s.isFile()) {
65
- if (matchesExtension(root, exts)) files.push(root);
66
- return files;
67
- }
68
- if (!s.isDirectory()) return files;
69
- function walk(dir) {
70
- let entries;
71
- try {
72
- entries = readdirSync(dir);
73
- } catch {
74
- return;
75
- }
76
- for (const entry of entries) {
77
- if (entry === "node_modules" || entry === "dist" || entry === ".git" || entry === "coverage") continue;
78
- const full = resolve2(dir, entry);
79
- let st;
80
- try {
81
- st = statSync(full);
82
- } catch {
83
- continue;
84
- }
85
- if (st.isDirectory()) {
86
- walk(full);
87
- } else if (st.isFile() && matchesExtension(full, exts)) {
88
- files.push(full);
89
- }
90
- }
91
- }
92
- walk(root);
93
- return files;
94
- }
95
99
  function toPosix(p) {
96
100
  return p.replace(/\\/g, "/");
97
101
  }
@@ -128,7 +132,7 @@ function scanPath(rawPath, cfg) {
128
132
  const root = process.cwd();
129
133
  const resolved = isAbsolute2(rawPath) ? resolve2(rawPath) : resolve2(root, rawPath);
130
134
  const exts = normalizeExtensions(cfg.extensions);
131
- const files = collectSourceFiles(resolved, exts);
135
+ const files = collectSourceFiles(resolved, { extensions: exts });
132
136
  const patterns = compilePatterns(cfg.patterns);
133
137
  const usages = [];
134
138
  for (const p of files) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/file-watcher/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AA2D/C,QAAA,MAAM,MAAM,EAAE,MAqXb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/file-watcher/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AA2D/C,QAAA,MAAM,MAAM,EAAE,MAsYb,CAAC;eAEa,MAAM"}
@@ -1,6 +1,6 @@
1
1
  // src/file-watcher/index.ts
2
2
  import { watch as fsWatch } from "node:fs";
3
- import { isAbsolute, relative, resolve } from "node:path";
3
+ import { isAbsolute, join, relative, resolve } from "node:path";
4
4
  var API_VERSION = "^0.1.10";
5
5
  function withinProject(p) {
6
6
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
@@ -109,7 +109,11 @@ var plugin = {
109
109
  try {
110
110
  const watcher = fsWatch(dirPath, { recursive }, (eventType, filename) => {
111
111
  if (!filename) return;
112
- const fullPath = `${dirPath}/${filename}`;
112
+ if (handle.events.length > 0 && !(eventType === "change" ? handle.events.includes("change") : handle.events.includes("add") || handle.events.includes("delete"))) {
113
+ return;
114
+ }
115
+ const rawPath = filename.startsWith(dirPath) ? filename : join(dirPath, filename);
116
+ const fullPath = rawPath.replace(/\\/g, "/");
113
117
  const key = `${handle.id}:${fullPath}:${eventType}`;
114
118
  debounceEvent(
115
119
  key,
@@ -3,7 +3,7 @@ import { execFileSync, execSync } from "node:child_process";
3
3
  import { existsSync, statSync } from "node:fs";
4
4
 
5
5
  // src/runtime/index.ts
6
- import { basename, isAbsolute, relative, resolve } from "node:path";
6
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
7
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
8
8
  function hasLeadingDash(arg) {
9
9
  return arg.length > 0 && arg.startsWith("-");
@@ -4,7 +4,7 @@ import { existsSync, statSync } from "node:fs";
4
4
  import { basename as basename2, isAbsolute as isAbsolute2 } from "node:path";
5
5
 
6
6
  // src/runtime/index.ts
7
- import { basename, isAbsolute, relative, resolve } from "node:path";
7
+ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
8
8
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
9
9
  function hasLeadingDash(arg) {
10
10
  return arg.length > 0 && arg.startsWith("-");