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,214 @@
1
+ /**
2
+ * Bus Integration for pi-lens
3
+ *
4
+ * Connects the event bus system to the existing pi-lens architecture.
5
+ * This provides:
6
+ * - Event aggregation for diagnostic collection
7
+ * - Real-time progress tracking
8
+ * - Hook integration for tool_result handler
9
+ */
10
+
11
+ import {
12
+ DiagnosticFound,
13
+ RunnerStarted,
14
+ RunnerCompleted,
15
+ ReportReady,
16
+ FileModified,
17
+ SessionStarted,
18
+ TurnEnded,
19
+ DiagnosticAggregator,
20
+ type Diagnostic,
21
+ } from "./events.js";
22
+ import { subscribe, enableDebug } from "./bus.js";
23
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
24
+
25
+ // --- Integration State ---
26
+
27
+ interface IntegrationState {
28
+ aggregator: DiagnosticAggregator;
29
+ runnerInProgress: Set<string>; // runnerId:filePath
30
+ lastReport: Map<string, { output: string; timestamp: number }>;
31
+ isEnabled: boolean;
32
+ }
33
+
34
+ const state: IntegrationState = {
35
+ aggregator: new DiagnosticAggregator(),
36
+ runnerInProgress: new Set(),
37
+ lastReport: new Map(),
38
+ isEnabled: false,
39
+ };
40
+
41
+ // --- Event Subscribers ---
42
+
43
+ let unsubscribers: Array<() => void> = [];
44
+
45
+ /**
46
+ * Initialize the bus integration
47
+ * Call this from session_start handler
48
+ */
49
+ export function initBusIntegration(pi: ExtensionAPI, options?: { debug?: boolean }): void {
50
+ if (state.isEnabled) return; // Already initialized
51
+
52
+ if (options?.debug) {
53
+ enableDebug(true);
54
+ }
55
+
56
+ // Start the diagnostic aggregator
57
+ state.aggregator.start();
58
+
59
+ // Subscribe to runner progress events for UI feedback
60
+ const unsubRunnerStarted = RunnerStarted.subscribe((event) => {
61
+ const { runnerId, filePath } = event.properties;
62
+ state.runnerInProgress.add(`${runnerId}:${filePath}`);
63
+ });
64
+
65
+ const unsubRunnerCompleted = RunnerCompleted.subscribe((event) => {
66
+ const { runnerId, filePath, durationMs, diagnosticCount } = event.properties;
67
+ state.runnerInProgress.delete(`${runnerId}:${filePath}`);
68
+
69
+ // Log slow runners in debug mode
70
+ if (options?.debug && durationMs > 5000) {
71
+ console.error(`[bus] Slow runner: ${runnerId} took ${durationMs}ms for ${filePath}`);
72
+ }
73
+
74
+ // Log runners that found issues
75
+ if (diagnosticCount > 0) {
76
+ console.error(`[bus] ${runnerId} found ${diagnosticCount} issues in ${filePath}`);
77
+ }
78
+ });
79
+
80
+ // Cache reports for quick retrieval
81
+ const unsubReportReady = ReportReady.subscribe((event) => {
82
+ const { filePath, report, durationMs } = event.properties;
83
+
84
+ // Store the report
85
+ state.lastReport.set(filePath, {
86
+ output: formatReport(report, durationMs),
87
+ timestamp: Date.now(),
88
+ });
89
+ });
90
+
91
+ // Track file modifications to clear stale data
92
+ const unsubFileModified = FileModified.subscribe((event) => {
93
+ const { filePath } = event.properties;
94
+
95
+ // Clear cached report for modified file
96
+ state.lastReport.delete(filePath);
97
+
98
+ // Clear diagnostics aggregator for this file (will be repopulated)
99
+ state.aggregator.clear(filePath);
100
+ });
101
+
102
+ // Store unsubscribers for cleanup
103
+ unsubscribers = [
104
+ unsubRunnerStarted,
105
+ unsubRunnerCompleted,
106
+ unsubReportReady,
107
+ unsubFileModified,
108
+ ];
109
+
110
+ state.isEnabled = true;
111
+
112
+ console.error("[pi-lens] Bus integration initialized");
113
+ }
114
+
115
+ /**
116
+ * Shutdown the bus integration
117
+ * Call this when the extension is disabled
118
+ */
119
+ export function shutdownBusIntegration(): void {
120
+ if (!state.isEnabled) return;
121
+
122
+ // Stop all subscribers
123
+ for (const unsub of unsubscribers) {
124
+ unsub();
125
+ }
126
+ unsubscribers = [];
127
+
128
+ // Stop the aggregator
129
+ state.aggregator.stop();
130
+
131
+ // Clear all state
132
+ state.runnerInProgress.clear();
133
+ state.lastReport.clear();
134
+ state.aggregator.clear();
135
+
136
+ state.isEnabled = false;
137
+ }
138
+
139
+ // --- Helper Functions ---
140
+
141
+ function formatReport(
142
+ report: { blockers: Diagnostic[]; warnings: Diagnostic[]; fixed: Diagnostic[]; silent: Diagnostic[] },
143
+ durationMs: number,
144
+ ): string {
145
+ const lines: string[] = [];
146
+
147
+ if (report.blockers.length > 0) {
148
+ lines.push(`🔴 STOP — ${report.blockers.length} issue(s) must be fixed:`);
149
+ for (const d of report.blockers.slice(0, 5)) {
150
+ const line = d.line ? `L${d.line}: ` : "";
151
+ lines.push(` ${line}${d.message.split("\n")[0]}`);
152
+ }
153
+ if (report.blockers.length > 5) {
154
+ lines.push(` ... and ${report.blockers.length - 5} more`);
155
+ }
156
+ }
157
+
158
+ if (report.fixed.length > 0) {
159
+ lines.push(`✅ Auto-fixed ${report.fixed.length} issue(s)`);
160
+ }
161
+
162
+ if (lines.length > 0) {
163
+ lines.push(`(completed in ${durationMs}ms)`);
164
+ }
165
+
166
+ return lines.join("\n");
167
+ }
168
+
169
+ // --- API for index.ts ---
170
+
171
+ /**
172
+ * Get aggregated diagnostics for a file
173
+ */
174
+ export function getDiagnosticsForFile(filePath: string): Diagnostic[] {
175
+ return state.aggregator.getForFile(filePath);
176
+ }
177
+
178
+ /**
179
+ * Get the last report output for a file
180
+ */
181
+ export function getLastReport(filePath: string): string | undefined {
182
+ return state.lastReport.get(filePath)?.output;
183
+ }
184
+
185
+ /**
186
+ * Check if any runners are currently in progress for a file
187
+ */
188
+ export function hasRunnersInProgress(filePath?: string): boolean {
189
+ if (filePath) {
190
+ for (const key of state.runnerInProgress) {
191
+ if (key.endsWith(`:${filePath}`)) return true;
192
+ }
193
+ return false;
194
+ }
195
+ return state.runnerInProgress.size > 0;
196
+ }
197
+
198
+ /**
199
+ * Get list of runners in progress
200
+ */
201
+ export function getRunnersInProgress(): Array<{ runnerId: string; filePath: string }> {
202
+ return Array.from(state.runnerInProgress).map((key) => {
203
+ const [runnerId, filePath] = key.split(":");
204
+ return { runnerId, filePath };
205
+ });
206
+ }
207
+
208
+ /**
209
+ * Clear all cached data
210
+ */
211
+ export function clearBusCache(): void {
212
+ state.lastReport.clear();
213
+ state.aggregator.clear();
214
+ }
@@ -319,24 +319,30 @@ export class ComplexityClient {
319
319
  */
320
320
  checkThresholds(metrics) {
321
321
  const warnings = [];
322
- if (metrics.maintainabilityIndex < 60) {
322
+ // TUNED: Only flag extreme cases to reduce noise
323
+ // MI < 30 is "critically poor" (was < 60, too aggressive)
324
+ if (metrics.maintainabilityIndex < 30) {
323
325
  warnings.push(`Maintainability dropped to ${metrics.maintainabilityIndex} — extract logic into helper functions`);
324
326
  }
325
- if (metrics.cyclomaticComplexity > 10) {
327
+ // Cyclomatic > 20 is very high (was > 10)
328
+ if (metrics.cyclomaticComplexity > 20) {
326
329
  warnings.push(`High complexity (${metrics.cyclomaticComplexity}) — use early returns or switch expressions`);
327
330
  }
328
- if (metrics.cognitiveComplexity > 15) {
331
+ // Cognitive > 50 is high (was > 15, flagged almost everything)
332
+ if (metrics.cognitiveComplexity > 50) {
329
333
  warnings.push(`Cognitive complexity (${metrics.cognitiveComplexity}) — simplify logic flow`);
330
334
  }
331
- if (metrics.maxNestingDepth > 4) {
335
+ // Nesting > 6 is deep (was > 4, normal for complex code)
336
+ if (metrics.maxNestingDepth > 6) {
332
337
  warnings.push(`Deep nesting (${metrics.maxNestingDepth} levels) — extract nested logic into separate functions`);
333
338
  }
334
- if (metrics.codeEntropy > 3.5) {
339
+ // Entropy > 5.0 is high (was > 3.5, too sensitive)
340
+ if (metrics.codeEntropy > 5.0) {
335
341
  warnings.push(`High entropy (${metrics.codeEntropy.toFixed(1)} bits) — follow project conventions`);
336
342
  }
337
- // Comments ratio (>40% = excessive comments, AI slop signal)
343
+ // Comments ratio (>60% = excessive, was > 40%)
338
344
  const totalLines = metrics.linesOfCode + metrics.commentLines;
339
- if (totalLines > 10 && metrics.commentLines / totalLines > 0.4) {
345
+ if (totalLines > 10 && metrics.commentLines / totalLines > 0.6) {
340
346
  warnings.push(`Excessive comments (${Math.round((metrics.commentLines / totalLines) * 100)}%) — remove obvious comments`);
341
347
  }
342
348
  // Verbose code (long functions with low complexity = overly verbose)
@@ -451,39 +451,45 @@ export class ComplexityClient {
451
451
  checkThresholds(metrics: FileComplexity): string[] {
452
452
  const warnings: string[] = [];
453
453
 
454
- if (metrics.maintainabilityIndex < 60) {
454
+ // TUNED: Only flag extreme cases to reduce noise
455
+ // MI < 30 is "critically poor" (was < 60, too aggressive)
456
+ if (metrics.maintainabilityIndex < 30) {
455
457
  warnings.push(
456
458
  `Maintainability dropped to ${metrics.maintainabilityIndex} — extract logic into helper functions`,
457
459
  );
458
460
  }
459
461
 
460
- if (metrics.cyclomaticComplexity > 10) {
462
+ // Cyclomatic > 20 is very high (was > 10)
463
+ if (metrics.cyclomaticComplexity > 20) {
461
464
  warnings.push(
462
465
  `High complexity (${metrics.cyclomaticComplexity}) — use early returns or switch expressions`,
463
466
  );
464
467
  }
465
468
 
466
- if (metrics.cognitiveComplexity > 15) {
469
+ // Cognitive > 50 is high (was > 15, flagged almost everything)
470
+ if (metrics.cognitiveComplexity > 50) {
467
471
  warnings.push(
468
472
  `Cognitive complexity (${metrics.cognitiveComplexity}) — simplify logic flow`,
469
473
  );
470
474
  }
471
475
 
472
- if (metrics.maxNestingDepth > 4) {
476
+ // Nesting > 6 is deep (was > 4, normal for complex code)
477
+ if (metrics.maxNestingDepth > 6) {
473
478
  warnings.push(
474
479
  `Deep nesting (${metrics.maxNestingDepth} levels) — extract nested logic into separate functions`,
475
480
  );
476
481
  }
477
482
 
478
- if (metrics.codeEntropy > 3.5) {
483
+ // Entropy > 5.0 is high (was > 3.5, too sensitive)
484
+ if (metrics.codeEntropy > 5.0) {
479
485
  warnings.push(
480
486
  `High entropy (${metrics.codeEntropy.toFixed(1)} bits) — follow project conventions`,
481
487
  );
482
488
  }
483
489
 
484
- // Comments ratio (>40% = excessive comments, AI slop signal)
490
+ // Comments ratio (>60% = excessive, was > 40%)
485
491
  const totalLines = metrics.linesOfCode + metrics.commentLines;
486
- if (totalLines > 10 && metrics.commentLines / totalLines > 0.4) {
492
+ if (totalLines > 10 && metrics.commentLines / totalLines > 0.6) {
487
493
  warnings.push(
488
494
  `Excessive comments (${Math.round((metrics.commentLines / totalLines) * 100)}%) — remove obvious comments`,
489
495
  );