pi-lens 2.2.9 → 3.0.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 (304) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/README.md +709 -519
  3. package/clients/__tests__/file-time.test.js +216 -0
  4. package/clients/__tests__/file-time.test.ts +276 -0
  5. package/clients/__tests__/format-service.test.js +245 -0
  6. package/clients/__tests__/format-service.test.ts +339 -0
  7. package/clients/__tests__/formatters.test.js +271 -0
  8. package/clients/__tests__/formatters.test.ts +401 -0
  9. package/clients/amain-types.js +164 -0
  10. package/clients/amain-types.ts +165 -0
  11. package/clients/architect-client.js +56 -12
  12. package/clients/architect-client.ts +81 -16
  13. package/clients/ast-grep-client.js +2 -2
  14. package/clients/ast-grep-client.ts +14 -39
  15. package/clients/ast-grep-parser.ts +1 -1
  16. package/clients/ast-grep-rule-manager.js +8 -0
  17. package/clients/ast-grep-rule-manager.ts +10 -1
  18. package/clients/ast-grep-types.js +9 -0
  19. package/clients/ast-grep-types.ts +106 -0
  20. package/clients/auto-loop.js +10 -0
  21. package/clients/auto-loop.ts +14 -1
  22. package/clients/biome-client.js +81 -19
  23. package/clients/biome-client.ts +103 -22
  24. package/clients/bus/bus.js +191 -0
  25. package/clients/bus/bus.ts +251 -0
  26. package/clients/bus/events.js +214 -0
  27. package/clients/bus/events.ts +279 -0
  28. package/clients/bus/index.js +8 -0
  29. package/clients/bus/index.ts +9 -0
  30. package/clients/bus/integration.js +158 -0
  31. package/clients/bus/integration.ts +214 -0
  32. package/clients/complexity-client.js +13 -7
  33. package/clients/complexity-client.ts +13 -7
  34. package/clients/config-validator.js +465 -0
  35. package/clients/config-validator.ts +558 -0
  36. package/clients/dependency-checker.js +4 -10
  37. package/clients/dependency-checker.ts +4 -10
  38. package/clients/dispatch/__tests__/autofix-integration.test.js +245 -0
  39. package/clients/dispatch/__tests__/autofix-integration.test.ts +300 -0
  40. package/clients/dispatch/__tests__/runner-registration.test.js +236 -0
  41. package/clients/dispatch/__tests__/runner-registration.test.ts +282 -0
  42. package/clients/dispatch/bus-dispatcher.js +177 -0
  43. package/clients/dispatch/bus-dispatcher.ts +251 -0
  44. package/clients/dispatch/dispatcher.edge.test.js +82 -0
  45. package/clients/dispatch/dispatcher.edge.test.ts +100 -0
  46. package/clients/dispatch/dispatcher.format.test.js +46 -0
  47. package/clients/dispatch/dispatcher.format.test.ts +58 -0
  48. package/clients/dispatch/dispatcher.inline.test.js +74 -0
  49. package/clients/dispatch/dispatcher.inline.test.ts +93 -0
  50. package/clients/dispatch/dispatcher.js +19 -53
  51. package/clients/dispatch/dispatcher.ts +20 -67
  52. package/clients/dispatch/plan.js +9 -4
  53. package/clients/dispatch/plan.ts +9 -4
  54. package/clients/dispatch/runners/architect.js +21 -7
  55. package/clients/dispatch/runners/architect.test.js +138 -0
  56. package/clients/dispatch/runners/architect.test.ts +162 -0
  57. package/clients/dispatch/runners/architect.ts +22 -7
  58. package/clients/dispatch/runners/ast-grep-napi.js +462 -0
  59. package/clients/dispatch/runners/ast-grep-napi.test.js +111 -0
  60. package/clients/dispatch/runners/ast-grep-napi.test.ts +133 -0
  61. package/clients/dispatch/runners/ast-grep-napi.ts +506 -0
  62. package/clients/dispatch/runners/ast-grep.js +62 -19
  63. package/clients/dispatch/runners/ast-grep.ts +70 -18
  64. package/clients/dispatch/runners/biome.js +29 -53
  65. package/clients/dispatch/runners/biome.ts +29 -63
  66. package/clients/dispatch/runners/config-validation.js +67 -0
  67. package/clients/dispatch/runners/config-validation.ts +82 -0
  68. package/clients/dispatch/runners/go-vet.js +4 -28
  69. package/clients/dispatch/runners/go-vet.ts +4 -32
  70. package/clients/dispatch/runners/index.js +30 -10
  71. package/clients/dispatch/runners/index.ts +30 -10
  72. package/clients/dispatch/runners/oxlint.js +141 -0
  73. package/clients/dispatch/runners/oxlint.test.js +230 -0
  74. package/clients/dispatch/runners/oxlint.test.ts +303 -0
  75. package/clients/dispatch/runners/oxlint.ts +175 -0
  76. package/clients/dispatch/runners/pyright.js +40 -70
  77. package/clients/dispatch/runners/pyright.test.js +16 -2
  78. package/clients/dispatch/runners/pyright.test.ts +14 -2
  79. package/clients/dispatch/runners/pyright.ts +48 -91
  80. package/clients/dispatch/runners/python-slop.js +97 -0
  81. package/clients/dispatch/runners/python-slop.test.js +203 -0
  82. package/clients/dispatch/runners/python-slop.test.ts +298 -0
  83. package/clients/dispatch/runners/python-slop.ts +124 -0
  84. package/clients/dispatch/runners/ruff.js +18 -71
  85. package/clients/dispatch/runners/ruff.ts +19 -79
  86. package/clients/dispatch/runners/rust-clippy.js +28 -32
  87. package/clients/dispatch/runners/rust-clippy.ts +29 -31
  88. package/clients/dispatch/runners/scan_codebase.test.js +89 -0
  89. package/clients/dispatch/runners/scan_codebase.test.ts +105 -0
  90. package/clients/dispatch/runners/shellcheck.js +147 -0
  91. package/clients/dispatch/runners/shellcheck.test.js +98 -0
  92. package/clients/dispatch/runners/shellcheck.test.ts +129 -0
  93. package/clients/dispatch/runners/shellcheck.ts +188 -0
  94. package/clients/dispatch/runners/similarity.js +230 -0
  95. package/clients/dispatch/runners/similarity.ts +339 -0
  96. package/clients/dispatch/runners/spellcheck.js +106 -0
  97. package/clients/dispatch/runners/spellcheck.test.js +158 -0
  98. package/clients/dispatch/runners/spellcheck.test.ts +214 -0
  99. package/clients/dispatch/runners/spellcheck.ts +136 -0
  100. package/clients/dispatch/runners/tree-sitter.js +107 -0
  101. package/clients/dispatch/runners/tree-sitter.ts +135 -0
  102. package/clients/dispatch/runners/ts-lsp.js +104 -33
  103. package/clients/dispatch/runners/ts-lsp.ts +120 -38
  104. package/clients/dispatch/runners/ts-slop.js +113 -0
  105. package/clients/dispatch/runners/ts-slop.test.js +180 -0
  106. package/clients/dispatch/runners/ts-slop.test.ts +230 -0
  107. package/clients/dispatch/runners/ts-slop.ts +142 -0
  108. package/clients/dispatch/runners/utils/diagnostic-parsers.js +134 -0
  109. package/clients/dispatch/runners/utils/diagnostic-parsers.ts +186 -0
  110. package/clients/dispatch/runners/utils/runner-helpers.js +115 -0
  111. package/clients/dispatch/runners/utils/runner-helpers.ts +167 -0
  112. package/clients/dispatch/runners/utils.js +2 -4
  113. package/clients/dispatch/runners/utils.ts +2 -4
  114. package/clients/dispatch/types.ts +1 -1
  115. package/clients/dispatch/utils/format-utils.js +49 -0
  116. package/clients/dispatch/utils/format-utils.ts +60 -0
  117. package/clients/dogfood.test.js +201 -0
  118. package/clients/dogfood.test.ts +269 -0
  119. package/clients/file-time.js +152 -0
  120. package/clients/file-time.ts +208 -0
  121. package/clients/file-utils.js +40 -0
  122. package/clients/file-utils.ts +44 -0
  123. package/clients/fix-scanners.js +10 -20
  124. package/clients/fix-scanners.ts +10 -22
  125. package/clients/format-service.js +172 -0
  126. package/clients/format-service.ts +254 -0
  127. package/clients/formatters.js +435 -0
  128. package/clients/formatters.ts +508 -0
  129. package/clients/go-client.js +5 -14
  130. package/clients/go-client.ts +5 -13
  131. package/clients/installer/index.js +356 -0
  132. package/clients/installer/index.ts +426 -0
  133. package/clients/jscpd-client.js +11 -9
  134. package/clients/jscpd-client.ts +12 -8
  135. package/clients/knip-client.js +3 -7
  136. package/clients/knip-client.ts +3 -6
  137. package/clients/lsp/__tests__/client.test.js +325 -0
  138. package/clients/lsp/__tests__/client.test.ts +434 -0
  139. package/clients/lsp/__tests__/config.test.js +166 -0
  140. package/clients/lsp/__tests__/config.test.ts +209 -0
  141. package/clients/lsp/__tests__/error-recovery.test.js +213 -0
  142. package/clients/lsp/__tests__/error-recovery.test.ts +279 -0
  143. package/clients/lsp/__tests__/integration.test.js +127 -0
  144. package/clients/lsp/__tests__/integration.test.ts +160 -0
  145. package/clients/lsp/__tests__/launch.test.js +260 -0
  146. package/clients/lsp/__tests__/launch.test.ts +329 -0
  147. package/clients/lsp/__tests__/server.test.js +259 -0
  148. package/clients/lsp/__tests__/server.test.ts +332 -0
  149. package/clients/lsp/__tests__/service.test.js +417 -0
  150. package/clients/lsp/__tests__/service.test.ts +499 -0
  151. package/clients/lsp/client.js +235 -0
  152. package/clients/lsp/client.ts +328 -0
  153. package/clients/lsp/config.js +115 -0
  154. package/clients/lsp/config.ts +149 -0
  155. package/clients/lsp/index.js +222 -0
  156. package/clients/lsp/index.ts +280 -0
  157. package/clients/lsp/installer/index.js +391 -0
  158. package/clients/lsp/interactive-install.js +210 -0
  159. package/clients/lsp/interactive-install.ts +251 -0
  160. package/clients/lsp/language.js +170 -0
  161. package/clients/lsp/language.ts +216 -0
  162. package/clients/lsp/launch.js +174 -0
  163. package/clients/lsp/launch.ts +240 -0
  164. package/clients/lsp/lsp/launch.js +116 -0
  165. package/clients/lsp/lsp/server.js +532 -0
  166. package/clients/lsp/lsp-index.js +10 -0
  167. package/clients/lsp/lsp-index.ts +11 -0
  168. package/clients/lsp/path-utils.js +48 -0
  169. package/clients/lsp/path-utils.ts +52 -0
  170. package/clients/lsp/server.js +615 -0
  171. package/clients/lsp/server.ts +800 -0
  172. package/clients/lsp/test-py-spawn/requirements.txt +1 -0
  173. package/clients/lsp/test-py-spawn/test.py +3 -0
  174. package/clients/lsp/test-py-svc/requirements.txt +1 -0
  175. package/clients/lsp/test-py-svc/test.py +3 -0
  176. package/clients/lsp/test-python-project/requirements.txt +1 -0
  177. package/clients/lsp/test-python-project/test.py +5 -0
  178. package/clients/metrics-history.js +2 -2
  179. package/clients/metrics-history.ts +2 -2
  180. package/clients/production-readiness.js +522 -0
  181. package/clients/production-readiness.ts +556 -0
  182. package/clients/project-index.js +255 -0
  183. package/clients/project-index.ts +383 -0
  184. package/clients/project-metadata.js +531 -0
  185. package/clients/project-metadata.ts +624 -0
  186. package/clients/ruff-client.js +56 -16
  187. package/clients/ruff-client.ts +72 -15
  188. package/clients/runner-tracker.js +152 -0
  189. package/clients/runner-tracker.ts +213 -0
  190. package/clients/rust-client.js +4 -11
  191. package/clients/rust-client.ts +5 -11
  192. package/clients/safe-spawn.js +96 -0
  193. package/clients/safe-spawn.ts +128 -0
  194. package/clients/scan-architectural-debt.js +3 -6
  195. package/clients/scan-architectural-debt.ts +3 -6
  196. package/clients/scan-utils.js +5 -20
  197. package/clients/scan-utils.ts +5 -29
  198. package/clients/secrets-scanner.js +3 -17
  199. package/clients/secrets-scanner.ts +4 -20
  200. package/clients/services/__tests__/effect-integration.test.js +86 -0
  201. package/clients/services/__tests__/effect-integration.test.ts +111 -0
  202. package/clients/services/effect-integration.js +194 -0
  203. package/clients/services/effect-integration.ts +268 -0
  204. package/clients/services/index.js +7 -0
  205. package/clients/services/index.ts +8 -0
  206. package/clients/services/runner-service.js +105 -0
  207. package/clients/services/runner-service.ts +179 -0
  208. package/clients/sg-runner.js +87 -13
  209. package/clients/sg-runner.ts +97 -13
  210. package/clients/state-matrix.js +160 -0
  211. package/clients/state-matrix.ts +202 -0
  212. package/clients/subprocess-client.js +10 -9
  213. package/clients/subprocess-client.ts +10 -8
  214. package/clients/test-runner-client.js +3 -7
  215. package/clients/test-runner-client.ts +3 -6
  216. package/clients/tool-availability.js +4 -10
  217. package/clients/tool-availability.ts +4 -9
  218. package/clients/tree-sitter-client.js +564 -0
  219. package/clients/tree-sitter-client.ts +797 -0
  220. package/clients/tree-sitter-query-loader.js +355 -0
  221. package/clients/tree-sitter-query-loader.ts +425 -0
  222. package/clients/type-coverage-client.js +3 -7
  223. package/clients/type-coverage-client.ts +3 -6
  224. package/clients/typescript-client.codefix.test.js +157 -0
  225. package/clients/typescript-client.codefix.test.ts +186 -0
  226. package/clients/typescript-client.js +43 -0
  227. package/clients/typescript-client.ts +98 -0
  228. package/commands/booboo.js +799 -219
  229. package/commands/booboo.ts +1004 -225
  230. package/commands/clients/ast-grep-client.js +250 -0
  231. package/commands/clients/ast-grep-parser.js +86 -0
  232. package/commands/clients/ast-grep-rule-manager.js +91 -0
  233. package/commands/clients/ast-grep-types.js +9 -0
  234. package/commands/clients/biome-client.js +380 -0
  235. package/commands/clients/complexity-client.js +667 -0
  236. package/commands/clients/file-kinds.js +177 -0
  237. package/commands/clients/file-utils.js +40 -0
  238. package/commands/clients/jscpd-client.js +169 -0
  239. package/commands/clients/knip-client.js +211 -0
  240. package/commands/clients/ruff-client.js +297 -0
  241. package/commands/clients/safe-spawn.js +88 -0
  242. package/commands/clients/scan-utils.js +83 -0
  243. package/commands/clients/sg-runner.js +190 -0
  244. package/commands/clients/types.js +11 -0
  245. package/commands/clients/typescript-client.js +505 -0
  246. package/commands/fix-from-booboo.js +398 -0
  247. package/commands/fix-from-booboo.ts +485 -0
  248. package/commands/fix-simplified.js +618 -0
  249. package/commands/fix-simplified.ts +768 -0
  250. package/commands/rate.js +10 -14
  251. package/commands/rate.ts +9 -16
  252. package/default-architect.yaml +59 -15
  253. package/index.ts +342 -429
  254. package/package.json +16 -3
  255. package/rules/ast-grep-rules/rules/empty-catch.yml +38 -13
  256. package/rules/ast-grep-rules/rules/no-array-constructor.yml +1 -0
  257. package/rules/ast-grep-rules/rules/no-debugger.yml +2 -0
  258. package/rules/python-slop-rules/.sgconfig.yml +4 -0
  259. package/rules/python-slop-rules/rules/slop-rules.yml +647 -0
  260. package/rules/tree-sitter-queries/python/bare-except.yml +54 -0
  261. package/rules/tree-sitter-queries/python/eval-exec.yml +50 -0
  262. package/rules/tree-sitter-queries/python/is-vs-equals.yml +60 -0
  263. package/rules/tree-sitter-queries/python/mutable-default-arg.yml +57 -0
  264. package/rules/tree-sitter-queries/python/unreachable-except.yml +60 -0
  265. package/rules/tree-sitter-queries/python/wildcard-import.yml +46 -0
  266. package/rules/tree-sitter-queries/tsx/dangerously-set-inner-html.yml +63 -0
  267. package/rules/tree-sitter-queries/typescript/await-in-loop.yml +56 -0
  268. package/rules/tree-sitter-queries/typescript/console-statement.yml +47 -0
  269. package/rules/tree-sitter-queries/typescript/debugger.yml +47 -0
  270. package/rules/tree-sitter-queries/typescript/deep-nesting.yml +117 -0
  271. package/rules/tree-sitter-queries/typescript/deep-promise-chain.yml +73 -0
  272. package/rules/tree-sitter-queries/typescript/empty-catch.yml +64 -0
  273. package/rules/tree-sitter-queries/typescript/eval.yml +48 -0
  274. package/rules/tree-sitter-queries/typescript/hardcoded-secrets.yml +78 -0
  275. package/rules/tree-sitter-queries/typescript/long-parameter-list.yml +62 -0
  276. package/rules/tree-sitter-queries/typescript/mixed-async-styles.yml +49 -0
  277. package/rules/tree-sitter-queries/typescript/nested-ternary.yml +45 -0
  278. package/rules/ts-slop-rules/.sgconfig.yml +4 -0
  279. package/rules/ts-slop-rules/rules/in-correct-optional-input-type.yml +10 -0
  280. package/rules/ts-slop-rules/rules/jwt-no-verify.yml +13 -0
  281. package/rules/ts-slop-rules/rules/no-architecture-violation.yml +10 -0
  282. package/rules/ts-slop-rules/rules/no-case-declarations.yml +10 -0
  283. package/rules/ts-slop-rules/rules/no-dangerously-set-inner-html.yml +10 -0
  284. package/rules/ts-slop-rules/rules/no-debugger.yml +10 -0
  285. package/rules/ts-slop-rules/rules/no-dupe-args.yml +10 -0
  286. package/rules/ts-slop-rules/rules/no-dupe-class-members.yml +10 -0
  287. package/rules/ts-slop-rules/rules/no-dupe-keys.yml +10 -0
  288. package/rules/ts-slop-rules/rules/no-eval.yml +13 -0
  289. package/rules/ts-slop-rules/rules/no-hardcoded-secrets.yml +12 -0
  290. package/rules/ts-slop-rules/rules/no-implied-eval.yml +12 -0
  291. package/rules/ts-slop-rules/rules/no-inner-html.yml +13 -0
  292. package/rules/ts-slop-rules/rules/no-javascript-url.yml +10 -0
  293. package/rules/ts-slop-rules/rules/no-mutable-default.yml +10 -0
  294. package/rules/ts-slop-rules/rules/no-nested-links.yml +12 -0
  295. package/rules/ts-slop-rules/rules/no-new-symbol.yml +10 -0
  296. package/rules/ts-slop-rules/rules/no-new-wrappers.yml +13 -0
  297. package/rules/ts-slop-rules/rules/no-open-redirect.yml +16 -0
  298. package/rules/ts-slop-rules/rules/slop-rules.yml +455 -0
  299. package/rules/ts-slop-rules/rules/weak-rsa-key.yml +12 -0
  300. package/skills/ast-grep/SKILL.md +182 -0
  301. package/clients/dispatch/runners/secrets.js +0 -109
  302. package/commands/fix.js +0 -244
  303. package/commands/fix.ts +0 -373
  304. package/rules/ast-grep-rules/rules/no-lonely-if.yml +0 -13
@@ -0,0 +1,64 @@
1
+ # Empty Catch Block
2
+ # Detects catch blocks that silently swallow errors
3
+ id: empty-catch
4
+ name: Empty Catch Block
5
+ severity: error
6
+ category: reliability
7
+ language: typescript
8
+
9
+ message: "Empty catch block — properly handle or log the error"
10
+
11
+ description: |
12
+ Silently swallowing errors makes debugging impossible.
13
+
14
+ ✅ PROPER FIXES (choose one):
15
+ 1. Log the error: console.error(`[context] Failed to X:`, err)
16
+ 2. Rethrow if can't handle: throw err
17
+ 3. Return a safe default: return null / return [] / return defaultValue
18
+ 4. Handle specific errors: if (err.code === 'ENOENT') { ... }
19
+ 5. Propagate to caller: callback(err) / reject(err)
20
+
21
+ ❌ NOT ACCEPTABLE:
22
+ - void err; (just references variable, does nothing)
23
+ - /* ignored */ comments without action
24
+ - console.log without the error object
25
+
26
+ query: |
27
+ (catch_clause
28
+ (identifier) @ERR
29
+ (statement_block) @BODY)
30
+
31
+ # Post-filter: Check if body is effectively empty (ignoring comments)
32
+ post_filter: empty_body
33
+
34
+ # Capture metavariables
35
+ metavars:
36
+ - ERR # The error parameter name
37
+ - BODY # The catch block body
38
+
39
+ # Additional metadata
40
+ tags:
41
+ - security
42
+ - debugging
43
+ - reliability
44
+ - best-practice
45
+
46
+ # Examples for documentation
47
+ examples:
48
+ bad: |
49
+ try {
50
+ await fetch('/api');
51
+ } catch (err) {
52
+ // Empty - BAD!
53
+ }
54
+
55
+ good: |
56
+ try {
57
+ await fetch('/api');
58
+ } catch (err) {
59
+ console.error('[API] Fetch failed:', err);
60
+ throw err; // or return safe default
61
+ }
62
+
63
+ # Auto-fix available
64
+ has_fix: false
@@ -0,0 +1,48 @@
1
+ # Eval Usage
2
+ # Detects eval() calls (security risk)
3
+ id: no-eval
4
+ name: Eval Usage
5
+ severity: error
6
+ category: security
7
+ language: typescript
8
+
9
+ message: "eval() detected — security risk, never use eval"
10
+
11
+ description: |
12
+ eval() executes arbitrary code and is a major security vulnerability.
13
+ It allows code injection attacks.
14
+
15
+ ✅ ALTERNATIVES:
16
+ - JSON.parse() for parsing JSON
17
+ - Function constructor for dynamic functions (still risky)
18
+ - Template literals for string interpolation
19
+ - Proper parsing libraries for complex needs
20
+
21
+ query: |
22
+ (call_expression
23
+ function: (identifier) @FUNC
24
+ (#eq? @FUNC "eval")
25
+ arguments: (arguments) @ARGS)
26
+
27
+ metavars:
28
+ - FUNC
29
+ - ARGS
30
+
31
+ tags:
32
+ - security
33
+ - xss
34
+ - owasp
35
+
36
+ examples:
37
+ bad: |
38
+ const userCode = "alert('hacked')";
39
+ eval(userCode); // DON'T DO THIS
40
+
41
+ good: |
42
+ // Use JSON.parse for JSON
43
+ const data = JSON.parse(jsonString);
44
+
45
+ // Use template literals
46
+ const message = `Hello, ${name}`;
47
+
48
+ has_fix: false
@@ -0,0 +1,78 @@
1
+ # Hardcoded Secrets
2
+ # Detects hardcoded API keys, passwords, tokens in code
3
+ id: hardcoded-secrets
4
+ name: Hardcoded Secret
5
+ severity: error
6
+ category: security
7
+ language: typescript
8
+
9
+ message: "Hardcoded {{VARNAME}} — use environment variables"
10
+
11
+ description: |
12
+ Hardcoded secrets in source code are a serious security risk.
13
+ They can be exposed through:
14
+ - Git history (even if deleted)
15
+ - Decompiled code
16
+ - Public repositories
17
+
18
+ ✅ FIX: Use environment variables
19
+
20
+ ```typescript
21
+ const apiKey = process.env.API_KEY;
22
+ if (!apiKey) throw new Error('API_KEY not set');
23
+ ```
24
+
25
+ Then add to .env file (which should be in .gitignore):
26
+ ```
27
+ API_KEY=your_secret_here
28
+ ```
29
+
30
+ query: |
31
+ (lexical_declaration
32
+ (variable_declarator
33
+ name: (identifier) @VARNAME
34
+ value: (string) @SECRET))
35
+ (#match? @VARNAME "^(api_key|apikey|password|secret|token|auth|private_key|access_token)$")
36
+ (assignment_expression
37
+ left: (identifier) @VARNAME
38
+ right: (string) @SECRET)
39
+ (#match? @VARNAME "^(api_key|apikey|password|secret|token|auth|private_key|access_token)$")
40
+
41
+ metavars:
42
+ - VARNAME
43
+ - SECRET
44
+
45
+ tags:
46
+ - security
47
+ - secrets
48
+ - best-practice
49
+ - owasp
50
+
51
+ examples:
52
+ bad: |
53
+ const api_key = "sk-live-abc123xyz789";
54
+ const password = "hunter2";
55
+ const SECRET = "my-secret-value";
56
+
57
+ good: |
58
+ const api_key = process.env.API_KEY;
59
+ const password = process.env.DATABASE_PASSWORD;
60
+ const secret = process.env.SECRET_KEY;
61
+
62
+ has_fix: false
63
+
64
+ # Additional patterns to match
65
+ patterns:
66
+ variable_names:
67
+ - api_key
68
+ - apikey
69
+ - apiKey
70
+ - API_KEY
71
+ - password
72
+ - secret
73
+ - token
74
+ - auth
75
+ - private_key
76
+ - access_token
77
+ - aws_secret
78
+ - github_token
@@ -0,0 +1,62 @@
1
+ # Long Parameter List
2
+ # Detects functions with 6+ parameters
3
+ id: long-parameter-list
4
+ name: Long Parameter List
5
+ severity: warning
6
+ category: complexity
7
+ language: typescript
8
+
9
+ message: "Function has {{PARAM_COUNT}} parameters — use object pattern"
10
+
11
+ description: |
12
+ Functions with many parameters are hard to use and maintain.
13
+ Use an options object instead.
14
+
15
+ ✅ FIX: Convert to options object pattern
16
+
17
+ query: |
18
+ (function_declaration
19
+ name: (identifier) @NAME
20
+ parameters: (formal_parameters) @PARAMS
21
+ body: (statement_block) @BODY)
22
+
23
+ metavars:
24
+ - NAME
25
+ - PARAMS
26
+ - BODY
27
+
28
+ # Post-filter: count parameters
29
+ post_filter: count_params
30
+ post_filter_params:
31
+ min_params: 6
32
+
33
+ tags:
34
+ - complexity
35
+ - refactoring
36
+ - maintainability
37
+
38
+ examples:
39
+ bad: |
40
+ function createUser(
41
+ firstName, lastName, email,
42
+ password, age, role, status
43
+ ) {
44
+ // ...
45
+ }
46
+
47
+ good: |
48
+ interface CreateUserOptions {
49
+ firstName: string;
50
+ lastName: string;
51
+ email: string;
52
+ password: string;
53
+ age: number;
54
+ role: string;
55
+ status: string;
56
+ }
57
+
58
+ function createUser(options: CreateUserOptions) {
59
+ // ...
60
+ }
61
+
62
+ has_fix: false
@@ -0,0 +1,49 @@
1
+ # Mixed Async Styles
2
+ # Detects mixing async/await with promise chains in the same function
3
+ id: mixed-async-styles
4
+ name: Mixed Async/Await and Promise Chains
5
+ severity: warning
6
+ category: style
7
+ language: typescript
8
+
9
+ message: "Mixed async/await + promise chains — use consistent async style"
10
+
11
+ description: |
12
+ Mixing async/await with .then()/.catch() chains in the same function
13
+ is confusing and inconsistent. Choose one style per function.
14
+
15
+ ✅ FIXES:
16
+ 1. Convert all to async/await (preferred)
17
+ 2. Convert all to promise chains (if needed for specific control flow)
18
+
19
+ query: |
20
+ (function_declaration
21
+ (async_modifier)
22
+ body: (statement_block) @BODY)
23
+
24
+ # Post-filter: Check if body contains both await and .then()
25
+ post_filter: has_mixed_async
26
+
27
+ metavars:
28
+ - BODY
29
+
30
+ tags:
31
+ - style
32
+ - async
33
+ - consistency
34
+
35
+ examples:
36
+ bad: |
37
+ async function getUser() {
38
+ const response = await fetch('/api/user');
39
+ return response.json().then(data => data.name); // Mixed!
40
+ }
41
+
42
+ good: |
43
+ async function getUser() {
44
+ const response = await fetch('/api/user');
45
+ const data = await response.json(); // Consistent async/await
46
+ return data.name;
47
+ }
48
+
49
+ has_fix: false
@@ -0,0 +1,45 @@
1
+ # Nested Ternary
2
+ # Detects deeply nested ternary operators (readability issue)
3
+ id: nested-ternary
4
+ name: Nested Ternary
5
+ severity: warning
6
+ category: readability
7
+ language: typescript
8
+
9
+ message: "Nested ternary — use if/else or early returns for clarity"
10
+
11
+ description: |
12
+ Nested ternary operators are hard to read and understand.
13
+ Prefer if/else statements or early returns.
14
+
15
+ ✅ FIX: Use if/else or switch statement
16
+
17
+ query: |
18
+ (ternary_expression
19
+ consequence: (ternary_expression) @NESTED)
20
+ (ternary_expression
21
+ alternative: (ternary_expression) @NESTED)
22
+
23
+ metavars:
24
+ - NESTED
25
+
26
+ tags:
27
+ - readability
28
+ - code-quality
29
+
30
+ examples:
31
+ bad: |
32
+ const value = condition1
33
+ ? condition2
34
+ ? condition3 ? "a" : "b"
35
+ : "c"
36
+ : "d";
37
+
38
+ good: |
39
+ function getValue(c1, c2, c3) {
40
+ if (!c1) return "d";
41
+ if (!c2) return "c";
42
+ return c3 ? "a" : "b";
43
+ }
44
+
45
+ has_fix: false
@@ -0,0 +1,4 @@
1
+ # TypeScript/JavaScript slop detection configuration
2
+ # Detects verbose patterns, defensive over-checking, and ceremony
3
+ ruleDirs:
4
+ - ./rules
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-incorrect-optional-input-type
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "This input is optional, but the type for it does not include undefined."
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ pattern: "$FIELD"
@@ -0,0 +1,13 @@
1
+ ---
2
+ id: ts-jwt-no-verify
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Unsafe JWT operation — verification is bypassed"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
11
+ - pattern: "jwt.decode($$$, { noVerify: true })"
12
+ - pattern: "jwt.verify($$$, { ignoreExpiration: true, $$$ })"
13
+ - pattern: "jwt.verify($$$, { ignoreNotBefore: true, $$$ })"
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-architecture-violation
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Forbidden import — layer boundary violation: importing from database/model layer"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ pattern: "import { $$$ } from \"$PATH\""
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-case-declarations
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Unexpected lexical declaration in case block — wrap in braces to restrict scope"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ all:
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-dangerously-set-inner-html
3
+ language: TSX
4
+ severity: warning
5
+ message: "dangerouslySetInnerHTML can expose XSS vulnerabilities — sanitize with DOMPurify"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ kind: jsx_attribute
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-debugger
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Unexpected `debugger` statement."
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ pattern: "debugger"
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-dupe-args
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Duplicate param '$NAME'."
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ pattern: "$NAME"
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-dupe-class-members
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Duplicate class member '$NAME'."
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-dupe-keys
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Disallow duplicate keys in object literals"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
@@ -0,0 +1,13 @@
1
+ ---
2
+ id: ts-no-eval
3
+ language: typescript
4
+ severity: warning
5
+ message: Avoid eval() — it can execute arbitrary code and is a security risk
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
11
+ - pattern: "eval($$$ARGS)"
12
+ - pattern: "window.eval($$$ARGS)"
13
+ - pattern: "global.eval($$$ARGS)"
@@ -0,0 +1,12 @@
1
+ ---
2
+ id: ts-no-hardcoded-secrets
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Hardcoded secret detected — use process.env instead"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
11
+ - pattern: "const $VAR = \"$_\""
12
+ - pattern: "const $VAR = '$_'"
@@ -0,0 +1,12 @@
1
+ ---
2
+ id: ts-no-implied-eval
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Avoid implied eval via setTimeout/setInterval with string arguments"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
11
+ - pattern: "setTimeout($$$ARGS)"
12
+ - pattern: "setInterval($$$ARGS)"
@@ -0,0 +1,13 @@
1
+ ---
2
+ id: ts-no-inner-html
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Avoid innerHTML/outerHTML — use textContent or a sanitizer to prevent XSS"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
11
+ - pattern: "$EL.innerHTML = $$$"
12
+ - pattern: "$EL.outerHTML = $$$"
13
+ - pattern: "$EL.insertAdjacentHTML($$$)"
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-javascript-url
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Avoid javascript: URLs — they can execute arbitrary code"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ all:
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-mutable-default
3
+ language: Python
4
+ severity: warning
5
+ message: "Mutable default argument detected — use None and initialize inside function"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ kind: default_parameter
@@ -0,0 +1,12 @@
1
+ ---
2
+ id: ts-no-nested-links
3
+ language: TSX
4
+ severity: warning
5
+ message: "Nested <a> tags are invalid HTML and cause unexpected behavior"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ all:
11
+ - has:
12
+ kind: jsx_element
@@ -0,0 +1,10 @@
1
+ ---
2
+ id: ts-no-new-symbol
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Symbol cannot be called as a constructor."
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ pattern: "new Symbol($$$)"
@@ -0,0 +1,13 @@
1
+ ---
2
+ id: ts-no-new-wrappers
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Do not use 'new' with wrapper objects — use literal primitives instead"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
11
+ - pattern: "new Boolean($$$ARGS)"
12
+ - pattern: "new Number($$$ARGS)"
13
+ - pattern: "new String($$$ARGS)"
@@ -0,0 +1,16 @@
1
+ ---
2
+ id: ts-no-open-redirect
3
+ language: TypeScript
4
+ severity: warning
5
+ message: "Potential open redirect vulnerability — validate redirect URLs"
6
+ metadata:
7
+ weight: 4
8
+ category: security
9
+ rule:
10
+ any:
11
+ - pattern: "window.location = $URL"
12
+ - pattern: "window.location.href = $URL"
13
+ - pattern: "window.open($URL, $$$)"
14
+ - pattern: "location.href = $URL"
15
+ - pattern: "res.redirect($URL)"
16
+ - pattern: "response.redirect($URL)"