@lbroth/rothunter 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/adapters/llm.d.ts +68 -0
  4. package/dist/adapters/llm.d.ts.map +1 -0
  5. package/dist/adapters/llm.js +189 -0
  6. package/dist/adapters/llm.js.map +1 -0
  7. package/dist/config.d.ts +37 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +81 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/detector-registry.d.ts +32 -0
  12. package/dist/detector-registry.d.ts.map +1 -0
  13. package/dist/detector-registry.js +74 -0
  14. package/dist/detector-registry.js.map +1 -0
  15. package/dist/detectors/api-race.d.ts +6 -0
  16. package/dist/detectors/api-race.d.ts.map +1 -0
  17. package/dist/detectors/api-race.js +222 -0
  18. package/dist/detectors/api-race.js.map +1 -0
  19. package/dist/detectors/bad-config.d.ts +6 -0
  20. package/dist/detectors/bad-config.d.ts.map +1 -0
  21. package/dist/detectors/bad-config.js +529 -0
  22. package/dist/detectors/bad-config.js.map +1 -0
  23. package/dist/detectors/console-log-prod.d.ts +6 -0
  24. package/dist/detectors/console-log-prod.d.ts.map +1 -0
  25. package/dist/detectors/console-log-prod.js +72 -0
  26. package/dist/detectors/console-log-prod.js.map +1 -0
  27. package/dist/detectors/dead-api.d.ts +10 -0
  28. package/dist/detectors/dead-api.d.ts.map +1 -0
  29. package/dist/detectors/dead-api.js +115 -0
  30. package/dist/detectors/dead-api.js.map +1 -0
  31. package/dist/detectors/dead-export.d.ts +12 -0
  32. package/dist/detectors/dead-export.d.ts.map +1 -0
  33. package/dist/detectors/dead-export.js +140 -0
  34. package/dist/detectors/dead-export.js.map +1 -0
  35. package/dist/detectors/dead-handler.d.ts +12 -0
  36. package/dist/detectors/dead-handler.d.ts.map +1 -0
  37. package/dist/detectors/dead-handler.js +40 -0
  38. package/dist/detectors/dead-handler.js.map +1 -0
  39. package/dist/detectors/dead-module.d.ts +14 -0
  40. package/dist/detectors/dead-module.d.ts.map +1 -0
  41. package/dist/detectors/dead-module.js +50 -0
  42. package/dist/detectors/dead-module.js.map +1 -0
  43. package/dist/detectors/deep-nesting.d.ts +12 -0
  44. package/dist/detectors/deep-nesting.d.ts.map +1 -0
  45. package/dist/detectors/deep-nesting.js +133 -0
  46. package/dist/detectors/deep-nesting.js.map +1 -0
  47. package/dist/detectors/duplicate-function.d.ts +9 -0
  48. package/dist/detectors/duplicate-function.d.ts.map +1 -0
  49. package/dist/detectors/duplicate-function.js +199 -0
  50. package/dist/detectors/duplicate-function.js.map +1 -0
  51. package/dist/detectors/duplicate-type.d.ts +9 -0
  52. package/dist/detectors/duplicate-type.d.ts.map +1 -0
  53. package/dist/detectors/duplicate-type.js +166 -0
  54. package/dist/detectors/duplicate-type.js.map +1 -0
  55. package/dist/detectors/hot-hub-file.d.ts +11 -0
  56. package/dist/detectors/hot-hub-file.d.ts.map +1 -0
  57. package/dist/detectors/hot-hub-file.js +42 -0
  58. package/dist/detectors/hot-hub-file.js.map +1 -0
  59. package/dist/detectors/long-file.d.ts +12 -0
  60. package/dist/detectors/long-file.d.ts.map +1 -0
  61. package/dist/detectors/long-file.js +82 -0
  62. package/dist/detectors/long-file.js.map +1 -0
  63. package/dist/detectors/long-function.d.ts +12 -0
  64. package/dist/detectors/long-function.d.ts.map +1 -0
  65. package/dist/detectors/long-function.js +45 -0
  66. package/dist/detectors/long-function.js.map +1 -0
  67. package/dist/detectors/magic-numbers.d.ts +10 -0
  68. package/dist/detectors/magic-numbers.d.ts.map +1 -0
  69. package/dist/detectors/magic-numbers.js +332 -0
  70. package/dist/detectors/magic-numbers.js.map +1 -0
  71. package/dist/detectors/mutable-globals.d.ts +6 -0
  72. package/dist/detectors/mutable-globals.d.ts.map +1 -0
  73. package/dist/detectors/mutable-globals.js +95 -0
  74. package/dist/detectors/mutable-globals.js.map +1 -0
  75. package/dist/detectors/mutation.d.ts +11 -0
  76. package/dist/detectors/mutation.d.ts.map +1 -0
  77. package/dist/detectors/mutation.js +397 -0
  78. package/dist/detectors/mutation.js.map +1 -0
  79. package/dist/detectors/public-any.d.ts +6 -0
  80. package/dist/detectors/public-any.d.ts.map +1 -0
  81. package/dist/detectors/public-any.js +52 -0
  82. package/dist/detectors/public-any.js.map +1 -0
  83. package/dist/detectors/race-condition.d.ts +6 -0
  84. package/dist/detectors/race-condition.d.ts.map +1 -0
  85. package/dist/detectors/race-condition.js +608 -0
  86. package/dist/detectors/race-condition.js.map +1 -0
  87. package/dist/detectors/shared-db-write.d.ts +6 -0
  88. package/dist/detectors/shared-db-write.d.ts.map +1 -0
  89. package/dist/detectors/shared-db-write.js +656 -0
  90. package/dist/detectors/shared-db-write.js.map +1 -0
  91. package/dist/detectors/silent-catch.d.ts +6 -0
  92. package/dist/detectors/silent-catch.d.ts.map +1 -0
  93. package/dist/detectors/silent-catch.js +167 -0
  94. package/dist/detectors/silent-catch.js.map +1 -0
  95. package/dist/detectors/similar-functions.d.ts +15 -0
  96. package/dist/detectors/similar-functions.d.ts.map +1 -0
  97. package/dist/detectors/similar-functions.js +334 -0
  98. package/dist/detectors/similar-functions.js.map +1 -0
  99. package/dist/detectors/skip-tests.d.ts +6 -0
  100. package/dist/detectors/skip-tests.d.ts.map +1 -0
  101. package/dist/detectors/skip-tests.js +69 -0
  102. package/dist/detectors/skip-tests.js.map +1 -0
  103. package/dist/detectors/todo-comments.d.ts +29 -0
  104. package/dist/detectors/todo-comments.d.ts.map +1 -0
  105. package/dist/detectors/todo-comments.js +154 -0
  106. package/dist/detectors/todo-comments.js.map +1 -0
  107. package/dist/detectors/unused-deps.d.ts +8 -0
  108. package/dist/detectors/unused-deps.d.ts.map +1 -0
  109. package/dist/detectors/unused-deps.js +115 -0
  110. package/dist/detectors/unused-deps.js.map +1 -0
  111. package/dist/extraction/api-race-confirmer.d.ts +31 -0
  112. package/dist/extraction/api-race-confirmer.d.ts.map +1 -0
  113. package/dist/extraction/api-race-confirmer.js +110 -0
  114. package/dist/extraction/api-race-confirmer.js.map +1 -0
  115. package/dist/extraction/llm-confirmer.d.ts +25 -0
  116. package/dist/extraction/llm-confirmer.d.ts.map +1 -0
  117. package/dist/extraction/llm-confirmer.js +118 -0
  118. package/dist/extraction/llm-confirmer.js.map +1 -0
  119. package/dist/extraction/mutation-confirmer.d.ts +30 -0
  120. package/dist/extraction/mutation-confirmer.d.ts.map +1 -0
  121. package/dist/extraction/mutation-confirmer.js +73 -0
  122. package/dist/extraction/mutation-confirmer.js.map +1 -0
  123. package/dist/extraction/prompt-chunking.d.ts +37 -0
  124. package/dist/extraction/prompt-chunking.d.ts.map +1 -0
  125. package/dist/extraction/prompt-chunking.js +61 -0
  126. package/dist/extraction/prompt-chunking.js.map +1 -0
  127. package/dist/extraction/race-confirmer.d.ts +28 -0
  128. package/dist/extraction/race-confirmer.d.ts.map +1 -0
  129. package/dist/extraction/race-confirmer.js +68 -0
  130. package/dist/extraction/race-confirmer.js.map +1 -0
  131. package/dist/extraction/shared-db-write-confirmer.d.ts +31 -0
  132. package/dist/extraction/shared-db-write-confirmer.d.ts.map +1 -0
  133. package/dist/extraction/shared-db-write-confirmer.js +141 -0
  134. package/dist/extraction/shared-db-write-confirmer.js.map +1 -0
  135. package/dist/extraction/triage-confirmer.d.ts +59 -0
  136. package/dist/extraction/triage-confirmer.d.ts.map +1 -0
  137. package/dist/extraction/triage-confirmer.js +104 -0
  138. package/dist/extraction/triage-confirmer.js.map +1 -0
  139. package/dist/graph/cfg.d.ts +45 -0
  140. package/dist/graph/cfg.d.ts.map +1 -0
  141. package/dist/graph/cfg.js +198 -0
  142. package/dist/graph/cfg.js.map +1 -0
  143. package/dist/graph/decorator-entries.d.ts +2 -0
  144. package/dist/graph/decorator-entries.d.ts.map +1 -0
  145. package/dist/graph/decorator-entries.js +89 -0
  146. package/dist/graph/decorator-entries.js.map +1 -0
  147. package/dist/graph/entry-points.d.ts +12 -0
  148. package/dist/graph/entry-points.d.ts.map +1 -0
  149. package/dist/graph/entry-points.js +282 -0
  150. package/dist/graph/entry-points.js.map +1 -0
  151. package/dist/graph/handler-conventions.d.ts +2 -0
  152. package/dist/graph/handler-conventions.d.ts.map +1 -0
  153. package/dist/graph/handler-conventions.js +26 -0
  154. package/dist/graph/handler-conventions.js.map +1 -0
  155. package/dist/graph/iac-entries.d.ts +2 -0
  156. package/dist/graph/iac-entries.d.ts.map +1 -0
  157. package/dist/graph/iac-entries.js +123 -0
  158. package/dist/graph/iac-entries.js.map +1 -0
  159. package/dist/graph/import-graph.d.ts +48 -0
  160. package/dist/graph/import-graph.d.ts.map +1 -0
  161. package/dist/graph/import-graph.js +86 -0
  162. package/dist/graph/import-graph.js.map +1 -0
  163. package/dist/graph/monorepo-detect.d.ts +3 -0
  164. package/dist/graph/monorepo-detect.d.ts.map +1 -0
  165. package/dist/graph/monorepo-detect.js +166 -0
  166. package/dist/graph/monorepo-detect.js.map +1 -0
  167. package/dist/graph/tsconfig-paths.d.ts +23 -0
  168. package/dist/graph/tsconfig-paths.d.ts.map +1 -0
  169. package/dist/graph/tsconfig-paths.js +217 -0
  170. package/dist/graph/tsconfig-paths.js.map +1 -0
  171. package/dist/multi-workspace-scanner.d.ts +13 -0
  172. package/dist/multi-workspace-scanner.d.ts.map +1 -0
  173. package/dist/multi-workspace-scanner.js +130 -0
  174. package/dist/multi-workspace-scanner.js.map +1 -0
  175. package/dist/normalizers/type-normalizer.d.ts +16 -0
  176. package/dist/normalizers/type-normalizer.d.ts.map +1 -0
  177. package/dist/normalizers/type-normalizer.js +189 -0
  178. package/dist/normalizers/type-normalizer.js.map +1 -0
  179. package/dist/parsers/typescript-parser.d.ts +57 -0
  180. package/dist/parsers/typescript-parser.d.ts.map +1 -0
  181. package/dist/parsers/typescript-parser.js +502 -0
  182. package/dist/parsers/typescript-parser.js.map +1 -0
  183. package/dist/reporter/json-reporter.d.ts +12 -0
  184. package/dist/reporter/json-reporter.d.ts.map +1 -0
  185. package/dist/reporter/json-reporter.js +28 -0
  186. package/dist/reporter/json-reporter.js.map +1 -0
  187. package/dist/reporter/markdown-reporter.d.ts +11 -0
  188. package/dist/reporter/markdown-reporter.d.ts.map +1 -0
  189. package/dist/reporter/markdown-reporter.js +77 -0
  190. package/dist/reporter/markdown-reporter.js.map +1 -0
  191. package/dist/rothunter.d.ts +125 -0
  192. package/dist/rothunter.d.ts.map +1 -0
  193. package/dist/rothunter.js +1038 -0
  194. package/dist/rothunter.js.map +1 -0
  195. package/dist/server/false-positives.d.ts +34 -0
  196. package/dist/server/false-positives.d.ts.map +1 -0
  197. package/dist/server/false-positives.js +85 -0
  198. package/dist/server/false-positives.js.map +1 -0
  199. package/dist/server/index.d.ts +2 -0
  200. package/dist/server/index.d.ts.map +1 -0
  201. package/dist/server/index.js +1529 -0
  202. package/dist/server/index.js.map +1 -0
  203. package/dist/server/marked-to-fix.d.ts +16 -0
  204. package/dist/server/marked-to-fix.d.ts.map +1 -0
  205. package/dist/server/marked-to-fix.js +36 -0
  206. package/dist/server/marked-to-fix.js.map +1 -0
  207. package/dist/server/scan-store.d.ts +147 -0
  208. package/dist/server/scan-store.d.ts.map +1 -0
  209. package/dist/server/scan-store.js +291 -0
  210. package/dist/server/scan-store.js.map +1 -0
  211. package/dist/server/settings-store.d.ts +28 -0
  212. package/dist/server/settings-store.d.ts.map +1 -0
  213. package/dist/server/settings-store.js +46 -0
  214. package/dist/server/settings-store.js.map +1 -0
  215. package/dist/server/workspace-store.d.ts +39 -0
  216. package/dist/server/workspace-store.d.ts.map +1 -0
  217. package/dist/server/workspace-store.js +108 -0
  218. package/dist/server/workspace-store.js.map +1 -0
  219. package/dist/types/detector-input.d.ts +37 -0
  220. package/dist/types/detector-input.d.ts.map +1 -0
  221. package/dist/types/detector-input.js +2 -0
  222. package/dist/types/detector-input.js.map +1 -0
  223. package/dist/types.d.ts +110 -0
  224. package/dist/types.d.ts.map +1 -0
  225. package/dist/types.js +2 -0
  226. package/dist/types.js.map +1 -0
  227. package/dist/utils/clustering.d.ts +14 -0
  228. package/dist/utils/clustering.d.ts.map +1 -0
  229. package/dist/utils/clustering.js +56 -0
  230. package/dist/utils/clustering.js.map +1 -0
  231. package/dist/utils/gitignore.d.ts +32 -0
  232. package/dist/utils/gitignore.d.ts.map +1 -0
  233. package/dist/utils/gitignore.js +122 -0
  234. package/dist/utils/gitignore.js.map +1 -0
  235. package/dist/utils/hash.d.ts +11 -0
  236. package/dist/utils/hash.d.ts.map +1 -0
  237. package/dist/utils/hash.js +14 -0
  238. package/dist/utils/hash.js.map +1 -0
  239. package/dist/utils/ignore-annotation.d.ts +28 -0
  240. package/dist/utils/ignore-annotation.d.ts.map +1 -0
  241. package/dist/utils/ignore-annotation.js +46 -0
  242. package/dist/utils/ignore-annotation.js.map +1 -0
  243. package/dist/utils/llm-json.d.ts +2 -0
  244. package/dist/utils/llm-json.d.ts.map +1 -0
  245. package/dist/utils/llm-json.js +53 -0
  246. package/dist/utils/llm-json.js.map +1 -0
  247. package/dist/utils/logger.d.ts +3 -0
  248. package/dist/utils/logger.d.ts.map +1 -0
  249. package/dist/utils/logger.js +4 -0
  250. package/dist/utils/logger.js.map +1 -0
  251. package/dist/utils/project-conventions.d.ts +2 -0
  252. package/dist/utils/project-conventions.d.ts.map +1 -0
  253. package/dist/utils/project-conventions.js +108 -0
  254. package/dist/utils/project-conventions.js.map +1 -0
  255. package/dist/utils/regex.d.ts +9 -0
  256. package/dist/utils/regex.d.ts.map +1 -0
  257. package/dist/utils/regex.js +11 -0
  258. package/dist/utils/regex.js.map +1 -0
  259. package/dist/utils/snippet.d.ts +20 -0
  260. package/dist/utils/snippet.d.ts.map +1 -0
  261. package/dist/utils/snippet.js +28 -0
  262. package/dist/utils/snippet.js.map +1 -0
  263. package/dist/utils/source-reader.d.ts +19 -0
  264. package/dist/utils/source-reader.d.ts.map +1 -0
  265. package/dist/utils/source-reader.js +32 -0
  266. package/dist/utils/source-reader.js.map +1 -0
  267. package/logo.png +0 -0
  268. package/package.json +92 -0
  269. package/scripts/start-llm.mjs +161 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-db-write-confirmer.js","sourceRoot":"","sources":["../../src/extraction/shared-db-write-confirmer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { z } from 'zod';
2
+ import { LlmClient } from '../adapters/llm.js';
3
+ /**
4
+ * Generic single-finding triage confirmer. Used by detectors whose
5
+ * findings have a high false-positive rate but no detector-specific
6
+ * confirmer of their own (silent-catch, public-any, mutable-globals,
7
+ * …). Asks the LLM: "given this code and the static analyzer's
8
+ * suspicion, is this a real defect worth fixing — or an intentional
9
+ * pattern the project relies on?"
10
+ *
11
+ * Verdict shape matches the cluster confirmers so the orchestrator's
12
+ * shared `applyClusterVerdict` helper can drive severity / confidence
13
+ * adjustments without a per-detector branch:
14
+ *
15
+ * { real: boolean, confidence: number 0..1, reason: string }
16
+ *
17
+ * `real: true` → keep severity, bump confidence (genuine defect).
18
+ * `real: false` → drop severity to 'low', deflate confidence
19
+ * (intentional pattern / framework convention).
20
+ */
21
+ declare const VerdictSchema: z.ZodObject<{
22
+ real: z.ZodBoolean;
23
+ confidence: z.ZodNumber;
24
+ reason: z.ZodString;
25
+ }, z.core.$strip>;
26
+ export type TriageVerdict = z.infer<typeof VerdictSchema>;
27
+ export interface TriageCheckInput {
28
+ /** Detector id — included in the prompt so the LLM applies the right rubric. */
29
+ detectorId: string;
30
+ /** Human-facing severity ('low' | 'medium' | 'high') from the deterministic pass. */
31
+ severity: string;
32
+ /** Finding title verbatim. */
33
+ title: string;
34
+ /** Finding description verbatim. */
35
+ description: string;
36
+ /** Detector-emitted suggestion, if any. */
37
+ suggestion?: string;
38
+ /** First evidence file + line range + snippet. */
39
+ evidenceFile: string;
40
+ evidenceStartLine: number;
41
+ evidenceEndLine: number;
42
+ evidenceSnippet: string;
43
+ /**
44
+ * Optional structural context the orchestrator can pass alongside the
45
+ * raw evidence — siblings, importer counts, package.json hits, etc.
46
+ * Kept opaque (free-form text) so detector-specific enrichment can
47
+ * evolve without breaking the schema. Truncated server-side to keep
48
+ * the prompt under the LLM context window.
49
+ */
50
+ extraContext?: string;
51
+ }
52
+ export declare class TriageConfirmer {
53
+ private llm;
54
+ private cache;
55
+ constructor(llm?: LlmClient);
56
+ confirm(input: TriageCheckInput): Promise<TriageVerdict | null>;
57
+ }
58
+ export {};
59
+ //# sourceMappingURL=triage-confirmer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage-confirmer.d.ts","sourceRoot":"","sources":["../../src/extraction/triage-confirmer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAA0B,MAAM,oBAAoB,CAAC;AAIvE;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,aAAa;;;;iBAIjB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0CD,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,KAAK,CAAoC;gBAErC,GAAG,CAAC,EAAE,SAAS;IAIrB,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;CAoCtE"}
@@ -0,0 +1,104 @@
1
+ import { z } from 'zod';
2
+ import { createDefaultLlmClient } from '../adapters/llm.js';
3
+ import { parseLlmJsonResponse } from '../utils/llm-json.js';
4
+ import { logger } from '../utils/logger.js';
5
+ /**
6
+ * Generic single-finding triage confirmer. Used by detectors whose
7
+ * findings have a high false-positive rate but no detector-specific
8
+ * confirmer of their own (silent-catch, public-any, mutable-globals,
9
+ * …). Asks the LLM: "given this code and the static analyzer's
10
+ * suspicion, is this a real defect worth fixing — or an intentional
11
+ * pattern the project relies on?"
12
+ *
13
+ * Verdict shape matches the cluster confirmers so the orchestrator's
14
+ * shared `applyClusterVerdict` helper can drive severity / confidence
15
+ * adjustments without a per-detector branch:
16
+ *
17
+ * { real: boolean, confidence: number 0..1, reason: string }
18
+ *
19
+ * `real: true` → keep severity, bump confidence (genuine defect).
20
+ * `real: false` → drop severity to 'low', deflate confidence
21
+ * (intentional pattern / framework convention).
22
+ */
23
+ const VerdictSchema = z.object({
24
+ real: z.boolean(),
25
+ confidence: z.number().min(0).max(1),
26
+ reason: z.string(),
27
+ });
28
+ const PROMPT = `You are reviewing a TypeScript / JavaScript static-analysis finding. Decide: is this a REAL defect the project should fix, or a FALSE POSITIVE the detector flagged but the code is intentionally written this way (framework convention, builder pattern, project-specific exception)?
29
+
30
+ Output ONE compact JSON object and STOP:
31
+ {"real": boolean, "confidence": <0..1>, "reason": "<max 20 words>"}
32
+
33
+ Heuristics by detector:
34
+
35
+ - **silent-catch**: REAL when the catch swallows errors that the operator would want to see (network, parse, DB). FALSE when the catch is documented as deliberate (comment explaining), the surrounding code already logs to a reporter, or the body is "return null" with a documented caller contract that treats null as "missing".
36
+ - **public-any**: REAL when an exported API surface uses \`any\` where a concrete type or a generic would convey the contract. FALSE when the \`any\` is at a third-party adapter boundary, in a generated type, or annotated with a comment explaining the deliberate widening.
37
+ - **mutable-globals**: REAL when a module-scope \`let\`/\`var\` is mutated from request-time code (shared across importers). FALSE when the mutation is bootstrap / one-shot init / lazy-cache with single-flight guards.
38
+ - **magic-numbers**: REAL when the literal carries domain meaning the reader has to guess (timeouts, retry counts, column counts). FALSE for: math constants (0/1/2/-1/π/τ), array indices, version numbers in package.json reads, HTTP status codes (200/404/500) used with descriptive variable names already in scope.
39
+ - **bad-config**: REAL when the disabled rule materially loosens safety (strict / noImplicitAny / no-explicit-any). FALSE when the rule is off behind a documented project-wide exception OR when the file is a build target intentionally relaxed (e.g. tsconfig.build.json with project references).
40
+ - **long-function**: REAL when the function mixes unrelated concerns. FALSE for React page components that act as composition roots and JSX layout — a 300+ line page is typical and refactor signals are already covered by other detectors. FALSE for linear HTTP handlers / streaming relays where extraction obscures flow.
41
+ - **long-file**: REAL when the file accumulates unrelated concerns across many features. FALSE for recognizer / config / pattern tables — single-table modules of 600+ lines are deliberate locality, not accumulation.
42
+ - **hot-hub-file**: REAL when a file accumulates unrelated re-exports / utilities. FALSE for a deliberate single type-surface module / barrel that the project explicitly maintains as the public import path.
43
+ - **dead-export**: REAL when the export is unused AND has no plausible public-API reason to exist. FALSE when: (a) the symbol IS the published-library type surface for an Apache/MIT npm package, (b) the export is consumed by another exported symbol's signature within the same module (interface used as return / param type), (c) it's a framework convention (Next route handler, etc.).
44
+ - **dead-module**: REAL when the file is genuinely unreachable. FALSE when: package.json scripts reference it (\`tsx watch src/dev.ts\`), it's loaded by convention (Next route, Vite plugin), or it's a dev-only entry point.
45
+ - **dead-handler / dead-api**: REAL when no client / route table references it. FALSE when the handler is registered dynamically (decorator + reflection, route table built at runtime).
46
+ - **todo-comments**: REAL only for actionable TODO / FIXME / HACK / XXX markers ("TODO: refactor", "FIXME before ship"). FALSE for explanatory NOTE comments documenting a deliberate design decision — those are documentation, not technical debt.
47
+ - **duplicate-function / duplicate-type / similar-functions**: REAL when two symbols implement the same concept with different code (true duplication). FALSE when they share a SKELETON but have unrelated semantics — \`registerDoctor\` vs \`registerPrefetch\`, \`getUserById\` vs \`getOrderById\`, framework-idiom command registrations.
48
+
49
+ Confidence calibration:
50
+ - Clear intentional pattern with explicit comment / framework idiom → real: false, confidence ≥ 0.85.
51
+ - Clear defect (no comment, obvious bug shape) → real: true, confidence ≥ 0.85.
52
+ - Genuinely ambiguous → real: true, confidence 0.6 (preserve the deterministic signal at low confidence).
53
+
54
+ If the "Project conventions" block in extra context contains a rule that DIRECTLY justifies the pattern under review (e.g. "three similar lines better than premature abstraction" → applies to duplicate-function / long-function on framework-idiom call sites; "default to writing no comments" → applies to silent-catch with explanatory comment), treat that as authoritative and verdict real: false, confidence ≥ 0.85. The project's own rules override generic best-practice — that is the whole point of including them.
55
+
56
+ Detector: {{DETECTOR}}
57
+ Severity (deterministic): {{SEVERITY}}
58
+ Title: {{TITLE}}
59
+ Description: {{DESCRIPTION}}
60
+ Suggested direction: {{SUGGESTION}}
61
+
62
+ Code evidence ({{FILE}}:{{START}}-{{END}}):
63
+ \`\`\`
64
+ {{SNIPPET}}
65
+ \`\`\`
66
+ {{EXTRA_CONTEXT}}`;
67
+ export class TriageConfirmer {
68
+ llm;
69
+ cache = new Map();
70
+ constructor(llm) {
71
+ this.llm = llm ?? createDefaultLlmClient();
72
+ }
73
+ async confirm(input) {
74
+ const cacheKey = `${input.detectorId}::${input.evidenceFile}:${input.evidenceStartLine}-${input.evidenceEndLine}`;
75
+ const cached = this.cache.get(cacheKey);
76
+ if (cached)
77
+ return cached;
78
+ const extraBlock = input.extraContext
79
+ ? `\nExtra structural context:\n${input.extraContext.slice(0, 1600)}\n`
80
+ : '';
81
+ const prompt = PROMPT.replace('{{DETECTOR}}', input.detectorId)
82
+ .replace('{{SEVERITY}}', input.severity)
83
+ .replace('{{TITLE}}', input.title)
84
+ .replace('{{DESCRIPTION}}', input.description.slice(0, 800))
85
+ .replace('{{SUGGESTION}}', input.suggestion ?? '(none)')
86
+ .replace('{{FILE}}', input.evidenceFile)
87
+ .replace('{{START}}', String(input.evidenceStartLine))
88
+ .replace('{{END}}', String(input.evidenceEndLine))
89
+ .replace('{{SNIPPET}}', input.evidenceSnippet.slice(0, 1600))
90
+ .replace('{{EXTRA_CONTEXT}}', extraBlock);
91
+ try {
92
+ const raw = await this.llm.chat([{ role: 'user', content: prompt }], { temperature: 0, maxTokens: 128 });
93
+ const parsed = parseLlmJsonResponse(raw);
94
+ const verdict = VerdictSchema.parse(parsed);
95
+ this.cache.set(cacheKey, verdict);
96
+ return verdict;
97
+ }
98
+ catch (err) {
99
+ logger.warn({ err: err.message, detector: input.detectorId, file: input.evidenceFile }, 'TriageConfirmer failed; returning null');
100
+ return null;
101
+ }
102
+ }
103
+ }
104
+ //# sourceMappingURL=triage-confirmer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage-confirmer.js","sourceRoot":"","sources":["../../src/extraction/triage-confirmer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { Node } from 'ts-morph';
2
+ /**
3
+ * Basic-block control-flow graph for an async function body. The race-
4
+ * condition detector previously used source-line ordering as a proxy for
5
+ * execution order — that misfires on conditional reads (`if (cond) { read }
6
+ * await x; write`) because the analyzer cannot tell whether `read` actually
7
+ * happened on a given execution. With a CFG we ask the precise question:
8
+ * "Does any execution path reach `read`, then `await`, then `write` of the
9
+ * same target?". If no such path exists → no race candidate.
10
+ *
11
+ * The graph is intentionally coarse: each node is a sequence of statements
12
+ * with no internal branch. Branch / loop / try-catch / switch produce
13
+ * separate nodes joined by `succ` edges. Statements that terminate a path
14
+ * (`return`, `throw`, `break`, `continue`) end the block with no successor
15
+ * to the synthetic exit. Reachability is plain forward BFS.
16
+ *
17
+ * Caveats:
18
+ * - Switch fall-through across cases is modelled correctly only when the
19
+ * case body ends with `break` / `return`. Implicit fall-through joins
20
+ * the next case's entry.
21
+ * - Labeled break/continue is reduced to plain break/continue (good
22
+ * enough for race-condition use; very rare in practice).
23
+ * - Nested function declarations / arrow functions are NOT followed —
24
+ * they have their own CFG built by the caller when needed.
25
+ */
26
+ export interface CfgBlock {
27
+ id: number;
28
+ stmts: Node[];
29
+ succ: number[];
30
+ }
31
+ export interface Cfg {
32
+ blocks: CfgBlock[];
33
+ entry: number;
34
+ exit: number;
35
+ }
36
+ export declare function buildCfg(body: Node): Cfg;
37
+ /**
38
+ * Return the CFG block id whose statement set contains `node` (walking up
39
+ * parents until a tracked statement is found). Returns -1 when `node`
40
+ * lives outside the CFG (nested function body, dead block, …).
41
+ */
42
+ export declare function blockOf(cfg: Cfg, node: Node): number;
43
+ /** Forward reachability over the CFG: is `to` reachable from `from`? */
44
+ export declare function reachable(cfg: Cfg, from: number, to: number): boolean;
45
+ //# sourceMappingURL=cfg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cfg.d.ts","sourceRoot":"","sources":["../../src/graph/cfg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAc,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,GAAG;IAClB,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAcD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,GAAG,CAmKxC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CASpD;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAgBrE"}
@@ -0,0 +1,198 @@
1
+ import { SyntaxKind } from 'ts-morph';
2
+ const TERMINATING_KINDS = new Set([
3
+ SyntaxKind.ReturnStatement,
4
+ SyntaxKind.ThrowStatement,
5
+ SyntaxKind.BreakStatement,
6
+ SyntaxKind.ContinueStatement,
7
+ ]);
8
+ export function buildCfg(body) {
9
+ const blocks = [];
10
+ const newBlock = () => {
11
+ const b = { id: blocks.length, stmts: [], succ: [] };
12
+ blocks.push(b);
13
+ return b;
14
+ };
15
+ const entry = newBlock();
16
+ const exit = newBlock();
17
+ const visitStmts = (stmts, cur, ctx) => {
18
+ let block = cur;
19
+ for (const s of stmts) {
20
+ block = visitStmt(s, block, ctx);
21
+ // After a terminator we keep a sink block so subsequent statements
22
+ // still have a CFG node — but with no successor to the exit, the
23
+ // reachability analysis correctly skips them.
24
+ if (TERMINATING_KINDS.has(s.getKind())) {
25
+ block = newBlock(); // dead block; intentionally unreachable
26
+ }
27
+ }
28
+ return block;
29
+ };
30
+ const stmtArray = (n) => {
31
+ if (!n)
32
+ return [];
33
+ const blockNode = n.asKind(SyntaxKind.Block);
34
+ if (blockNode)
35
+ return blockNode.getStatements();
36
+ return [n];
37
+ };
38
+ const bodyStmts = stmtArray(body);
39
+ const visitStmt = (s, cur, ctx) => {
40
+ cur.stmts.push(s);
41
+ const k = s.getKind();
42
+ if (k === SyntaxKind.IfStatement) {
43
+ const ifn = s.asKindOrThrow(SyntaxKind.IfStatement);
44
+ const thenB = newBlock();
45
+ const elseB = newBlock();
46
+ const join = newBlock();
47
+ cur.succ.push(thenB.id, elseB.id);
48
+ const endThen = visitStmts(stmtArray(ifn.getThenStatement()), thenB, ctx);
49
+ endThen.succ.push(join.id);
50
+ const elseStmt = ifn.getElseStatement();
51
+ if (elseStmt) {
52
+ const endElse = visitStmts(stmtArray(elseStmt), elseB, ctx);
53
+ endElse.succ.push(join.id);
54
+ }
55
+ else {
56
+ elseB.succ.push(join.id);
57
+ }
58
+ return join;
59
+ }
60
+ if (k === SyntaxKind.WhileStatement || k === SyntaxKind.DoStatement) {
61
+ const loopNode = s.asKindOrThrow(k === SyntaxKind.WhileStatement ? SyntaxKind.WhileStatement : SyntaxKind.DoStatement);
62
+ const header = newBlock();
63
+ const bodyB = newBlock();
64
+ const afterB = newBlock();
65
+ cur.succ.push(header.id);
66
+ header.succ.push(bodyB.id, afterB.id);
67
+ const endBody = visitStmts(stmtArray(loopNode.getStatement()), bodyB, {
68
+ breakTarget: afterB,
69
+ continueTarget: header,
70
+ });
71
+ endBody.succ.push(header.id);
72
+ return afterB;
73
+ }
74
+ if (k === SyntaxKind.ForStatement ||
75
+ k === SyntaxKind.ForOfStatement ||
76
+ k === SyntaxKind.ForInStatement) {
77
+ const loopNode = s;
78
+ const header = newBlock();
79
+ const bodyB = newBlock();
80
+ const afterB = newBlock();
81
+ cur.succ.push(header.id);
82
+ header.succ.push(bodyB.id, afterB.id);
83
+ const endBody = visitStmts(stmtArray(loopNode.getStatement()), bodyB, {
84
+ breakTarget: afterB,
85
+ continueTarget: header,
86
+ });
87
+ endBody.succ.push(header.id);
88
+ return afterB;
89
+ }
90
+ if (k === SyntaxKind.TryStatement) {
91
+ const tryNode = s.asKindOrThrow(SyntaxKind.TryStatement);
92
+ const tryB = newBlock();
93
+ const catchB = newBlock();
94
+ const finallyB = newBlock();
95
+ const after = newBlock();
96
+ cur.succ.push(tryB.id);
97
+ // Any point in the try block can throw, so the catch is potentially
98
+ // reachable from the try entry. We approximate with edge tryB → catchB.
99
+ tryB.succ.push(catchB.id);
100
+ const endTry = visitStmts(tryNode.getTryBlock().getStatements(), tryB, ctx);
101
+ endTry.succ.push(finallyB.id);
102
+ const catchClause = tryNode.getCatchClause();
103
+ if (catchClause) {
104
+ const endCatch = visitStmts(catchClause.getBlock().getStatements(), catchB, ctx);
105
+ endCatch.succ.push(finallyB.id);
106
+ }
107
+ else {
108
+ catchB.succ.push(finallyB.id);
109
+ }
110
+ const fin = tryNode.getFinallyBlock();
111
+ if (fin) {
112
+ const endFin = visitStmts(fin.getStatements(), finallyB, ctx);
113
+ endFin.succ.push(after.id);
114
+ }
115
+ else {
116
+ finallyB.succ.push(after.id);
117
+ }
118
+ return after;
119
+ }
120
+ if (k === SyntaxKind.SwitchStatement) {
121
+ const sw = s.asKindOrThrow(SyntaxKind.SwitchStatement);
122
+ const after = newBlock();
123
+ const cases = sw.getCaseBlock().getClauses();
124
+ let prev = null;
125
+ for (const c of cases) {
126
+ const cb = newBlock();
127
+ cur.succ.push(cb.id);
128
+ if (prev)
129
+ prev.succ.push(cb.id); // implicit fall-through
130
+ const stmts = c.getStatements?.() ?? [];
131
+ const endCase = visitStmts(stmts, cb, { breakTarget: after, continueTarget: ctx.continueTarget });
132
+ endCase.succ.push(after.id);
133
+ prev = endCase;
134
+ }
135
+ cur.succ.push(after.id); // path with no matching case
136
+ return after;
137
+ }
138
+ if (k === SyntaxKind.BreakStatement && ctx.breakTarget) {
139
+ cur.succ.push(ctx.breakTarget.id);
140
+ return cur;
141
+ }
142
+ if (k === SyntaxKind.ContinueStatement && ctx.continueTarget) {
143
+ cur.succ.push(ctx.continueTarget.id);
144
+ return cur;
145
+ }
146
+ if (k === SyntaxKind.ReturnStatement || k === SyntaxKind.ThrowStatement) {
147
+ // No successor — path ends here.
148
+ return cur;
149
+ }
150
+ if (k === SyntaxKind.Block) {
151
+ // Nested block — recurse into its statements but stay in the same
152
+ // logical block-list path (no branching).
153
+ return visitStmts(s.asKindOrThrow(SyntaxKind.Block).getStatements(), cur, ctx);
154
+ }
155
+ return cur;
156
+ };
157
+ const last = visitStmts(bodyStmts, entry, {});
158
+ last.succ.push(exit.id);
159
+ return { blocks, entry: entry.id, exit: exit.id };
160
+ }
161
+ /**
162
+ * Return the CFG block id whose statement set contains `node` (walking up
163
+ * parents until a tracked statement is found). Returns -1 when `node`
164
+ * lives outside the CFG (nested function body, dead block, …).
165
+ */
166
+ export function blockOf(cfg, node) {
167
+ let cur = node;
168
+ while (cur) {
169
+ for (const b of cfg.blocks) {
170
+ if (b.stmts.includes(cur))
171
+ return b.id;
172
+ }
173
+ cur = cur.getParent();
174
+ }
175
+ return -1;
176
+ }
177
+ /** Forward reachability over the CFG: is `to` reachable from `from`? */
178
+ export function reachable(cfg, from, to) {
179
+ if (from < 0 || to < 0)
180
+ return false;
181
+ if (from === to)
182
+ return true;
183
+ const visited = new Set([from]);
184
+ const queue = [from];
185
+ while (queue.length > 0) {
186
+ const id = queue.shift();
187
+ for (const s of cfg.blocks[id].succ) {
188
+ if (s === to)
189
+ return true;
190
+ if (!visited.has(s)) {
191
+ visited.add(s);
192
+ queue.push(s);
193
+ }
194
+ }
195
+ }
196
+ return false;
197
+ }
198
+ //# sourceMappingURL=cfg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cfg.js","sourceRoot":"","sources":["../../src/graph/cfg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function resolveDecoratorEntryFiles(workspaceRoot: string, files: ReadonlyArray<string>): Set<string>;
2
+ //# sourceMappingURL=decorator-entries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator-entries.d.ts","sourceRoot":"","sources":["../../src/graph/decorator-entries.ts"],"names":[],"mappings":"AAmDA,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAC3B,GAAG,CAAC,MAAM,CAAC,CAgBb"}
@@ -0,0 +1,89 @@
1
+ import * as path from 'node:path';
2
+ import { Project, SyntaxKind } from 'ts-morph';
3
+ // Files with framework decorators (NestJS, Angular, TypeGraphQL, Inversify,
4
+ // TypeORM, tsoa) are entry points — DI / ORM discovers them at runtime.
5
+ // Textual match; over-match is safe direction (protects from dead-module).
6
+ const FRAMEWORK_DECORATOR_NAMES = new Set([
7
+ // NestJS class-level
8
+ 'Controller',
9
+ 'Module',
10
+ 'Injectable',
11
+ 'Catch',
12
+ 'Pipe',
13
+ 'WebSocketGateway',
14
+ 'Resolver',
15
+ // NestJS method-level
16
+ 'Get',
17
+ 'Post',
18
+ 'Put',
19
+ 'Patch',
20
+ 'Delete',
21
+ 'All',
22
+ 'Options',
23
+ 'Head',
24
+ 'Sse',
25
+ 'MessagePattern',
26
+ 'EventPattern',
27
+ 'SubscribeMessage',
28
+ // GraphQL (TypeGraphQL / Nest-graphql)
29
+ 'Query',
30
+ 'Mutation',
31
+ 'FieldResolver',
32
+ 'Subscription',
33
+ 'ObjectType',
34
+ 'InputType',
35
+ // Angular
36
+ 'Component',
37
+ 'NgModule',
38
+ 'Directive',
39
+ // ORM auto-discovery
40
+ 'Entity',
41
+ 'ViewEntity',
42
+ 'Schema',
43
+ // InversifyJS DI
44
+ 'injectable',
45
+ 'inject',
46
+ // tsoa / route-decorator HTTP frameworks
47
+ 'Route',
48
+ 'Tags',
49
+ ]);
50
+ export function resolveDecoratorEntryFiles(workspaceRoot, files) {
51
+ const project = new Project({
52
+ skipAddingFilesFromTsConfig: true,
53
+ skipFileDependencyResolution: true,
54
+ });
55
+ for (const rel of files) {
56
+ project.addSourceFileAtPathIfExists(path.join(workspaceRoot, rel));
57
+ }
58
+ const out = new Set();
59
+ for (const sf of project.getSourceFiles()) {
60
+ if (fileHasFrameworkDecorator(sf)) {
61
+ out.add(path.relative(workspaceRoot, sf.getFilePath()));
62
+ }
63
+ }
64
+ return out;
65
+ }
66
+ function fileHasFrameworkDecorator(sf) {
67
+ // Class-level + method-level decorators. We use the Decorator AST kind so
68
+ // we catch both `@Decorator()` and `@Decorator` invocation shapes.
69
+ for (const dec of sf.getDescendantsOfKind(SyntaxKind.Decorator)) {
70
+ const expr = dec.getExpression();
71
+ let name = null;
72
+ const callShape = expr.asKind(SyntaxKind.CallExpression);
73
+ if (callShape) {
74
+ name = callShape.getExpression().getText();
75
+ }
76
+ else if (expr.getKind() === SyntaxKind.Identifier) {
77
+ name = expr.getText();
78
+ }
79
+ if (!name)
80
+ continue;
81
+ // Decorators are often imported with their bare name (e.g. `@Controller`),
82
+ // sometimes namespaced (`@nestjs.Controller`). Pick the last segment.
83
+ const baseName = name.split('.').pop() ?? name;
84
+ if (FRAMEWORK_DECORATOR_NAMES.has(baseName))
85
+ return true;
86
+ }
87
+ return false;
88
+ }
89
+ //# sourceMappingURL=decorator-entries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator-entries.js","sourceRoot":"","sources":["../../src/graph/decorator-entries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE/C,4EAA4E;AAC5E,wEAAwE;AACxE,2EAA2E;AAC3E,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC;IACxC,qBAAqB;IACrB,YAAY;IACZ,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,MAAM;IACN,kBAAkB;IAClB,UAAU;IACV,sBAAsB;IACtB,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,KAAK;IACL,SAAS;IACT,MAAM;IACN,KAAK;IACL,gBAAgB;IAChB,cAAc;IACd,kBAAkB;IAClB,uCAAuC;IACvC,OAAO;IACP,UAAU;IACV,eAAe;IACf,cAAc;IACd,YAAY;IACZ,WAAW;IACX,UAAU;IACV,WAAW;IACX,UAAU;IACV,WAAW;IACX,qBAAqB;IACrB,QAAQ;IACR,YAAY;IACZ,QAAQ;IACR,iBAAiB;IACjB,YAAY;IACZ,QAAQ;IACR,yCAAyC;IACzC,OAAO;IACP,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,UAAU,0BAA0B,CACxC,aAAqB,EACrB,KAA4B;IAE5B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;QAC1B,2BAA2B,EAAE,IAAI;QACjC,4BAA4B,EAAE,IAAI;KACnC,CAAC,CAAC;IACH,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1C,IAAI,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,yBAAyB,CAAC,EAAiD;IAClF,0EAA0E;IAC1E,mEAAmE;IACnE,KAAK,MAAM,GAAG,IAAI,EAAE,CAAC,oBAAoB,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC;QACjC,IAAI,IAAI,GAAkB,IAAI,CAAC;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QACzD,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;QAC7C,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;YACpD,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,2EAA2E;QAC3E,sEAAsE;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;QAC/C,IAAI,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;IAC3D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Decide whether the workspace at `root` describes a published npm
3
+ * library. Heuristic: top-level `package.json` has a name + version,
4
+ * is NOT marked private, AND declares one of the standard package
5
+ * entry fields (main / module / exports / bin). When this is true,
6
+ * downstream consumers can import individual files and dead-export
7
+ * verdicts need to lean toward FALSE-POSITIVE for any symbol that
8
+ * looks like a utility / config / type-surface helper.
9
+ */
10
+ export declare function isPublishedLibrary(root: string): boolean;
11
+ export declare function discoverEntryPoints(workspaceRoot: string, knownFiles: ReadonlySet<string>): Set<string>;
12
+ //# sourceMappingURL=entry-points.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-points.d.ts","sourceRoot":"","sources":["../../src/graph/entry-points.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBxD;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAevG"}