deep-slop 1.4.1 → 1.6.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.
@@ -1,4 +1,4 @@
1
- import { _ as parseFile, d as initParser, n as extractImportFromNode, o as findNodesOfTypes, y as walkAST } from "./tree-sitter-CM-cP0nl.js";
1
+ import { b as walkAST, f as initParser, r as extractImportFromNode, s as findNodesOfTypes, v as parseFile } from "./tree-sitter-CBpekmYc.js";
2
2
  import { t as collectFiles } from "./discover-B_S_Fy2S.js";
3
3
  import { i as toLines, n as extractImports, r as readFileContent } from "./file-utils-B_HFXhCs.js";
4
4
  import { basename, dirname, join, relative, resolve } from "node:path";
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { t as clearParseCache } from "./tree-sitter-CBpekmYc.js";
1
2
  import { n as detectFrameworks, r as detectLanguages, t as collectFiles } from "./discover-B_S_Fy2S.js";
2
3
  import { performance } from "node:perf_hooks";
3
4
  import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
@@ -863,9 +864,9 @@ const EXT_TO_LANG = {
863
864
  };
864
865
  /** Registry of all 18 engines (loaded lazily) */
865
866
  const ENGINE_REGISTRY = {
866
- "ast-slop": () => import("./ast-slop-BGdr58wZ.js").then((m) => m.astSlopEngine),
867
- "import-intelligence": () => import("./import-intelligence-SK4F7XpL.js").then((m) => m.importIntelligenceEngine),
868
- "dead-flow": () => import("./dead-flow-DHRkyxZT.js").then((m) => m.deadFlowEngine),
867
+ "ast-slop": () => import("./ast-slop-B6Y39w1U.js").then((m) => m.astSlopEngine),
868
+ "import-intelligence": () => import("./import-intelligence-B7R90PWJ.js").then((m) => m.importIntelligenceEngine),
869
+ "dead-flow": () => import("./dead-flow-BgowgQ-_.js").then((m) => m.deadFlowEngine),
869
870
  "type-safety": () => import("./type-safety-Dboj2C1t.js").then((m) => m.typeSafetyEngine),
870
871
  "syntax-deep": () => import("./syntax-deep-ZQYMutky.js").then((m) => m.syntaxDeepEngine),
871
872
  "security-deep": () => import("./security-deep-DJRINs10.js").then((m) => m.securityDeepEngine),
@@ -886,6 +887,7 @@ const ENGINE_REGISTRY = {
886
887
  async function runScan(context, callbacks) {
887
888
  const startTotal = performance.now();
888
889
  clearFileCache();
890
+ clearParseCache();
889
891
  if (context.files?.length) await preloadFiles(context.files);
890
892
  const pluginEngines = await discoverAndLoadPlugins(context.rootDirectory);
891
893
  const enabledEngines = Object.entries(ENGINE_REGISTRY).filter(([name]) => context.config.engines[name] !== false);
package/dist/mcp.js CHANGED
@@ -6904,93 +6904,10 @@ var require_dist = __commonJS({
6904
6904
  }
6905
6905
  });
6906
6906
 
6907
- // src/utils/file-utils.ts
6908
- import { readFile as readFile2 } from "node:fs/promises";
6909
- async function readFileContent(filePath) {
6910
- const buffer = await readFile2(filePath);
6911
- let content = buffer.toString("utf-8");
6912
- if (content.charCodeAt(0) === 65279) {
6913
- content = content.slice(1);
6914
- }
6915
- return content;
6916
- }
6917
- function detectEncodingAnomalies(content) {
6918
- const hasBom = content.charCodeAt(0) === 65279;
6919
- const hasCrlf = content.includes("\r\n");
6920
- const hasZwnbsp = content.includes("\uFEFF");
6921
- const lfOnly = (content.match(/(?<!\r)\n/g) ?? []).length;
6922
- const crlfCount = (content.match(/\r\n/g) ?? []).length;
6923
- const lineEnding = crlfCount > 0 && lfOnly > crlfCount ? "mixed" : crlfCount > 0 ? "crlf" : "lf";
6924
- return { hasBom, hasCrlf, hasZwnbsp, lineEnding };
6925
- }
6926
- function toLines(content) {
6927
- return content.split("\n").map((text, i) => ({ num: i + 1, text }));
6928
- }
6929
- function extractImports(content, language) {
6930
- const imports = [];
6931
- const lines = toLines(content);
6932
- for (const { num, text } of lines) {
6933
- const trimmed = text.trim();
6934
- if (language === "typescript" || language === "javascript") {
6935
- const jsMatch = trimmed.match(
6936
- /^import\s+(?:type\s+)?(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/
6937
- );
6938
- if (jsMatch) {
6939
- imports.push({
6940
- line: num,
6941
- source: jsMatch[1],
6942
- raw: trimmed,
6943
- isTypeOnly: trimmed.includes("import type"),
6944
- isDefault: !trimmed.includes("{")
6945
- });
6946
- }
6947
- const dynMatch = trimmed.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/);
6948
- if (dynMatch) {
6949
- imports.push({
6950
- line: num,
6951
- source: dynMatch[1],
6952
- raw: trimmed,
6953
- isTypeOnly: false,
6954
- isDynamic: true
6955
- });
6956
- }
6957
- const reqMatch = trimmed.match(/(?:const|let|var)\s+[^=]*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/);
6958
- if (reqMatch) {
6959
- imports.push({
6960
- line: num,
6961
- source: reqMatch[1],
6962
- raw: trimmed,
6963
- isTypeOnly: false,
6964
- isRequire: true
6965
- });
6966
- }
6967
- }
6968
- if (language === "python") {
6969
- const pyMatch = trimmed.match(/^from\s+([^\s]+)\s+import/);
6970
- if (pyMatch) {
6971
- imports.push({ line: num, source: pyMatch[1], raw: trimmed, isTypeOnly: false });
6972
- }
6973
- const pyImport = trimmed.match(/^import\s+([^\s]+)/);
6974
- if (pyImport) {
6975
- imports.push({ line: num, source: pyImport[1], raw: trimmed, isTypeOnly: false });
6976
- }
6977
- }
6978
- if (language === "go") {
6979
- const goMatch = trimmed.match(/"([^"]+)"/);
6980
- if (trimmed.startsWith("import") && goMatch) {
6981
- imports.push({ line: num, source: goMatch[1], raw: trimmed, isTypeOnly: false });
6982
- }
6983
- }
6984
- }
6985
- return imports;
6986
- }
6987
- var init_file_utils = __esm({
6988
- "src/utils/file-utils.ts"() {
6989
- "use strict";
6990
- }
6991
- });
6992
-
6993
6907
  // src/utils/tree-sitter.ts
6908
+ function clearParseCache() {
6909
+ parseCache.clear();
6910
+ }
6994
6911
  async function initParser() {
6995
6912
  if (initDone) return initOk;
6996
6913
  if (initPromise) return initPromise;
@@ -7182,14 +7099,19 @@ function isPythonAvailable() {
7182
7099
  return pyInitOk && pyLang !== null;
7183
7100
  }
7184
7101
  async function parseFile(content, isTsx = false, filePath) {
7102
+ if (filePath) {
7103
+ const cacheKey = `${filePath}:${isTsx ? "tsx" : "ts"}`;
7104
+ const cached = parseCache.get(cacheKey);
7105
+ if (cached !== void 0) return cached;
7106
+ }
7185
7107
  if (filePath) {
7186
7108
  const ext2 = filePath.toLowerCase();
7187
- if (ext2.endsWith(".go")) return parseGoFile(content);
7188
- if (ext2.endsWith(".rs")) return parseRustFile(content);
7189
- if (ext2.endsWith(".php")) return parsePhpFile(content);
7190
- if (ext2.endsWith(".cs")) return parseCsharpFile(content);
7191
- if (ext2.endsWith(".swift")) return parseSwiftFile(content);
7192
- if (ext2.endsWith(".py")) return parsePython(content);
7109
+ if (ext2.endsWith(".go")) return parseGoFile(content, filePath);
7110
+ if (ext2.endsWith(".rs")) return parseRustFile(content, filePath);
7111
+ if (ext2.endsWith(".php")) return parsePhpFile(content, filePath);
7112
+ if (ext2.endsWith(".cs")) return parseCsharpFile(content, filePath);
7113
+ if (ext2.endsWith(".swift")) return parseSwiftFile(content, filePath);
7114
+ if (ext2.endsWith(".py")) return parsePython(content, filePath);
7193
7115
  }
7194
7116
  if (!parserInstance || !tsLang && !tsxLang) {
7195
7117
  const ok = await initParser();
@@ -7200,12 +7122,21 @@ async function parseFile(content, isTsx = false, filePath) {
7200
7122
  parserInstance.setLanguage(lang);
7201
7123
  const tree = parserInstance.parse(content);
7202
7124
  if (!tree) return null;
7203
- return convertNode(tree.rootNode, null);
7125
+ const result = convertNode(tree.rootNode, null);
7126
+ if (filePath) {
7127
+ parseCache.set(`${filePath}:${isTsx ? "tsx" : "ts"}`, result);
7128
+ }
7129
+ return result;
7204
7130
  } catch {
7131
+ if (filePath) parseCache.set(`${filePath}:${isTsx ? "tsx" : "ts"}`, null);
7205
7132
  return null;
7206
7133
  }
7207
7134
  }
7208
- async function parsePython(content) {
7135
+ async function parsePython(content, filePath) {
7136
+ if (filePath) {
7137
+ const cached = parseCache.get(`py:${filePath}`);
7138
+ if (cached !== void 0) return cached;
7139
+ }
7209
7140
  if (!pyLang) {
7210
7141
  const ok = await initPythonParser();
7211
7142
  if (!ok) return null;
@@ -7217,13 +7148,23 @@ async function parsePython(content) {
7217
7148
  try {
7218
7149
  parserInstance.setLanguage(pyLang);
7219
7150
  const tree = parserInstance.parse(content);
7220
- if (!tree) return null;
7221
- return convertNode(tree.rootNode, null);
7151
+ if (!tree) {
7152
+ if (filePath) parseCache.set(`py:${filePath}`, null);
7153
+ return null;
7154
+ }
7155
+ const result = convertNode(tree.rootNode, null);
7156
+ if (filePath) parseCache.set(`py:${filePath}`, result);
7157
+ return result;
7222
7158
  } catch {
7159
+ if (filePath) parseCache.set(`py:${filePath}`, null);
7223
7160
  return null;
7224
7161
  }
7225
7162
  }
7226
- async function parseGoFile(content) {
7163
+ async function parseGoFile(content, filePath) {
7164
+ if (filePath) {
7165
+ const cached = parseCache.get(`go:${filePath}`);
7166
+ if (cached !== void 0) return cached;
7167
+ }
7227
7168
  if (!goLang) {
7228
7169
  const ok = await initGoParser();
7229
7170
  if (!ok) return null;
@@ -7235,13 +7176,23 @@ async function parseGoFile(content) {
7235
7176
  try {
7236
7177
  parserInstance.setLanguage(goLang);
7237
7178
  const tree = parserInstance.parse(content);
7238
- if (!tree) return null;
7239
- return convertNode(tree.rootNode, null);
7179
+ if (!tree) {
7180
+ if (filePath) parseCache.set(`go:${filePath}`, null);
7181
+ return null;
7182
+ }
7183
+ const result = convertNode(tree.rootNode, null);
7184
+ if (filePath) parseCache.set(`go:${filePath}`, result);
7185
+ return result;
7240
7186
  } catch {
7187
+ if (filePath) parseCache.set(`go:${filePath}`, null);
7241
7188
  return null;
7242
7189
  }
7243
7190
  }
7244
- async function parseRustFile(content) {
7191
+ async function parseRustFile(content, filePath) {
7192
+ if (filePath) {
7193
+ const cached = parseCache.get(`rs:${filePath}`);
7194
+ if (cached !== void 0) return cached;
7195
+ }
7245
7196
  if (!rustLang) {
7246
7197
  const ok = await initRustParser();
7247
7198
  if (!ok) return null;
@@ -7253,13 +7204,23 @@ async function parseRustFile(content) {
7253
7204
  try {
7254
7205
  parserInstance.setLanguage(rustLang);
7255
7206
  const tree = parserInstance.parse(content);
7256
- if (!tree) return null;
7257
- return convertNode(tree.rootNode, null);
7207
+ if (!tree) {
7208
+ if (filePath) parseCache.set(`rs:${filePath}`, null);
7209
+ return null;
7210
+ }
7211
+ const result = convertNode(tree.rootNode, null);
7212
+ if (filePath) parseCache.set(`rs:${filePath}`, result);
7213
+ return result;
7258
7214
  } catch {
7215
+ if (filePath) parseCache.set(`rs:${filePath}`, null);
7259
7216
  return null;
7260
7217
  }
7261
7218
  }
7262
- async function parsePhpFile(content) {
7219
+ async function parsePhpFile(content, filePath) {
7220
+ if (filePath) {
7221
+ const cached = parseCache.get(`php:${filePath}`);
7222
+ if (cached !== void 0) return cached;
7223
+ }
7263
7224
  if (!phpLang) {
7264
7225
  const ok = await initPhpParser();
7265
7226
  if (!ok) return null;
@@ -7271,13 +7232,23 @@ async function parsePhpFile(content) {
7271
7232
  try {
7272
7233
  parserInstance.setLanguage(phpLang);
7273
7234
  const tree = parserInstance.parse(content);
7274
- if (!tree) return null;
7275
- return convertNode(tree.rootNode, null);
7235
+ if (!tree) {
7236
+ if (filePath) parseCache.set(`php:${filePath}`, null);
7237
+ return null;
7238
+ }
7239
+ const result = convertNode(tree.rootNode, null);
7240
+ if (filePath) parseCache.set(`php:${filePath}`, result);
7241
+ return result;
7276
7242
  } catch {
7243
+ if (filePath) parseCache.set(`php:${filePath}`, null);
7277
7244
  return null;
7278
7245
  }
7279
7246
  }
7280
- async function parseCsharpFile(content) {
7247
+ async function parseCsharpFile(content, filePath) {
7248
+ if (filePath) {
7249
+ const cached = parseCache.get(`cs:${filePath}`);
7250
+ if (cached !== void 0) return cached;
7251
+ }
7281
7252
  if (!csharpLang) {
7282
7253
  const ok = await initCsharpParser();
7283
7254
  if (!ok) return null;
@@ -7289,13 +7260,23 @@ async function parseCsharpFile(content) {
7289
7260
  try {
7290
7261
  parserInstance.setLanguage(csharpLang);
7291
7262
  const tree = parserInstance.parse(content);
7292
- if (!tree) return null;
7293
- return convertNode(tree.rootNode, null);
7263
+ if (!tree) {
7264
+ if (filePath) parseCache.set(`cs:${filePath}`, null);
7265
+ return null;
7266
+ }
7267
+ const result = convertNode(tree.rootNode, null);
7268
+ if (filePath) parseCache.set(`cs:${filePath}`, result);
7269
+ return result;
7294
7270
  } catch {
7271
+ if (filePath) parseCache.set(`cs:${filePath}`, null);
7295
7272
  return null;
7296
7273
  }
7297
7274
  }
7298
- async function parseSwiftFile(content) {
7275
+ async function parseSwiftFile(content, filePath) {
7276
+ if (filePath) {
7277
+ const cached = parseCache.get(`swift:${filePath}`);
7278
+ if (cached !== void 0) return cached;
7279
+ }
7299
7280
  if (!swiftLang) {
7300
7281
  const ok = await initSwiftParser();
7301
7282
  if (!ok) return null;
@@ -7307,9 +7288,15 @@ async function parseSwiftFile(content) {
7307
7288
  try {
7308
7289
  parserInstance.setLanguage(swiftLang);
7309
7290
  const tree = parserInstance.parse(content);
7310
- if (!tree) return null;
7311
- return convertNode(tree.rootNode, null);
7291
+ if (!tree) {
7292
+ if (filePath) parseCache.set(`swift:${filePath}`, null);
7293
+ return null;
7294
+ }
7295
+ const result = convertNode(tree.rootNode, null);
7296
+ if (filePath) parseCache.set(`swift:${filePath}`, result);
7297
+ return result;
7312
7298
  } catch {
7299
+ if (filePath) parseCache.set(`swift:${filePath}`, null);
7313
7300
  return null;
7314
7301
  }
7315
7302
  }
@@ -7663,10 +7650,11 @@ function convertNode(node, parent) {
7663
7650
  }
7664
7651
  return astNode;
7665
7652
  }
7666
- var parserInstance, tsLang, tsxLang, initPromise, initDone, initOk, pyLang, pyInitDone, pyInitOk, goLang, goInitDone, goInitOk, rustLang, rustInitDone, rustInitOk, phpLang, phpInitDone, phpInitOk, csharpLang, csharpInitDone, csharpInitOk, swiftLang, swiftInitDone, swiftInitOk;
7653
+ var parseCache, parserInstance, tsLang, tsxLang, initPromise, initDone, initOk, pyLang, pyInitDone, pyInitOk, goLang, goInitDone, goInitOk, rustLang, rustInitDone, rustInitOk, phpLang, phpInitDone, phpInitOk, csharpLang, csharpInitDone, csharpInitOk, swiftLang, swiftInitDone, swiftInitOk;
7667
7654
  var init_tree_sitter = __esm({
7668
7655
  "src/utils/tree-sitter.ts"() {
7669
7656
  "use strict";
7657
+ parseCache = /* @__PURE__ */ new Map();
7670
7658
  parserInstance = null;
7671
7659
  tsLang = null;
7672
7660
  tsxLang = null;
@@ -7694,6 +7682,92 @@ var init_tree_sitter = __esm({
7694
7682
  }
7695
7683
  });
7696
7684
 
7685
+ // src/utils/file-utils.ts
7686
+ import { readFile as readFile2 } from "node:fs/promises";
7687
+ async function readFileContent(filePath) {
7688
+ const buffer = await readFile2(filePath);
7689
+ let content = buffer.toString("utf-8");
7690
+ if (content.charCodeAt(0) === 65279) {
7691
+ content = content.slice(1);
7692
+ }
7693
+ return content;
7694
+ }
7695
+ function detectEncodingAnomalies(content) {
7696
+ const hasBom = content.charCodeAt(0) === 65279;
7697
+ const hasCrlf = content.includes("\r\n");
7698
+ const hasZwnbsp = content.includes("\uFEFF");
7699
+ const lfOnly = (content.match(/(?<!\r)\n/g) ?? []).length;
7700
+ const crlfCount = (content.match(/\r\n/g) ?? []).length;
7701
+ const lineEnding = crlfCount > 0 && lfOnly > crlfCount ? "mixed" : crlfCount > 0 ? "crlf" : "lf";
7702
+ return { hasBom, hasCrlf, hasZwnbsp, lineEnding };
7703
+ }
7704
+ function toLines(content) {
7705
+ return content.split("\n").map((text, i) => ({ num: i + 1, text }));
7706
+ }
7707
+ function extractImports(content, language) {
7708
+ const imports = [];
7709
+ const lines = toLines(content);
7710
+ for (const { num, text } of lines) {
7711
+ const trimmed = text.trim();
7712
+ if (language === "typescript" || language === "javascript") {
7713
+ const jsMatch = trimmed.match(
7714
+ /^import\s+(?:type\s+)?(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/
7715
+ );
7716
+ if (jsMatch) {
7717
+ imports.push({
7718
+ line: num,
7719
+ source: jsMatch[1],
7720
+ raw: trimmed,
7721
+ isTypeOnly: trimmed.includes("import type"),
7722
+ isDefault: !trimmed.includes("{")
7723
+ });
7724
+ }
7725
+ const dynMatch = trimmed.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/);
7726
+ if (dynMatch) {
7727
+ imports.push({
7728
+ line: num,
7729
+ source: dynMatch[1],
7730
+ raw: trimmed,
7731
+ isTypeOnly: false,
7732
+ isDynamic: true
7733
+ });
7734
+ }
7735
+ const reqMatch = trimmed.match(/(?:const|let|var)\s+[^=]*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/);
7736
+ if (reqMatch) {
7737
+ imports.push({
7738
+ line: num,
7739
+ source: reqMatch[1],
7740
+ raw: trimmed,
7741
+ isTypeOnly: false,
7742
+ isRequire: true
7743
+ });
7744
+ }
7745
+ }
7746
+ if (language === "python") {
7747
+ const pyMatch = trimmed.match(/^from\s+([^\s]+)\s+import/);
7748
+ if (pyMatch) {
7749
+ imports.push({ line: num, source: pyMatch[1], raw: trimmed, isTypeOnly: false });
7750
+ }
7751
+ const pyImport = trimmed.match(/^import\s+([^\s]+)/);
7752
+ if (pyImport) {
7753
+ imports.push({ line: num, source: pyImport[1], raw: trimmed, isTypeOnly: false });
7754
+ }
7755
+ }
7756
+ if (language === "go") {
7757
+ const goMatch = trimmed.match(/"([^"]+)"/);
7758
+ if (trimmed.startsWith("import") && goMatch) {
7759
+ imports.push({ line: num, source: goMatch[1], raw: trimmed, isTypeOnly: false });
7760
+ }
7761
+ }
7762
+ }
7763
+ return imports;
7764
+ }
7765
+ var init_file_utils = __esm({
7766
+ "src/utils/file-utils.ts"() {
7767
+ "use strict";
7768
+ }
7769
+ });
7770
+
7697
7771
  // src/engines/ast-slop/index.ts
7698
7772
  var ast_slop_exports = {};
7699
7773
  __export(ast_slop_exports, {
@@ -34231,6 +34305,9 @@ function clearFileCache() {
34231
34305
  cache.clear();
34232
34306
  }
34233
34307
 
34308
+ // src/engines/orchestrator.ts
34309
+ init_tree_sitter();
34310
+
34234
34311
  // src/plugins/loader.ts
34235
34312
  async function loadPlugin(pluginPath) {
34236
34313
  try {
@@ -34608,6 +34685,7 @@ var ENGINE_REGISTRY = {
34608
34685
  async function runScan(context, callbacks) {
34609
34686
  const startTotal = performance3.now();
34610
34687
  clearFileCache();
34688
+ clearParseCache();
34611
34689
  if (context.files?.length) {
34612
34690
  await preloadFiles(context.files);
34613
34691
  }
@@ -34871,7 +34949,7 @@ var ALL_ENGINE_NAMES = [
34871
34949
  ];
34872
34950
 
34873
34951
  // src/version.ts
34874
- var APP_VERSION = "1.4.1";
34952
+ var APP_VERSION = "1.6.0";
34875
34953
 
34876
34954
  // src/output/rule-labels.ts
34877
34955
  var labels = {