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
package/README.md CHANGED
@@ -1,519 +1,709 @@
1
- # pi-lens
2
-
3
- Real-time code quality feedback for [pi](https://github.com/mariozechner/pi-coding-agent). Every write and edit is automatically analysed diagnostics are injected directly into the tool result so the agent sees them without any extra steps.
4
-
5
- ## Install
6
-
7
- ```bash
8
- pi install npm:pi-lens
9
- ```
10
-
11
- Or directly from git:
12
-
13
- ```bash
14
- pi install git:github.com/apmantza/pi-lens
15
- ```
16
-
17
- ---
18
-
19
- ## Features
20
-
21
- ### On every write / edit
22
-
23
- Every file write is automatically checked. Blocking issues appear inline:
24
-
25
- ```
26
- 🔴 STOP 1 issue(s) must be fixed:
27
- L23: var total = sum(items); — use 'let' or 'const'
28
- ```
29
-
30
- **Runners:** TypeScript type-checking, Python type-checking (pyright), linting (ruff, biome), secrets scan, architectural rules.
31
-
32
- ### Code quality scoring
33
-
34
- ```
35
- /lens-rate
36
- ```
37
-
38
- ```
39
- 📊 CODE QUALITY SCORE: 85/100 (B)
40
- ┌─────────────────────────────────────────────────────────┐
41
- │ 🔷 Type Safety 🟩🟩🟩🟩🟩🟩🟩🟩⬜⬜ 85 │
42
- │ 🧩 Complexity 🟩🟩🟩🟩🟩🟩🟩🟩⬜⬜ 82
43
- │ 🔒 Security 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 100 │
44
- │ 🏗️ Architecture 🟩🟩🟩🟩🟩🟩🟩🟩⬜⬜ 80 │
45
- │ 🗑️ Dead Code 🟩🟩🟩🟩🟩🟩🟩🟩🟩⬜ 90 │
46
- │ ✅ Tests 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 100 │
47
- └─────────────────────────────────────────────────────────┘
48
- ```
49
-
50
- ### On-demand commands
51
-
52
- | Command | What it does |
53
- |---------|--------------|
54
- | `/lens-booboo` | Full codebase review (design smells, complexity, dead code, duplicates, type coverage) |
55
- | `/lens-booboo-fix` | Automated mechanical fixes for lint issues |
56
- | `/lens-booboo-refactor` | Interactive architectural refactoring |
57
- | `/lens-rate` | Code quality score with visual breakdown |
58
- | `/lens-metrics` | Complexity metrics for all files |
59
- | `/lens-format` | Apply Biome formatting |
60
-
61
- ### Context-aware rules
62
-
63
- Rules are automatically skipped for test files no more `no-console-log` warnings in `*.test.ts`.
64
-
65
- ### Project rules integration
66
-
67
- Scans for `.claude/rules/`, `.agents/rules/`, `CLAUDE.md`, `AGENTS.md` at session start. Project-specific rules are surfaced in the system prompt.
68
-
69
- ### Secret scanning
70
-
71
- Catches secrets in ANY file type on write/edit — `.env`, `.yaml`, `.json`, not just TypeScript:
72
-
73
- ```
74
- 🔴 STOP — 1 potential secret(s) in src/config.ts:
75
- L12: Possible Stripe or OpenAI API key (sk-*)
76
- Remove before continuing. Use env vars instead.
77
- ```
78
-
79
- ### Delta-mode feedback
80
-
81
- First edit: full feedback. Subsequent edits: only NEW issues. Pre-existing issues are tracked and excluded from inline output.
82
-
83
- ---
84
-
85
- ## Dependent Tools
86
-
87
- pi-lens works out of the box for TypeScript/JavaScript. For full language support, install these tools — **all are optional and gracefully skip if not installed**:
88
-
89
- ### JavaScript / TypeScript
90
-
91
- | Tool | Install | What it does |
92
- |------|---------|--------------|
93
- | `@biomejs/biome` | `npm i -D @biomejs/biome` | Linting + formatting |
94
- | `knip` | `npm i -D knip` | Dead code / unused exports |
95
- | `jscpd` | `npm i -D jscpd` | Copy-paste detection |
96
- | `type-coverage` | `npm i -D type-coverage` | TypeScript `any` coverage % |
97
-
98
- ### Python
99
-
100
- | Tool | Install | What it does |
101
- |------|---------|--------------|
102
- | `ruff` | `pip install ruff` | Linting + formatting |
103
- | `pyright` | `pip install pyright` | Type-checking (catches type errors) |
104
-
105
- ### Go
106
-
107
- | Tool | Install | What it does |
108
- |------|---------|--------------|
109
- | `go` | [golang.org](https://golang.org) | Built-in `go vet` for static analysis |
110
-
111
- ### Rust
112
-
113
- | Tool | Install | What it does |
114
- |------|---------|--------------|
115
- | `rust` + `clippy` | [rustup.rs](https://rustup.rs) | Linting via `cargo clippy` |
116
-
117
- ### All Languages
118
-
119
- | Tool | Install | What it does |
120
- |------|---------|--------------|
121
- | `@ast-grep/cli` | `npm i -D @ast-grep/cli` | Structural pattern matching (80+ rules) |
122
-
123
- ---
124
-
125
- ## Flags
126
-
127
- | Flag | Description |
128
- |------|-------------|
129
- | `--lens-verbose` | Enable console logging |
130
- | `--autofix-biome` | Auto-fix lint issues with Biome |
131
-
132
- ---
133
-
134
- ## Rules
135
-
136
- pi-lens includes 80+ ast-grep rules for:
137
-
138
- ## ast-grep rules
139
-
140
- Rules live in `rules/ast-grep-rules/rules/`. All rules are YAML files you can edit or extend.
141
-
142
- Each rule includes a `message` and `note` that are shown in diagnostics, so the agent understands why something violated a rule and how to fix it.
143
-
144
- **Security**
145
- `no-eval`, `no-implied-eval`, `no-hardcoded-secrets`, `no-insecure-randomness`, `no-open-redirect`, `no-sql-in-code`, `no-inner-html`, `no-dangerously-set-inner-html`, `no-javascript-url`
146
-
147
- **TypeScript**
148
- `no-any-type`, `no-as-any`, `no-non-null-assertion`
149
-
150
- **Style** (Biome handles `no-var`, `prefer-const`, `prefer-template`, `no-useless-concat` natively)
151
- `prefer-nullish-coalescing`, `prefer-optional-chain`, `nested-ternary`, `no-lonely-if`
152
-
153
- **Correctness**
154
- `no-debugger`, `no-throw-string`, `no-return-await`, `no-await-in-loop`, `no-await-in-promise-all`, `require-await`, `empty-catch`, `strict-equality`, `strict-inequality`
155
-
156
- **Patterns**
157
- `no-console-log`, `no-alert`, `no-delete-operator`, `no-shadow`, `no-star-imports`, `switch-needs-default`, `switch-without-default`
158
-
159
- **Type Safety** (type-aware checks via `type-safety-client.ts`)
160
- `switch-exhaustiveness` detects missing cases in union type switches (inline blocker)
161
-
162
- **Design Smells**
163
- `long-method`, `long-parameter-list`, `large-class`
164
-
165
- **AI Slop Detection**
166
- `no-param-reassign`, `no-single-char-var`, `no-process-env`, `no-architecture-violation`
167
-
168
- ---
169
-
170
- ## TypeScript LSP — tsconfig detection
171
-
172
- The LSP walks up from the edited file's directory until it finds a `tsconfig.json`. If found, it uses that project's exact `compilerOptions` (paths, strict settings, lib, etc.). If not found, it falls back to sensible defaults:
173
-
174
- - `target: ES2020`
175
- - `lib: ["es2020", "dom", "dom.iterable"]`
176
- - `moduleResolution: bundler`
177
- - `strict: true`
178
-
179
- The compiler options are refreshed automatically when you switch between projects within a session.
180
-
181
- ---
182
-
183
-
184
- ---
185
-
186
- ## Changelog
187
-
188
-
189
- ## [2.1.1] - 2026-03-29
190
-
191
- ### Added
192
- - **Content-level secret scanning**: Catches secrets in ANY file type on write/edit (`.env`, `.yaml`, `.json`, not just TypeScript). Blocks before save with patterns for `sk-*`, `ghp_*`, `AKIA*`, private keys, hardcoded passwords.
193
- - **Project rules integration**: Scans for `.claude/rules/`, `.agents/rules/`, `CLAUDE.md`, `AGENTS.md` at session start and surfaces in system prompt.
194
- - **Grep-ability rules**: New ast-grep rules for `no-default-export` and `no-relative-cross-package-import` to improve agent searchability.
195
-
196
- ### Changed
197
- - **Inline feedback stripped to blocking only**: Warnings no longer shown inline (noise). Only blocking violations and test failures interrupt the agent.
198
- - **booboo-fix output compacted**: Summary in terminal, full plan in `.pi-lens/reports/fix-plan.tsv`.
199
- - **booboo-refactor output compacted**: Top 5 worst offenders in terminal, full ranked list in `.pi-lens/reports/refactor-ranked.tsv`.
200
- - **`ast_grep_search` new params**: Added `selector` (extract specific AST node) and `context` (show surrounding lines).
201
- - **`ast_grep_replace` mode indicator**: Shows `[DRY-RUN]` or `[APPLIED]` prefix.
202
- - **no-hardcoded-secrets**: Fixed to only flag actual hardcoded strings (not `process.env` assignments).
203
- - **no-process-env**: Now only flags secret-related env vars (not PORT, NODE_ENV, etc.).
204
- - **Removed Factory AI article reference** from architect.yaml.
205
-
206
- ## [2.0.40] - 2026-03-27
207
-
208
- ### Changed
209
- - **Passive capture on every file edit**: `captureSnapshot()` now called from `tool_call` hook with 5s debounce. Zero latency — reuses complexity metrics already computed for real-time feedback.
210
- - **Skip duplicate snapshots**: Same commit + same MI = no write (reduces noise).
211
-
212
- ## [2.0.39] - 2026-03-27
213
-
214
- ### Added
215
- - **Historical metrics tracking**: New `clients/metrics-history.ts` module captures complexity snapshots per commit. Tracks MI, cognitive complexity, and nesting depth across sessions.
216
- - **Trend analysis in `/lens-metrics`**: New "Trend" column shows 📈/📉/➡️ with MI delta. "Trend Summary" section aggregates improving/stable/regressing counts with worst regressions.
217
- - **Passive capture**: Snapshots captured on every file edit (tool_call hook) + `/lens-metrics` run. Max 20 snapshots per file (sliding window).
218
-
219
- ## [2.0.38] - 2026-03-27
220
-
221
- ### Changed
222
- - **Refactored 4 client files** via `/lens-booboo-refactor` loop:
223
- - `biome-client.ts`: Extracted `withValidatedPath()` guard pattern (4 methods consolidated)
224
- - `complexity-client.ts`: Extracted `analyzeFile()` pipeline into `readAndParse()`, `computeMetrics()`, `aggregateFunctionStats()`
225
- - `dependency-checker.ts`: Simplified `importsChanged()` — replaced 3 for-loops with `setsEqual()` helper
226
- - `ast-grep-client.ts`: Simplified `groupSimilarFunctions()` with `filter().map()` pattern + `extractFunctionName()` helper
227
-
228
- ## [2.0.29] - 2026-03-26
229
-
230
- ### Added
231
- - **`clients/ts-service.ts`**: Shared TypeScript service that creates one `ts.Program` per session. Both `complexity-client` and `type-safety-client` now share the same program instead of creating a new one per file. Significant performance improvement on large codebases.
232
-
233
- ### Removed
234
- - **3 redundant ast-grep rules** that overlap with Biome: `no-var`, `prefer-template`, `no-useless-concat`. Biome handles these natively with auto-fix. ast-grep no longer duplicates this coverage.
235
- - **`prefer-const` from RULE_ACTIONS** no longer needed (Biome handles directly).
236
-
237
- ### Changed
238
- - **Consolidated rule overlap**: Biome is now the single source of truth for style/format rules. ast-grep focuses on structural patterns Biome doesn't cover (security, design smells, AI slop).
239
-
240
- ## [2.0.27] - 2026-03-26
241
-
242
- ### Added
243
- - **`switch-exhaustiveness` check**: New type safety rule detects missing cases in union type switches. Uses TypeScript compiler API for type-aware analysis. Reports as inline blocker: `🔴 STOP — Switch on 'X' is not exhaustive. Missing cases: 'Y'`.
244
- - **`clients/type-safety-client.ts`**: New client for type safety checks. Extensible for future checks (null safety, exhaustive type guards).
245
-
246
- ### Changed
247
- - **Type safety violations added to inline feedback**: Missing switch cases now block the agent mid-task, same as TypeScript errors.
248
- - **Type safety violations in `/lens-booboo-fix`**: Marked as agent-fixable (add missing case or default clause).
249
-
250
- ## [2.0.26] - 2026-03-26
251
-
252
- ### Added
253
- - **5 new ast-grep rules** for AI slop detection:
254
- - `no-process-env`: Block direct `process.env` access (use DI or config module) — error level
255
- - `no-param-reassign`: Detect function parameter reassignment — warning level
256
- - `no-single-char-var`: Flag single-character variable names — info level
257
- - `switch-without-default`: Ensure switch statements have default case — warning level
258
- - `no-architecture-violation`: Block cross-layer imports (models/db) — error level
259
-
260
- ### Changed
261
- - **RULE_ACTIONS updated** for new rules:
262
- - `agent` type (inline + booboo-fix): `no-param-reassign`, `switch-without-default`, `switch-exhaustiveness`
263
- - `skip` type (booboo-refactor only): `no-process-env`, `no-single-char-var`, `no-architecture-violation`
264
-
265
- ## [2.0.24] - 2026-03-26
266
-
267
- ### Changed
268
- - **Simplified `/lens-booboo-refactor` confirmation flow**: Post-change report instead of pre-change gate. Agent implements first, then shows what was changed (git diff + metrics delta). User reviews and can request refinements via chat. No more temp files or dry-run diffs.
269
- - **Confirmation screen**: "✅ Looks good move to next offender" / "💬 Request changes" (chat textarea). Diff display is optional.
270
-
271
- ## [2.0.23] - 2026-03-26
272
-
273
- ### Changed
274
- - **Extracted interviewer and scan modules from `index.ts`**: `index.ts` reduced by 460 lines.
275
- - `clients/interviewer.ts` all browser interview infrastructure (HTML generation, HTTP server, browser launch, option selection, diff confirmation screen)
276
- - `clients/scan-architectural-debt.ts` shared scanning utilities (`scanSkipViolations`, `scanComplexityMetrics`, `scoreFiles`, `extractCodeSnippet`)
277
- - **`/lens-booboo-refactor`** now uses imported scan functions instead of duplicated inline code.
278
-
279
- ## [2.0.22] - 2026-03-26
280
-
281
- ### Added
282
- - **Impact metrics in interview options**: Each option now supports an `impact` object (`linesReduced`, `miProjection`, `cognitiveProjection`) rendered as colored badges in the browser form. Agent estimates impact when presenting refactoring options.
283
- - **Iterative confirmation loop**: Confirmation screen now includes "🔄 Describe a different approach" option with free-text textarea. Agent regenerates plan+diff based on feedback, re-opens confirmation. Repeat until user confirms or cancels.
284
- - **Auto-close on confirm**: Browser tab closes automatically after user submits.
285
-
286
- ## [2.0.21] - 2026-03-26
287
-
288
- ### Added
289
- - **Two-step confirmation for `/lens-booboo-refactor`**: Agent implements changes, then calls `interviewer` with `confirmationMode=true` to show plan (markdown) + unified diff (green/red line coloring) + line counts at the top. User can Confirm, Cancel, or describe a different approach.
290
- - **Plan + diff confirmation screen**: Plan rendered as styled markdown, diff rendered with syntax-colored `+`/`-` lines. Line counts (`+N / −N`) shown in diff header.
291
-
292
- ## [2.0.20] - 2026-03-26
293
-
294
- ### Added
295
- - **Impact metrics in interview options**: Structured `impact` field per option with `linesReduced`, `miProjection`, `cognitiveProjection`. Rendered as colored badges (green for lines reduced, blue for metric projections) inside each option card.
296
-
297
- ## [2.0.19] - 2026-03-26
298
-
299
- ### Changed
300
- - **`/lens-booboo-fix` jscpd filter**: Only within-file duplicates shown in actionable section. Cross-file duplicates are architectural shown in skip section only.
301
- - **AI slop filter tightened**: Require 2+ signals per file (was 1+). Single-issue flags on small files are noise — skip them.
302
-
303
- ## [2.0.18] - 2026-03-26
304
-
305
- ### Fixed
306
- - **`/lens-booboo-fix` max iterations**: Session file auto-deletes when hitting max iterations. Previously blocked with a manual "delete .pi-lens/fix-session.json" message.
307
-
308
- ## [2.0.17] - 2026-03-26
309
-
310
- ### Changed
311
- - **Agent-driven option generation**: `/lens-booboo-refactor` no longer hardcodes refactoring options per violation type. The command scans and presents the problem + code to the agent; the agent analyzes the actual code and generates 3-5 contextual options with rationale and impact estimates. Calls the `interviewer` tool to present them.
312
- - **`interviewer` tool**: Generic, reusable browser-based interview mechanism. Accepts `question`, `options` (with `value`, `label`, `context`, `recommended`, `impact`), and `confirmationMode`. Zero dependencies — Node's built-in `http` module + platform CLI `open`/`start`/`xdg-open`.
313
-
314
- ## [2.0.16] - 2026-03-26
315
-
316
- ### Added
317
- - **`/lens-booboo-refactor`**: Interactive architectural refactor session. Scans for worst offender by combined debt score (ast-grep skip violations + complexity metrics). Opens a browser interview with the problem, code context, and AI-generated options. Steers the agent to propose a plan and wait for user confirmation before making changes.
318
-
319
- ### Changed
320
- - **Inline tool_result suppresses skip-category rules**: `long-method`, `large-class`, `long-parameter-list`, `no-shadow`, `no-as-any`, `no-non-null-assertion`, `no-star-imports` no longer show as hard stops in real-time feedback. They are architectural — handled by `/lens-booboo-refactor` instead.
321
-
322
- ## [2.0.15] - 2026-03-26
323
-
324
- ### Removed
325
- - **Complexity metrics from real-time feedback**: MI, cognitive complexity, nesting depth, try/catch counts, and entropy scores removed from tool_result output. These were always noise — the agent never acted on "MI dropped to 5.6" mid-task. Metrics still available via `/lens-metrics` and `/lens-booboo`.
326
- - **Session summary injection**: The `[Session Start]` block (TODOs, dead code, jscpd, type-coverage) is no longer injected into the first tool result. Scans still run for caching purposes (exports, clones, baselines). Data surfaced on-demand via explicit commands.
327
- - **`/lens-todos`**: Removed (covered by `/lens-booboo`).
328
- - **`/lens-dead-code`**: Removed (covered by `/lens-booboo`).
329
- - **`/lens-deps`**: Removed — circular dep scan added to `/lens-booboo` as Part 8.
330
-
331
- ### Changed
332
- - **Hardened stop signals**: New violations (ast-grep, Biome, jscpd, duplicate exports) now all use `🔴 STOP` framing. The agent is instructed to fix these before continuing.
333
- - **`/lens-booboo` now includes circular dependencies**: Added as Part 8 (after type coverage) using `depChecker.scanProject`.
334
-
335
- ## [2.0.14] - 2026-03-26
336
-
337
- ### Fixed
338
- - **`/lens-booboo-fix` excludes `.js` compiled output**: Detects `tsconfig.json` and excludes `*.js` from jscpd, ast-grep, and complexity scans. Prevents double-counting of the same code in `.ts` and `.js` forms.
339
- - **`raw-strings` rule added to skip list**: 230 false positives in CLI/tooling codebases.
340
- - **`typescript-client.ts` duplication**: Extracted `resolvePosition()`, `resolveTree()`, and `toLocations()` helpers, deduplicating 6+ LSP methods.
341
- - **All clients**: `console.log` `console.error` in verbose loggers (stderr for debug, stdout for data).
342
-
343
- ## [2.0.13] - 2026-03-26
344
-
345
- ### Removed
346
- - **`raw-strings` ast-grep rule**: Not an AI-specific pattern. Humans write magic strings too. Biome handles style. Generated 230 false positives on first real run.
347
-
348
- ## [2.0.12] - 2026-03-26
349
-
350
- ### Fixed
351
- - **`/lens-booboo-fix` sequential scan order**: Reordered to Biome/Ruff → jscpd (duplicates) → knip (dead code) → ast-grep → AI slop → remaining Biome. Duplicates should be fixed before violations (fixing one fixes both). Dead code should be deleted before fixing violations in it.
352
-
353
- ### Changed
354
- - **Remaining Biome section rephrased**: "These couldn't be auto-fixed even with `--unsafe` — fix each manually."
355
-
356
- ## [2.0.11] - 2026-03-26
357
-
358
- ### Added
359
- - **Circular dependency scan to `/lens-booboo`**: Added as Part 8, using `depChecker.scanProject()` to detect circular chains across the codebase.
360
-
361
- ### Removed
362
- - **`/lens-todos`**, **`/lens-dead-code`**, **`/lens-deps`**: Removed standalone commands — all covered by `/lens-booboo`.
363
-
364
- ## [2.0.10] - 2026-03-26
365
-
366
- ### Changed
367
- - **Session summary injection removed**: The `[Session Start]` block is no longer injected into the first tool result. Scans still run silently for caching (exports for duplicate detection, clones for jscpd, complexity baselines for deltas).
368
-
369
- ## [2.0.1] - 2026-03-25
370
-
371
- ### Fixed
372
- - **ast-grep in `/lens-booboo` was silently dropping all results** — newer ast-grep versions exit `0` with `--json` even when issues are found; fixed the exit code check.
373
- - **Renamed "Design Smells" to "ast-grep"** in booboo report — the scan runs all 65 rules (security, correctness, style, design), not just design smells.
374
-
375
- ### Changed
376
- - **Stronger real-time feedback messages** — all messages now use severity emoji and imperative language:
377
- - `🔴 Fix N TypeScript error(s) — these must be resolved`
378
- - `🧹 Remove N unused import(s) they are dead code`
379
- - `🔴 You introduced N new structural violation(s) — fix before moving on`
380
- - `🟠 You introduced N new Biome violation(s) — fix before moving on`
381
- - `🟡 Complexity issues refactor when you get a chance`
382
- - `🟠 This file has N duplicate block(s) — extract to shared utilities`
383
- - `🔴 Do not redefine — N function(s) already exist elsewhere`
384
- - **Biome fix command is now a real bash command** — `npx @biomejs/biome check --write <file>` instead of `/lens-format` (which is a pi UI command, not runnable from agent tools).
385
- - **Complexity warnings skip test files in real-time** — same exclusion as lens-booboo.
386
-
387
- ## [2.0.0] - 2026-03-25
388
-
389
- ### Added
390
- - **`/lens-metrics` command**: Measure complexity metrics for all files. Exports a full `report.md` with A-F grades, summary stats, AI slop aggregate table, and top 10 worst files with actionable warnings.
391
- - **`/lens-booboo` saves full report**: Results saved to `.pi-lens/reviews/booboo-<timestamp>.md` — no truncation, all issues, agent-readable.
392
- - **AI slop indicators**: Four new real-time and report-based detectors:
393
- - `AI-style comments` emoji and boilerplate comment phrases
394
- - `Many try/catch blocks` — lazy error handling pattern
395
- - `Over-abstraction` single-use helper functions
396
- - `Long parameter list` — functions with > 6 params
397
- - **`SubprocessClient` base class**: Shared foundation for CLI tool clients (availability check, logging, command execution).
398
- - **Shared test utilities**: `createTempFile` and `setupTestEnvironment` extracted to `clients/test-utils.ts`, eliminating copy-paste across 13 test files.
399
-
400
- ### Changed
401
- - **Delta mode for real-time feedback**: ast-grep and Biome now only show *new* violations introduced by the current edit — not all pre-existing ones. Fixed violations shown as `✓ Fixed: rule-name (-N)`. No change = silent.
402
- - **Removed redundant pre-write hints**: ast-grep and Biome pre-write counts removed (delta mode makes them obsolete). TypeScript pre-write warning kept (blocking errors).
403
- - **Test files excluded from AI slop warnings**: MI/complexity thresholds are inherently low in test files warnings suppressed for `*.test.ts` / `*.spec.ts`.
404
- - **Test files excluded from TODO scanner**: Test fixture annotations (`FIXME`, `BUG`, etc.) no longer appear in TODO reports.
405
- - **ast-grep excludes test files and `.pi-lens/`**: Design smell scan in `/lens-booboo` skips test files (no magic-numbers noise) and internal review reports.
406
- - **jscpd excludes non-code files**: `.md`, `.json`, `.yaml`, `.yml`, `.toml`, `.lock`, and `.pi-lens/` excluded from duplicate detection — no more false positives from report files.
407
- - **Removed unused dependencies**: `vscode-languageserver-protocol` and `vscode-languageserver-types` removed; `@sinclair/typebox` added (was unlisted).
408
-
409
- ### Fixed
410
- - Removed 3 unconditional `console.log` calls leaking `[scan_exports]` to terminal.
411
- - Duplicate Biome scan in `tool_call` hook eliminated (was scanning twice for pre-write hint + baseline).
412
-
413
- ## [1.3.14] - 2026-03-25
414
-
415
- ### Added
416
- - **Actionable feedback messages**: All real-time warnings now include specific guidance on what to do.
417
- - **Code entropy metric**: Shannon entropy in bits (threshold: >3.5 indicates risky AI-induced complexity).
418
- - **Advanced pattern matching**: `/lens-booboo` now finds structurally similar functions (e.g., `formatDate` and `formatTimestamp`).
419
- - **Duplicate export detection**: Warns when redefining a function that already exists in the codebase.
420
- - **Biome formatting noise removed**: Only lint issues shown in real-time; use `/lens-format` for formatting.
421
-
422
- ## [1.3.10] - 2026-03-25
423
-
424
- ### Added
425
- - **Actionable complexity warnings**: Real-time feedback when metrics break limits with specific fix guidance.
426
-
427
- ## [1.3.9] - 2026-03-25
428
-
429
- ### Fixed
430
- - **Entropy calculation**: Corrected to use bits with 3.5-bit threshold for AI-induced complexity.
431
-
432
- ## [1.3.8] - 2026-03-25
433
-
434
- ### Added
435
- - **Code entropy metric**: Shannon entropy to detect repetitive or unpredictable code patterns.
436
-
437
- ## [1.3.7] - 2026-03-25
438
-
439
- ### Added
440
- - **Advanced pattern matching in `/lens-booboo`**: Finds structurally similar functions across the codebase.
441
-
442
- ## [1.3.6] - 2026-03-25
443
-
444
- ### Added
445
- - **Duplicate export detection on write**: Warns when defining a function that already exists elsewhere.
446
-
447
- ## [1.3.5] - 2026-03-25
448
-
449
- ### Changed
450
- - **Consistent command prefix**: All commands now start with `lens-`.
451
- - `/find-todos` → `/lens-todos`
452
- - `/dead-code` → `/lens-dead-code`
453
- - `/check-deps` → `/lens-deps`
454
- - `/format` `/lens-format`
455
- - `/design-review` + `/lens-metrics` → `/lens-booboo`
456
-
457
- ## [1.5.0] - 2026-03-23
458
-
459
- ### Added
460
- - **Real-time jscpd duplicate detection**: Code duplication is now detected on every write. Duplicates involving the edited file are shown to the agent in real-time.
461
- - **`/lens-review` command**: Combined code review: design smells + complexity metrics in one command.
462
-
463
- ### Changed
464
- - **Consistent command prefix**: All commands now start with `lens-`.
465
- - `/find-todos` `/lens-todos`
466
- - `/dead-code` `/lens-dead-code`
467
- - `/check-deps` → `/lens-deps`
468
- - `/format` → `/lens-format`
469
- - `/design-review` + `/lens-metrics` → `/lens-review`
470
-
471
- ## [1.4.0] - 2026-03-23
472
-
473
- ### Added
474
- - **Test runner feedback**: Runs corresponding test file on every write (vitest, jest, pytest). Silent if no test file exists. Disable with `--no-tests`.
475
- - **Complexity metrics**: AST-based analysis: Maintainability Index, Cyclomatic/Cognitive Complexity, Halstead Volume, nesting depth, function length.
476
- - **`/lens-metrics` command**: Full project complexity scan.
477
- - **Design smell rules**: New `long-method`, `long-parameter-list`, and `large-class` rules for structural quality checks.
478
- - **`/design-review` command**: Analyze files for design smells. Usage: `/design-review [path]`
479
- - **Go language support**: New Go client for Go projects.
480
- - **Rust language support**: New Rust client for Rust projects.
481
-
482
- ### Changed
483
- - **Improved ast-grep tool descriptions**: Better pattern guidance to prevent overly broad searches.
484
-
485
- ## [2.2.1] - 2026-03-29
486
-
487
- ### Fixed
488
- - **No auto-install**: Runners (biome, pyright) now use direct CLI commands instead of `npx`. If not installed, gracefully skip instead of attempting to download.
489
-
490
- ## [2.2.0] - 2026-03-29
491
-
492
- ### Added
493
- - **`/lens-rate` command**: Visual code quality scoring across 6 dimensions (Type Safety, Complexity, Security, Architecture, Dead Code, Tests). Shows grade A-F and colored progress bars.
494
- - **Pyright runner**: Real Python type-checking via pyright. Catches type errors like `result: str = add(1, 2)` that ruff misses. Runs alongside ruff (pyright for types, ruff for linting).
495
- - **Vitest config**: Increased test timeout to 15s for CLI spawn tests. Fixes flaky test failures when npx downloads packages.
496
-
497
- ### Fixed
498
- - **Test flakiness**: Availability tests (biome, knip, jscpd) no longer timeout when npx is downloading packages.
499
-
500
- ## [1.3.0] - 2026-03-23
501
-
502
- ### Changed
503
- - **Biome auto-fix disabled by default**: Biome still provides linting feedback, but no longer auto-fixes on write. Use `/format` to apply fixes or enable with `--autofix-biome`.
504
-
505
- ### Added
506
- - **ast-grep search/replace tools**: New `ast_grep_search` and `ast_grep_replace` tools for AST-aware code pattern matching. Supports meta-variables and 24 languages.
507
- - **Rule descriptions in diagnostics**: ast-grep violations now include the rule's message and note, making feedback more actionable for the agent.
508
-
509
- ### Changed
510
- - **Reduced console noise**: Extension no longer prints to console by default. Enable with `--lens-verbose`.
511
-
512
- ## [1.2.0] - 2026-03-23
513
-
514
- ### Added
515
- - GitHub repository link in npm package
516
-
517
- ## [1.1.2] - Previous
518
-
519
- - See git history for earlier releases
1
+ # pi-lens
2
+
3
+ Real-time code feedback for [pi](https://github.com/mariozechner/pi-coding-agent) LSP, linters, formatters, type-checking, structural analysis (ast-grep), TODO scanner, dead code detection, duplicate detection, type coverage, complexity metrics, and AI slop detection.
4
+
5
+ ## What pi-lens Does
6
+
7
+ **For every file you edit:**
8
+ 1. **Auto-formats** — Detects and runs formatters (Biome, Prettier, Ruff, gofmt, rustfmt, etc.)
9
+ 2. **Type-checks** TypeScript, Python, Go, Rust (and 27 more languages with `--lens-lsp`)
10
+ 3. **Scans for secrets** — blocks on hardcoded API keys, tokens, passwords
11
+ 4. **Runs linters** — Biome (TS/JS), Ruff (Python), plus structural analysis
12
+ 5. **Detects code smells** — empty catch blocks, debuggers, nested ternaries, etc.
13
+ 6. **Only shows NEW issues** — delta-mode tracks baselines and filters pre-existing problems (reduces noise)
14
+
15
+ **Blocking issues** (type errors, secrets) appear inline and stop the agent until fixed. **Warnings** are tracked but hidden inline — run `/lens-booboo` to see them all.
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Install
21
+ pi install npm:pi-lens
22
+
23
+ # Standard mode (auto-formatting, type-checking, linting enabled by default)
24
+ pi
25
+
26
+ # Disable auto-formatting if needed
27
+ pi --no-autoformat
28
+
29
+ # Full LSP mode (31 language servers)
30
+ pi --lens-lsp
31
+
32
+ # Fastest mode (LSP + concurrent execution) (Experimental)
33
+ pi --lens-lsp --lens-effect
34
+ ```
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ pi install npm:pi-lens
40
+ ```
41
+
42
+ Or directly from git:
43
+
44
+ ```bash
45
+ pi install git:github.com/apmantza/pi-lens
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Features
51
+
52
+ ### Auto-Formatting (Default Enabled)
53
+
54
+ pi-lens **automatically formats** every file you write or edit. Formatters are auto-detected based on your project configuration.
55
+
56
+ **Priority:** **Biome** is the default. **Prettier** runs only if Biome is not configured. This prevents race conditions and ensures consistent formatting.
57
+
58
+ | Formatter | Languages | Detection | Installation | Role |
59
+ |-----------|-----------|-----------|--------------|------|
60
+ | **Biome** ⭐ | TS/JS/JSON/CSS | `biome.json` or `@biomejs/biome` in devDependencies | ✅ Automatic | **Default** |
61
+ | **Prettier** | TS/JS/JSON/CSS/Markdown | `.prettierrc` or `prettier` in devDependencies | Manual (`npm install -g prettier`) | Fallback |
62
+ | **Ruff** ⭐ | Python | `[tool.ruff]` in `pyproject.toml` | ✅ Automatic | **Default** |
63
+ | **Black** | Python | `[tool.black]` in `pyproject.toml` | Manual (`pip install black`) | Fallback |
64
+ | **gofmt** | Go | `go` binary available | Manual (included with Go SDK) | Default |
65
+ | **rustfmt** | Rust | `rustfmt` binary available | Manual (included with Rust toolchain) | Default |
66
+ | **zig fmt** | Zig | `zig` binary available | Manual (included with Zig SDK) | Default |
67
+ | **dart format** | Dart | `dart` binary available | Manual (included with Dart SDK) | Default |
68
+ | **shfmt** | Shell | `shfmt` binary available | Manual (download binary) | Default |
69
+ | **mix format** | Elixir | `mix` binary available | Manual (included with Elixir) | Default |
70
+
71
+ = Auto-installed (no manual setup required)
72
+
73
+ **How it works:**
74
+ 1. Agent writes a file
75
+ 2. pi-lens detects formatters based on config files/dependencies
76
+ 3. Biome takes priority; Prettier runs only if Biome is not configured
77
+ 4. FileTime tracking ensures safety (agents re-read if file changes externally)
78
+
79
+ **Safety:** If a formatter changes the file, the agent is notified and must re-read before next edit — preventing stale content overwrites.
80
+
81
+ **Disable:**
82
+ ```bash
83
+ pi --no-autoformat # Skip automatic formatting
84
+ ```
85
+
86
+ ---
87
+
88
+ ### Auto-Linting (Default Enabled)
89
+
90
+ pi-lens **automatically lints** every file you write or edit. Linters are auto-detected based on your project configuration.
91
+
92
+ | Linter | Languages | Installation | Role | Priority |
93
+ |--------|-----------|--------------|------|----------|
94
+ | **Biome** | TS/JS/JSON/CSS | Automatic | **Default** | 10 |
95
+ | **Ruff** | Python | Automatic | **Default** | 10 |
96
+ | **oxlint** | TS/JS | Manual (`npm i -g oxlint`) | Fast alternative | 12 |
97
+ | **ESLint** | JS/Vue/Svelte | `npx` via `--lens-lsp` | LSP only | - |
98
+ | **shellcheck** | Bash/sh/zsh/fish | Manual (`apt install shellcheck`) | Shell scripts | 20 |
99
+
100
+ = Auto-installed (no manual setup required)
101
+
102
+ **Priority:** Lower numbers = run earlier. Biome/Ruff run first, followed by specialized linters.
103
+
104
+ **How it works:**
105
+ 1. Agent writes a file
106
+ 2. pi-lens detects linters based on config files and file type
107
+ 3. Biome takes priority for TS/JS; Ruff takes priority for Python
108
+ 4. Multiple linters can run on the same file (e.g., Biome + oxlint)
109
+ 5. Issues are delta-tracked (only new issues shown after first write)
110
+
111
+ **Notes:**
112
+ - Biome and Ruff are **dual-purpose** (lint + format)
113
+ - oxlint is a faster Rust-based alternative to ESLint
114
+ - ESLint only runs when `--lens-lsp` is enabled
115
+ - shellcheck requires manual installation on most systems
116
+
117
+ ---
118
+
119
+ ### LSP Support (NEW) 31 Language Servers
120
+
121
+ Enable full Language Server Protocol support with `--lens-lsp`:
122
+
123
+ | Category | Languages |
124
+ |----------|-----------|
125
+ | **Core** | TypeScript, Python, Go, Rust, Ruby, PHP, C#, F#, Java, Kotlin |
126
+ | **Native** | C/C++, Zig, Swift, Haskell, OCaml, Lua, Dart |
127
+ | **Functional** | Elixir, Gleam, Clojure, Haskell |
128
+ | **DevOps** | Terraform, Nix, Docker, Bash |
129
+ | **Config** | YAML, JSON, Prisma |
130
+ | **Web** | Vue, Svelte, CSS/SCSS/Sass/Less |
131
+
132
+ **Auto-installation (4 core tools):** TypeScript, Python, and formatting tools auto-install on first use to `.pi-lens/tools/`. Other LSP servers are launched via `npx` when available or require manual installation.
133
+
134
+ **Usage:**
135
+ ```bash
136
+ pi --lens-lsp # Enable LSP
137
+ pi --lens-lsp --lens-effect # LSP + concurrent execution
138
+ ```
139
+
140
+ ### `pi` vs `pi --lens-lsp`
141
+
142
+ | Feature | `pi` (Default) | `pi --lens-lsp` |
143
+ |---------|----------------|-----------------|
144
+ | **Type Checking** | Built-in TypeScriptClient | Full LSP (31 language servers) |
145
+ | **Auto-format** | Biome, Prettier, Ruff, etc. | ✅ Same |
146
+ | **Auto-fix** | ✅ Enabled by default | ✅ Same |
147
+ | **Secrets scan** | ✅ Blocks on hardcoded secrets | ✅ Same |
148
+ | **Languages** | TypeScript, Python (built-in) | 31 languages via LSP |
149
+ | **Python** | Ruff/pyright (built-in) | Pyright LSP |
150
+ | **Go, Rust, etc.** | Basic linting | Full LSP support |
151
+
152
+ **Recommendation:** Use `pi` for TypeScript/Python projects. Use `pi --lens-lsp` for multi-language projects or when you need full language server features.
153
+
154
+ See [docs/LSP_CONFIG.md](docs/LSP_CONFIG.md) for configuration options.
155
+
156
+ ---
157
+
158
+ ### Execution Modes
159
+
160
+ | Mode | Flag | Description |
161
+ |------|------|-------------|
162
+ | **Sequential** | (default) | Runners execute one at a time |
163
+ | **Concurrent** | `--lens-effect` | All runners in parallel via Effect-TS (Experimental) |
164
+
165
+ ---
166
+
167
+ ### On every write / edit
168
+
169
+ Every file write/edit triggers multiple analysis phases:
170
+
171
+ **Execution flow:**
172
+ 1. **Secrets scan** (pre-flight) Hardcoded secrets block immediately (non-runner check)
173
+ 2. **LSP integration** (Phase 3, with `--lens-lsp`) — Real-time type errors from language servers
174
+ 3. **Dispatch system** — Routes file to appropriate runners by `FileKind`
175
+ 4. **Runners execute** by priority (lower = earlier). See [Runners](#runners) section for full list.
176
+ 5. **Test runner detection** (post-write) Detects Jest/Vitest/Pytest and runs relevant tests
177
+
178
+ **With `--lens-effect`:** Dispatch runners execute concurrently via Effect-TS. Test runner remains sequential (step 5).
179
+
180
+ **Delta mode behavior:**
181
+ - **First write:** All issues tracked and stored in baseline
182
+ - **Subsequent edits:** Only **NEW** issues shown (pre-existing issues filtered out)
183
+ - **Goal:** Don't spam agent with issues they didn't cause
184
+
185
+ **Output shown inline:**
186
+ ```
187
+ 🔴 STOP — 1 issue(s) must be fixed:
188
+ L23: var total = sum(items); — use 'let' or 'const'
189
+ ```
190
+
191
+ > **Note:** Only **blocking** issues (`ts-lsp`, `pyright` errors, `type-safety` switch errors, secrets) appear inline. Warnings are tracked but not shown inline (noise reduction) — run `/lens-booboo` to see all warnings.
192
+
193
+ ---
194
+
195
+ ### Runners
196
+
197
+ pi-lens uses a **dispatcher-runner architecture** for extensible multi-language support. Runners are executed by priority (lower = earlier).
198
+
199
+ | Runner | Language | Priority | Output | Description |
200
+ |--------|----------|----------|--------|-------------|
201
+ | **ts-lsp** | TypeScript | 5 | Blocking | TypeScript errors (hard stops) |
202
+ | **pyright** | Python | 5 | Blocking | Python type errors (hard stops) |
203
+ | **biome** | TS/JS | 10 | Warning | Linting issues (delta-tracked) |
204
+ | **ruff** | Python | 10 | Warning | Python linting (delta-tracked) |
205
+ | **oxlint** | TS/JS | 12 | Warning | Fast Rust-based JS/TS linter |
206
+ | **tree-sitter** | TS/JS, Python | 14 | Mixed | AST-based structural analysis (17 patterns) |
207
+ | **ast-grep-napi** | TS/JS | 15 | Warning | **100x faster** structural analysis |
208
+ | **type-safety** | TS | 20 | Mixed | Switch exhaustiveness (blocking), other (warning) |
209
+ | **shellcheck** | Shell | 20 | Warning | Bash/sh/zsh/fish linting |
210
+ | **python-slop** | Python | 25 | Warning | AI slop detection (~40 patterns) |
211
+ | **spellcheck** | Markdown | 30 | Warning | Typo detection in docs |
212
+ | **ast-grep** | Go, Rust, Python, etc. | 30 | Warning | Structural analysis via CLI (fallback for non-TS/JS) |
213
+ | **similarity** | TS | 35 | Silent | Semantic duplicate detection (metrics only) |
214
+ | **architect** | All | 40 | Warning | Architectural rule violations |
215
+ | **go-vet** | Go | 50 | Warning | Go static analysis |
216
+ | **rust-clippy** | Rust | 50 | Warning | Rust linting |
217
+
218
+ **Priority legend:**
219
+ - **5** Type checkers (blocking errors)
220
+ - **10-15** — Linters and structural analysis
221
+ - **20-30** — Specialized checks (safety, slop, spellcheck)
222
+ - **35** Metrics only (silent)
223
+ - **40-50** Language-specific and architectural
224
+
225
+ **Output semantics:**
226
+ - **Blocking** Hard stop, must fix (type errors, secrets)
227
+ - **Warning** — Shown in `/lens-booboo`, not inline (noise reduction)
228
+ - **Silent** Tracked in metrics only, never shown
229
+
230
+ **Disabled runners:** `ts-slop` (merged into `ast-grep-napi`)
231
+
232
+ **Tree-sitter runner patterns** (priority 14, AST-based structural analysis):
233
+
234
+ TypeScript/JavaScript (12 patterns):
235
+ - 🔴 **Error**: empty-catch, hardcoded-secrets, eval
236
+ - 🟡 **Warning**: debugger, await-in-loop, console-statement, long-parameter-list, nested-ternary, deep-promise-chain, mixed-async-styles, deep-nesting
237
+
238
+ Python (6 patterns):
239
+ - 🔴 **Error**: bare-except, mutable-default-arg, eval-exec, unreachable-except
240
+ - 🟡 **Warning**: wildcard-import, is-vs-equals
241
+
242
+ **Custom tree-sitter queries:** Add `.yml` files to `.pi-lens/rules/tree-sitter-queries/{typescript,python}/`
243
+
244
+ **AI Slop Detection:** The `python-slop` runner (priority 25) detects low-quality patterns in Python code (~40 patterns). TypeScript/JavaScript slop detection is integrated into `ast-grep-napi` runner.
245
+
246
+ ---
247
+
248
+ ### Additional Safeguards
249
+
250
+ Safeguards that run **before** the dispatch system:
251
+
252
+ #### Secrets Scanning (Pre-flight)
253
+
254
+ Runs on every file write/edit **before** any other checks. Scans for:
255
+ - Stripe/OpenAI keys (`sk-*`)
256
+ - GitHub tokens (`ghp_*`, `github_pat_*`)
257
+ - AWS keys (`AKIA*`)
258
+ - Slack tokens (`xoxb-*`, `xoxp-*`)
259
+ - Private keys (`BEGIN PRIVATE KEY`)
260
+ - Hardcoded passwords and API keys
261
+
262
+ **Behavior:** Always blocking, always runs on all file types. Cannot be disabled — security takes precedence.
263
+
264
+ #### Agent Behavior Warnings
265
+
266
+ Inline heuristics to catch anti-patterns in real-time:
267
+
268
+ **Blind Write Detection**
269
+ - **Triggers:** Agent edits a file without reading it in the last 5 tool calls
270
+ - **Warning:** `⚠ BLIND WRITE — editing 'file.ts' without reading in the last 5 tool calls.`
271
+ - **Why:** Prevents edits based on stale assumptions
272
+
273
+ **Thrashing Detection**
274
+ - **Triggers:** 3+ consecutive identical tool calls within 30 seconds
275
+ - **Warning:** `🔴 THRASHING 3 consecutive 'edit' calls with no other action.`
276
+ - **Why:** Catches stuck loops where the agent repeats failed actions
277
+
278
+ **Behavior:** Warnings appear inline but do **not** block execution.
279
+
280
+ #### Custom ast-grep Rules
281
+
282
+ Create your own structural rules in `.pi-lens/rules/`:
283
+
284
+ ```yaml
285
+ # .pi-lens/rules/no-console-prod.yml
286
+ id: no-console-prod
287
+ language: javascript
288
+ rule:
289
+ pattern: console.$METHOD($$$ARGS)
290
+ message: "Remove console statements before production"
291
+ severity: warning
292
+ ```
293
+
294
+ See [docs/ast-grep-rules.md](docs/ast-grep-rules.md) for full guide.
295
+
296
+ ---
297
+
298
+ ### At Session Start
299
+
300
+ When pi starts a new session, pi-lens performs initialization scans to establish baselines and surface existing technical debt:
301
+
302
+ **Initialization sequence:**
303
+ 1. **Reset session state** — Clear metrics and complexity baselines
304
+ 2. **Initialize LSP** (with `--lens-lsp`) — Detect and auto-install language servers
305
+ 3. **Pre-install TypeScript LSP** (with `--lens-lsp`) — Warm up cache for instant response
306
+ 4. **Detect available tools** Biome, ast-grep, Ruff, Knip, jscpd, Madge, type-coverage, Go, Rust
307
+ 5. **Load architect rules** — If `architect.yml` or `.architect.yml` present
308
+ 6. **Detect test runner** — Jest, Vitest, Pytest, etc.
309
+
310
+ **Cached scans** (with 5-min TTL):
311
+ | Scan | Tool | Cached | Purpose |
312
+ |------|------|--------|---------|
313
+ | **TODOs** | Internal | No | Tech debt markers |
314
+ | **Dead code** | Knip | Yes | Unused exports/files/deps |
315
+ | **Duplicates** | jscpd | Yes | Copy-paste detection |
316
+ | **Exports** | ast-grep | No | Function index for similarity |
317
+
318
+ **Error debt tracking** (with `--error-debt` flag):
319
+ - If tests passed at end of previous session but fail now → **regression detected**
320
+ - Blocks agent until tests pass again
321
+
322
+ **Output:** Scan results appear in session startup notification
323
+
324
+ ---
325
+
326
+ ### Code Review
327
+
328
+ ```
329
+ /lens-booboo [path]
330
+ ```
331
+
332
+ Full codebase analysis with **10 tracked runners** producing a comprehensive report:
333
+
334
+ | # | Runner | What it finds |
335
+ |---|--------|---------------|
336
+ | 1 | **ast-grep (design smells)** | Structural issues (empty catch, no-debugger, etc.) |
337
+ | 2 | **ast-grep (similar functions)** | Duplicate function patterns across files |
338
+ | 3 | **semantic similarity (Amain)** | 57×72 matrix semantic clones (>75% similarity) |
339
+ | 4 | **complexity metrics** | Low MI, high cognitive complexity, AI slop indicators |
340
+ | 5 | **TODO scanner** | TODO/FIXME annotations and tech debt markers |
341
+ | 6 | **dead code (Knip)** | Unused exports, files, dependencies |
342
+ | 7 | **duplicate code (jscpd)** | Copy-paste blocks with line/token counts |
343
+ | 8 | **type coverage** | Percentage typed vs `any`, low-coverage files |
344
+ | 9 | **circular deps (Madge)** | Import cycles and dependency chains |
345
+ | 10 | **architectural rules** | Layer violations, file size limits, path rules |
346
+
347
+ **Output:**
348
+ - **Terminal:** Progress `[1/10] runner...` with timing, summary with findings per runner
349
+ - **JSON:** `.pi-lens/reviews/booboo-{timestamp}.json` (structured data for AI processing)
350
+ - **Markdown:** `.pi-lens/reviews/booboo-{timestamp}.md` (human-readable report)
351
+
352
+ **Usage:**
353
+ ```bash
354
+ /lens-booboo # Scan current directory
355
+ /lens-booboo ./src # Scan specific path
356
+ ```
357
+
358
+ ---
359
+
360
+ ### Test Runner
361
+
362
+ **Auto-detected test runners:**
363
+ | Runner | Config Files | Languages |
364
+ |--------|--------------|-----------|
365
+ | **Vitest** | `vitest.config.ts`, `vitest.config.js` | TypeScript, JavaScript |
366
+ | **Jest** | `jest.config.js`, `jest.config.ts`, `package.json` (jest field) | TypeScript, JavaScript |
367
+ | **Pytest** | `pytest.ini`, `setup.cfg`, `pyproject.toml` | Python |
368
+
369
+ **Behavior:**
370
+ - **On file write:** Detects corresponding test file and runs it
371
+ - **Pattern matching:** `file.ts` → `file.test.ts` or `__tests__/file.test.ts`
372
+ - **Output:** Inline pass/fail with failure details (shown with lint results)
373
+ - **Flag:** Use `--no-tests` to disable automatic test running
374
+
375
+ **Execution flow:**
376
+ 1. Agent writes `src/utils.ts`
377
+ 2. pi-lens finds `src/utils.test.ts` (or `__tests__/utils.test.ts`)
378
+ 3. Runs only that test file (not full suite)
379
+ 4. Results appear inline:
380
+ ```
381
+ [tests] 3 passed, 1 failed (42ms)
382
+ should calculate total
383
+ should handle empty array (expected 0, got undefined)
384
+ ```
385
+
386
+ **Why only corresponding tests?**
387
+ Running the full suite on every edit would be too slow. Targeted testing gives immediate feedback for the code being edited.
388
+
389
+ ---
390
+
391
+ ### Complexity Metrics
392
+
393
+ pi-lens calculates comprehensive code quality metrics for every source file:
394
+
395
+ | Metric | Range | Description | Thresholds |
396
+ |--------|-------|-------------|------------|
397
+ | **Maintainability Index (MI)** | 0-100 | Composite score combining complexity, size, and structure | <20: 🔴 Unmaintainable, 20-40: 🟡 Poor, >60: ✅ Good |
398
+ | **Cognitive Complexity** | 0+ | Human mental effort to understand code (nesting penalties) | >20: 🟡 Hard to understand, >50: 🔴 Very complex |
399
+ | **Cyclomatic Complexity** | 1+ | Independent code paths (branch points + 1) | >10: 🟡 Complex function, >20: 🔴 Highly complex |
400
+ | **Max Cyclomatic** | 1+ | Worst function in file | >10 flagged |
401
+ | **Nesting Depth** | 0+ | Maximum block nesting level | >4: 🟡 Deep nesting, >6: 🔴 Excessive |
402
+ | **Code Entropy** | 0-8+ bits | Shannon entropy unpredictability of code patterns | >3.5: 🟡 Risky AI-induced complexity |
403
+ | **Halstead Volume** | 0+ | Vocabulary × length unique ops/operands | High = many different operations |
404
+
405
+ **AI Slop Indicators:**
406
+ - Low MI + high cognitive complexity + high entropy = potential AI-generated spaghetti code
407
+ - Excessive comments (>40%) + low MI = hand-holding anti-patterns
408
+ - Single-use helpers with high entropy = over-abstraction
409
+
410
+ **Usage:**
411
+ - `/lens-booboo` Shows complexity table for all files
412
+ - `tool_result` — Complexity tracked per file, AI slop warnings inline
413
+
414
+ ---
415
+
416
+ ## Dependent Tools
417
+
418
+ pi-lens works out of the box for TypeScript/JavaScript. For full language support, install these tools — **all are optional and gracefully skip if not installed**:
419
+
420
+ ### JavaScript / TypeScript
421
+
422
+ | Tool | Install | What it does |
423
+ |------|---------|--------------|
424
+ | `@biomejs/biome` | `npm i -D @biomejs/biome` | Linting + formatting |
425
+ | `oxlint` | `npm i -D oxlint` | Fast Rust-based JS/TS linting |
426
+ | `knip` | `npm i -D knip` | Dead code / unused exports |
427
+ | `jscpd` | `npm i -D jscpd` | Copy-paste detection |
428
+ | `type-coverage` | `npm i -D type-coverage` | TypeScript `any` coverage % |
429
+ | `@ast-grep/napi` | `npm i -D @ast-grep/napi` | Fast structural analysis (TS/JS) |
430
+ | `@ast-grep/cli` | `npm i -D @ast-grep/cli` | Structural pattern matching (all languages) |
431
+ | `typos-cli` | `cargo install typos-cli` | Spellcheck for Markdown |
432
+
433
+ ### Python
434
+
435
+ | Tool | Install | What it does |
436
+ |------|---------|--------------|
437
+ | `ruff` | `pip install ruff` | Linting + formatting |
438
+ | `pyright` | `pip install pyright` | Type-checking (catches type errors) |
439
+
440
+ ### Go
441
+
442
+ | Tool | Install | What it does |
443
+ |------|---------|--------------|
444
+ | `go` | [golang.org](https://golang.org) | Built-in `go vet` for static analysis |
445
+
446
+ ### Rust
447
+
448
+ | Tool | Install | What it does |
449
+ |------|---------|--------------|
450
+ | `rust` + `clippy` | [rustup.rs](https://rustup.rs) | Linting via `cargo clippy` |
451
+
452
+ ### Shell
453
+
454
+ | Tool | Install | What it does |
455
+ |------|---------|--------------|
456
+ | `shellcheck` | `apt install shellcheck` / `brew install shellcheck` | Shell script linting (bash/sh/zsh/fish) |
457
+
458
+ ---
459
+
460
+ ## Commands
461
+
462
+ | Command | Description |
463
+ |---------|-------------|
464
+ | `/lens-booboo` | Full codebase review (10 analysis runners) |
465
+ | `/lens-format` | Apply Biome formatting |
466
+ | `/lens-tdi` | Technical Debt Index and trends |
467
+
468
+ ---
469
+
470
+ ## Execution Modes
471
+
472
+ | Mode | Command | What happens |
473
+ |------|---------|--------------|
474
+ | **Standard** (default) | `pi` | Auto-formatting, TS/Python type-checking, sequential execution |
475
+ | **Full LSP** | `pi --lens-lsp` | Real LSP servers (31 languages), sequential execution |
476
+ | **Fastest** | `pi --lens-lsp --lens-effect` | Real LSP + concurrent execution (all runners in parallel) |
477
+
478
+
479
+ ### Flag Reference
480
+
481
+ | Flag | Description |
482
+ |------|-------------|
483
+ | `--lens-lsp` | Use real Language Server Protocol servers instead of built-in type-checking |
484
+ | `--lens-effect` | Run all runners **concurrently** (faster) instead of sequentially (Experimental) |
485
+ | `--lens-verbose` | Enable detailed console logging |
486
+ | `--no-autoformat` | Disable automatic formatting (formatting is **enabled by default**) |
487
+ | `--no-autofix` | Disable all auto-fixing (Biome + Ruff autofix is **enabled by default**) |
488
+ | `--no-autofix-biome` | Disable Biome auto-fix only |
489
+ | `--no-autofix-ruff` | Disable Ruff auto-fix only |
490
+ | `--no-oxlint` | Skip Oxlint linting |
491
+ | `--no-shellcheck` | Skip shellcheck for shell scripts |
492
+ | `--no-tests` | Disable automatic test running on file write |
493
+ | `--no-madge` | Skip circular dependency checks |
494
+ | `--no-ast-grep` | Skip ast-grep structural analysis |
495
+ | `--no-biome` | Skip Biome linting |
496
+ | `--no-lsp` | Skip TypeScript/Python type checking |
497
+ | `--error-debt` | Track test regressions across sessions |
498
+
499
+ **Recommended combinations:**
500
+ ```bash
501
+ pi # Default: auto-format, auto-fix, built-in type-checking
502
+ pi --lens-lsp # LSP type-checking (31 languages)
503
+ pi --lens-lsp --lens-effect # LSP + concurrent execution (fastest)
504
+ ```
505
+
506
+ ---
507
+
508
+ ## TypeScript LSP — tsconfig detection
509
+
510
+ The LSP walks up from the edited file's directory until it finds a `tsconfig.json`. If found, it uses that project's exact `compilerOptions` (paths, strict settings, lib, etc.). If not found, it falls back to sensible defaults:
511
+
512
+ - `target: ES2020`
513
+ - `lib: ["es2020", "dom", "dom.iterable"]`
514
+ - `moduleResolution: bundler`
515
+ - `strict: true`
516
+
517
+ The compiler options are refreshed automatically when you switch between projects within a session.
518
+
519
+ ---
520
+
521
+ ## Exclusion Criteria
522
+
523
+ pi-lens automatically excludes certain files from analysis to reduce noise and focus on production code.
524
+
525
+ ### Test Files
526
+
527
+ All runners respect test file exclusions — both in the dispatch system (`skipTestFiles: true`) and the `/lens-booboo` command.
528
+
529
+ **Excluded patterns:**
530
+ ```
531
+ **/*.test.ts **/*.test.tsx **/*.test.js **/*.test.jsx
532
+ **/*.spec.ts **/*.spec.tsx **/*.spec.js **/*.spec.jsx
533
+ **/*.poc.test.ts **/*.poc.test.tsx
534
+ **/test-utils.ts **/test-*.ts
535
+ **/__tests__/** **/tests/** **/test/**
536
+ ```
537
+
538
+ **Why:** Test files intentionally duplicate patterns (test fixtures, mock setups) and have different complexity standards. Including them creates false positives.
539
+
540
+ ### Build Artifacts (TypeScript Projects)
541
+
542
+ In TypeScript projects (detected by `tsconfig.json` presence), compiled `.js` files are excluded:
543
+
544
+ ```
545
+ **/*.js **/*.jsx (when corresponding .ts/.tsx exists)
546
+ ```
547
+
548
+ **Why:** In TS projects, `.js` files are build artifacts. Analyzing them duplicates every issue (once in source `.ts`, once in compiled `.js`).
549
+
550
+ **Note:** In pure JavaScript projects (no `tsconfig.json`), `.js` files are **included** as they are the source files.
551
+
552
+ ### Excluded Directories
553
+
554
+ | Directory | Reason |
555
+ |-----------|--------|
556
+ | `node_modules/` | Third-party dependencies |
557
+ | `.git/` | Version control metadata |
558
+ | `dist/`, `build/` | Build outputs |
559
+ | `.pi-lens/`, `.pi/` | pi agent internal files |
560
+ | `.next/`, `.ruff_cache/` | Framework/build caches |
561
+ | `coverage/` | Test coverage reports |
562
+
563
+ ### Per-Runner Exclusion Summary
564
+
565
+ | Runner | Test Files | Build Artifacts | Directories |
566
+ |--------|-----------|-----------------|-------------|
567
+ | **dispatch runners** | ✅ `skipTestFiles` | ✅ `.js` excluded in TS | ✅ `EXCLUDED_DIRS` |
568
+ | **booboo /lens-booboo** | ✅ `shouldIncludeFile()` | ✅ `isTsProject` check | ✅ `EXCLUDED_DIRS` |
569
+ | **Secrets scan** | ❌ No exclusion (security) | ❌ No exclusion | ✅ Dirs excluded |
570
+
571
+ ---
572
+
573
+ ## Caching Architecture
574
+
575
+ pi-lens uses a multi-layer caching strategy to avoid redundant work:
576
+
577
+ ### 1. Tool Availability Cache
578
+
579
+ **Location:** `clients/tool-availability.ts`
580
+
581
+ ```
582
+ ┌─────────────────────────────────────────┐
583
+ │ TOOL AVAILABILITY CACHE │
584
+ │ Map<toolName, {available, version}> │
585
+ │ • Persisted for session lifetime │
586
+ │ • Refreshed on extension restart │
587
+ └─────────────────────────────────────────┘
588
+ ```
589
+
590
+ Avoids repeated `which`/`where` calls to check if `biome`, `ruff`, `pyright`, etc. are installed.
591
+
592
+ ### 2. Dispatch Baselines (Delta Mode)
593
+
594
+ **Location:** `clients/dispatch/dispatcher.ts`
595
+
596
+ ```
597
+ ┌─────────────────────────────────────────┐
598
+ │ DISPATCH BASELINES │
599
+ │ Map<filePath, Diagnostic[]> │
600
+ │ • Cleared at turn start │
601
+ │ • Updated after each runner execution │
602
+ │ • Filters: only NEW issues shown │
603
+ └─────────────────────────────────────────┘
604
+ ```
605
+
606
+ Delta mode tracking: first edit shows all issues, subsequent edits only show issues that weren't there before.
607
+
608
+ ### 3. Client-Level Caches
609
+
610
+ | Client | Cache | TTL | Purpose |
611
+ |--------|-------|-----|---------|
612
+ | **Knip** | `clients/cache-manager.ts` | 5 min | Dead code analysis (slow) |
613
+ | **jscpd** | `clients/cache-manager.ts` | 5 min | Duplicate detection (slow) |
614
+ | **Type Coverage** | In-memory | Session | `any` type percentage |
615
+ | **Complexity** | In-memory | File-level | MI, cognitive complexity per file |
616
+
617
+ ### 4. Session Turn State
618
+
619
+ **Location:** `clients/cache-manager.ts`
620
+
621
+ ```
622
+ ┌─────────────────────────────────────────┐
623
+ │ TURN STATE TRACKING │
624
+ │ • Modified files this turn │
625
+ │ • Modified line ranges per file │
626
+ │ • Import changes detected │
627
+ │ • Turn cycle counter (max 10) │
628
+ └─────────────────────────────────────────┘
629
+ ```
630
+
631
+ Tracks which files were edited in the current agent turn for:
632
+ - jscpd: Only re-scan modified files
633
+ - Madge: Only check deps if imports changed
634
+ - Cycle detection: Prevents infinite fix loops
635
+
636
+ ### 5. Runner Internal Caches
637
+
638
+ | Runner | Cache | Notes |
639
+ |--------|-------|-------|
640
+ | `ast-grep-napi` | Rule descriptions | Loaded once per session |
641
+ | `biome` | Tool availability | Checked once, cached |
642
+ | `pyright` | Command path | Venv lookup cached |
643
+ | `ruff` | Command path | Venv lookup cached |
644
+
645
+ ---
646
+
647
+ ## Project Structure
648
+
649
+ ```
650
+ pi-lens/
651
+ ├── clients/ # Lint tool wrappers and utilities
652
+ │ ├── bus/ # Event bus system (Phase 1)
653
+ │ │ ├── bus.ts
654
+ │ │ ├── events.ts
655
+ │ │ └── integration.ts
656
+ │ ├── dispatch/ # Dispatcher and runners
657
+ │ │ ├── dispatcher.ts
658
+ │ │ └── runners/ # Individual runners
659
+ │ │ ├── ast-grep-napi.ts # Fast TS/JS runner
660
+ │ │ ├── python-slop.ts # Python slop detection
661
+ │ │ ├── ts-lsp.ts # TS type checking
662
+ │ │ ├── biome.ts
663
+ │ │ ├── ruff.ts
664
+ │ │ ├── pyright.ts
665
+ │ │ ├── go-vet.ts
666
+ │ │ └── rust-clippy.ts
667
+ │ ├── lsp/ # LSP client system (Phase 3)
668
+ │ │ ├── client.ts
669
+ │ │ ├── server.ts # 31 LSP server definitions
670
+ │ │ ├── language.ts
671
+ │ │ ├── launch.ts
672
+ │ │ └── config.ts # Custom LSP configuration
673
+ │ ├── installer/ # Auto-installation (Phase 4)
674
+ │ │ └── index.ts
675
+ │ ├── services/ # Effect-TS services (Phase 2)
676
+ │ │ ├── runner-service.ts
677
+ │ │ └── effect-integration.ts
678
+ │ ├── complexity-client.ts
679
+ │ ├── type-safety-client.ts
680
+ │ └── secrets-scanner.ts
681
+ ├── commands/ # pi commands
682
+ │ ├── booboo.ts
683
+ │ └── fix-simplified.ts
684
+ ├── docs/ # Documentation
685
+ │ └── LSP_CONFIG.md # LSP configuration guide
686
+ ├── rules/ # AST-grep rules
687
+ │ └── ast-grep-rules/ # General structural rules
688
+ ├── index.ts # Main entry point
689
+ └── package.json
690
+ ```
691
+
692
+ ---
693
+
694
+ ## Changelog
695
+
696
+ See [CHANGELOG.md](CHANGELOG.md) for full history.
697
+
698
+ ### Latest Highlights
699
+
700
+ - **LSP Support:** 31 Language Server Protocol clients (4 core auto-installed, others via npx or manual)
701
+ - **Concurrent Execution:** Effect-TS-based parallel runner execution with `--lens-effect`
702
+ - **NAPI Runner:** 100x faster TypeScript/JavaScript structural analysis (~9ms vs ~1200ms)
703
+ - **Slop Detection:** 30+ TypeScript and 40+ Python patterns for AI-generated code quality issues
704
+
705
+ ---
706
+
707
+ ## License
708
+
709
+ MIT