deep-slop 1.5.0 → 1.6.1
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/README.md +3 -27
- package/dist/{ast-slop-BGdr58wZ.js → ast-slop-B6Y39w1U.js} +1 -1
- package/dist/{dead-flow-DHRkyxZT.js → dead-flow-BgowgQ-_.js} +1 -1
- package/dist/deep-slop-bundled.js +27445 -12288
- package/dist/{import-intelligence-SK4F7XpL.js → import-intelligence-B7R90PWJ.js} +1 -1
- package/dist/index.js +5 -3
- package/dist/mcp.js +19772 -1273
- package/dist/{tree-sitter-CM-cP0nl.js → tree-sitter-CBpekmYc.js} +99 -26
- package/package.json +3 -3
|
@@ -5,6 +5,11 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
5
5
|
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/utils/tree-sitter.ts
|
|
8
|
+
const parseCache = /* @__PURE__ */ new Map();
|
|
9
|
+
/** Clear the AST parse cache. Call at the start of each scan run. */
|
|
10
|
+
function clearParseCache() {
|
|
11
|
+
parseCache.clear();
|
|
12
|
+
}
|
|
8
13
|
let parserInstance = null;
|
|
9
14
|
let tsLang = null;
|
|
10
15
|
let tsxLang = null;
|
|
@@ -232,14 +237,19 @@ function isPythonAvailable() {
|
|
|
232
237
|
* When omitted, parses as TypeScript (or TSX when `isTsx` is true).
|
|
233
238
|
*/
|
|
234
239
|
async function parseFile(content, isTsx = false, filePath) {
|
|
240
|
+
if (filePath) {
|
|
241
|
+
const cacheKey = `${filePath}:${isTsx ? "tsx" : "ts"}`;
|
|
242
|
+
const cached = parseCache.get(cacheKey);
|
|
243
|
+
if (cached !== void 0) return cached;
|
|
244
|
+
}
|
|
235
245
|
if (filePath) {
|
|
236
246
|
const ext = filePath.toLowerCase();
|
|
237
|
-
if (ext.endsWith(".go")) return parseGoFile(content);
|
|
238
|
-
if (ext.endsWith(".rs")) return parseRustFile(content);
|
|
239
|
-
if (ext.endsWith(".php")) return parsePhpFile(content);
|
|
240
|
-
if (ext.endsWith(".cs")) return parseCsharpFile(content);
|
|
241
|
-
if (ext.endsWith(".swift")) return parseSwiftFile(content);
|
|
242
|
-
if (ext.endsWith(".py")) return parsePython(content);
|
|
247
|
+
if (ext.endsWith(".go")) return parseGoFile(content, filePath);
|
|
248
|
+
if (ext.endsWith(".rs")) return parseRustFile(content, filePath);
|
|
249
|
+
if (ext.endsWith(".php")) return parsePhpFile(content, filePath);
|
|
250
|
+
if (ext.endsWith(".cs")) return parseCsharpFile(content, filePath);
|
|
251
|
+
if (ext.endsWith(".swift")) return parseSwiftFile(content, filePath);
|
|
252
|
+
if (ext.endsWith(".py")) return parsePython(content, filePath);
|
|
243
253
|
}
|
|
244
254
|
if (!parserInstance || !tsLang && !tsxLang) {
|
|
245
255
|
if (!await initParser()) return null;
|
|
@@ -249,8 +259,11 @@ async function parseFile(content, isTsx = false, filePath) {
|
|
|
249
259
|
parserInstance.setLanguage(lang);
|
|
250
260
|
const tree = parserInstance.parse(content);
|
|
251
261
|
if (!tree) return null;
|
|
252
|
-
|
|
262
|
+
const result = convertNode(tree.rootNode, null);
|
|
263
|
+
if (filePath) parseCache.set(`${filePath}:${isTsx ? "tsx" : "ts"}`, result);
|
|
264
|
+
return result;
|
|
253
265
|
} catch {
|
|
266
|
+
if (filePath) parseCache.set(`${filePath}:${isTsx ? "tsx" : "ts"}`, null);
|
|
254
267
|
return null;
|
|
255
268
|
}
|
|
256
269
|
}
|
|
@@ -258,7 +271,11 @@ async function parseFile(content, isTsx = false, filePath) {
|
|
|
258
271
|
* Parse Python source content into an AST tree.
|
|
259
272
|
* Returns null if tree-sitter-python is not available or parsing fails.
|
|
260
273
|
*/
|
|
261
|
-
async function parsePython(content) {
|
|
274
|
+
async function parsePython(content, filePath) {
|
|
275
|
+
if (filePath) {
|
|
276
|
+
const cached = parseCache.get(`py:${filePath}`);
|
|
277
|
+
if (cached !== void 0) return cached;
|
|
278
|
+
}
|
|
262
279
|
if (!pyLang) {
|
|
263
280
|
if (!await initPythonParser()) return null;
|
|
264
281
|
}
|
|
@@ -268,9 +285,15 @@ async function parsePython(content) {
|
|
|
268
285
|
try {
|
|
269
286
|
parserInstance.setLanguage(pyLang);
|
|
270
287
|
const tree = parserInstance.parse(content);
|
|
271
|
-
if (!tree)
|
|
272
|
-
|
|
288
|
+
if (!tree) {
|
|
289
|
+
if (filePath) parseCache.set(`py:${filePath}`, null);
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
const result = convertNode(tree.rootNode, null);
|
|
293
|
+
if (filePath) parseCache.set(`py:${filePath}`, result);
|
|
294
|
+
return result;
|
|
273
295
|
} catch {
|
|
296
|
+
if (filePath) parseCache.set(`py:${filePath}`, null);
|
|
274
297
|
return null;
|
|
275
298
|
}
|
|
276
299
|
}
|
|
@@ -278,7 +301,11 @@ async function parsePython(content) {
|
|
|
278
301
|
* Parse Go source content into an AST tree.
|
|
279
302
|
* Returns null if tree-sitter-go is not available or parsing fails.
|
|
280
303
|
*/
|
|
281
|
-
async function parseGoFile(content) {
|
|
304
|
+
async function parseGoFile(content, filePath) {
|
|
305
|
+
if (filePath) {
|
|
306
|
+
const cached = parseCache.get(`go:${filePath}`);
|
|
307
|
+
if (cached !== void 0) return cached;
|
|
308
|
+
}
|
|
282
309
|
if (!goLang) {
|
|
283
310
|
if (!await initGoParser()) return null;
|
|
284
311
|
}
|
|
@@ -288,9 +315,15 @@ async function parseGoFile(content) {
|
|
|
288
315
|
try {
|
|
289
316
|
parserInstance.setLanguage(goLang);
|
|
290
317
|
const tree = parserInstance.parse(content);
|
|
291
|
-
if (!tree)
|
|
292
|
-
|
|
318
|
+
if (!tree) {
|
|
319
|
+
if (filePath) parseCache.set(`go:${filePath}`, null);
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
const result = convertNode(tree.rootNode, null);
|
|
323
|
+
if (filePath) parseCache.set(`go:${filePath}`, result);
|
|
324
|
+
return result;
|
|
293
325
|
} catch {
|
|
326
|
+
if (filePath) parseCache.set(`go:${filePath}`, null);
|
|
294
327
|
return null;
|
|
295
328
|
}
|
|
296
329
|
}
|
|
@@ -298,7 +331,11 @@ async function parseGoFile(content) {
|
|
|
298
331
|
* Parse Rust source content into an AST tree.
|
|
299
332
|
* Returns null if tree-sitter-rust is not available or parsing fails.
|
|
300
333
|
*/
|
|
301
|
-
async function parseRustFile(content) {
|
|
334
|
+
async function parseRustFile(content, filePath) {
|
|
335
|
+
if (filePath) {
|
|
336
|
+
const cached = parseCache.get(`rs:${filePath}`);
|
|
337
|
+
if (cached !== void 0) return cached;
|
|
338
|
+
}
|
|
302
339
|
if (!rustLang) {
|
|
303
340
|
if (!await initRustParser()) return null;
|
|
304
341
|
}
|
|
@@ -308,9 +345,15 @@ async function parseRustFile(content) {
|
|
|
308
345
|
try {
|
|
309
346
|
parserInstance.setLanguage(rustLang);
|
|
310
347
|
const tree = parserInstance.parse(content);
|
|
311
|
-
if (!tree)
|
|
312
|
-
|
|
348
|
+
if (!tree) {
|
|
349
|
+
if (filePath) parseCache.set(`rs:${filePath}`, null);
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
const result = convertNode(tree.rootNode, null);
|
|
353
|
+
if (filePath) parseCache.set(`rs:${filePath}`, result);
|
|
354
|
+
return result;
|
|
313
355
|
} catch {
|
|
356
|
+
if (filePath) parseCache.set(`rs:${filePath}`, null);
|
|
314
357
|
return null;
|
|
315
358
|
}
|
|
316
359
|
}
|
|
@@ -318,7 +361,11 @@ async function parseRustFile(content) {
|
|
|
318
361
|
* Parse PHP source content into an AST tree.
|
|
319
362
|
* Returns null if tree-sitter-php is not available or parsing fails.
|
|
320
363
|
*/
|
|
321
|
-
async function parsePhpFile(content) {
|
|
364
|
+
async function parsePhpFile(content, filePath) {
|
|
365
|
+
if (filePath) {
|
|
366
|
+
const cached = parseCache.get(`php:${filePath}`);
|
|
367
|
+
if (cached !== void 0) return cached;
|
|
368
|
+
}
|
|
322
369
|
if (!phpLang) {
|
|
323
370
|
if (!await initPhpParser()) return null;
|
|
324
371
|
}
|
|
@@ -328,9 +375,15 @@ async function parsePhpFile(content) {
|
|
|
328
375
|
try {
|
|
329
376
|
parserInstance.setLanguage(phpLang);
|
|
330
377
|
const tree = parserInstance.parse(content);
|
|
331
|
-
if (!tree)
|
|
332
|
-
|
|
378
|
+
if (!tree) {
|
|
379
|
+
if (filePath) parseCache.set(`php:${filePath}`, null);
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
const result = convertNode(tree.rootNode, null);
|
|
383
|
+
if (filePath) parseCache.set(`php:${filePath}`, result);
|
|
384
|
+
return result;
|
|
333
385
|
} catch {
|
|
386
|
+
if (filePath) parseCache.set(`php:${filePath}`, null);
|
|
334
387
|
return null;
|
|
335
388
|
}
|
|
336
389
|
}
|
|
@@ -338,7 +391,11 @@ async function parsePhpFile(content) {
|
|
|
338
391
|
* Parse C# source content into an AST tree.
|
|
339
392
|
* Returns null if tree-sitter-c-sharp is not available or parsing fails.
|
|
340
393
|
*/
|
|
341
|
-
async function parseCsharpFile(content) {
|
|
394
|
+
async function parseCsharpFile(content, filePath) {
|
|
395
|
+
if (filePath) {
|
|
396
|
+
const cached = parseCache.get(`cs:${filePath}`);
|
|
397
|
+
if (cached !== void 0) return cached;
|
|
398
|
+
}
|
|
342
399
|
if (!csharpLang) {
|
|
343
400
|
if (!await initCsharpParser()) return null;
|
|
344
401
|
}
|
|
@@ -348,9 +405,15 @@ async function parseCsharpFile(content) {
|
|
|
348
405
|
try {
|
|
349
406
|
parserInstance.setLanguage(csharpLang);
|
|
350
407
|
const tree = parserInstance.parse(content);
|
|
351
|
-
if (!tree)
|
|
352
|
-
|
|
408
|
+
if (!tree) {
|
|
409
|
+
if (filePath) parseCache.set(`cs:${filePath}`, null);
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
const result = convertNode(tree.rootNode, null);
|
|
413
|
+
if (filePath) parseCache.set(`cs:${filePath}`, result);
|
|
414
|
+
return result;
|
|
353
415
|
} catch {
|
|
416
|
+
if (filePath) parseCache.set(`cs:${filePath}`, null);
|
|
354
417
|
return null;
|
|
355
418
|
}
|
|
356
419
|
}
|
|
@@ -358,7 +421,11 @@ async function parseCsharpFile(content) {
|
|
|
358
421
|
* Parse Swift source content into an AST tree.
|
|
359
422
|
* Returns null if tree-sitter-swift is not available or parsing fails.
|
|
360
423
|
*/
|
|
361
|
-
async function parseSwiftFile(content) {
|
|
424
|
+
async function parseSwiftFile(content, filePath) {
|
|
425
|
+
if (filePath) {
|
|
426
|
+
const cached = parseCache.get(`swift:${filePath}`);
|
|
427
|
+
if (cached !== void 0) return cached;
|
|
428
|
+
}
|
|
362
429
|
if (!swiftLang) {
|
|
363
430
|
if (!await initSwiftParser()) return null;
|
|
364
431
|
}
|
|
@@ -368,9 +435,15 @@ async function parseSwiftFile(content) {
|
|
|
368
435
|
try {
|
|
369
436
|
parserInstance.setLanguage(swiftLang);
|
|
370
437
|
const tree = parserInstance.parse(content);
|
|
371
|
-
if (!tree)
|
|
372
|
-
|
|
438
|
+
if (!tree) {
|
|
439
|
+
if (filePath) parseCache.set(`swift:${filePath}`, null);
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
442
|
+
const result = convertNode(tree.rootNode, null);
|
|
443
|
+
if (filePath) parseCache.set(`swift:${filePath}`, result);
|
|
444
|
+
return result;
|
|
373
445
|
} catch {
|
|
446
|
+
if (filePath) parseCache.set(`swift:${filePath}`, null);
|
|
374
447
|
return null;
|
|
375
448
|
}
|
|
376
449
|
}
|
|
@@ -658,4 +731,4 @@ function convertNode(node, parent) {
|
|
|
658
731
|
}
|
|
659
732
|
|
|
660
733
|
//#endregion
|
|
661
|
-
export {
|
|
734
|
+
export { isPythonAvailable as _, findAncestorOfType as a, walkAST as b, findPythonClasses as c, getAsExpressionType as d, initParser as f, isInsideCatch as g, isCatchBodyEmpty as h, findAncestor as i, findPythonImports as l, isAvailable as m, detectPythonAIPatterns as n, findNodesOfType as o, initPythonParser as p, extractImportFromNode as r, findNodesOfTypes as s, clearParseCache as t, getAsExpressionContext as u, parseFile as v, parsePython as y };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deep-slop",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Deep AI slop detection with AST
|
|
3
|
+
"version": "1.6.1",
|
|
4
|
+
"description": "Deep AI slop detection with 18 AST-powered engines, 181+ rules, density-aware scoring, SARIF 2.1.0 output, MCP server, and auto-fix pipeline.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"deep-slop": "./dist/deep-slop-bundled.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"dev": "tsdown --watch",
|
|
29
|
-
"build": "rm -rf dist && NODE_ENV=production tsdown && npx esbuild src/cli.ts --bundle --platform=node --format=esm --outfile=dist/deep-slop-bundled.js --external:web-tree-sitter --external:tree-sitter-typescript --external:tree-sitter-python --external:tree-sitter-go --external:tree-sitter-rust --external:tree-sitter-php --external:tree-sitter-c-sharp --external:tree-sitter-swift --
|
|
29
|
+
"build": "rm -rf dist && NODE_ENV=production tsdown && npx esbuild src/cli.ts --bundle --platform=node --format=esm --outfile=dist/deep-slop-bundled.js --external:web-tree-sitter --external:tree-sitter-typescript --external:tree-sitter-python --external:tree-sitter-go --external:tree-sitter-rust --external:tree-sitter-php --external:tree-sitter-c-sharp --external:tree-sitter-swift --banner:js=\"import{createRequire}from\\\"node:module\\\";const require=createRequire(import.meta.url);\" && npx esbuild src/mcp.ts --bundle --platform=node --format=esm --outfile=dist/mcp.js --external:web-tree-sitter --external:tree-sitter-typescript --external:tree-sitter-python --external:tree-sitter-go --external:tree-sitter-rust --external:tree-sitter-php --external:tree-sitter-c-sharp --external:tree-sitter-swift --banner:js=\"import{createRequire}from\\\"node:module\\\";const require=createRequire(import.meta.url);\"",
|
|
30
30
|
"typecheck": "tsc --noEmit",
|
|
31
31
|
"test": "vitest run",
|
|
32
32
|
"scan": "pnpm build && node dist/deep-slop-bundled.js scan .",
|