thuban 0.4.9 → 0.4.11

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 (1531) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +437 -437
  3. package/dist/LICENSE +21 -0
  4. package/dist/README.md +437 -0
  5. package/dist/cli.js +2 -0
  6. package/dist/package.json +63 -0
  7. package/dist/packages/crucible/.golden/golden-master.json +414 -0
  8. package/dist/packages/crucible/report-generator.js +1 -0
  9. package/dist/packages/crucible/rules/code-scanner-core.json +303 -0
  10. package/dist/packages/crucible/rules/command-injection.json +411 -0
  11. package/dist/packages/crucible/rules/crypto-misuse.json +35 -0
  12. package/dist/packages/crucible/rules/deserialization.json +152 -0
  13. package/dist/packages/crucible/rules/env-injection.json +46 -0
  14. package/dist/packages/crucible/rules/eval-abuse.json +104 -0
  15. package/dist/packages/crucible/rules/file-upload.json +46 -0
  16. package/dist/packages/crucible/rules/hallucination.json +22 -0
  17. package/dist/packages/crucible/rules/hardcoded-secret.json +397 -0
  18. package/dist/packages/crucible/rules/hardcoded-url.json +13 -0
  19. package/dist/packages/crucible/rules/insecure-crypto.json +302 -0
  20. package/dist/packages/crucible/rules/integer-overflow.json +35 -0
  21. package/dist/packages/crucible/rules/log-injection.json +33 -0
  22. package/dist/packages/crucible/rules/mass-assignment.json +112 -0
  23. package/dist/packages/crucible/rules/open-redirect.json +196 -0
  24. package/dist/packages/crucible/rules/path-traversal.json +422 -0
  25. package/dist/packages/crucible/rules/prototype-pollution.json +22 -0
  26. package/dist/packages/crucible/rules/sql-injection.json +619 -0
  27. package/dist/packages/crucible/rules/ssrf.json +557 -0
  28. package/dist/packages/crucible/rules/timing-attack.json +55 -0
  29. package/dist/packages/crucible/rules/unsafe-block.json +24 -0
  30. package/dist/packages/crucible/rules/xss.json +663 -0
  31. package/dist/packages/crucible/rules/xxe.json +66 -0
  32. package/dist/packages/crucible/rules/yaml-deserialization.json +22 -0
  33. package/dist/packages/crucible/rules/yaml-injection.json +22 -0
  34. package/dist/packages/crucible/seeds/csharp/seed-001.cs +28 -0
  35. package/dist/packages/crucible/seeds/csharp/seed-002.cs +24 -0
  36. package/dist/packages/crucible/seeds/csharp/seed-003.cs +30 -0
  37. package/dist/packages/crucible/seeds/csharp/seed-004.cs +31 -0
  38. package/dist/packages/crucible/seeds/csharp/seed-005.cs +28 -0
  39. package/dist/packages/crucible/seeds/csharp/seed-006.cs +25 -0
  40. package/dist/packages/crucible/seeds/csharp/seed-007.cs +34 -0
  41. package/dist/packages/crucible/seeds/csharp/seed-008.cs +23 -0
  42. package/dist/packages/crucible/seeds/csharp/seed-009.cs +27 -0
  43. package/dist/packages/crucible/seeds/csharp/seed-010.cs +29 -0
  44. package/dist/packages/crucible/seeds/csharp/seed-011.cs +32 -0
  45. package/dist/packages/crucible/seeds/csharp/seed-012.cs +27 -0
  46. package/dist/packages/crucible/seeds/csharp/seed-013.cs +27 -0
  47. package/dist/packages/crucible/seeds/csharp/seed-014.cs +26 -0
  48. package/dist/packages/crucible/seeds/csharp/seed-015.cs +33 -0
  49. package/dist/packages/crucible/seeds/csharp/seed-016.cs +25 -0
  50. package/dist/packages/crucible/seeds/csharp/seed-017.cs +22 -0
  51. package/dist/packages/crucible/seeds/csharp/seed-018.cs +26 -0
  52. package/dist/packages/crucible/seeds/csharp/seed-019.cs +25 -0
  53. package/dist/packages/crucible/seeds/csharp/seed-020.cs +22 -0
  54. package/dist/packages/crucible/seeds/csharp/seed-021.cs +28 -0
  55. package/dist/packages/crucible/seeds/csharp/seed-022.cs +25 -0
  56. package/dist/packages/crucible/seeds/csharp/seed-023.cs +33 -0
  57. package/dist/packages/crucible/seeds/csharp/seed-024.cs +31 -0
  58. package/dist/packages/crucible/seeds/csharp/seed-025.cs +31 -0
  59. package/dist/packages/crucible/seeds/csharp/seed-026.cs +25 -0
  60. package/dist/packages/crucible/seeds/csharp/seed-027.cs +29 -0
  61. package/dist/packages/crucible/seeds/csharp/seed-028.cs +25 -0
  62. package/dist/packages/crucible/seeds/csharp/seed-029.cs +27 -0
  63. package/dist/packages/crucible/seeds/csharp/seed-030.cs +27 -0
  64. package/dist/packages/crucible/seeds/csharp/seed-031.cs +28 -0
  65. package/dist/packages/crucible/seeds/csharp/seed-032.cs +30 -0
  66. package/dist/packages/crucible/seeds/csharp/seed-033.cs +27 -0
  67. package/dist/packages/crucible/seeds/csharp/seed-034.cs +25 -0
  68. package/dist/packages/crucible/seeds/csharp/seed-035.cs +32 -0
  69. package/dist/packages/crucible/seeds/csharp/seed-036.cs +28 -0
  70. package/dist/packages/crucible/seeds/csharp/seed-037.cs +29 -0
  71. package/dist/packages/crucible/seeds/csharp/seed-038.cs +28 -0
  72. package/dist/packages/crucible/seeds/csharp/seed-039.cs +29 -0
  73. package/dist/packages/crucible/seeds/csharp/seed-040.cs +28 -0
  74. package/dist/packages/crucible/seeds/csharp/seed-041.cs +33 -0
  75. package/dist/packages/crucible/seeds/csharp/seed-042.cs +27 -0
  76. package/dist/packages/crucible/seeds/csharp/seed-043.cs +27 -0
  77. package/dist/packages/crucible/seeds/csharp/seed-044.cs +25 -0
  78. package/dist/packages/crucible/seeds/csharp/seed-045.cs +30 -0
  79. package/dist/packages/crucible/seeds/csharp/seed-046.cs +29 -0
  80. package/dist/packages/crucible/seeds/csharp/seed-047.cs +26 -0
  81. package/dist/packages/crucible/seeds/csharp/seed-048.cs +31 -0
  82. package/dist/packages/crucible/seeds/csharp/seed-049.cs +27 -0
  83. package/dist/packages/crucible/seeds/csharp/seed-050.cs +30 -0
  84. package/dist/packages/crucible/seeds/csharp/seed-051.cs +34 -0
  85. package/dist/packages/crucible/seeds/csharp/seed-052.cs +36 -0
  86. package/dist/packages/crucible/seeds/go/seed-001.go +29 -0
  87. package/dist/packages/crucible/seeds/go/seed-002.go +27 -0
  88. package/dist/packages/crucible/seeds/go/seed-003.go +31 -0
  89. package/dist/packages/crucible/seeds/go/seed-004.go +27 -0
  90. package/dist/packages/crucible/seeds/go/seed-005.go +27 -0
  91. package/dist/packages/crucible/seeds/go/seed-006.go +29 -0
  92. package/dist/packages/crucible/seeds/go/seed-007.go +24 -0
  93. package/dist/packages/crucible/seeds/go/seed-008.go +25 -0
  94. package/dist/packages/crucible/seeds/go/seed-009.go +30 -0
  95. package/dist/packages/crucible/seeds/go/seed-010.go +35 -0
  96. package/dist/packages/crucible/seeds/go/seed-011.go +24 -0
  97. package/dist/packages/crucible/seeds/go/seed-012.go +24 -0
  98. package/dist/packages/crucible/seeds/go/seed-013.go +31 -0
  99. package/dist/packages/crucible/seeds/go/seed-014.go +35 -0
  100. package/dist/packages/crucible/seeds/go/seed-015.go +25 -0
  101. package/dist/packages/crucible/seeds/go/seed-016.go +19 -0
  102. package/dist/packages/crucible/seeds/go/seed-017.go +23 -0
  103. package/dist/packages/crucible/seeds/go/seed-018.go +23 -0
  104. package/dist/packages/crucible/seeds/go/seed-019.go +22 -0
  105. package/dist/packages/crucible/seeds/go/seed-020.go +31 -0
  106. package/dist/packages/crucible/seeds/go/seed-021.go +22 -0
  107. package/dist/packages/crucible/seeds/go/seed-022.go +29 -0
  108. package/dist/packages/crucible/seeds/go/seed-023.go +26 -0
  109. package/dist/packages/crucible/seeds/go/seed-024.go +27 -0
  110. package/dist/packages/crucible/seeds/go/seed-025.go +23 -0
  111. package/dist/packages/crucible/seeds/go/seed-026.go +29 -0
  112. package/dist/packages/crucible/seeds/go/seed-027.go +26 -0
  113. package/dist/packages/crucible/seeds/go/seed-028.go +23 -0
  114. package/dist/packages/crucible/seeds/go/seed-029.go +28 -0
  115. package/dist/packages/crucible/seeds/go/seed-030.go +27 -0
  116. package/dist/packages/crucible/seeds/go/seed-031.go +28 -0
  117. package/dist/packages/crucible/seeds/go/seed-032.go +27 -0
  118. package/dist/packages/crucible/seeds/go/seed-033.go +29 -0
  119. package/dist/packages/crucible/seeds/go/seed-034.go +22 -0
  120. package/dist/packages/crucible/seeds/go/seed-035.go +32 -0
  121. package/dist/packages/crucible/seeds/go/seed-036.go +27 -0
  122. package/dist/packages/crucible/seeds/go/seed-037.go +27 -0
  123. package/dist/packages/crucible/seeds/go/seed-038.go +27 -0
  124. package/dist/packages/crucible/seeds/go/seed-039.go +26 -0
  125. package/dist/packages/crucible/seeds/go/seed-040.go +37 -0
  126. package/dist/packages/crucible/seeds/go/seed-041.go +23 -0
  127. package/dist/packages/crucible/seeds/go/seed-042.go +32 -0
  128. package/dist/packages/crucible/seeds/go/seed-043.go +35 -0
  129. package/dist/packages/crucible/seeds/go/seed-044.go +25 -0
  130. package/dist/packages/crucible/seeds/go/seed-045.go +26 -0
  131. package/dist/packages/crucible/seeds/go/seed-046.go +34 -0
  132. package/dist/packages/crucible/seeds/go/seed-047.go +26 -0
  133. package/dist/packages/crucible/seeds/go/seed-048.go +29 -0
  134. package/dist/packages/crucible/seeds/go/seed-049.go +24 -0
  135. package/dist/packages/crucible/seeds/go/seed-050.go +27 -0
  136. package/dist/packages/crucible/seeds/go/seed-051.go +38 -0
  137. package/dist/packages/crucible/seeds/go/seed-052.go +27 -0
  138. package/dist/packages/crucible/seeds/java/seed-001.java +23 -0
  139. package/dist/packages/crucible/seeds/java/seed-002.java +22 -0
  140. package/dist/packages/crucible/seeds/java/seed-003.java +28 -0
  141. package/dist/packages/crucible/seeds/java/seed-004.java +26 -0
  142. package/dist/packages/crucible/seeds/java/seed-005.java +33 -0
  143. package/dist/packages/crucible/seeds/java/seed-006.java +22 -0
  144. package/dist/packages/crucible/seeds/java/seed-007.java +21 -0
  145. package/dist/packages/crucible/seeds/java/seed-008.java +29 -0
  146. package/dist/packages/crucible/seeds/java/seed-009.java +24 -0
  147. package/dist/packages/crucible/seeds/java/seed-010.java +30 -0
  148. package/dist/packages/crucible/seeds/java/seed-011.java +25 -0
  149. package/dist/packages/crucible/seeds/java/seed-012.java +20 -0
  150. package/dist/packages/crucible/seeds/java/seed-013.java +26 -0
  151. package/dist/packages/crucible/seeds/java/seed-014.java +23 -0
  152. package/dist/packages/crucible/seeds/java/seed-015.java +25 -0
  153. package/dist/packages/crucible/seeds/java/seed-016.java +22 -0
  154. package/dist/packages/crucible/seeds/java/seed-017.java +24 -0
  155. package/dist/packages/crucible/seeds/java/seed-018.java +24 -0
  156. package/dist/packages/crucible/seeds/java/seed-019.java +38 -0
  157. package/dist/packages/crucible/seeds/java/seed-020.java +24 -0
  158. package/dist/packages/crucible/seeds/java/seed-021.java +22 -0
  159. package/dist/packages/crucible/seeds/java/seed-022.java +22 -0
  160. package/dist/packages/crucible/seeds/java/seed-023.java +22 -0
  161. package/dist/packages/crucible/seeds/java/seed-024.java +25 -0
  162. package/dist/packages/crucible/seeds/java/seed-025.java +27 -0
  163. package/dist/packages/crucible/seeds/java/seed-026.java +25 -0
  164. package/dist/packages/crucible/seeds/java/seed-027.java +22 -0
  165. package/dist/packages/crucible/seeds/java/seed-028.java +21 -0
  166. package/dist/packages/crucible/seeds/java/seed-029.java +28 -0
  167. package/dist/packages/crucible/seeds/java/seed-030.java +27 -0
  168. package/dist/packages/crucible/seeds/java/seed-031.java +23 -0
  169. package/dist/packages/crucible/seeds/java/seed-032.java +22 -0
  170. package/dist/packages/crucible/seeds/java/seed-033.java +24 -0
  171. package/dist/packages/crucible/seeds/java/seed-034.java +24 -0
  172. package/dist/packages/crucible/seeds/java/seed-035.java +29 -0
  173. package/dist/packages/crucible/seeds/java/seed-036.java +25 -0
  174. package/dist/packages/crucible/seeds/java/seed-037.java +30 -0
  175. package/dist/packages/crucible/seeds/java/seed-038.java +29 -0
  176. package/dist/packages/crucible/seeds/java/seed-039.java +26 -0
  177. package/dist/packages/crucible/seeds/java/seed-040.java +31 -0
  178. package/dist/packages/crucible/seeds/java/seed-041.java +20 -0
  179. package/dist/packages/crucible/seeds/java/seed-042.java +26 -0
  180. package/dist/packages/crucible/seeds/java/seed-043.java +31 -0
  181. package/dist/packages/crucible/seeds/java/seed-044.java +22 -0
  182. package/dist/packages/crucible/seeds/java/seed-045.java +25 -0
  183. package/dist/packages/crucible/seeds/java/seed-046.java +22 -0
  184. package/dist/packages/crucible/seeds/java/seed-047.java +26 -0
  185. package/dist/packages/crucible/seeds/java/seed-048.java +24 -0
  186. package/dist/packages/crucible/seeds/java/seed-049.java +28 -0
  187. package/dist/packages/crucible/seeds/java/seed-050.java +29 -0
  188. package/dist/packages/crucible/seeds/java/seed-051.java +25 -0
  189. package/dist/packages/crucible/seeds/java/seed-052.java +32 -0
  190. package/dist/packages/crucible/seeds/js/seed-001.js +27 -0
  191. package/dist/packages/crucible/seeds/js/seed-002.js +28 -0
  192. package/dist/packages/crucible/seeds/js/seed-003.js +30 -0
  193. package/dist/packages/crucible/seeds/js/seed-004.js +28 -0
  194. package/dist/packages/crucible/seeds/js/seed-005.js +31 -0
  195. package/dist/packages/crucible/seeds/js/seed-006.js +28 -0
  196. package/dist/packages/crucible/seeds/js/seed-007.js +26 -0
  197. package/dist/packages/crucible/seeds/js/seed-008.js +30 -0
  198. package/dist/packages/crucible/seeds/js/seed-009.js +30 -0
  199. package/dist/packages/crucible/seeds/js/seed-010.js +29 -0
  200. package/dist/packages/crucible/seeds/js/seed-011.js +34 -0
  201. package/dist/packages/crucible/seeds/js/seed-012.js +32 -0
  202. package/dist/packages/crucible/seeds/js/seed-013.js +29 -0
  203. package/dist/packages/crucible/seeds/js/seed-014.js +29 -0
  204. package/dist/packages/crucible/seeds/js/seed-015.js +31 -0
  205. package/dist/packages/crucible/seeds/js/seed-016.js +31 -0
  206. package/dist/packages/crucible/seeds/js/seed-017.js +30 -0
  207. package/dist/packages/crucible/seeds/js/seed-018.js +29 -0
  208. package/dist/packages/crucible/seeds/js/seed-019.js +32 -0
  209. package/dist/packages/crucible/seeds/js/seed-020.js +29 -0
  210. package/dist/packages/crucible/seeds/js/seed-021.js +31 -0
  211. package/dist/packages/crucible/seeds/js/seed-022.js +31 -0
  212. package/dist/packages/crucible/seeds/js/seed-023.js +29 -0
  213. package/dist/packages/crucible/seeds/js/seed-024.js +29 -0
  214. package/dist/packages/crucible/seeds/js/seed-025.js +34 -0
  215. package/dist/packages/crucible/seeds/js/seed-026.js +31 -0
  216. package/dist/packages/crucible/seeds/js/seed-027.js +31 -0
  217. package/dist/packages/crucible/seeds/js/seed-028.js +33 -0
  218. package/dist/packages/crucible/seeds/js/seed-029.js +33 -0
  219. package/dist/packages/crucible/seeds/js/seed-030.js +30 -0
  220. package/dist/packages/crucible/seeds/js/seed-031.js +31 -0
  221. package/dist/packages/crucible/seeds/js/seed-032.js +34 -0
  222. package/dist/packages/crucible/seeds/js/seed-033.js +33 -0
  223. package/dist/packages/crucible/seeds/js/seed-034.js +33 -0
  224. package/dist/packages/crucible/seeds/js/seed-035.js +30 -0
  225. package/dist/packages/crucible/seeds/js/seed-036.js +30 -0
  226. package/dist/packages/crucible/seeds/js/seed-037.js +29 -0
  227. package/dist/packages/crucible/seeds/js/seed-038.js +31 -0
  228. package/dist/packages/crucible/seeds/js/seed-039.js +34 -0
  229. package/dist/packages/crucible/seeds/js/seed-040.js +35 -0
  230. package/dist/packages/crucible/seeds/js/seed-041.js +32 -0
  231. package/dist/packages/crucible/seeds/js/seed-042.js +32 -0
  232. package/dist/packages/crucible/seeds/js/seed-043.js +27 -0
  233. package/dist/packages/crucible/seeds/js/seed-044.js +29 -0
  234. package/dist/packages/crucible/seeds/js/seed-045.js +33 -0
  235. package/dist/packages/crucible/seeds/js/seed-046.js +33 -0
  236. package/dist/packages/crucible/seeds/js/seed-047.js +29 -0
  237. package/dist/packages/crucible/seeds/js/seed-048.js +29 -0
  238. package/dist/packages/crucible/seeds/js/seed-049.js +34 -0
  239. package/dist/packages/crucible/seeds/js/seed-050.js +34 -0
  240. package/dist/packages/crucible/seeds/js/seed-051.js +30 -0
  241. package/dist/packages/crucible/seeds/js/seed-052.js +30 -0
  242. package/dist/packages/crucible/seeds/js/seed-053.js +26 -0
  243. package/dist/packages/crucible/seeds/js/seed-054.js +35 -0
  244. package/dist/packages/crucible/seeds/js/seed-055.js +33 -0
  245. package/dist/packages/crucible/seeds/kotlin/seed-001.kt +24 -0
  246. package/dist/packages/crucible/seeds/kotlin/seed-002.kt +27 -0
  247. package/dist/packages/crucible/seeds/kotlin/seed-003.kt +29 -0
  248. package/dist/packages/crucible/seeds/kotlin/seed-004.kt +24 -0
  249. package/dist/packages/crucible/seeds/kotlin/seed-005.kt +29 -0
  250. package/dist/packages/crucible/seeds/kotlin/seed-006.kt +21 -0
  251. package/dist/packages/crucible/seeds/kotlin/seed-007.kt +23 -0
  252. package/dist/packages/crucible/seeds/kotlin/seed-008.kt +25 -0
  253. package/dist/packages/crucible/seeds/kotlin/seed-009.kt +21 -0
  254. package/dist/packages/crucible/seeds/kotlin/seed-010.kt +28 -0
  255. package/dist/packages/crucible/seeds/kotlin/seed-011.kt +22 -0
  256. package/dist/packages/crucible/seeds/kotlin/seed-012.kt +25 -0
  257. package/dist/packages/crucible/seeds/kotlin/seed-013.kt +30 -0
  258. package/dist/packages/crucible/seeds/kotlin/seed-014.kt +27 -0
  259. package/dist/packages/crucible/seeds/kotlin/seed-015.kt +24 -0
  260. package/dist/packages/crucible/seeds/kotlin/seed-016.kt +28 -0
  261. package/dist/packages/crucible/seeds/kotlin/seed-017.kt +33 -0
  262. package/dist/packages/crucible/seeds/kotlin/seed-018.kt +31 -0
  263. package/dist/packages/crucible/seeds/kotlin/seed-019.kt +28 -0
  264. package/dist/packages/crucible/seeds/kotlin/seed-020.kt +31 -0
  265. package/dist/packages/crucible/seeds/kotlin/seed-021.kt +34 -0
  266. package/dist/packages/crucible/seeds/kotlin/seed-022.kt +29 -0
  267. package/dist/packages/crucible/seeds/kotlin/seed-023.kt +20 -0
  268. package/dist/packages/crucible/seeds/kotlin/seed-024.kt +23 -0
  269. package/dist/packages/crucible/seeds/kotlin/seed-025.kt +23 -0
  270. package/dist/packages/crucible/seeds/kotlin/seed-026.kt +26 -0
  271. package/dist/packages/crucible/seeds/kotlin/seed-027.kt +29 -0
  272. package/dist/packages/crucible/seeds/kotlin/seed-028.kt +24 -0
  273. package/dist/packages/crucible/seeds/kotlin/seed-029.kt +27 -0
  274. package/dist/packages/crucible/seeds/kotlin/seed-030.kt +26 -0
  275. package/dist/packages/crucible/seeds/kotlin/seed-031.kt +28 -0
  276. package/dist/packages/crucible/seeds/kotlin/seed-032.kt +29 -0
  277. package/dist/packages/crucible/seeds/kotlin/seed-033.kt +30 -0
  278. package/dist/packages/crucible/seeds/kotlin/seed-034.kt +26 -0
  279. package/dist/packages/crucible/seeds/kotlin/seed-035.kt +33 -0
  280. package/dist/packages/crucible/seeds/kotlin/seed-036.kt +25 -0
  281. package/dist/packages/crucible/seeds/kotlin/seed-037.kt +26 -0
  282. package/dist/packages/crucible/seeds/kotlin/seed-038.kt +25 -0
  283. package/dist/packages/crucible/seeds/kotlin/seed-039.kt +29 -0
  284. package/dist/packages/crucible/seeds/kotlin/seed-040.kt +28 -0
  285. package/dist/packages/crucible/seeds/kotlin/seed-041.kt +31 -0
  286. package/dist/packages/crucible/seeds/kotlin/seed-042.kt +27 -0
  287. package/dist/packages/crucible/seeds/kotlin/seed-043.kt +26 -0
  288. package/dist/packages/crucible/seeds/kotlin/seed-044.kt +27 -0
  289. package/dist/packages/crucible/seeds/kotlin/seed-045.kt +27 -0
  290. package/dist/packages/crucible/seeds/kotlin/seed-046.kt +33 -0
  291. package/dist/packages/crucible/seeds/kotlin/seed-047.kt +32 -0
  292. package/dist/packages/crucible/seeds/kotlin/seed-048.kt +20 -0
  293. package/dist/packages/crucible/seeds/kotlin/seed-049.kt +23 -0
  294. package/dist/packages/crucible/seeds/kotlin/seed-050.kt +19 -0
  295. package/dist/packages/crucible/seeds/php/seed-001.php +23 -0
  296. package/dist/packages/crucible/seeds/php/seed-002.php +18 -0
  297. package/dist/packages/crucible/seeds/php/seed-003.php +25 -0
  298. package/dist/packages/crucible/seeds/php/seed-004.php +21 -0
  299. package/dist/packages/crucible/seeds/php/seed-005.php +21 -0
  300. package/dist/packages/crucible/seeds/php/seed-006.php +21 -0
  301. package/dist/packages/crucible/seeds/php/seed-007.php +18 -0
  302. package/dist/packages/crucible/seeds/php/seed-008.php +19 -0
  303. package/dist/packages/crucible/seeds/php/seed-009.php +24 -0
  304. package/dist/packages/crucible/seeds/php/seed-010.php +24 -0
  305. package/dist/packages/crucible/seeds/php/seed-011.php +18 -0
  306. package/dist/packages/crucible/seeds/php/seed-012.php +24 -0
  307. package/dist/packages/crucible/seeds/php/seed-013.php +23 -0
  308. package/dist/packages/crucible/seeds/php/seed-014.php +20 -0
  309. package/dist/packages/crucible/seeds/php/seed-015.php +18 -0
  310. package/dist/packages/crucible/seeds/php/seed-016.php +18 -0
  311. package/dist/packages/crucible/seeds/php/seed-017.php +18 -0
  312. package/dist/packages/crucible/seeds/php/seed-018.php +17 -0
  313. package/dist/packages/crucible/seeds/php/seed-019.php +24 -0
  314. package/dist/packages/crucible/seeds/php/seed-020.php +19 -0
  315. package/dist/packages/crucible/seeds/php/seed-021.php +22 -0
  316. package/dist/packages/crucible/seeds/php/seed-022.php +15 -0
  317. package/dist/packages/crucible/seeds/php/seed-023.php +24 -0
  318. package/dist/packages/crucible/seeds/php/seed-024.php +22 -0
  319. package/dist/packages/crucible/seeds/php/seed-025.php +20 -0
  320. package/dist/packages/crucible/seeds/php/seed-026.php +22 -0
  321. package/dist/packages/crucible/seeds/php/seed-027.php +15 -0
  322. package/dist/packages/crucible/seeds/php/seed-028.php +15 -0
  323. package/dist/packages/crucible/seeds/php/seed-029.php +21 -0
  324. package/dist/packages/crucible/seeds/php/seed-030.php +21 -0
  325. package/dist/packages/crucible/seeds/php/seed-031.php +23 -0
  326. package/dist/packages/crucible/seeds/php/seed-032.php +18 -0
  327. package/dist/packages/crucible/seeds/php/seed-033.php +18 -0
  328. package/dist/packages/crucible/seeds/php/seed-034.php +24 -0
  329. package/dist/packages/crucible/seeds/php/seed-035.php +22 -0
  330. package/dist/packages/crucible/seeds/php/seed-036.php +17 -0
  331. package/dist/packages/crucible/seeds/php/seed-037.php +19 -0
  332. package/dist/packages/crucible/seeds/php/seed-038.php +20 -0
  333. package/dist/packages/crucible/seeds/php/seed-039.php +15 -0
  334. package/dist/packages/crucible/seeds/php/seed-040.php +21 -0
  335. package/dist/packages/crucible/seeds/php/seed-041.php +20 -0
  336. package/dist/packages/crucible/seeds/php/seed-042.php +21 -0
  337. package/dist/packages/crucible/seeds/php/seed-043.php +21 -0
  338. package/dist/packages/crucible/seeds/php/seed-044.php +25 -0
  339. package/dist/packages/crucible/seeds/php/seed-045.php +25 -0
  340. package/dist/packages/crucible/seeds/php/seed-046.php +20 -0
  341. package/dist/packages/crucible/seeds/php/seed-047.php +21 -0
  342. package/dist/packages/crucible/seeds/php/seed-048.php +19 -0
  343. package/dist/packages/crucible/seeds/php/seed-049.php +18 -0
  344. package/dist/packages/crucible/seeds/php/seed-050.php +20 -0
  345. package/dist/packages/crucible/seeds/python/seed-001.py +33 -0
  346. package/dist/packages/crucible/seeds/python/seed-002.py +39 -0
  347. package/dist/packages/crucible/seeds/python/seed-003.py +31 -0
  348. package/dist/packages/crucible/seeds/python/seed-004.py +33 -0
  349. package/dist/packages/crucible/seeds/python/seed-005.py +33 -0
  350. package/dist/packages/crucible/seeds/python/seed-006.py +34 -0
  351. package/dist/packages/crucible/seeds/python/seed-007.py +33 -0
  352. package/dist/packages/crucible/seeds/python/seed-008.py +38 -0
  353. package/dist/packages/crucible/seeds/python/seed-009.py +38 -0
  354. package/dist/packages/crucible/seeds/python/seed-010.py +42 -0
  355. package/dist/packages/crucible/seeds/python/seed-011.py +30 -0
  356. package/dist/packages/crucible/seeds/python/seed-012.py +35 -0
  357. package/dist/packages/crucible/seeds/python/seed-013.py +33 -0
  358. package/dist/packages/crucible/seeds/python/seed-014.py +40 -0
  359. package/dist/packages/crucible/seeds/python/seed-015.py +33 -0
  360. package/dist/packages/crucible/seeds/python/seed-016.py +34 -0
  361. package/dist/packages/crucible/seeds/python/seed-017.py +34 -0
  362. package/dist/packages/crucible/seeds/python/seed-018.py +30 -0
  363. package/dist/packages/crucible/seeds/python/seed-019.py +33 -0
  364. package/dist/packages/crucible/seeds/python/seed-020.py +37 -0
  365. package/dist/packages/crucible/seeds/python/seed-021 2.py +37 -0
  366. package/dist/packages/crucible/seeds/python/seed-021.py +37 -0
  367. package/dist/packages/crucible/seeds/python/seed-022 2.py +34 -0
  368. package/dist/packages/crucible/seeds/python/seed-022.py +34 -0
  369. package/dist/packages/crucible/seeds/python/seed-023 2.py +37 -0
  370. package/dist/packages/crucible/seeds/python/seed-023.py +37 -0
  371. package/dist/packages/crucible/seeds/python/seed-024 2.py +38 -0
  372. package/dist/packages/crucible/seeds/python/seed-024.py +38 -0
  373. package/dist/packages/crucible/seeds/python/seed-025 2.py +40 -0
  374. package/dist/packages/crucible/seeds/python/seed-025.py +40 -0
  375. package/dist/packages/crucible/seeds/python/seed-026 2.py +35 -0
  376. package/dist/packages/crucible/seeds/python/seed-026.py +35 -0
  377. package/dist/packages/crucible/seeds/python/seed-027 2.py +35 -0
  378. package/dist/packages/crucible/seeds/python/seed-027.py +35 -0
  379. package/dist/packages/crucible/seeds/python/seed-028 2.py +42 -0
  380. package/dist/packages/crucible/seeds/python/seed-028.py +42 -0
  381. package/dist/packages/crucible/seeds/python/seed-029.py +42 -0
  382. package/dist/packages/crucible/seeds/python/seed-030 2.py +37 -0
  383. package/dist/packages/crucible/seeds/python/seed-030.py +37 -0
  384. package/dist/packages/crucible/seeds/python/seed-031 2.py +34 -0
  385. package/dist/packages/crucible/seeds/python/seed-031.py +34 -0
  386. package/dist/packages/crucible/seeds/python/seed-032.py +33 -0
  387. package/dist/packages/crucible/seeds/python/seed-033.py +32 -0
  388. package/dist/packages/crucible/seeds/python/seed-034.py +38 -0
  389. package/dist/packages/crucible/seeds/python/seed-035.py +35 -0
  390. package/dist/packages/crucible/seeds/python/seed-036 2.py +33 -0
  391. package/dist/packages/crucible/seeds/python/seed-036.py +33 -0
  392. package/dist/packages/crucible/seeds/python/seed-037 2.py +41 -0
  393. package/dist/packages/crucible/seeds/python/seed-037.py +41 -0
  394. package/dist/packages/crucible/seeds/python/seed-038 2.py +33 -0
  395. package/dist/packages/crucible/seeds/python/seed-038.py +33 -0
  396. package/dist/packages/crucible/seeds/python/seed-039 2.py +39 -0
  397. package/dist/packages/crucible/seeds/python/seed-039.py +39 -0
  398. package/dist/packages/crucible/seeds/python/seed-040 2.py +39 -0
  399. package/dist/packages/crucible/seeds/python/seed-040.py +39 -0
  400. package/dist/packages/crucible/seeds/python/seed-041 2.py +37 -0
  401. package/dist/packages/crucible/seeds/python/seed-041.py +37 -0
  402. package/dist/packages/crucible/seeds/python/seed-042 2.py +38 -0
  403. package/dist/packages/crucible/seeds/python/seed-042.py +38 -0
  404. package/dist/packages/crucible/seeds/python/seed-043 2.py +32 -0
  405. package/dist/packages/crucible/seeds/python/seed-043.py +32 -0
  406. package/dist/packages/crucible/seeds/python/seed-044 2.py +38 -0
  407. package/dist/packages/crucible/seeds/python/seed-044.py +38 -0
  408. package/dist/packages/crucible/seeds/python/seed-045 2.py +36 -0
  409. package/dist/packages/crucible/seeds/python/seed-045.py +36 -0
  410. package/dist/packages/crucible/seeds/python/seed-046 2.py +33 -0
  411. package/dist/packages/crucible/seeds/python/seed-046.py +33 -0
  412. package/dist/packages/crucible/seeds/python/seed-047 2.py +44 -0
  413. package/dist/packages/crucible/seeds/python/seed-047.py +44 -0
  414. package/dist/packages/crucible/seeds/python/seed-048 2.py +35 -0
  415. package/dist/packages/crucible/seeds/python/seed-048.py +35 -0
  416. package/dist/packages/crucible/seeds/python/seed-049 2.py +39 -0
  417. package/dist/packages/crucible/seeds/python/seed-049.py +39 -0
  418. package/dist/packages/crucible/seeds/python/seed-050 2.py +39 -0
  419. package/dist/packages/crucible/seeds/python/seed-050.py +39 -0
  420. package/dist/packages/crucible/seeds/python/seed-051 2.py +38 -0
  421. package/dist/packages/crucible/seeds/python/seed-051.py +38 -0
  422. package/dist/packages/crucible/seeds/python/seed-052 2.py +41 -0
  423. package/dist/packages/crucible/seeds/python/seed-052.py +41 -0
  424. package/dist/packages/crucible/seeds/ruby/seed-001 2.rb +15 -0
  425. package/dist/packages/crucible/seeds/ruby/seed-001.rb +15 -0
  426. package/dist/packages/crucible/seeds/ruby/seed-002 2.rb +22 -0
  427. package/dist/packages/crucible/seeds/ruby/seed-002.rb +22 -0
  428. package/dist/packages/crucible/seeds/ruby/seed-003 2.rb +25 -0
  429. package/dist/packages/crucible/seeds/ruby/seed-003.rb +25 -0
  430. package/dist/packages/crucible/seeds/ruby/seed-004 2.rb +17 -0
  431. package/dist/packages/crucible/seeds/ruby/seed-004.rb +17 -0
  432. package/dist/packages/crucible/seeds/ruby/seed-005 2.rb +21 -0
  433. package/dist/packages/crucible/seeds/ruby/seed-005.rb +21 -0
  434. package/dist/packages/crucible/seeds/ruby/seed-006 2.rb +17 -0
  435. package/dist/packages/crucible/seeds/ruby/seed-006.rb +17 -0
  436. package/dist/packages/crucible/seeds/ruby/seed-007 2.rb +16 -0
  437. package/dist/packages/crucible/seeds/ruby/seed-007.rb +16 -0
  438. package/dist/packages/crucible/seeds/ruby/seed-008 2.rb +18 -0
  439. package/dist/packages/crucible/seeds/ruby/seed-008.rb +18 -0
  440. package/dist/packages/crucible/seeds/ruby/seed-009 2.rb +20 -0
  441. package/dist/packages/crucible/seeds/ruby/seed-009.rb +20 -0
  442. package/dist/packages/crucible/seeds/ruby/seed-010 2.rb +24 -0
  443. package/dist/packages/crucible/seeds/ruby/seed-010.rb +24 -0
  444. package/dist/packages/crucible/seeds/ruby/seed-011 2.rb +21 -0
  445. package/dist/packages/crucible/seeds/ruby/seed-011.rb +21 -0
  446. package/dist/packages/crucible/seeds/ruby/seed-012 2.rb +22 -0
  447. package/dist/packages/crucible/seeds/ruby/seed-012.rb +22 -0
  448. package/dist/packages/crucible/seeds/ruby/seed-013 2.rb +21 -0
  449. package/dist/packages/crucible/seeds/ruby/seed-013.rb +21 -0
  450. package/dist/packages/crucible/seeds/ruby/seed-014 2.rb +16 -0
  451. package/dist/packages/crucible/seeds/ruby/seed-014.rb +16 -0
  452. package/dist/packages/crucible/seeds/ruby/seed-015 2.rb +18 -0
  453. package/dist/packages/crucible/seeds/ruby/seed-015.rb +18 -0
  454. package/dist/packages/crucible/seeds/ruby/seed-016 2.rb +17 -0
  455. package/dist/packages/crucible/seeds/ruby/seed-016.rb +17 -0
  456. package/dist/packages/crucible/seeds/ruby/seed-017 2.rb +25 -0
  457. package/dist/packages/crucible/seeds/ruby/seed-017.rb +25 -0
  458. package/dist/packages/crucible/seeds/ruby/seed-018 2.rb +23 -0
  459. package/dist/packages/crucible/seeds/ruby/seed-018.rb +23 -0
  460. package/dist/packages/crucible/seeds/ruby/seed-019 2.rb +20 -0
  461. package/dist/packages/crucible/seeds/ruby/seed-019.rb +20 -0
  462. package/dist/packages/crucible/seeds/ruby/seed-020 2.rb +17 -0
  463. package/dist/packages/crucible/seeds/ruby/seed-020.rb +17 -0
  464. package/dist/packages/crucible/seeds/ruby/seed-021 2.rb +20 -0
  465. package/dist/packages/crucible/seeds/ruby/seed-021.rb +20 -0
  466. package/dist/packages/crucible/seeds/ruby/seed-022 2.rb +21 -0
  467. package/dist/packages/crucible/seeds/ruby/seed-022.rb +21 -0
  468. package/dist/packages/crucible/seeds/ruby/seed-023 2.rb +19 -0
  469. package/dist/packages/crucible/seeds/ruby/seed-023.rb +19 -0
  470. package/dist/packages/crucible/seeds/ruby/seed-024 2.rb +17 -0
  471. package/dist/packages/crucible/seeds/ruby/seed-024.rb +17 -0
  472. package/dist/packages/crucible/seeds/ruby/seed-025 2.rb +17 -0
  473. package/dist/packages/crucible/seeds/ruby/seed-025.rb +17 -0
  474. package/dist/packages/crucible/seeds/ruby/seed-026 2.rb +18 -0
  475. package/dist/packages/crucible/seeds/ruby/seed-026.rb +18 -0
  476. package/dist/packages/crucible/seeds/ruby/seed-027 2.rb +21 -0
  477. package/dist/packages/crucible/seeds/ruby/seed-027.rb +21 -0
  478. package/dist/packages/crucible/seeds/ruby/seed-028 2.rb +22 -0
  479. package/dist/packages/crucible/seeds/ruby/seed-028.rb +22 -0
  480. package/dist/packages/crucible/seeds/ruby/seed-029 2.rb +19 -0
  481. package/dist/packages/crucible/seeds/ruby/seed-029.rb +19 -0
  482. package/dist/packages/crucible/seeds/ruby/seed-030 2.rb +20 -0
  483. package/dist/packages/crucible/seeds/ruby/seed-030.rb +20 -0
  484. package/dist/packages/crucible/seeds/ruby/seed-031 2.rb +17 -0
  485. package/dist/packages/crucible/seeds/ruby/seed-031.rb +17 -0
  486. package/dist/packages/crucible/seeds/ruby/seed-032 2.rb +22 -0
  487. package/dist/packages/crucible/seeds/ruby/seed-032.rb +22 -0
  488. package/dist/packages/crucible/seeds/ruby/seed-033 2.rb +18 -0
  489. package/dist/packages/crucible/seeds/ruby/seed-033.rb +18 -0
  490. package/dist/packages/crucible/seeds/ruby/seed-034 2.rb +19 -0
  491. package/dist/packages/crucible/seeds/ruby/seed-034.rb +19 -0
  492. package/dist/packages/crucible/seeds/ruby/seed-035 2.rb +19 -0
  493. package/dist/packages/crucible/seeds/ruby/seed-035.rb +19 -0
  494. package/dist/packages/crucible/seeds/ruby/seed-036 2.rb +18 -0
  495. package/dist/packages/crucible/seeds/ruby/seed-036.rb +18 -0
  496. package/dist/packages/crucible/seeds/ruby/seed-037 2.rb +21 -0
  497. package/dist/packages/crucible/seeds/ruby/seed-037.rb +21 -0
  498. package/dist/packages/crucible/seeds/ruby/seed-038 2.rb +24 -0
  499. package/dist/packages/crucible/seeds/ruby/seed-038.rb +24 -0
  500. package/dist/packages/crucible/seeds/ruby/seed-039 2.rb +24 -0
  501. package/dist/packages/crucible/seeds/ruby/seed-039.rb +24 -0
  502. package/dist/packages/crucible/seeds/ruby/seed-040 2.rb +22 -0
  503. package/dist/packages/crucible/seeds/ruby/seed-040.rb +22 -0
  504. package/dist/packages/crucible/seeds/ruby/seed-041 2.rb +23 -0
  505. package/dist/packages/crucible/seeds/ruby/seed-041.rb +23 -0
  506. package/dist/packages/crucible/seeds/ruby/seed-042 2.rb +25 -0
  507. package/dist/packages/crucible/seeds/ruby/seed-042.rb +25 -0
  508. package/dist/packages/crucible/seeds/ruby/seed-043 2.rb +23 -0
  509. package/dist/packages/crucible/seeds/ruby/seed-043.rb +23 -0
  510. package/dist/packages/crucible/seeds/ruby/seed-044 2.rb +16 -0
  511. package/dist/packages/crucible/seeds/ruby/seed-044.rb +16 -0
  512. package/dist/packages/crucible/seeds/ruby/seed-045 2.rb +22 -0
  513. package/dist/packages/crucible/seeds/ruby/seed-045.rb +22 -0
  514. package/dist/packages/crucible/seeds/ruby/seed-046 2.rb +27 -0
  515. package/dist/packages/crucible/seeds/ruby/seed-046.rb +27 -0
  516. package/dist/packages/crucible/seeds/ruby/seed-047 2.rb +26 -0
  517. package/dist/packages/crucible/seeds/ruby/seed-047.rb +26 -0
  518. package/dist/packages/crucible/seeds/ruby/seed-048 2.rb +24 -0
  519. package/dist/packages/crucible/seeds/ruby/seed-048.rb +24 -0
  520. package/dist/packages/crucible/seeds/ruby/seed-049 2.rb +20 -0
  521. package/dist/packages/crucible/seeds/ruby/seed-049.rb +20 -0
  522. package/dist/packages/crucible/seeds/ruby/seed-050 2.rb +27 -0
  523. package/dist/packages/crucible/seeds/ruby/seed-050.rb +27 -0
  524. package/dist/packages/crucible/seeds/rust/seed-001 2.rs +25 -0
  525. package/dist/packages/crucible/seeds/rust/seed-001.rs +25 -0
  526. package/dist/packages/crucible/seeds/rust/seed-002 2.rs +20 -0
  527. package/dist/packages/crucible/seeds/rust/seed-002.rs +20 -0
  528. package/dist/packages/crucible/seeds/rust/seed-003 2.rs +23 -0
  529. package/dist/packages/crucible/seeds/rust/seed-003.rs +23 -0
  530. package/dist/packages/crucible/seeds/rust/seed-004 2.rs +21 -0
  531. package/dist/packages/crucible/seeds/rust/seed-004.rs +21 -0
  532. package/dist/packages/crucible/seeds/rust/seed-005 2.rs +21 -0
  533. package/dist/packages/crucible/seeds/rust/seed-005.rs +21 -0
  534. package/dist/packages/crucible/seeds/rust/seed-006 2.rs +24 -0
  535. package/dist/packages/crucible/seeds/rust/seed-006.rs +24 -0
  536. package/dist/packages/crucible/seeds/rust/seed-007 2.rs +20 -0
  537. package/dist/packages/crucible/seeds/rust/seed-007.rs +20 -0
  538. package/dist/packages/crucible/seeds/rust/seed-008 2.rs +19 -0
  539. package/dist/packages/crucible/seeds/rust/seed-008.rs +19 -0
  540. package/dist/packages/crucible/seeds/rust/seed-009 2.rs +28 -0
  541. package/dist/packages/crucible/seeds/rust/seed-009.rs +28 -0
  542. package/dist/packages/crucible/seeds/rust/seed-010 2.rs +28 -0
  543. package/dist/packages/crucible/seeds/rust/seed-010.rs +28 -0
  544. package/dist/packages/crucible/seeds/rust/seed-011 2.rs +25 -0
  545. package/dist/packages/crucible/seeds/rust/seed-011.rs +25 -0
  546. package/dist/packages/crucible/seeds/rust/seed-012 2.rs +31 -0
  547. package/dist/packages/crucible/seeds/rust/seed-012.rs +31 -0
  548. package/dist/packages/crucible/seeds/rust/seed-013 2.rs +27 -0
  549. package/dist/packages/crucible/seeds/rust/seed-013.rs +27 -0
  550. package/dist/packages/crucible/seeds/rust/seed-014 2.rs +30 -0
  551. package/dist/packages/crucible/seeds/rust/seed-014.rs +30 -0
  552. package/dist/packages/crucible/seeds/rust/seed-015 2.rs +33 -0
  553. package/dist/packages/crucible/seeds/rust/seed-015.rs +33 -0
  554. package/dist/packages/crucible/seeds/rust/seed-016 2.rs +22 -0
  555. package/dist/packages/crucible/seeds/rust/seed-016.rs +22 -0
  556. package/dist/packages/crucible/seeds/rust/seed-017 2.rs +28 -0
  557. package/dist/packages/crucible/seeds/rust/seed-017.rs +28 -0
  558. package/dist/packages/crucible/seeds/rust/seed-018 2.rs +21 -0
  559. package/dist/packages/crucible/seeds/rust/seed-018.rs +21 -0
  560. package/dist/packages/crucible/seeds/rust/seed-019 2.rs +36 -0
  561. package/dist/packages/crucible/seeds/rust/seed-019.rs +36 -0
  562. package/dist/packages/crucible/seeds/rust/seed-020 2.rs +27 -0
  563. package/dist/packages/crucible/seeds/rust/seed-020.rs +27 -0
  564. package/dist/packages/crucible/seeds/rust/seed-021 2.rs +26 -0
  565. package/dist/packages/crucible/seeds/rust/seed-021.rs +26 -0
  566. package/dist/packages/crucible/seeds/rust/seed-022 2.rs +23 -0
  567. package/dist/packages/crucible/seeds/rust/seed-022.rs +23 -0
  568. package/dist/packages/crucible/seeds/rust/seed-023 2.rs +22 -0
  569. package/dist/packages/crucible/seeds/rust/seed-023.rs +22 -0
  570. package/dist/packages/crucible/seeds/rust/seed-024 2.rs +24 -0
  571. package/dist/packages/crucible/seeds/rust/seed-024.rs +24 -0
  572. package/dist/packages/crucible/seeds/rust/seed-025 2.rs +29 -0
  573. package/dist/packages/crucible/seeds/rust/seed-025.rs +29 -0
  574. package/dist/packages/crucible/seeds/rust/seed-026 2.rs +23 -0
  575. package/dist/packages/crucible/seeds/rust/seed-026.rs +23 -0
  576. package/dist/packages/crucible/seeds/rust/seed-027 2.rs +24 -0
  577. package/dist/packages/crucible/seeds/rust/seed-027.rs +24 -0
  578. package/dist/packages/crucible/seeds/rust/seed-028 2.rs +25 -0
  579. package/dist/packages/crucible/seeds/rust/seed-028.rs +25 -0
  580. package/dist/packages/crucible/seeds/rust/seed-029 2.rs +25 -0
  581. package/dist/packages/crucible/seeds/rust/seed-029.rs +25 -0
  582. package/dist/packages/crucible/seeds/rust/seed-030 2.rs +30 -0
  583. package/dist/packages/crucible/seeds/rust/seed-030.rs +30 -0
  584. package/dist/packages/crucible/seeds/rust/seed-031 2.rs +22 -0
  585. package/dist/packages/crucible/seeds/rust/seed-031.rs +22 -0
  586. package/dist/packages/crucible/seeds/rust/seed-032 2.rs +25 -0
  587. package/dist/packages/crucible/seeds/rust/seed-032.rs +25 -0
  588. package/dist/packages/crucible/seeds/rust/seed-033 2.rs +25 -0
  589. package/dist/packages/crucible/seeds/rust/seed-033.rs +25 -0
  590. package/dist/packages/crucible/seeds/rust/seed-034 2.rs +20 -0
  591. package/dist/packages/crucible/seeds/rust/seed-034.rs +20 -0
  592. package/dist/packages/crucible/seeds/rust/seed-035 2.rs +28 -0
  593. package/dist/packages/crucible/seeds/rust/seed-035.rs +28 -0
  594. package/dist/packages/crucible/seeds/rust/seed-036 2.rs +26 -0
  595. package/dist/packages/crucible/seeds/rust/seed-036.rs +26 -0
  596. package/dist/packages/crucible/seeds/rust/seed-037 2.rs +31 -0
  597. package/dist/packages/crucible/seeds/rust/seed-037.rs +31 -0
  598. package/dist/packages/crucible/seeds/rust/seed-038 2.rs +25 -0
  599. package/dist/packages/crucible/seeds/rust/seed-038.rs +25 -0
  600. package/dist/packages/crucible/seeds/rust/seed-039 2.rs +28 -0
  601. package/dist/packages/crucible/seeds/rust/seed-039.rs +28 -0
  602. package/dist/packages/crucible/seeds/rust/seed-040 2.rs +27 -0
  603. package/dist/packages/crucible/seeds/rust/seed-040.rs +27 -0
  604. package/dist/packages/crucible/seeds/rust/seed-041 2.rs +32 -0
  605. package/dist/packages/crucible/seeds/rust/seed-041.rs +32 -0
  606. package/dist/packages/crucible/seeds/rust/seed-042 2.rs +27 -0
  607. package/dist/packages/crucible/seeds/rust/seed-042.rs +27 -0
  608. package/dist/packages/crucible/seeds/rust/seed-043 2.rs +29 -0
  609. package/dist/packages/crucible/seeds/rust/seed-043.rs +29 -0
  610. package/dist/packages/crucible/seeds/rust/seed-044 2.rs +25 -0
  611. package/dist/packages/crucible/seeds/rust/seed-044.rs +25 -0
  612. package/dist/packages/crucible/seeds/rust/seed-045 2.rs +28 -0
  613. package/dist/packages/crucible/seeds/rust/seed-045.rs +28 -0
  614. package/dist/packages/crucible/seeds/rust/seed-046 2.rs +25 -0
  615. package/dist/packages/crucible/seeds/rust/seed-046.rs +25 -0
  616. package/dist/packages/crucible/seeds/rust/seed-047 2.rs +34 -0
  617. package/dist/packages/crucible/seeds/rust/seed-047.rs +34 -0
  618. package/dist/packages/crucible/seeds/rust/seed-048 2.rs +21 -0
  619. package/dist/packages/crucible/seeds/rust/seed-048.rs +21 -0
  620. package/dist/packages/crucible/seeds/rust/seed-049 2.rs +26 -0
  621. package/dist/packages/crucible/seeds/rust/seed-049.rs +26 -0
  622. package/dist/packages/crucible/seeds/rust/seed-050 2.rs +23 -0
  623. package/dist/packages/crucible/seeds/rust/seed-050.rs +23 -0
  624. package/dist/packages/crucible/seeds/ts/seed-001 2.ts +32 -0
  625. package/dist/packages/crucible/seeds/ts/seed-001.ts +32 -0
  626. package/dist/packages/crucible/seeds/ts/seed-002 2.ts +34 -0
  627. package/dist/packages/crucible/seeds/ts/seed-002.ts +34 -0
  628. package/dist/packages/crucible/seeds/ts/seed-003 2.ts +28 -0
  629. package/dist/packages/crucible/seeds/ts/seed-003.ts +28 -0
  630. package/dist/packages/crucible/seeds/ts/seed-004 2.ts +34 -0
  631. package/dist/packages/crucible/seeds/ts/seed-004.ts +34 -0
  632. package/dist/packages/crucible/seeds/ts/seed-005 2.ts +32 -0
  633. package/dist/packages/crucible/seeds/ts/seed-005.ts +32 -0
  634. package/dist/packages/crucible/seeds/ts/seed-006 2.ts +31 -0
  635. package/dist/packages/crucible/seeds/ts/seed-006.ts +31 -0
  636. package/dist/packages/crucible/seeds/ts/seed-007 2.ts +28 -0
  637. package/dist/packages/crucible/seeds/ts/seed-007.ts +28 -0
  638. package/dist/packages/crucible/seeds/ts/seed-008 2.ts +40 -0
  639. package/dist/packages/crucible/seeds/ts/seed-008.ts +40 -0
  640. package/dist/packages/crucible/seeds/ts/seed-009 2.ts +31 -0
  641. package/dist/packages/crucible/seeds/ts/seed-009.ts +31 -0
  642. package/dist/packages/crucible/seeds/ts/seed-010 2.ts +33 -0
  643. package/dist/packages/crucible/seeds/ts/seed-010.ts +33 -0
  644. package/dist/packages/crucible/seeds/ts/seed-011 2.ts +29 -0
  645. package/dist/packages/crucible/seeds/ts/seed-011.ts +29 -0
  646. package/dist/packages/crucible/seeds/ts/seed-012 2.ts +34 -0
  647. package/dist/packages/crucible/seeds/ts/seed-012.ts +34 -0
  648. package/dist/packages/crucible/seeds/ts/seed-013 2.ts +31 -0
  649. package/dist/packages/crucible/seeds/ts/seed-013.ts +31 -0
  650. package/dist/packages/crucible/seeds/ts/seed-014 2.ts +36 -0
  651. package/dist/packages/crucible/seeds/ts/seed-014.ts +36 -0
  652. package/dist/packages/crucible/seeds/ts/seed-015 2.ts +31 -0
  653. package/dist/packages/crucible/seeds/ts/seed-015.ts +31 -0
  654. package/dist/packages/crucible/seeds/ts/seed-016 2.ts +37 -0
  655. package/dist/packages/crucible/seeds/ts/seed-016.ts +37 -0
  656. package/dist/packages/crucible/seeds/ts/seed-017 2.ts +44 -0
  657. package/dist/packages/crucible/seeds/ts/seed-017.ts +44 -0
  658. package/dist/packages/crucible/seeds/ts/seed-018 2.ts +33 -0
  659. package/dist/packages/crucible/seeds/ts/seed-018.ts +33 -0
  660. package/dist/packages/crucible/seeds/ts/seed-019 2.ts +32 -0
  661. package/dist/packages/crucible/seeds/ts/seed-019.ts +32 -0
  662. package/dist/packages/crucible/seeds/ts/seed-020 2.ts +33 -0
  663. package/dist/packages/crucible/seeds/ts/seed-020.ts +33 -0
  664. package/dist/packages/crucible/seeds/ts/seed-021 2.ts +33 -0
  665. package/dist/packages/crucible/seeds/ts/seed-021.ts +33 -0
  666. package/dist/packages/crucible/seeds/ts/seed-022 2.ts +34 -0
  667. package/dist/packages/crucible/seeds/ts/seed-022.ts +34 -0
  668. package/dist/packages/crucible/seeds/ts/seed-023 2.ts +33 -0
  669. package/dist/packages/crucible/seeds/ts/seed-023.ts +33 -0
  670. package/dist/packages/crucible/seeds/ts/seed-024 2.ts +35 -0
  671. package/dist/packages/crucible/seeds/ts/seed-024.ts +35 -0
  672. package/dist/packages/crucible/seeds/ts/seed-025 2.ts +29 -0
  673. package/dist/packages/crucible/seeds/ts/seed-025.ts +29 -0
  674. package/dist/packages/crucible/seeds/ts/seed-026 2.ts +36 -0
  675. package/dist/packages/crucible/seeds/ts/seed-026.ts +36 -0
  676. package/dist/packages/crucible/seeds/ts/seed-027 2.ts +30 -0
  677. package/dist/packages/crucible/seeds/ts/seed-027.ts +30 -0
  678. package/dist/packages/crucible/seeds/ts/seed-028 2.ts +32 -0
  679. package/dist/packages/crucible/seeds/ts/seed-028.ts +32 -0
  680. package/dist/packages/crucible/seeds/ts/seed-029 2.ts +34 -0
  681. package/dist/packages/crucible/seeds/ts/seed-029.ts +34 -0
  682. package/dist/packages/crucible/seeds/ts/seed-030 2.ts +37 -0
  683. package/dist/packages/crucible/seeds/ts/seed-030.ts +37 -0
  684. package/dist/packages/crucible/seeds/ts/seed-031 2.ts +31 -0
  685. package/dist/packages/crucible/seeds/ts/seed-031.ts +31 -0
  686. package/dist/packages/crucible/seeds/ts/seed-032 2.ts +32 -0
  687. package/dist/packages/crucible/seeds/ts/seed-032.ts +32 -0
  688. package/dist/packages/crucible/seeds/ts/seed-033 2.ts +32 -0
  689. package/dist/packages/crucible/seeds/ts/seed-033.ts +32 -0
  690. package/dist/packages/crucible/seeds/ts/seed-034 2.ts +34 -0
  691. package/dist/packages/crucible/seeds/ts/seed-034.ts +34 -0
  692. package/dist/packages/crucible/seeds/ts/seed-035 2.ts +29 -0
  693. package/dist/packages/crucible/seeds/ts/seed-035.ts +29 -0
  694. package/dist/packages/crucible/seeds/ts/seed-036 2.ts +34 -0
  695. package/dist/packages/crucible/seeds/ts/seed-036.ts +34 -0
  696. package/dist/packages/crucible/seeds/ts/seed-037 2.ts +33 -0
  697. package/dist/packages/crucible/seeds/ts/seed-037.ts +33 -0
  698. package/dist/packages/crucible/seeds/ts/seed-038 2.ts +29 -0
  699. package/dist/packages/crucible/seeds/ts/seed-038.ts +29 -0
  700. package/dist/packages/crucible/seeds/ts/seed-039 2.ts +35 -0
  701. package/dist/packages/crucible/seeds/ts/seed-039.ts +35 -0
  702. package/dist/packages/crucible/seeds/ts/seed-040 2.ts +31 -0
  703. package/dist/packages/crucible/seeds/ts/seed-040.ts +31 -0
  704. package/dist/packages/crucible/seeds/ts/seed-041 2.ts +29 -0
  705. package/dist/packages/crucible/seeds/ts/seed-041.ts +29 -0
  706. package/dist/packages/crucible/seeds/ts/seed-042 2.ts +33 -0
  707. package/dist/packages/crucible/seeds/ts/seed-042.ts +33 -0
  708. package/dist/packages/crucible/seeds/ts/seed-043 2.ts +32 -0
  709. package/dist/packages/crucible/seeds/ts/seed-043.ts +32 -0
  710. package/dist/packages/crucible/seeds/ts/seed-044 2.ts +36 -0
  711. package/dist/packages/crucible/seeds/ts/seed-044.ts +36 -0
  712. package/dist/packages/crucible/seeds/ts/seed-045 2.ts +39 -0
  713. package/dist/packages/crucible/seeds/ts/seed-045.ts +39 -0
  714. package/dist/packages/crucible/seeds/ts/seed-046 2.ts +41 -0
  715. package/dist/packages/crucible/seeds/ts/seed-046.ts +41 -0
  716. package/dist/packages/crucible/seeds/ts/seed-047 2.ts +33 -0
  717. package/dist/packages/crucible/seeds/ts/seed-047.ts +33 -0
  718. package/dist/packages/crucible/seeds/ts/seed-048 2.ts +33 -0
  719. package/dist/packages/crucible/seeds/ts/seed-048.ts +33 -0
  720. package/dist/packages/crucible/seeds/ts/seed-049 2.ts +34 -0
  721. package/dist/packages/crucible/seeds/ts/seed-049.ts +34 -0
  722. package/dist/packages/crucible/seeds/ts/seed-050 2.ts +41 -0
  723. package/dist/packages/crucible/seeds/ts/seed-050.ts +41 -0
  724. package/dist/packages/crucible/seeds/ts/seed-051 2.ts +34 -0
  725. package/dist/packages/crucible/seeds/ts/seed-051.ts +34 -0
  726. package/dist/packages/crucible/seeds/ts/seed-052 2.ts +36 -0
  727. package/dist/packages/crucible/seeds/ts/seed-052.ts +36 -0
  728. package/dist/packages/scanner/alert-manager.js +1 -0
  729. package/dist/packages/scanner/architecture-map.js +1 -0
  730. package/dist/packages/scanner/ast-analyzer.js +1 -0
  731. package/dist/packages/scanner/benchmarks.js +1 -0
  732. package/dist/packages/scanner/cfg-analyzer.js +1 -0
  733. package/dist/packages/scanner/code-scanner.js +1 -0
  734. package/dist/packages/scanner/compliance-mapper.js +1 -0
  735. package/dist/packages/scanner/file-collector.js +1 -0
  736. package/dist/packages/scanner/file-watcher.js +1 -0
  737. package/dist/packages/scanner/ghost-code-detector.js +1 -0
  738. package/dist/packages/scanner/git-velocity.js +1 -0
  739. package/dist/packages/scanner/hallucination-detector.js +1 -0
  740. package/dist/packages/scanner/health-checker.js +1 -0
  741. package/dist/packages/scanner/investor-report.js +1 -0
  742. package/dist/packages/scanner/json-file-util.js +1 -0
  743. package/dist/packages/scanner/monitor-store.js +1 -0
  744. package/dist/packages/scanner/python_ast_helper.py +426 -0
  745. package/dist/packages/scanner/risk-valuation.js +1 -0
  746. package/dist/packages/scanner/scan-history.js +1 -0
  747. package/dist/packages/scanner/secret-scanner.js +1 -0
  748. package/dist/packages/scanner/sentinel-core.js +1 -0
  749. package/dist/packages/scanner/supply-chain.js +1 -0
  750. package/dist/packages/scanner/support-bot.js +1 -0
  751. package/dist/packages/scanner/support-knowledge.js +1 -0
  752. package/dist/packages/scanner/taint-tracker.js +1 -0
  753. package/package.json +65 -65
  754. package/cli.js +0 -2
  755. package/packages/crucible/.golden/golden-master.json +0 -414
  756. package/packages/crucible/README.md +0 -93
  757. package/packages/crucible/report-generator.js +0 -1
  758. package/packages/crucible/rules/code-scanner-core.json +0 -281
  759. package/packages/crucible/rules/command-injection.json +0 -411
  760. package/packages/crucible/rules/crypto-misuse.json +0 -35
  761. package/packages/crucible/rules/deserialization.json +0 -152
  762. package/packages/crucible/rules/env-injection.json +0 -46
  763. package/packages/crucible/rules/eval-abuse.json +0 -104
  764. package/packages/crucible/rules/file-upload.json +0 -46
  765. package/packages/crucible/rules/hallucination.json +0 -22
  766. package/packages/crucible/rules/hardcoded-secret.json +0 -397
  767. package/packages/crucible/rules/hardcoded-url.json +0 -13
  768. package/packages/crucible/rules/insecure-crypto.json +0 -302
  769. package/packages/crucible/rules/integer-overflow.json +0 -35
  770. package/packages/crucible/rules/log-injection.json +0 -33
  771. package/packages/crucible/rules/mass-assignment.json +0 -112
  772. package/packages/crucible/rules/open-redirect.json +0 -196
  773. package/packages/crucible/rules/path-traversal.json +0 -422
  774. package/packages/crucible/rules/prototype-pollution.json +0 -22
  775. package/packages/crucible/rules/sql-injection.json +0 -619
  776. package/packages/crucible/rules/ssrf.json +0 -557
  777. package/packages/crucible/rules/timing-attack.json +0 -55
  778. package/packages/crucible/rules/unsafe-block.json +0 -24
  779. package/packages/crucible/rules/xss.json +0 -663
  780. package/packages/crucible/rules/xxe.json +0 -66
  781. package/packages/crucible/rules/yaml-deserialization.json +0 -22
  782. package/packages/crucible/rules/yaml-injection.json +0 -22
  783. package/packages/crucible/seeds/csharp/seed-001.cs +0 -28
  784. package/packages/crucible/seeds/csharp/seed-002.cs +0 -24
  785. package/packages/crucible/seeds/csharp/seed-003.cs +0 -30
  786. package/packages/crucible/seeds/csharp/seed-004.cs +0 -31
  787. package/packages/crucible/seeds/csharp/seed-005.cs +0 -28
  788. package/packages/crucible/seeds/csharp/seed-006.cs +0 -25
  789. package/packages/crucible/seeds/csharp/seed-007.cs +0 -34
  790. package/packages/crucible/seeds/csharp/seed-008.cs +0 -23
  791. package/packages/crucible/seeds/csharp/seed-009.cs +0 -27
  792. package/packages/crucible/seeds/csharp/seed-010.cs +0 -29
  793. package/packages/crucible/seeds/csharp/seed-011.cs +0 -32
  794. package/packages/crucible/seeds/csharp/seed-012.cs +0 -27
  795. package/packages/crucible/seeds/csharp/seed-013.cs +0 -27
  796. package/packages/crucible/seeds/csharp/seed-014.cs +0 -26
  797. package/packages/crucible/seeds/csharp/seed-015.cs +0 -33
  798. package/packages/crucible/seeds/csharp/seed-016.cs +0 -25
  799. package/packages/crucible/seeds/csharp/seed-017.cs +0 -22
  800. package/packages/crucible/seeds/csharp/seed-018.cs +0 -26
  801. package/packages/crucible/seeds/csharp/seed-019.cs +0 -25
  802. package/packages/crucible/seeds/csharp/seed-020.cs +0 -22
  803. package/packages/crucible/seeds/csharp/seed-021.cs +0 -28
  804. package/packages/crucible/seeds/csharp/seed-022.cs +0 -25
  805. package/packages/crucible/seeds/csharp/seed-023.cs +0 -33
  806. package/packages/crucible/seeds/csharp/seed-024.cs +0 -31
  807. package/packages/crucible/seeds/csharp/seed-025.cs +0 -31
  808. package/packages/crucible/seeds/csharp/seed-026.cs +0 -25
  809. package/packages/crucible/seeds/csharp/seed-027.cs +0 -29
  810. package/packages/crucible/seeds/csharp/seed-028.cs +0 -25
  811. package/packages/crucible/seeds/csharp/seed-029.cs +0 -27
  812. package/packages/crucible/seeds/csharp/seed-030.cs +0 -27
  813. package/packages/crucible/seeds/csharp/seed-031.cs +0 -28
  814. package/packages/crucible/seeds/csharp/seed-032.cs +0 -30
  815. package/packages/crucible/seeds/csharp/seed-033.cs +0 -27
  816. package/packages/crucible/seeds/csharp/seed-034.cs +0 -25
  817. package/packages/crucible/seeds/csharp/seed-035.cs +0 -32
  818. package/packages/crucible/seeds/csharp/seed-036.cs +0 -28
  819. package/packages/crucible/seeds/csharp/seed-037.cs +0 -29
  820. package/packages/crucible/seeds/csharp/seed-038.cs +0 -28
  821. package/packages/crucible/seeds/csharp/seed-039.cs +0 -29
  822. package/packages/crucible/seeds/csharp/seed-040.cs +0 -28
  823. package/packages/crucible/seeds/csharp/seed-041.cs +0 -33
  824. package/packages/crucible/seeds/csharp/seed-042.cs +0 -27
  825. package/packages/crucible/seeds/csharp/seed-043.cs +0 -27
  826. package/packages/crucible/seeds/csharp/seed-044.cs +0 -25
  827. package/packages/crucible/seeds/csharp/seed-045.cs +0 -30
  828. package/packages/crucible/seeds/csharp/seed-046.cs +0 -29
  829. package/packages/crucible/seeds/csharp/seed-047.cs +0 -26
  830. package/packages/crucible/seeds/csharp/seed-048.cs +0 -31
  831. package/packages/crucible/seeds/csharp/seed-049.cs +0 -27
  832. package/packages/crucible/seeds/csharp/seed-050.cs +0 -30
  833. package/packages/crucible/seeds/csharp/seed-051.cs +0 -34
  834. package/packages/crucible/seeds/csharp/seed-052.cs +0 -36
  835. package/packages/crucible/seeds/go/seed-001.go +0 -29
  836. package/packages/crucible/seeds/go/seed-002.go +0 -27
  837. package/packages/crucible/seeds/go/seed-003.go +0 -31
  838. package/packages/crucible/seeds/go/seed-004.go +0 -27
  839. package/packages/crucible/seeds/go/seed-005.go +0 -27
  840. package/packages/crucible/seeds/go/seed-006.go +0 -29
  841. package/packages/crucible/seeds/go/seed-007.go +0 -24
  842. package/packages/crucible/seeds/go/seed-008.go +0 -25
  843. package/packages/crucible/seeds/go/seed-009.go +0 -30
  844. package/packages/crucible/seeds/go/seed-010.go +0 -35
  845. package/packages/crucible/seeds/go/seed-011.go +0 -24
  846. package/packages/crucible/seeds/go/seed-012.go +0 -24
  847. package/packages/crucible/seeds/go/seed-013.go +0 -31
  848. package/packages/crucible/seeds/go/seed-014.go +0 -35
  849. package/packages/crucible/seeds/go/seed-015.go +0 -25
  850. package/packages/crucible/seeds/go/seed-016.go +0 -19
  851. package/packages/crucible/seeds/go/seed-017.go +0 -23
  852. package/packages/crucible/seeds/go/seed-018.go +0 -23
  853. package/packages/crucible/seeds/go/seed-019.go +0 -22
  854. package/packages/crucible/seeds/go/seed-020.go +0 -31
  855. package/packages/crucible/seeds/go/seed-021.go +0 -22
  856. package/packages/crucible/seeds/go/seed-022.go +0 -29
  857. package/packages/crucible/seeds/go/seed-023.go +0 -26
  858. package/packages/crucible/seeds/go/seed-024.go +0 -27
  859. package/packages/crucible/seeds/go/seed-025.go +0 -23
  860. package/packages/crucible/seeds/go/seed-026.go +0 -29
  861. package/packages/crucible/seeds/go/seed-027.go +0 -26
  862. package/packages/crucible/seeds/go/seed-028.go +0 -23
  863. package/packages/crucible/seeds/go/seed-029.go +0 -28
  864. package/packages/crucible/seeds/go/seed-030.go +0 -27
  865. package/packages/crucible/seeds/go/seed-031.go +0 -28
  866. package/packages/crucible/seeds/go/seed-032.go +0 -27
  867. package/packages/crucible/seeds/go/seed-033.go +0 -29
  868. package/packages/crucible/seeds/go/seed-034.go +0 -22
  869. package/packages/crucible/seeds/go/seed-035.go +0 -32
  870. package/packages/crucible/seeds/go/seed-036.go +0 -27
  871. package/packages/crucible/seeds/go/seed-037.go +0 -27
  872. package/packages/crucible/seeds/go/seed-038.go +0 -27
  873. package/packages/crucible/seeds/go/seed-039.go +0 -26
  874. package/packages/crucible/seeds/go/seed-040.go +0 -37
  875. package/packages/crucible/seeds/go/seed-041.go +0 -23
  876. package/packages/crucible/seeds/go/seed-042.go +0 -32
  877. package/packages/crucible/seeds/go/seed-043.go +0 -35
  878. package/packages/crucible/seeds/go/seed-044.go +0 -25
  879. package/packages/crucible/seeds/go/seed-045.go +0 -26
  880. package/packages/crucible/seeds/go/seed-046.go +0 -34
  881. package/packages/crucible/seeds/go/seed-047.go +0 -26
  882. package/packages/crucible/seeds/go/seed-048.go +0 -29
  883. package/packages/crucible/seeds/go/seed-049.go +0 -24
  884. package/packages/crucible/seeds/go/seed-050.go +0 -27
  885. package/packages/crucible/seeds/go/seed-051.go +0 -38
  886. package/packages/crucible/seeds/go/seed-052.go +0 -27
  887. package/packages/crucible/seeds/java/seed-001.java +0 -23
  888. package/packages/crucible/seeds/java/seed-002.java +0 -22
  889. package/packages/crucible/seeds/java/seed-003.java +0 -28
  890. package/packages/crucible/seeds/java/seed-004.java +0 -26
  891. package/packages/crucible/seeds/java/seed-005.java +0 -33
  892. package/packages/crucible/seeds/java/seed-006.java +0 -22
  893. package/packages/crucible/seeds/java/seed-007.java +0 -21
  894. package/packages/crucible/seeds/java/seed-008.java +0 -29
  895. package/packages/crucible/seeds/java/seed-009.java +0 -24
  896. package/packages/crucible/seeds/java/seed-010.java +0 -30
  897. package/packages/crucible/seeds/java/seed-011.java +0 -25
  898. package/packages/crucible/seeds/java/seed-012.java +0 -20
  899. package/packages/crucible/seeds/java/seed-013.java +0 -26
  900. package/packages/crucible/seeds/java/seed-014.java +0 -23
  901. package/packages/crucible/seeds/java/seed-015.java +0 -25
  902. package/packages/crucible/seeds/java/seed-016.java +0 -22
  903. package/packages/crucible/seeds/java/seed-017.java +0 -24
  904. package/packages/crucible/seeds/java/seed-018.java +0 -24
  905. package/packages/crucible/seeds/java/seed-019.java +0 -38
  906. package/packages/crucible/seeds/java/seed-020.java +0 -24
  907. package/packages/crucible/seeds/java/seed-021.java +0 -22
  908. package/packages/crucible/seeds/java/seed-022.java +0 -22
  909. package/packages/crucible/seeds/java/seed-023.java +0 -22
  910. package/packages/crucible/seeds/java/seed-024.java +0 -25
  911. package/packages/crucible/seeds/java/seed-025.java +0 -27
  912. package/packages/crucible/seeds/java/seed-026.java +0 -25
  913. package/packages/crucible/seeds/java/seed-027.java +0 -22
  914. package/packages/crucible/seeds/java/seed-028.java +0 -21
  915. package/packages/crucible/seeds/java/seed-029.java +0 -28
  916. package/packages/crucible/seeds/java/seed-030.java +0 -27
  917. package/packages/crucible/seeds/java/seed-031.java +0 -23
  918. package/packages/crucible/seeds/java/seed-032.java +0 -22
  919. package/packages/crucible/seeds/java/seed-033.java +0 -24
  920. package/packages/crucible/seeds/java/seed-034.java +0 -24
  921. package/packages/crucible/seeds/java/seed-035.java +0 -29
  922. package/packages/crucible/seeds/java/seed-036.java +0 -25
  923. package/packages/crucible/seeds/java/seed-037.java +0 -30
  924. package/packages/crucible/seeds/java/seed-038.java +0 -29
  925. package/packages/crucible/seeds/java/seed-039.java +0 -26
  926. package/packages/crucible/seeds/java/seed-040.java +0 -31
  927. package/packages/crucible/seeds/java/seed-041.java +0 -20
  928. package/packages/crucible/seeds/java/seed-042.java +0 -26
  929. package/packages/crucible/seeds/java/seed-043.java +0 -31
  930. package/packages/crucible/seeds/java/seed-044.java +0 -22
  931. package/packages/crucible/seeds/java/seed-045.java +0 -25
  932. package/packages/crucible/seeds/java/seed-046.java +0 -22
  933. package/packages/crucible/seeds/java/seed-047.java +0 -26
  934. package/packages/crucible/seeds/java/seed-048.java +0 -24
  935. package/packages/crucible/seeds/java/seed-049.java +0 -28
  936. package/packages/crucible/seeds/java/seed-050.java +0 -29
  937. package/packages/crucible/seeds/java/seed-051.java +0 -25
  938. package/packages/crucible/seeds/java/seed-052.java +0 -32
  939. package/packages/crucible/seeds/js/seed-001.js +0 -27
  940. package/packages/crucible/seeds/js/seed-002.js +0 -28
  941. package/packages/crucible/seeds/js/seed-003.js +0 -30
  942. package/packages/crucible/seeds/js/seed-004.js +0 -28
  943. package/packages/crucible/seeds/js/seed-005.js +0 -31
  944. package/packages/crucible/seeds/js/seed-006.js +0 -28
  945. package/packages/crucible/seeds/js/seed-007.js +0 -26
  946. package/packages/crucible/seeds/js/seed-008.js +0 -30
  947. package/packages/crucible/seeds/js/seed-009.js +0 -30
  948. package/packages/crucible/seeds/js/seed-010.js +0 -29
  949. package/packages/crucible/seeds/js/seed-011.js +0 -34
  950. package/packages/crucible/seeds/js/seed-012.js +0 -32
  951. package/packages/crucible/seeds/js/seed-013.js +0 -29
  952. package/packages/crucible/seeds/js/seed-014.js +0 -29
  953. package/packages/crucible/seeds/js/seed-015.js +0 -31
  954. package/packages/crucible/seeds/js/seed-016.js +0 -31
  955. package/packages/crucible/seeds/js/seed-017.js +0 -30
  956. package/packages/crucible/seeds/js/seed-018.js +0 -29
  957. package/packages/crucible/seeds/js/seed-019.js +0 -32
  958. package/packages/crucible/seeds/js/seed-020.js +0 -29
  959. package/packages/crucible/seeds/js/seed-021.js +0 -31
  960. package/packages/crucible/seeds/js/seed-022.js +0 -31
  961. package/packages/crucible/seeds/js/seed-023.js +0 -29
  962. package/packages/crucible/seeds/js/seed-024.js +0 -29
  963. package/packages/crucible/seeds/js/seed-025.js +0 -34
  964. package/packages/crucible/seeds/js/seed-026.js +0 -31
  965. package/packages/crucible/seeds/js/seed-027.js +0 -31
  966. package/packages/crucible/seeds/js/seed-028.js +0 -33
  967. package/packages/crucible/seeds/js/seed-029.js +0 -33
  968. package/packages/crucible/seeds/js/seed-030.js +0 -30
  969. package/packages/crucible/seeds/js/seed-031.js +0 -31
  970. package/packages/crucible/seeds/js/seed-032.js +0 -34
  971. package/packages/crucible/seeds/js/seed-033.js +0 -33
  972. package/packages/crucible/seeds/js/seed-034.js +0 -33
  973. package/packages/crucible/seeds/js/seed-035.js +0 -30
  974. package/packages/crucible/seeds/js/seed-036.js +0 -30
  975. package/packages/crucible/seeds/js/seed-037.js +0 -29
  976. package/packages/crucible/seeds/js/seed-038.js +0 -31
  977. package/packages/crucible/seeds/js/seed-039.js +0 -34
  978. package/packages/crucible/seeds/js/seed-040.js +0 -35
  979. package/packages/crucible/seeds/js/seed-041.js +0 -32
  980. package/packages/crucible/seeds/js/seed-042.js +0 -32
  981. package/packages/crucible/seeds/js/seed-043.js +0 -27
  982. package/packages/crucible/seeds/js/seed-044.js +0 -29
  983. package/packages/crucible/seeds/js/seed-045.js +0 -33
  984. package/packages/crucible/seeds/js/seed-046.js +0 -33
  985. package/packages/crucible/seeds/js/seed-047.js +0 -29
  986. package/packages/crucible/seeds/js/seed-048.js +0 -29
  987. package/packages/crucible/seeds/js/seed-049.js +0 -34
  988. package/packages/crucible/seeds/js/seed-050.js +0 -34
  989. package/packages/crucible/seeds/js/seed-051.js +0 -30
  990. package/packages/crucible/seeds/js/seed-052.js +0 -30
  991. package/packages/crucible/seeds/js/seed-053.js +0 -26
  992. package/packages/crucible/seeds/js/seed-054.js +0 -35
  993. package/packages/crucible/seeds/js/seed-055.js +0 -33
  994. package/packages/crucible/seeds/kotlin/seed-001.kt +0 -24
  995. package/packages/crucible/seeds/kotlin/seed-002.kt +0 -27
  996. package/packages/crucible/seeds/kotlin/seed-003.kt +0 -29
  997. package/packages/crucible/seeds/kotlin/seed-004.kt +0 -24
  998. package/packages/crucible/seeds/kotlin/seed-005.kt +0 -29
  999. package/packages/crucible/seeds/kotlin/seed-006.kt +0 -21
  1000. package/packages/crucible/seeds/kotlin/seed-007.kt +0 -23
  1001. package/packages/crucible/seeds/kotlin/seed-008.kt +0 -25
  1002. package/packages/crucible/seeds/kotlin/seed-009.kt +0 -21
  1003. package/packages/crucible/seeds/kotlin/seed-010.kt +0 -28
  1004. package/packages/crucible/seeds/kotlin/seed-011.kt +0 -22
  1005. package/packages/crucible/seeds/kotlin/seed-012.kt +0 -25
  1006. package/packages/crucible/seeds/kotlin/seed-013.kt +0 -30
  1007. package/packages/crucible/seeds/kotlin/seed-014.kt +0 -27
  1008. package/packages/crucible/seeds/kotlin/seed-015.kt +0 -24
  1009. package/packages/crucible/seeds/kotlin/seed-016.kt +0 -28
  1010. package/packages/crucible/seeds/kotlin/seed-017.kt +0 -33
  1011. package/packages/crucible/seeds/kotlin/seed-018.kt +0 -31
  1012. package/packages/crucible/seeds/kotlin/seed-019.kt +0 -28
  1013. package/packages/crucible/seeds/kotlin/seed-020.kt +0 -31
  1014. package/packages/crucible/seeds/kotlin/seed-021.kt +0 -34
  1015. package/packages/crucible/seeds/kotlin/seed-022.kt +0 -29
  1016. package/packages/crucible/seeds/kotlin/seed-023.kt +0 -20
  1017. package/packages/crucible/seeds/kotlin/seed-024.kt +0 -23
  1018. package/packages/crucible/seeds/kotlin/seed-025.kt +0 -23
  1019. package/packages/crucible/seeds/kotlin/seed-026.kt +0 -26
  1020. package/packages/crucible/seeds/kotlin/seed-027.kt +0 -29
  1021. package/packages/crucible/seeds/kotlin/seed-028.kt +0 -24
  1022. package/packages/crucible/seeds/kotlin/seed-029.kt +0 -27
  1023. package/packages/crucible/seeds/kotlin/seed-030.kt +0 -26
  1024. package/packages/crucible/seeds/kotlin/seed-031.kt +0 -28
  1025. package/packages/crucible/seeds/kotlin/seed-032.kt +0 -29
  1026. package/packages/crucible/seeds/kotlin/seed-033.kt +0 -30
  1027. package/packages/crucible/seeds/kotlin/seed-034.kt +0 -26
  1028. package/packages/crucible/seeds/kotlin/seed-035.kt +0 -33
  1029. package/packages/crucible/seeds/kotlin/seed-036.kt +0 -25
  1030. package/packages/crucible/seeds/kotlin/seed-037.kt +0 -26
  1031. package/packages/crucible/seeds/kotlin/seed-038.kt +0 -25
  1032. package/packages/crucible/seeds/kotlin/seed-039.kt +0 -29
  1033. package/packages/crucible/seeds/kotlin/seed-040.kt +0 -28
  1034. package/packages/crucible/seeds/kotlin/seed-041.kt +0 -31
  1035. package/packages/crucible/seeds/kotlin/seed-042.kt +0 -27
  1036. package/packages/crucible/seeds/kotlin/seed-043.kt +0 -26
  1037. package/packages/crucible/seeds/kotlin/seed-044.kt +0 -27
  1038. package/packages/crucible/seeds/kotlin/seed-045.kt +0 -27
  1039. package/packages/crucible/seeds/kotlin/seed-046.kt +0 -33
  1040. package/packages/crucible/seeds/kotlin/seed-047.kt +0 -32
  1041. package/packages/crucible/seeds/kotlin/seed-048.kt +0 -20
  1042. package/packages/crucible/seeds/kotlin/seed-049.kt +0 -23
  1043. package/packages/crucible/seeds/kotlin/seed-050.kt +0 -19
  1044. package/packages/crucible/seeds/php/seed-001.php +0 -23
  1045. package/packages/crucible/seeds/php/seed-002.php +0 -18
  1046. package/packages/crucible/seeds/php/seed-003.php +0 -25
  1047. package/packages/crucible/seeds/php/seed-004.php +0 -21
  1048. package/packages/crucible/seeds/php/seed-005.php +0 -21
  1049. package/packages/crucible/seeds/php/seed-006.php +0 -21
  1050. package/packages/crucible/seeds/php/seed-007.php +0 -18
  1051. package/packages/crucible/seeds/php/seed-008.php +0 -19
  1052. package/packages/crucible/seeds/php/seed-009.php +0 -24
  1053. package/packages/crucible/seeds/php/seed-010.php +0 -24
  1054. package/packages/crucible/seeds/php/seed-011.php +0 -18
  1055. package/packages/crucible/seeds/php/seed-012.php +0 -24
  1056. package/packages/crucible/seeds/php/seed-013.php +0 -23
  1057. package/packages/crucible/seeds/php/seed-014.php +0 -20
  1058. package/packages/crucible/seeds/php/seed-015.php +0 -18
  1059. package/packages/crucible/seeds/php/seed-016.php +0 -18
  1060. package/packages/crucible/seeds/php/seed-017.php +0 -18
  1061. package/packages/crucible/seeds/php/seed-018.php +0 -17
  1062. package/packages/crucible/seeds/php/seed-019.php +0 -24
  1063. package/packages/crucible/seeds/php/seed-020.php +0 -19
  1064. package/packages/crucible/seeds/php/seed-021.php +0 -22
  1065. package/packages/crucible/seeds/php/seed-022.php +0 -15
  1066. package/packages/crucible/seeds/php/seed-023.php +0 -24
  1067. package/packages/crucible/seeds/php/seed-024.php +0 -22
  1068. package/packages/crucible/seeds/php/seed-025.php +0 -20
  1069. package/packages/crucible/seeds/php/seed-026.php +0 -22
  1070. package/packages/crucible/seeds/php/seed-027.php +0 -15
  1071. package/packages/crucible/seeds/php/seed-028.php +0 -15
  1072. package/packages/crucible/seeds/php/seed-029.php +0 -21
  1073. package/packages/crucible/seeds/php/seed-030.php +0 -21
  1074. package/packages/crucible/seeds/php/seed-031.php +0 -23
  1075. package/packages/crucible/seeds/php/seed-032.php +0 -18
  1076. package/packages/crucible/seeds/php/seed-033.php +0 -18
  1077. package/packages/crucible/seeds/php/seed-034.php +0 -24
  1078. package/packages/crucible/seeds/php/seed-035.php +0 -22
  1079. package/packages/crucible/seeds/php/seed-036.php +0 -17
  1080. package/packages/crucible/seeds/php/seed-037.php +0 -19
  1081. package/packages/crucible/seeds/php/seed-038.php +0 -20
  1082. package/packages/crucible/seeds/php/seed-039.php +0 -15
  1083. package/packages/crucible/seeds/php/seed-040.php +0 -21
  1084. package/packages/crucible/seeds/php/seed-041.php +0 -20
  1085. package/packages/crucible/seeds/php/seed-042.php +0 -21
  1086. package/packages/crucible/seeds/php/seed-043.php +0 -21
  1087. package/packages/crucible/seeds/php/seed-044.php +0 -25
  1088. package/packages/crucible/seeds/php/seed-045.php +0 -25
  1089. package/packages/crucible/seeds/php/seed-046.php +0 -20
  1090. package/packages/crucible/seeds/php/seed-047.php +0 -21
  1091. package/packages/crucible/seeds/php/seed-048.php +0 -19
  1092. package/packages/crucible/seeds/php/seed-049.php +0 -18
  1093. package/packages/crucible/seeds/php/seed-050.php +0 -20
  1094. package/packages/crucible/seeds/python/seed-001.py +0 -33
  1095. package/packages/crucible/seeds/python/seed-002.py +0 -39
  1096. package/packages/crucible/seeds/python/seed-003.py +0 -31
  1097. package/packages/crucible/seeds/python/seed-004.py +0 -33
  1098. package/packages/crucible/seeds/python/seed-005.py +0 -33
  1099. package/packages/crucible/seeds/python/seed-006.py +0 -34
  1100. package/packages/crucible/seeds/python/seed-007.py +0 -33
  1101. package/packages/crucible/seeds/python/seed-008.py +0 -38
  1102. package/packages/crucible/seeds/python/seed-009.py +0 -38
  1103. package/packages/crucible/seeds/python/seed-010.py +0 -42
  1104. package/packages/crucible/seeds/python/seed-011.py +0 -30
  1105. package/packages/crucible/seeds/python/seed-012.py +0 -35
  1106. package/packages/crucible/seeds/python/seed-013.py +0 -33
  1107. package/packages/crucible/seeds/python/seed-014.py +0 -40
  1108. package/packages/crucible/seeds/python/seed-015.py +0 -33
  1109. package/packages/crucible/seeds/python/seed-016.py +0 -34
  1110. package/packages/crucible/seeds/python/seed-017.py +0 -34
  1111. package/packages/crucible/seeds/python/seed-018.py +0 -30
  1112. package/packages/crucible/seeds/python/seed-019.py +0 -33
  1113. package/packages/crucible/seeds/python/seed-020.py +0 -37
  1114. package/packages/crucible/seeds/python/seed-021 2.py +0 -37
  1115. package/packages/crucible/seeds/python/seed-021.py +0 -37
  1116. package/packages/crucible/seeds/python/seed-022 2.py +0 -34
  1117. package/packages/crucible/seeds/python/seed-022.py +0 -34
  1118. package/packages/crucible/seeds/python/seed-023 2.py +0 -37
  1119. package/packages/crucible/seeds/python/seed-023.py +0 -37
  1120. package/packages/crucible/seeds/python/seed-024 2.py +0 -38
  1121. package/packages/crucible/seeds/python/seed-024.py +0 -38
  1122. package/packages/crucible/seeds/python/seed-025 2.py +0 -40
  1123. package/packages/crucible/seeds/python/seed-025.py +0 -40
  1124. package/packages/crucible/seeds/python/seed-026 2.py +0 -35
  1125. package/packages/crucible/seeds/python/seed-026.py +0 -35
  1126. package/packages/crucible/seeds/python/seed-027 2.py +0 -35
  1127. package/packages/crucible/seeds/python/seed-027.py +0 -35
  1128. package/packages/crucible/seeds/python/seed-028 2.py +0 -42
  1129. package/packages/crucible/seeds/python/seed-028.py +0 -42
  1130. package/packages/crucible/seeds/python/seed-029.py +0 -42
  1131. package/packages/crucible/seeds/python/seed-030 2.py +0 -37
  1132. package/packages/crucible/seeds/python/seed-030.py +0 -37
  1133. package/packages/crucible/seeds/python/seed-031 2.py +0 -34
  1134. package/packages/crucible/seeds/python/seed-031.py +0 -34
  1135. package/packages/crucible/seeds/python/seed-032.py +0 -33
  1136. package/packages/crucible/seeds/python/seed-033.py +0 -32
  1137. package/packages/crucible/seeds/python/seed-034.py +0 -38
  1138. package/packages/crucible/seeds/python/seed-035.py +0 -35
  1139. package/packages/crucible/seeds/python/seed-036 2.py +0 -33
  1140. package/packages/crucible/seeds/python/seed-036.py +0 -33
  1141. package/packages/crucible/seeds/python/seed-037 2.py +0 -41
  1142. package/packages/crucible/seeds/python/seed-037.py +0 -41
  1143. package/packages/crucible/seeds/python/seed-038 2.py +0 -33
  1144. package/packages/crucible/seeds/python/seed-038.py +0 -33
  1145. package/packages/crucible/seeds/python/seed-039 2.py +0 -39
  1146. package/packages/crucible/seeds/python/seed-039.py +0 -39
  1147. package/packages/crucible/seeds/python/seed-040 2.py +0 -39
  1148. package/packages/crucible/seeds/python/seed-040.py +0 -39
  1149. package/packages/crucible/seeds/python/seed-041 2.py +0 -37
  1150. package/packages/crucible/seeds/python/seed-041.py +0 -37
  1151. package/packages/crucible/seeds/python/seed-042 2.py +0 -38
  1152. package/packages/crucible/seeds/python/seed-042.py +0 -38
  1153. package/packages/crucible/seeds/python/seed-043 2.py +0 -32
  1154. package/packages/crucible/seeds/python/seed-043.py +0 -32
  1155. package/packages/crucible/seeds/python/seed-044 2.py +0 -38
  1156. package/packages/crucible/seeds/python/seed-044.py +0 -38
  1157. package/packages/crucible/seeds/python/seed-045 2.py +0 -36
  1158. package/packages/crucible/seeds/python/seed-045.py +0 -36
  1159. package/packages/crucible/seeds/python/seed-046 2.py +0 -33
  1160. package/packages/crucible/seeds/python/seed-046.py +0 -33
  1161. package/packages/crucible/seeds/python/seed-047 2.py +0 -44
  1162. package/packages/crucible/seeds/python/seed-047.py +0 -44
  1163. package/packages/crucible/seeds/python/seed-048 2.py +0 -35
  1164. package/packages/crucible/seeds/python/seed-048.py +0 -35
  1165. package/packages/crucible/seeds/python/seed-049 2.py +0 -39
  1166. package/packages/crucible/seeds/python/seed-049.py +0 -39
  1167. package/packages/crucible/seeds/python/seed-050 2.py +0 -39
  1168. package/packages/crucible/seeds/python/seed-050.py +0 -39
  1169. package/packages/crucible/seeds/python/seed-051 2.py +0 -38
  1170. package/packages/crucible/seeds/python/seed-051.py +0 -38
  1171. package/packages/crucible/seeds/python/seed-052 2.py +0 -41
  1172. package/packages/crucible/seeds/python/seed-052.py +0 -41
  1173. package/packages/crucible/seeds/ruby/seed-001 2.rb +0 -15
  1174. package/packages/crucible/seeds/ruby/seed-001.rb +0 -15
  1175. package/packages/crucible/seeds/ruby/seed-002 2.rb +0 -22
  1176. package/packages/crucible/seeds/ruby/seed-002.rb +0 -22
  1177. package/packages/crucible/seeds/ruby/seed-003 2.rb +0 -25
  1178. package/packages/crucible/seeds/ruby/seed-003.rb +0 -25
  1179. package/packages/crucible/seeds/ruby/seed-004 2.rb +0 -17
  1180. package/packages/crucible/seeds/ruby/seed-004.rb +0 -17
  1181. package/packages/crucible/seeds/ruby/seed-005 2.rb +0 -21
  1182. package/packages/crucible/seeds/ruby/seed-005.rb +0 -21
  1183. package/packages/crucible/seeds/ruby/seed-006 2.rb +0 -17
  1184. package/packages/crucible/seeds/ruby/seed-006.rb +0 -17
  1185. package/packages/crucible/seeds/ruby/seed-007 2.rb +0 -16
  1186. package/packages/crucible/seeds/ruby/seed-007.rb +0 -16
  1187. package/packages/crucible/seeds/ruby/seed-008 2.rb +0 -18
  1188. package/packages/crucible/seeds/ruby/seed-008.rb +0 -18
  1189. package/packages/crucible/seeds/ruby/seed-009 2.rb +0 -20
  1190. package/packages/crucible/seeds/ruby/seed-009.rb +0 -20
  1191. package/packages/crucible/seeds/ruby/seed-010 2.rb +0 -24
  1192. package/packages/crucible/seeds/ruby/seed-010.rb +0 -24
  1193. package/packages/crucible/seeds/ruby/seed-011 2.rb +0 -21
  1194. package/packages/crucible/seeds/ruby/seed-011.rb +0 -21
  1195. package/packages/crucible/seeds/ruby/seed-012 2.rb +0 -22
  1196. package/packages/crucible/seeds/ruby/seed-012.rb +0 -22
  1197. package/packages/crucible/seeds/ruby/seed-013 2.rb +0 -21
  1198. package/packages/crucible/seeds/ruby/seed-013.rb +0 -21
  1199. package/packages/crucible/seeds/ruby/seed-014 2.rb +0 -16
  1200. package/packages/crucible/seeds/ruby/seed-014.rb +0 -16
  1201. package/packages/crucible/seeds/ruby/seed-015 2.rb +0 -18
  1202. package/packages/crucible/seeds/ruby/seed-015.rb +0 -18
  1203. package/packages/crucible/seeds/ruby/seed-016 2.rb +0 -17
  1204. package/packages/crucible/seeds/ruby/seed-016.rb +0 -17
  1205. package/packages/crucible/seeds/ruby/seed-017 2.rb +0 -25
  1206. package/packages/crucible/seeds/ruby/seed-017.rb +0 -25
  1207. package/packages/crucible/seeds/ruby/seed-018 2.rb +0 -23
  1208. package/packages/crucible/seeds/ruby/seed-018.rb +0 -23
  1209. package/packages/crucible/seeds/ruby/seed-019 2.rb +0 -20
  1210. package/packages/crucible/seeds/ruby/seed-019.rb +0 -20
  1211. package/packages/crucible/seeds/ruby/seed-020 2.rb +0 -17
  1212. package/packages/crucible/seeds/ruby/seed-020.rb +0 -17
  1213. package/packages/crucible/seeds/ruby/seed-021 2.rb +0 -20
  1214. package/packages/crucible/seeds/ruby/seed-021.rb +0 -20
  1215. package/packages/crucible/seeds/ruby/seed-022 2.rb +0 -21
  1216. package/packages/crucible/seeds/ruby/seed-022.rb +0 -21
  1217. package/packages/crucible/seeds/ruby/seed-023 2.rb +0 -19
  1218. package/packages/crucible/seeds/ruby/seed-023.rb +0 -19
  1219. package/packages/crucible/seeds/ruby/seed-024 2.rb +0 -17
  1220. package/packages/crucible/seeds/ruby/seed-024.rb +0 -17
  1221. package/packages/crucible/seeds/ruby/seed-025 2.rb +0 -17
  1222. package/packages/crucible/seeds/ruby/seed-025.rb +0 -17
  1223. package/packages/crucible/seeds/ruby/seed-026 2.rb +0 -18
  1224. package/packages/crucible/seeds/ruby/seed-026.rb +0 -18
  1225. package/packages/crucible/seeds/ruby/seed-027 2.rb +0 -21
  1226. package/packages/crucible/seeds/ruby/seed-027.rb +0 -21
  1227. package/packages/crucible/seeds/ruby/seed-028 2.rb +0 -22
  1228. package/packages/crucible/seeds/ruby/seed-028.rb +0 -22
  1229. package/packages/crucible/seeds/ruby/seed-029 2.rb +0 -19
  1230. package/packages/crucible/seeds/ruby/seed-029.rb +0 -19
  1231. package/packages/crucible/seeds/ruby/seed-030 2.rb +0 -20
  1232. package/packages/crucible/seeds/ruby/seed-030.rb +0 -20
  1233. package/packages/crucible/seeds/ruby/seed-031 2.rb +0 -17
  1234. package/packages/crucible/seeds/ruby/seed-031.rb +0 -17
  1235. package/packages/crucible/seeds/ruby/seed-032 2.rb +0 -22
  1236. package/packages/crucible/seeds/ruby/seed-032.rb +0 -22
  1237. package/packages/crucible/seeds/ruby/seed-033 2.rb +0 -18
  1238. package/packages/crucible/seeds/ruby/seed-033.rb +0 -18
  1239. package/packages/crucible/seeds/ruby/seed-034 2.rb +0 -19
  1240. package/packages/crucible/seeds/ruby/seed-034.rb +0 -19
  1241. package/packages/crucible/seeds/ruby/seed-035 2.rb +0 -19
  1242. package/packages/crucible/seeds/ruby/seed-035.rb +0 -19
  1243. package/packages/crucible/seeds/ruby/seed-036 2.rb +0 -18
  1244. package/packages/crucible/seeds/ruby/seed-036.rb +0 -18
  1245. package/packages/crucible/seeds/ruby/seed-037 2.rb +0 -21
  1246. package/packages/crucible/seeds/ruby/seed-037.rb +0 -21
  1247. package/packages/crucible/seeds/ruby/seed-038 2.rb +0 -24
  1248. package/packages/crucible/seeds/ruby/seed-038.rb +0 -24
  1249. package/packages/crucible/seeds/ruby/seed-039 2.rb +0 -24
  1250. package/packages/crucible/seeds/ruby/seed-039.rb +0 -24
  1251. package/packages/crucible/seeds/ruby/seed-040 2.rb +0 -22
  1252. package/packages/crucible/seeds/ruby/seed-040.rb +0 -22
  1253. package/packages/crucible/seeds/ruby/seed-041 2.rb +0 -23
  1254. package/packages/crucible/seeds/ruby/seed-041.rb +0 -23
  1255. package/packages/crucible/seeds/ruby/seed-042 2.rb +0 -25
  1256. package/packages/crucible/seeds/ruby/seed-042.rb +0 -25
  1257. package/packages/crucible/seeds/ruby/seed-043 2.rb +0 -23
  1258. package/packages/crucible/seeds/ruby/seed-043.rb +0 -23
  1259. package/packages/crucible/seeds/ruby/seed-044 2.rb +0 -16
  1260. package/packages/crucible/seeds/ruby/seed-044.rb +0 -16
  1261. package/packages/crucible/seeds/ruby/seed-045 2.rb +0 -22
  1262. package/packages/crucible/seeds/ruby/seed-045.rb +0 -22
  1263. package/packages/crucible/seeds/ruby/seed-046 2.rb +0 -27
  1264. package/packages/crucible/seeds/ruby/seed-046.rb +0 -27
  1265. package/packages/crucible/seeds/ruby/seed-047 2.rb +0 -26
  1266. package/packages/crucible/seeds/ruby/seed-047.rb +0 -26
  1267. package/packages/crucible/seeds/ruby/seed-048 2.rb +0 -24
  1268. package/packages/crucible/seeds/ruby/seed-048.rb +0 -24
  1269. package/packages/crucible/seeds/ruby/seed-049 2.rb +0 -20
  1270. package/packages/crucible/seeds/ruby/seed-049.rb +0 -20
  1271. package/packages/crucible/seeds/ruby/seed-050 2.rb +0 -27
  1272. package/packages/crucible/seeds/ruby/seed-050.rb +0 -27
  1273. package/packages/crucible/seeds/rust/seed-001 2.rs +0 -25
  1274. package/packages/crucible/seeds/rust/seed-001.rs +0 -25
  1275. package/packages/crucible/seeds/rust/seed-002 2.rs +0 -20
  1276. package/packages/crucible/seeds/rust/seed-002.rs +0 -20
  1277. package/packages/crucible/seeds/rust/seed-003 2.rs +0 -23
  1278. package/packages/crucible/seeds/rust/seed-003.rs +0 -23
  1279. package/packages/crucible/seeds/rust/seed-004 2.rs +0 -21
  1280. package/packages/crucible/seeds/rust/seed-004.rs +0 -21
  1281. package/packages/crucible/seeds/rust/seed-005 2.rs +0 -21
  1282. package/packages/crucible/seeds/rust/seed-005.rs +0 -21
  1283. package/packages/crucible/seeds/rust/seed-006 2.rs +0 -24
  1284. package/packages/crucible/seeds/rust/seed-006.rs +0 -24
  1285. package/packages/crucible/seeds/rust/seed-007 2.rs +0 -20
  1286. package/packages/crucible/seeds/rust/seed-007.rs +0 -20
  1287. package/packages/crucible/seeds/rust/seed-008 2.rs +0 -19
  1288. package/packages/crucible/seeds/rust/seed-008.rs +0 -19
  1289. package/packages/crucible/seeds/rust/seed-009 2.rs +0 -28
  1290. package/packages/crucible/seeds/rust/seed-009.rs +0 -28
  1291. package/packages/crucible/seeds/rust/seed-010 2.rs +0 -28
  1292. package/packages/crucible/seeds/rust/seed-010.rs +0 -28
  1293. package/packages/crucible/seeds/rust/seed-011 2.rs +0 -25
  1294. package/packages/crucible/seeds/rust/seed-011.rs +0 -25
  1295. package/packages/crucible/seeds/rust/seed-012 2.rs +0 -31
  1296. package/packages/crucible/seeds/rust/seed-012.rs +0 -31
  1297. package/packages/crucible/seeds/rust/seed-013 2.rs +0 -27
  1298. package/packages/crucible/seeds/rust/seed-013.rs +0 -27
  1299. package/packages/crucible/seeds/rust/seed-014 2.rs +0 -30
  1300. package/packages/crucible/seeds/rust/seed-014.rs +0 -30
  1301. package/packages/crucible/seeds/rust/seed-015 2.rs +0 -33
  1302. package/packages/crucible/seeds/rust/seed-015.rs +0 -33
  1303. package/packages/crucible/seeds/rust/seed-016 2.rs +0 -22
  1304. package/packages/crucible/seeds/rust/seed-016.rs +0 -22
  1305. package/packages/crucible/seeds/rust/seed-017 2.rs +0 -28
  1306. package/packages/crucible/seeds/rust/seed-017.rs +0 -28
  1307. package/packages/crucible/seeds/rust/seed-018 2.rs +0 -21
  1308. package/packages/crucible/seeds/rust/seed-018.rs +0 -21
  1309. package/packages/crucible/seeds/rust/seed-019 2.rs +0 -36
  1310. package/packages/crucible/seeds/rust/seed-019.rs +0 -36
  1311. package/packages/crucible/seeds/rust/seed-020 2.rs +0 -27
  1312. package/packages/crucible/seeds/rust/seed-020.rs +0 -27
  1313. package/packages/crucible/seeds/rust/seed-021 2.rs +0 -26
  1314. package/packages/crucible/seeds/rust/seed-021.rs +0 -26
  1315. package/packages/crucible/seeds/rust/seed-022 2.rs +0 -23
  1316. package/packages/crucible/seeds/rust/seed-022.rs +0 -23
  1317. package/packages/crucible/seeds/rust/seed-023 2.rs +0 -22
  1318. package/packages/crucible/seeds/rust/seed-023.rs +0 -22
  1319. package/packages/crucible/seeds/rust/seed-024 2.rs +0 -24
  1320. package/packages/crucible/seeds/rust/seed-024.rs +0 -24
  1321. package/packages/crucible/seeds/rust/seed-025 2.rs +0 -29
  1322. package/packages/crucible/seeds/rust/seed-025.rs +0 -29
  1323. package/packages/crucible/seeds/rust/seed-026 2.rs +0 -23
  1324. package/packages/crucible/seeds/rust/seed-026.rs +0 -23
  1325. package/packages/crucible/seeds/rust/seed-027 2.rs +0 -24
  1326. package/packages/crucible/seeds/rust/seed-027.rs +0 -24
  1327. package/packages/crucible/seeds/rust/seed-028 2.rs +0 -25
  1328. package/packages/crucible/seeds/rust/seed-028.rs +0 -25
  1329. package/packages/crucible/seeds/rust/seed-029 2.rs +0 -25
  1330. package/packages/crucible/seeds/rust/seed-029.rs +0 -25
  1331. package/packages/crucible/seeds/rust/seed-030 2.rs +0 -30
  1332. package/packages/crucible/seeds/rust/seed-030.rs +0 -30
  1333. package/packages/crucible/seeds/rust/seed-031 2.rs +0 -22
  1334. package/packages/crucible/seeds/rust/seed-031.rs +0 -22
  1335. package/packages/crucible/seeds/rust/seed-032 2.rs +0 -25
  1336. package/packages/crucible/seeds/rust/seed-032.rs +0 -25
  1337. package/packages/crucible/seeds/rust/seed-033 2.rs +0 -25
  1338. package/packages/crucible/seeds/rust/seed-033.rs +0 -25
  1339. package/packages/crucible/seeds/rust/seed-034 2.rs +0 -20
  1340. package/packages/crucible/seeds/rust/seed-034.rs +0 -20
  1341. package/packages/crucible/seeds/rust/seed-035 2.rs +0 -28
  1342. package/packages/crucible/seeds/rust/seed-035.rs +0 -28
  1343. package/packages/crucible/seeds/rust/seed-036 2.rs +0 -26
  1344. package/packages/crucible/seeds/rust/seed-036.rs +0 -26
  1345. package/packages/crucible/seeds/rust/seed-037 2.rs +0 -31
  1346. package/packages/crucible/seeds/rust/seed-037.rs +0 -31
  1347. package/packages/crucible/seeds/rust/seed-038 2.rs +0 -25
  1348. package/packages/crucible/seeds/rust/seed-038.rs +0 -25
  1349. package/packages/crucible/seeds/rust/seed-039 2.rs +0 -28
  1350. package/packages/crucible/seeds/rust/seed-039.rs +0 -28
  1351. package/packages/crucible/seeds/rust/seed-040 2.rs +0 -27
  1352. package/packages/crucible/seeds/rust/seed-040.rs +0 -27
  1353. package/packages/crucible/seeds/rust/seed-041 2.rs +0 -32
  1354. package/packages/crucible/seeds/rust/seed-041.rs +0 -32
  1355. package/packages/crucible/seeds/rust/seed-042 2.rs +0 -27
  1356. package/packages/crucible/seeds/rust/seed-042.rs +0 -27
  1357. package/packages/crucible/seeds/rust/seed-043 2.rs +0 -29
  1358. package/packages/crucible/seeds/rust/seed-043.rs +0 -29
  1359. package/packages/crucible/seeds/rust/seed-044 2.rs +0 -25
  1360. package/packages/crucible/seeds/rust/seed-044.rs +0 -25
  1361. package/packages/crucible/seeds/rust/seed-045 2.rs +0 -28
  1362. package/packages/crucible/seeds/rust/seed-045.rs +0 -28
  1363. package/packages/crucible/seeds/rust/seed-046 2.rs +0 -25
  1364. package/packages/crucible/seeds/rust/seed-046.rs +0 -25
  1365. package/packages/crucible/seeds/rust/seed-047 2.rs +0 -34
  1366. package/packages/crucible/seeds/rust/seed-047.rs +0 -34
  1367. package/packages/crucible/seeds/rust/seed-048 2.rs +0 -21
  1368. package/packages/crucible/seeds/rust/seed-048.rs +0 -21
  1369. package/packages/crucible/seeds/rust/seed-049 2.rs +0 -26
  1370. package/packages/crucible/seeds/rust/seed-049.rs +0 -26
  1371. package/packages/crucible/seeds/rust/seed-050 2.rs +0 -23
  1372. package/packages/crucible/seeds/rust/seed-050.rs +0 -23
  1373. package/packages/crucible/seeds/ts/seed-001 2.ts +0 -32
  1374. package/packages/crucible/seeds/ts/seed-001.ts +0 -32
  1375. package/packages/crucible/seeds/ts/seed-002 2.ts +0 -34
  1376. package/packages/crucible/seeds/ts/seed-002.ts +0 -34
  1377. package/packages/crucible/seeds/ts/seed-003 2.ts +0 -28
  1378. package/packages/crucible/seeds/ts/seed-003.ts +0 -28
  1379. package/packages/crucible/seeds/ts/seed-004 2.ts +0 -34
  1380. package/packages/crucible/seeds/ts/seed-004.ts +0 -34
  1381. package/packages/crucible/seeds/ts/seed-005 2.ts +0 -32
  1382. package/packages/crucible/seeds/ts/seed-005.ts +0 -32
  1383. package/packages/crucible/seeds/ts/seed-006 2.ts +0 -31
  1384. package/packages/crucible/seeds/ts/seed-006.ts +0 -31
  1385. package/packages/crucible/seeds/ts/seed-007 2.ts +0 -28
  1386. package/packages/crucible/seeds/ts/seed-007.ts +0 -28
  1387. package/packages/crucible/seeds/ts/seed-008 2.ts +0 -40
  1388. package/packages/crucible/seeds/ts/seed-008.ts +0 -40
  1389. package/packages/crucible/seeds/ts/seed-009 2.ts +0 -31
  1390. package/packages/crucible/seeds/ts/seed-009.ts +0 -31
  1391. package/packages/crucible/seeds/ts/seed-010 2.ts +0 -33
  1392. package/packages/crucible/seeds/ts/seed-010.ts +0 -33
  1393. package/packages/crucible/seeds/ts/seed-011 2.ts +0 -29
  1394. package/packages/crucible/seeds/ts/seed-011.ts +0 -29
  1395. package/packages/crucible/seeds/ts/seed-012 2.ts +0 -34
  1396. package/packages/crucible/seeds/ts/seed-012.ts +0 -34
  1397. package/packages/crucible/seeds/ts/seed-013 2.ts +0 -31
  1398. package/packages/crucible/seeds/ts/seed-013.ts +0 -31
  1399. package/packages/crucible/seeds/ts/seed-014 2.ts +0 -36
  1400. package/packages/crucible/seeds/ts/seed-014.ts +0 -36
  1401. package/packages/crucible/seeds/ts/seed-015 2.ts +0 -31
  1402. package/packages/crucible/seeds/ts/seed-015.ts +0 -31
  1403. package/packages/crucible/seeds/ts/seed-016 2.ts +0 -37
  1404. package/packages/crucible/seeds/ts/seed-016.ts +0 -37
  1405. package/packages/crucible/seeds/ts/seed-017 2.ts +0 -44
  1406. package/packages/crucible/seeds/ts/seed-017.ts +0 -44
  1407. package/packages/crucible/seeds/ts/seed-018 2.ts +0 -33
  1408. package/packages/crucible/seeds/ts/seed-018.ts +0 -33
  1409. package/packages/crucible/seeds/ts/seed-019 2.ts +0 -32
  1410. package/packages/crucible/seeds/ts/seed-019.ts +0 -32
  1411. package/packages/crucible/seeds/ts/seed-020 2.ts +0 -33
  1412. package/packages/crucible/seeds/ts/seed-020.ts +0 -33
  1413. package/packages/crucible/seeds/ts/seed-021 2.ts +0 -33
  1414. package/packages/crucible/seeds/ts/seed-021.ts +0 -33
  1415. package/packages/crucible/seeds/ts/seed-022 2.ts +0 -34
  1416. package/packages/crucible/seeds/ts/seed-022.ts +0 -34
  1417. package/packages/crucible/seeds/ts/seed-023 2.ts +0 -33
  1418. package/packages/crucible/seeds/ts/seed-023.ts +0 -33
  1419. package/packages/crucible/seeds/ts/seed-024 2.ts +0 -35
  1420. package/packages/crucible/seeds/ts/seed-024.ts +0 -35
  1421. package/packages/crucible/seeds/ts/seed-025 2.ts +0 -29
  1422. package/packages/crucible/seeds/ts/seed-025.ts +0 -29
  1423. package/packages/crucible/seeds/ts/seed-026 2.ts +0 -36
  1424. package/packages/crucible/seeds/ts/seed-026.ts +0 -36
  1425. package/packages/crucible/seeds/ts/seed-027 2.ts +0 -30
  1426. package/packages/crucible/seeds/ts/seed-027.ts +0 -30
  1427. package/packages/crucible/seeds/ts/seed-028 2.ts +0 -32
  1428. package/packages/crucible/seeds/ts/seed-028.ts +0 -32
  1429. package/packages/crucible/seeds/ts/seed-029 2.ts +0 -34
  1430. package/packages/crucible/seeds/ts/seed-029.ts +0 -34
  1431. package/packages/crucible/seeds/ts/seed-030 2.ts +0 -37
  1432. package/packages/crucible/seeds/ts/seed-030.ts +0 -37
  1433. package/packages/crucible/seeds/ts/seed-031 2.ts +0 -31
  1434. package/packages/crucible/seeds/ts/seed-031.ts +0 -31
  1435. package/packages/crucible/seeds/ts/seed-032 2.ts +0 -32
  1436. package/packages/crucible/seeds/ts/seed-032.ts +0 -32
  1437. package/packages/crucible/seeds/ts/seed-033 2.ts +0 -32
  1438. package/packages/crucible/seeds/ts/seed-033.ts +0 -32
  1439. package/packages/crucible/seeds/ts/seed-034 2.ts +0 -34
  1440. package/packages/crucible/seeds/ts/seed-034.ts +0 -34
  1441. package/packages/crucible/seeds/ts/seed-035 2.ts +0 -29
  1442. package/packages/crucible/seeds/ts/seed-035.ts +0 -29
  1443. package/packages/crucible/seeds/ts/seed-036 2.ts +0 -34
  1444. package/packages/crucible/seeds/ts/seed-036.ts +0 -34
  1445. package/packages/crucible/seeds/ts/seed-037 2.ts +0 -33
  1446. package/packages/crucible/seeds/ts/seed-037.ts +0 -33
  1447. package/packages/crucible/seeds/ts/seed-038 2.ts +0 -29
  1448. package/packages/crucible/seeds/ts/seed-038.ts +0 -29
  1449. package/packages/crucible/seeds/ts/seed-039 2.ts +0 -35
  1450. package/packages/crucible/seeds/ts/seed-039.ts +0 -35
  1451. package/packages/crucible/seeds/ts/seed-040 2.ts +0 -31
  1452. package/packages/crucible/seeds/ts/seed-040.ts +0 -31
  1453. package/packages/crucible/seeds/ts/seed-041 2.ts +0 -29
  1454. package/packages/crucible/seeds/ts/seed-041.ts +0 -29
  1455. package/packages/crucible/seeds/ts/seed-042 2.ts +0 -33
  1456. package/packages/crucible/seeds/ts/seed-042.ts +0 -33
  1457. package/packages/crucible/seeds/ts/seed-043 2.ts +0 -32
  1458. package/packages/crucible/seeds/ts/seed-043.ts +0 -32
  1459. package/packages/crucible/seeds/ts/seed-044 2.ts +0 -36
  1460. package/packages/crucible/seeds/ts/seed-044.ts +0 -36
  1461. package/packages/crucible/seeds/ts/seed-045 2.ts +0 -39
  1462. package/packages/crucible/seeds/ts/seed-045.ts +0 -39
  1463. package/packages/crucible/seeds/ts/seed-046 2.ts +0 -41
  1464. package/packages/crucible/seeds/ts/seed-046.ts +0 -41
  1465. package/packages/crucible/seeds/ts/seed-047 2.ts +0 -33
  1466. package/packages/crucible/seeds/ts/seed-047.ts +0 -33
  1467. package/packages/crucible/seeds/ts/seed-048 2.ts +0 -33
  1468. package/packages/crucible/seeds/ts/seed-048.ts +0 -33
  1469. package/packages/crucible/seeds/ts/seed-049 2.ts +0 -34
  1470. package/packages/crucible/seeds/ts/seed-049.ts +0 -34
  1471. package/packages/crucible/seeds/ts/seed-050 2.ts +0 -41
  1472. package/packages/crucible/seeds/ts/seed-050.ts +0 -41
  1473. package/packages/crucible/seeds/ts/seed-051 2.ts +0 -34
  1474. package/packages/crucible/seeds/ts/seed-051.ts +0 -34
  1475. package/packages/crucible/seeds/ts/seed-052 2.ts +0 -36
  1476. package/packages/crucible/seeds/ts/seed-052.ts +0 -36
  1477. package/packages/scanner/alert-manager.js +0 -1
  1478. package/packages/scanner/ast-analyzer.js +0 -1
  1479. package/packages/scanner/cfg-analyzer.js +0 -1
  1480. package/packages/scanner/code-scanner.js +0 -1
  1481. package/packages/scanner/file-collector.js +0 -1
  1482. package/packages/scanner/file-watcher.js +0 -1
  1483. package/packages/scanner/ghost-code-detector.js +0 -1
  1484. package/packages/scanner/hallucination-detector.js +0 -1
  1485. package/packages/scanner/health-checker.js +0 -1
  1486. package/packages/scanner/investor-report.js +0 -1
  1487. package/packages/scanner/master-health-checker.js +0 -1
  1488. package/packages/scanner/monitor-store.js +0 -1
  1489. package/packages/scanner/python_ast_helper.py +0 -426
  1490. package/packages/scanner/secret-scanner.js +0 -1
  1491. package/packages/scanner/sentinel-core.js +0 -1
  1492. package/packages/scanner/support-bot.js +0 -1
  1493. package/packages/scanner/support-knowledge.js +0 -1
  1494. package/packages/scanner/taint-tracker.js +0 -1
  1495. /package/{packages → dist/packages}/crucible/badge-generator.js +0 -0
  1496. /package/{packages → dist/packages}/crucible/banner.js +0 -0
  1497. /package/{packages → dist/packages}/crucible/ci-integration.js +0 -0
  1498. /package/{packages → dist/packages}/crucible/golden-master.js +0 -0
  1499. /package/{packages → dist/packages}/crucible/index.js +0 -0
  1500. /package/{packages → dist/packages}/crucible/kenny-mode.js +0 -0
  1501. /package/{packages → dist/packages}/crucible/leaderboard.js +0 -0
  1502. /package/{packages → dist/packages}/crucible/mutation-engine.js +0 -0
  1503. /package/{packages → dist/packages}/crucible/pattern-learner.js +0 -0
  1504. /package/{packages → dist/packages}/crucible/rule-loader.js +0 -0
  1505. /package/{packages → dist/packages}/crucible/seeding-engine.js +0 -0
  1506. /package/{packages → dist/packages}/crucible/self-attack.js +0 -0
  1507. /package/{packages → dist/packages}/scanner/ai-confidence-scorer.js +0 -0
  1508. /package/{packages → dist/packages}/scanner/baseline-manager.js +0 -0
  1509. /package/{packages → dist/packages}/scanner/codebase-passport.js +0 -0
  1510. /package/{packages → dist/packages}/scanner/copy-paste-detector.js +0 -0
  1511. /package/{packages → dist/packages}/scanner/dependency-graph.js +0 -0
  1512. /package/{packages → dist/packages}/scanner/drift-detector.js +0 -0
  1513. /package/{packages → dist/packages}/scanner/executive-report.js +0 -0
  1514. /package/{packages → dist/packages}/scanner/export-verifier.js +0 -0
  1515. /package/{packages → dist/packages}/scanner/feedback-client.js +0 -0
  1516. /package/{packages → dist/packages}/scanner/go-ast-analyzer.js +0 -0
  1517. /package/{packages → dist/packages}/scanner/html-report.js +0 -0
  1518. /package/{packages → dist/packages}/scanner/index.js +0 -0
  1519. /package/{packages → dist/packages}/scanner/license-manager.js +0 -0
  1520. /package/{packages → dist/packages}/scanner/monitor-notifier.js +0 -0
  1521. /package/{packages → dist/packages}/scanner/monitor-service.js +0 -0
  1522. /package/{packages → dist/packages}/scanner/pre-commit-gate.js +0 -0
  1523. /package/{packages → dist/packages}/scanner/python-ast-analyzer.js +0 -0
  1524. /package/{packages → dist/packages}/scanner/read-file.js +0 -0
  1525. /package/{packages → dist/packages}/scanner/scan-diff.js +0 -0
  1526. /package/{packages → dist/packages}/scanner/scan-runner.js +0 -0
  1527. /package/{packages → dist/packages}/scanner/sentinel-knowledge.js +0 -0
  1528. /package/{packages → dist/packages}/scanner/slack-notifier.js +0 -0
  1529. /package/{packages → dist/packages}/scanner/tech-debt-analyzer.js +0 -0
  1530. /package/{packages → dist/packages}/scanner/tech-debt-cost.js +0 -0
  1531. /package/{packages → dist/packages}/scanner/widget-generator.js +0 -0
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),exportVerifier=require("./export-verifier");class HallucinationDetector{constructor(e={}){const t=new Set(["rootPath","ignorePatterns","maxFileSize"]),s={};for(const n of Object.keys(e))t.has(n)&&(s[n]=e[n]);this.config={rootPath:s.rootPath||process.cwd()},this.builtins=new Set(["assert","async_hooks","buffer","child_process","cluster","console","constants","crypto","dgram","diagnostics_channel","dns","domain","events","fs","http","http2","https","inspector","module","net","os","path","perf_hooks","process","punycode","querystring","readline","repl","stream","string_decoder","sys","test","timers","tls","trace_events","tty","url","util","v8","vm","wasi","worker_threads","zlib","node:fs","node:path","node:os","node:crypto","node:http","node:https","node:events","node:util","node:stream","node:child_process","node:url","node:querystring","node:buffer","node:net","node:tls","node:dns","node:readline","node:zlib","node:worker_threads","node:cluster","node:vm","node:assert","node:timers","node:timers/promises","node:test","fs/promises","stream/promises","timers/promises","dns/promises","readline/promises"]),this.phantomPackages=new Set(["node-fetch-extra","express-async","mongoose-v2","react-native-web-view","axios-retry-enhanced","lodash-extended","moment-timezone-v2","socket.io-extra","graphql-tools-v2","next-auth-v5","prisma-client-v2","tailwind-utils","react-query-v4","jest-extended-v2"]),this.knownRealPackages=new Set(["express","koa","fastify","hapi","nest","@nestjs/core","@nestjs/common","next","nuxt","gatsby","remix","@remix-run/node","@remix-run/react","react","react-dom","react-native","react-router","react-router-dom","@tanstack/react-query","react-query","react-hook-form","react-redux","redux","@reduxjs/toolkit","zustand","jotai","recoil","mobx","vue","vuex","pinia","vue-router","@vue/compiler-sfc","@angular/core","@angular/common","@angular/router","@angular/forms","lodash","lodash-es","underscore","ramda","date-fns","dayjs","moment","uuid","nanoid","chalk","colors","debug","dotenv","cross-env","commander","yargs","inquirer","ora","glob","minimatch","semver","minimist","meow","execa","shelljs","fs-extra","rimraf","mkdirp","del","cpy","globby","fast-glob","chokidar","nodemon","axios","node-fetch","got","superagent","ky","undici","isomorphic-fetch","cors","helmet","body-parser","cookie-parser","compression","express-validator","joi","yup","zod","ajv","mongoose","sequelize","typeorm","prisma","@prisma/client","knex","pg","mysql","mysql2","sqlite3","better-sqlite3","redis","ioredis","mongodb","drizzle-orm","objection","bookshelf","jsonwebtoken","bcrypt","bcryptjs","passport","passport-local","passport-jwt","express-session","cookie-session","csurf","hpp","rate-limiter-flexible","express-rate-limit","next-auth","@auth/core","jest","mocha","chai","sinon","vitest","@testing-library/react","@testing-library/jest-dom","supertest","nock","cypress","playwright","@playwright/test","enzyme","nyc","istanbul","c8","ava","tap","webpack","vite","esbuild","rollup","parcel","turbo","tsup","babel-loader","@babel/core","@babel/preset-env","@babel/preset-react","@babel/preset-typescript","ts-node","tsx","typescript","tailwindcss","postcss","autoprefixer","sass","less","styled-components","@emotion/react","@emotion/styled","css-modules","classnames","clsx","winston","pino","bunyan","morgan","log4js","loglevel","sentry","@sentry/node","@sentry/react","newrelic","datadog-metrics","aws-sdk","@aws-sdk/client-s3","@aws-sdk/client-dynamodb","@google-cloud/storage","@google-cloud/pubsub","@google-cloud/firestore","firebase","firebase-admin","@supabase/supabase-js","socket.io","socket.io-client","ws","mqtt","amqplib","bull","bullmq","multer","sharp","jimp","formidable","busboy","csv-parse","csv-parser","papaparse","xlsx","exceljs","pdfkit","puppeteer","cheerio","jsdom","graphql","apollo-server","@apollo/server","@apollo/client","graphql-tag","type-graphql","graphql-yoga","urql","async","bluebird","rxjs","immutable","immer","p-limit","p-queue","eventemitter3","mitt","cron","node-cron","agenda","handlebars","ejs","pug","nunjucks","mustache","marked","markdown-it","remark","rehype","unified","nodemailer","twilio","stripe","@stripe/stripe-js","i18next","intl","i18n","luxon","eslint","prettier","stylelint","lint-staged","husky","lerna","nx","@nrwl/workspace","changesets","@changesets/cli","vscode"]),this.phantomAPIs=[{pattern:/fs\.readFileAsync\s*\(/,suggestion:"Use fs.promises.readFile() or fs.readFileSync()",name:"fs.readFileAsync",id:"HALL_API001"},{pattern:/fs\.writeFileAsync\s*\(/,suggestion:"Use fs.promises.writeFile() or fs.writeFileSync()",name:"fs.writeFileAsync",id:"HALL_API002"},{pattern:/fs\.existsAsync\s*\(/,suggestion:"Use fs.promises.access() or fs.existsSync()",name:"fs.existsAsync",id:"HALL_API003"},{pattern:/path\.exists\s*\(/,suggestion:"Use fs.existsSync() — path module has no exists()",name:"path.exists",id:"HALL_API004"},{pattern:/path\.isFile\s*\(/,suggestion:"Use fs.statSync().isFile() — path module has no isFile()",name:"path.isFile",id:"HALL_API005"},{pattern:/path\.isDirectory\s*\(/,suggestion:"Use fs.statSync().isDirectory()",name:"path.isDirectory",id:"HALL_API006"},{pattern:/console\.success\s*\(/,suggestion:"Use console.log() — console.success() does not exist",name:"console.success",id:"HALL_API007"},{pattern:/console\.verbose\s*\(/,suggestion:"Use console.log() or console.debug()",name:"console.verbose",id:"HALL_API008"},{pattern:/JSON\.tryParse\s*\(/,suggestion:"Use try/catch with JSON.parse()",name:"JSON.tryParse",id:"HALL_API009"},{pattern:/JSON\.safeStringify\s*\(/,suggestion:"Use JSON.stringify() with a replacer",name:"JSON.safeStringify",id:"HALL_API010"},{pattern:/Array\.flatten\s*\(/,suggestion:"Use Array.prototype.flat()",name:"Array.flatten",id:"HALL_API011"},{pattern:/Object\.deepClone\s*\(/,suggestion:"Use structuredClone() or JSON.parse(JSON.stringify())",name:"Object.deepClone",id:"HALL_API012"},{pattern:/Object\.deepMerge\s*\(/,suggestion:"Use a library like lodash.merge or write a custom function",name:"Object.deepMerge",id:"HALL_API013"},{pattern:/String\.prototype\.replaceAll\s*&&.*polyfill/i,suggestion:"replaceAll() is native since ES2021 — no polyfill needed",name:"replaceAll polyfill",id:"HALL_API014"},{pattern:/require\s*\(\s*['"]fs\/sync['"]\s*\)/,suggestion:"fs/sync is not a real module — use fs directly",name:"fs/sync",id:"HALL_API015"},{pattern:/require\s*\(\s*['"]http\/server['"]\s*\)/,suggestion:"http/server is not a real module — use http.createServer()",name:"http/server",id:"HALL_API016"},{pattern:/process\.env\.get\s*\(/,suggestion:"Use process.env.VAR_NAME — process.env is a plain object, not a Map",name:"process.env.get()",id:"HALL_API017"},{pattern:/process\.exit\s*\(\s*['"]/,suggestion:"process.exit() takes a number, not a string",name:"process.exit(string)",id:"HALL_API018"}],this.pythonPhantomAPIs=[{pattern:/os\.path\.exists_sync\s*\(/,suggestion:"Use os.path.exists() — exists_sync does not exist in Python",name:"os.path.exists_sync",id:"PY_HALL001"},{pattern:/json\.tryParse\s*\(/,suggestion:"Use json.loads() with try/except",name:"json.tryParse",id:"PY_HALL002"},{pattern:/\w+\.flatMap\s*\(/,suggestion:"Python lists have no flatMap — use list comprehension or itertools.chain.from_iterable()",name:"list.flatMap",id:"PY_HALL003"},{pattern:/\w+\.merge\s*\((?!.*\bself\b)/,suggestion:"Use {**dict1, **dict2} or dict1 | dict2 (3.9+)",name:"dict.merge",id:"PY_HALL004"},{pattern:/\w+\.format_map\s*\(/,suggestion:"str.format_map exists but is rarely correct — did you mean .format()?",name:"string.format_map misuse",id:"PY_HALL005"},{pattern:/from\s+collections\s+import\s+OrderedDict.*#.*maintain\s+order/i,suggestion:"Regular dict maintains order since Python 3.7 — OrderedDict is unnecessary",name:"Unnecessary OrderedDict",id:"PY_HALL006"},{pattern:/async\s+def\s+\w+.*asyncio\.sleep\s*\(\s*0\s*\)\s*#.*yield/i,suggestion:"asyncio.sleep(0) to yield is a code smell — review async design",name:"asyncio.sleep(0) hack",id:"PY_HALL007"},{pattern:/import\s+tensorflow\.v2/,suggestion:"tensorflow.v2 is not a real module — use import tensorflow",name:"tensorflow.v2",id:"PY_HALL008"},{pattern:/from\s+sklearn\.model_selection\s+import\s+train_test_split_v2/,suggestion:"train_test_split_v2 does not exist — use train_test_split",name:"sklearn v2 hallucination",id:"PY_HALL009"},{pattern:/requests\.async_get\s*\(/,suggestion:"requests has no async_get — use aiohttp or httpx",name:"requests.async_get",id:"PY_HALL010"}],this.pythonDeprecated=[{pattern:/from\s+distutils/,suggestion:"distutils removed in Python 3.12 — use setuptools",since:"Python 3.12",name:"distutils",id:"PY_DEPR001"},{pattern:/from\s+imp\s+import/,suggestion:"imp removed in Python 3.12 — use importlib",since:"Python 3.12",name:"imp module",id:"PY_DEPR002"},{pattern:/asyncio\.get_event_loop\(\)/,suggestion:"Deprecated in 3.10+ — use asyncio.run() or get_running_loop()",since:"Python 3.10",name:"asyncio.get_event_loop()",id:"PY_DEPR003"},{pattern:/collections\.MutableMapping/,suggestion:"Moved to collections.abc.MutableMapping in Python 3.3+",since:"Python 3.9",name:"collections.MutableMapping",id:"PY_DEPR004"},{pattern:/optparse\.OptionParser/,suggestion:"optparse deprecated since Python 3.2 — use argparse",since:"Python 3.2",name:"optparse",id:"PY_DEPR005"},{pattern:/cgi\.parse_header\s*\(/,suggestion:"cgi module deprecated in Python 3.11, removed in 3.13",since:"Python 3.11",name:"cgi module",id:"PY_DEPR006"},{pattern:/from\s+typing\s+import\s+(List|Dict|Tuple|Set)\b/,suggestion:"Use built-in list, dict, tuple, set for type hints (Python 3.9+)",since:"Python 3.9",name:"typing.List/Dict/Tuple",id:"PY_DEPR007"},{pattern:/unittest\.makeSuite\s*\(/,suggestion:"makeSuite deprecated — use TestLoader.loadTestsFromTestCase",since:"Python 3.11",name:"unittest.makeSuite",id:"PY_DEPR008"}],this.pythonSmells=[{pattern:/print\s*\(\s*f?['"]\s*debug/i,id:"PY_SMELL001",name:"Debug Print",message:"Debug print statement left in code"},{pattern:/except\s*:\s*$|except\s+Exception\s*:\s*\n\s*pass/m,id:"PY_SMELL002",name:"Bare Except",message:"Bare except or swallowed exception — hides real errors"},{pattern:/#\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"PY_SMELL003",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/raise\s+NotImplementedError\s*\(?\s*\)?/,id:"PY_SMELL004",name:"Not Implemented",message:"Stub implementation — function body was not generated"},{pattern:/['"]your.api.key.here['"]|['"]sk-[.]{3,}['"]/i,id:"PY_SMELL005",name:"Dummy Credential",message:"Placeholder credential — will fail at runtime"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"PY_SMELL006",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"},{pattern:/import\s+\*/,id:"PY_SMELL007",name:"Wildcard Import",message:"Wildcard import — pollutes namespace, hides dependencies"}],this.goDeprecated=[{pattern:/ioutil\.ReadFile\s*\(/,suggestion:"ioutil removed in Go 1.16 — use os.ReadFile()",since:"Go 1.16",name:"ioutil.ReadFile",id:"GO_DEPR001"},{pattern:/ioutil\.WriteFile\s*\(/,suggestion:"ioutil removed in Go 1.16 — use os.WriteFile()",since:"Go 1.16",name:"ioutil.WriteFile",id:"GO_DEPR002"},{pattern:/ioutil\.TempDir\s*\(/,suggestion:"ioutil removed in Go 1.16 — use os.MkdirTemp()",since:"Go 1.16",name:"ioutil.TempDir",id:"GO_DEPR003"},{pattern:/ioutil\.ReadAll\s*\(/,suggestion:"ioutil removed in Go 1.16 — use io.ReadAll()",since:"Go 1.16",name:"ioutil.ReadAll",id:"GO_DEPR004"},{pattern:/strings\.Title\s*\(/,suggestion:"strings.Title deprecated in Go 1.18 — use cases.Title from golang.org/x/text",since:"Go 1.18",name:"strings.Title",id:"GO_DEPR005"}],this.goSmells=[{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"GO_SMELL001",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/panic\s*\(\s*["']not implemented["']\s*\)/,id:"GO_SMELL002",name:"Panic Not Implemented",message:"Stub implementation — will panic at runtime"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"GO_SMELL003",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"}],this.rustPhantomAPIs=[{pattern:/std::fs::File::open_async\s*\(/,suggestion:"Use tokio::fs::File::open() for async file I/O",name:"File::open_async",id:"RS_HALL001"},{pattern:/Vec::flatten\s*\(/,suggestion:"Use .into_iter().flatten() — Vec has no flatten() method",name:"Vec::flatten",id:"RS_HALL002"},{pattern:/HashMap::get_or_default\s*\(/,suggestion:"Use .get().unwrap_or(&default) or entry().or_insert()",name:"HashMap::get_or_default",id:"RS_HALL003"},{pattern:/String::from_utf8_lossy_owned\s*\(/,suggestion:"Use String::from_utf8_lossy().into_owned()",name:"String::from_utf8_lossy_owned",id:"RS_HALL004"},{pattern:/\.async_iter\s*\(/,suggestion:"Use futures::stream::iter() from the futures crate",name:".async_iter()",id:"RS_HALL005"},{pattern:/std::net::TcpStream::connect_async\s*\(/,suggestion:"Use tokio::net::TcpStream::connect()",name:"TcpStream::connect_async",id:"RS_HALL006"},{pattern:/std::thread::sleep_async\s*\(/,suggestion:"Use tokio::time::sleep() for async sleep",name:"thread::sleep_async",id:"RS_HALL007"},{pattern:/Vec::remove_all\s*\(/,suggestion:"Use .retain(|x| condition) or .clear()",name:"Vec::remove_all",id:"RS_HALL008"},{pattern:/str::split_whitespace_n\s*\(/,suggestion:"Use .splitn(n, char::is_whitespace) instead",name:"str::split_whitespace_n",id:"RS_HALL009"},{pattern:/\.map_async\s*\(/,suggestion:"Use futures::future::join_all() or tokio::task::spawn",name:".map_async()",id:"RS_HALL010"}],this.rustDeprecated=[{pattern:/std::sync::ONCE_INIT/,suggestion:"std::sync::ONCE_INIT removed — use Once::new()",since:"Rust 1.38",name:"ONCE_INIT",id:"RS_DEPR001"},{pattern:/\bstd::mem::uninitialized\s*\(/,suggestion:"std::mem::uninitialized() removed — use MaybeUninit::uninit()",since:"Rust 1.39",name:"mem::uninitialized",id:"RS_DEPR002"},{pattern:/\btry!\s*\(/,suggestion:"try!() macro removed — use the ? operator",since:"Rust 2018",name:"try!() macro",id:"RS_DEPR003"},{pattern:/extern\s+crate\s+std\s*;/,suggestion:"extern crate std is implicit since Rust 2018 edition",since:"Rust 2018",name:"extern crate std",id:"RS_DEPR004"},{pattern:/extern\s+crate\s+alloc\s*;/,suggestion:"extern crate alloc is implicit in 2018+ edition",since:"Rust 2018",name:"extern crate alloc",id:"RS_DEPR005"},{pattern:/std::error::Error::cause\s*\(/,suggestion:".cause() deprecated — use .source() instead",since:"Rust 1.33",name:"Error::cause()",id:"RS_DEPR006"}],this.rustSmells=[{pattern:/todo!\s*\(\s*\)/,id:"RS_SMELL001",name:"todo! macro",message:"todo!() macro — will panic at runtime"},{pattern:/unimplemented!\s*\(\s*\)/,id:"RS_SMELL002",name:"unimplemented! macro",message:"unimplemented!() macro — will panic at runtime"},{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"RS_SMELL003",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/unwrap\(\).*unwrap\(\)/,id:"RS_SMELL004",name:"Double Unwrap",message:"Chained unwrap() — will panic on None/Err"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"RS_SMELL005",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"},{pattern:/unsafe\s*\{/,id:"RS_SMELL006",name:"Unsafe Block",message:"unsafe block — verify memory safety guarantees"},{pattern:/\.unwrap\(\)\s*;/,id:"RS_SMELL007",name:"Bare unwrap()",message:".unwrap() will panic on None/Err — use ? or match"},{pattern:/println!\s*\(\s*["'].*[Dd]ebug/,id:"RS_SMELL008",name:"Debug println!",message:"Debug println! left in code — use the log crate"},{pattern:/eprintln!\s*\(\s*["'].*[Dd]ebug/,id:"RS_SMELL009",name:"Debug eprintln!",message:"Debug eprintln! left in code — use the log crate"},{pattern:/#\[allow\(dead_code\)\]/,id:"RS_SMELL010",name:"Suppressed Dead Code",message:"#[allow(dead_code)] suppresses warnings — remove unused code"}],this.javaSmells=[{pattern:/System\.out\.println\s*\(.*debug/i,id:"JAVA_SMELL001",name:"Debug Println",message:"Debug System.out.println — use a logger"},{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"JAVA_SMELL002",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/throw\s+new\s+(?:Runtime)?Exception\s*\(\s*["']Not\s+implemented["']/i,id:"JAVA_SMELL003",name:"Not Implemented",message:"Stub implementation — will throw at runtime"},{pattern:/catch\s*\(\s*Exception\s+\w+\s*\)\s*\{\s*\}/,id:"JAVA_SMELL004",name:"Empty Catch",message:"Empty catch block — swallows all exceptions"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"JAVA_SMELL005",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"}],this.csharpSmells=[{pattern:/Console\.WriteLine\s*\(.*[Dd]ebug/i,id:"CS_SMELL001",name:"Debug WriteLine",message:"Debug Console.WriteLine — use ILogger or Debug.Write"},{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"CS_SMELL002",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/throw\s+new\s+(?:NotImplementedException)\s*\(/,id:"CS_SMELL003",name:"Not Implemented",message:"Stub implementation — will throw at runtime"},{pattern:/catch\s*\(\s*Exception\s+\w+\s*\)\s*\{\s*\}/,id:"CS_SMELL004",name:"Empty Catch",message:"Empty catch block — swallows all exceptions"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"CS_SMELL005",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"}],this.kotlinPhantomAPIs=[{pattern:/\.flatMap\s*\{[^}]*\}(?!.*asSequence)/,suggestion:"Use .flatMap { } — verify this is not confusing sequence vs list behavior",name:"flatMap confusion",id:"KT_HALL001"},{pattern:/listOf\(\)\.stream\s*\(/,suggestion:"Kotlin lists have no .stream() — use .asSequence() or direct collection ops",name:"listOf().stream()",id:"KT_HALL002"},{pattern:/String\.format\s*\(/,suggestion:'Prefer Kotlin string templates "$variable" over String.format()',name:"String.format Java-style",id:"KT_HALL003"},{pattern:/\bObject\s*\(\s*\)/,suggestion:"Kotlin uses Any() not Object() — or use object keyword for singletons",name:"Object() Java-style",id:"KT_HALL004"},{pattern:/\.forEach\s*\(\s*::println\s*\)(?!.*debug)/i,suggestion:"println is for debug output — use a logger",name:"println via forEach",id:"KT_HALL005"},{pattern:/coroutineScope\s*\{\s*launch\s*\{[^}]*\}\s*\}(?!\s*\.join)/,suggestion:"Unjoined coroutine in coroutineScope may cause issues — ensure structured concurrency",name:"Unawaited launch",id:"KT_HALL006"},{pattern:/Dispatchers\.IO\s*\+\s*Dispatchers/,suggestion:"Combining Dispatchers is not valid — use one dispatcher at a time",name:"Combined Dispatchers",id:"KT_HALL007"},{pattern:/\.toList\(\)\.stream\(\)/,suggestion:"Use Kotlin sequences (.asSequence()) instead of .toList().stream()",name:"toList().stream()",id:"KT_HALL008"},{pattern:/companion object.*getInstance/i,suggestion:"Kotlin idiom for singletons is object keyword, not companion object + getInstance()",name:"Java-style singleton",id:"KT_HALL009"},{pattern:/lateinit var.*\?/,suggestion:"lateinit properties cannot be nullable — remove ? or use by lazy {}",name:"lateinit nullable",id:"KT_HALL010"}],this.kotlinDeprecated=[{pattern:/\bapply\s+plugin:\s*['"]kotlin-android-extensions['"]/,suggestion:"kotlin-android-extensions deprecated — use view binding or Jetpack ViewBinding",since:"Kotlin 1.8",name:"kotlin-android-extensions",id:"KT_DEPR001"},{pattern:/\bkotlinx\.android\.synthetic/,suggestion:"Synthetic imports deprecated — use view binding or findViewById",since:"Kotlin 1.8",name:"Synthetic imports",id:"KT_DEPR002"},{pattern:/\bCoroutineScope\(EmptyCoroutineContext\)/,suggestion:"EmptyCoroutineContext coroutine scope is error-prone — use viewModelScope or lifecycleScope",since:"Kotlin Coroutines 1.6",name:"EmptyCoroutineContext scope",id:"KT_DEPR003"},{pattern:/\bBuildersKt\.launch\b/,suggestion:"Internal BuildersKt APIs are deprecated — use coroutineScope { launch {} }",since:"Kotlin Coroutines 1.5",name:"BuildersKt.launch",id:"KT_DEPR004"},{pattern:/\basyncLazy\s*\{/,suggestion:"asyncLazy {} is not a standard Kotlin API — use lazy {} or async {}",since:"Kotlin 1.6",name:"asyncLazy",id:"KT_DEPR005"}],this.kotlinSmells=[{pattern:/\bprintln\s*\(/,id:"KT_SMELL001",name:"Debug println",message:"println() is for debug output — use a proper logger"},{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"KT_SMELL002",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/TODO\s*\(\s*\)/,id:"KT_SMELL003",name:"TODO() stub",message:"TODO() will throw NotImplementedError at runtime"},{pattern:/!!\s*\./,id:"KT_SMELL004",name:"Non-null assertion chain",message:"!! non-null assertion — will throw NullPointerException if null"},{pattern:/\bas\s+\w+\b(?!.*\?)/,suggestion:"Unsafe cast — prefer safe cast (as? Type) with null check",id:"KT_SMELL005",name:"Unsafe cast",message:"Unsafe cast with as — will throw ClassCastException if wrong type"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"KT_SMELL006",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"},{pattern:/catch\s*\(\s*e:\s*Exception\s*\)\s*\{\s*\}/,id:"KT_SMELL007",name:"Empty Catch",message:"Empty catch block — swallows all exceptions"},{pattern:/throw\s+NotImplementedError\s*\(/,id:"KT_SMELL008",name:"Not Implemented",message:"Stub implementation — will throw at runtime"}],this.phpPhantomAPIs=[{pattern:/array_flatten\s*\(/,suggestion:"PHP has no array_flatten() — use array_merge(...$array) or a recursive function",name:"array_flatten",id:"PHP_HALL001"},{pattern:/str_contains_all\s*\(/,suggestion:"PHP has no str_contains_all() — use multiple str_contains() calls",name:"str_contains_all",id:"PHP_HALL002"},{pattern:/array_unique_values\s*\(/,suggestion:"PHP has no array_unique_values() — use array_values(array_unique())",name:"array_unique_values",id:"PHP_HALL003"},{pattern:/\$pdo->fetchAll\s*\(/,suggestion:"fetchAll() is on PDOStatement not PDO — call $stmt->fetchAll()",name:"PDO::fetchAll",id:"PHP_HALL004"},{pattern:/json_decode_safe\s*\(/,suggestion:"PHP has no json_decode_safe() — wrap json_decode() with json_last_error() check",name:"json_decode_safe",id:"PHP_HALL005"},{pattern:/str_replace_all\s*\(/,suggestion:"PHP has no str_replace_all() — use str_replace() which already replaces all occurrences",name:"str_replace_all",id:"PHP_HALL006"},{pattern:/array_map_keys\s*\(/,suggestion:"PHP has no array_map_keys() — use array_combine(array_map(...), array_keys())",name:"array_map_keys",id:"PHP_HALL007"},{pattern:/\$request->getJson\s*\(/,suggestion:'Not a standard PHP function — use json_decode(file_get_contents("php://input"))',name:"$request->getJson",id:"PHP_HALL008"},{pattern:/Date::now\s*\(/,suggestion:"PHP has no Date::now() — use new DateTime() or time()",name:"Date::now",id:"PHP_HALL009"},{pattern:/\bawait\s+/,suggestion:"PHP has no await keyword — use synchronous code or ReactPHP for async",name:"await keyword",id:"PHP_HALL010"}],this.phpDeprecated=[{pattern:/\bmysql_connect\s*\(/,suggestion:"mysql_* functions removed in PHP 7 — use PDO or MySQLi",since:"PHP 7.0",name:"mysql_connect",id:"PHP_DEPR001"},{pattern:/\bmysql_query\s*\(/,suggestion:"mysql_* functions removed in PHP 7 — use PDO or MySQLi",since:"PHP 7.0",name:"mysql_query",id:"PHP_DEPR002"},{pattern:/\bmysql_fetch_array\s*\(/,suggestion:"mysql_* functions removed in PHP 7 — use PDO or MySQLi",since:"PHP 7.0",name:"mysql_fetch_array",id:"PHP_DEPR003"},{pattern:/\bereg\s*\(/,suggestion:"ereg() removed in PHP 7 — use preg_match()",since:"PHP 7.0",name:"ereg()",id:"PHP_DEPR004"},{pattern:/\bsplit\s*\(/,suggestion:"split() removed in PHP 7 — use preg_split() or explode()",since:"PHP 7.0",name:"split()",id:"PHP_DEPR005"},{pattern:/\bcreate_function\s*\(/,suggestion:"create_function() removed in PHP 8 — use anonymous functions (closures)",since:"PHP 8.0",name:"create_function",id:"PHP_DEPR006"},{pattern:/\bmagic_quotes_gpc\b/,suggestion:"magic_quotes_gpc removed in PHP 7 — sanitize inputs manually",since:"PHP 7.0",name:"magic_quotes_gpc",id:"PHP_DEPR007"},{pattern:/\beach\s*\(/,suggestion:"each() deprecated in PHP 7.2, removed in PHP 8 — use foreach",since:"PHP 8.0",name:"each()",id:"PHP_DEPR008"},{pattern:/\bmcrypt_/,suggestion:"mcrypt removed in PHP 7.2 — use OpenSSL functions",since:"PHP 7.2",name:"mcrypt functions",id:"PHP_DEPR009"}],this.phpSmells=[{pattern:/\beval\s*\(/,id:"PHP_SMELL001",name:"eval() Usage",message:"eval() is dangerous — code injection risk"},{pattern:/\bextract\s*\(\s*\$_(?:GET|POST|REQUEST)/,id:"PHP_SMELL002",name:"extract() from superglobal",message:"extract($_GET/_POST) — variable injection vulnerability"},{pattern:/\$\$\w+/,id:"PHP_SMELL003",name:"Variable variable",message:"Variable variables ($$var) — hard to trace and injection risk"},{pattern:/\bshell_exec\s*\(/,id:"PHP_SMELL004",name:"shell_exec()",message:"shell_exec() — remote code execution risk if input unsanitized"},{pattern:/\bsystem\s*\(/,id:"PHP_SMELL005",name:"system()",message:"system() — remote code execution risk if input unsanitized"},{pattern:/\bpassthru\s*\(/,id:"PHP_SMELL006",name:"passthru()",message:"passthru() — remote code execution risk if input unsanitized"},{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"PHP_SMELL007",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"PHP_SMELL008",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"},{pattern:/\$_(?:GET|POST|REQUEST)\[.*\].*SELECT.*\./i,id:"PHP_SMELL009",name:"SQL Injection Risk",message:"User input directly in SQL string — use prepared statements"},{pattern:/\bvar_dump\s*\(/,id:"PHP_SMELL010",name:"Debug var_dump",message:"var_dump() is for debug only — remove before production"}],this.rubyPhantomAPIs=[{pattern:/\.flatten_map\s*\{/,suggestion:"Ruby has no .flatten_map — use .flat_map { }",name:".flatten_map",id:"RB_HALL001"},{pattern:/Array\.of\s*\(/,suggestion:"Ruby has no Array.of() — use Array() or []",name:"Array.of()",id:"RB_HALL002"},{pattern:/Hash\.from_array\s*\(/,suggestion:"Ruby has no Hash.from_array() — use array.to_h or Hash[array]",name:"Hash.from_array",id:"RB_HALL003"},{pattern:/\.async\s*\{/,suggestion:"Ruby has no .async {} — use Thread.new or concurrent-ruby gem",name:".async block",id:"RB_HALL004"},{pattern:/String\.format\s*\(/,suggestion:"Ruby has no String.format() — use string interpolation or % operator",name:"String.format",id:"RB_HALL005"},{pattern:/\bpromise\s*\{/,suggestion:"Ruby has no built-in promise {} — use concurrent-ruby gem or Thread",name:"promise block",id:"RB_HALL006"},{pattern:/\.try!\s*\(/,suggestion:"Ruby has no .try!() — use &. (safe navigation) or Rails .try()",name:".try!()",id:"RB_HALL007"},{pattern:/JSON\.safe_parse\s*\(/,suggestion:"Ruby has no JSON.safe_parse — use JSON.parse with rescue",name:"JSON.safe_parse",id:"RB_HALL008"},{pattern:/ActiveRecord::Base\.execute\s*\(/,suggestion:"ActiveRecord::Base has no .execute() — use connection.execute() or where()",name:"Base.execute",id:"RB_HALL009"},{pattern:/\.collect_map\s*\{/,suggestion:"Ruby has no .collect_map — use .map { }.flatten(1) or .flat_map",name:".collect_map",id:"RB_HALL010"}],this.rubyDeprecated=[{pattern:/\brequire\s+['"]thread['"]/,suggestion:'require "thread" is deprecated — Thread is now built-in without require',since:"Ruby 2.0",name:'require "thread"',id:"RB_DEPR001"},{pattern:/\bObject#type\b|\.type\s*==/,suggestion:".type is deprecated — use .class or .is_a?",since:"Ruby 1.8",name:"Object#type",id:"RB_DEPR002"},{pattern:/\bERB::Util\.html_escape\b/,suggestion:"ERB::Util.html_escape deprecated — use CGI.escapeHTML or h() in views",since:"Ruby 2.6",name:"ERB::Util.html_escape",id:"RB_DEPR003"},{pattern:/\bFile\.exists\?\s*\(/,suggestion:"File.exists? deprecated — use File.exist? (no s)",since:"Ruby 2.2",name:"File.exists?",id:"RB_DEPR004"},{pattern:/\bDir\.exists\?\s*\(/,suggestion:"Dir.exists? deprecated — use Dir.exist? (no s)",since:"Ruby 2.2",name:"Dir.exists?",id:"RB_DEPR005"},{pattern:/\bObject#returning\b|\s+returning\s+/,suggestion:"Object#returning removed from Rails core — use tap { |obj| }",since:"Rails 3.0",name:"Object#returning",id:"RB_DEPR006"}],this.rubySmells=[{pattern:/\bputs\s+(?!STDOUT)/,id:"RB_SMELL001",name:"Debug puts",message:"puts is for debug output — use Rails logger or a logging library"},{pattern:/\bp\s+\w/,id:"RB_SMELL002",name:"Debug p()",message:"p() is for debug output — remove before production"},{pattern:/\beval\s*\(/,id:"RB_SMELL003",name:"eval() Usage",message:"eval() is dangerous — code injection risk"},{pattern:/\bsystem\s*\(/,id:"RB_SMELL004",name:"system() Shell Call",message:"system() call — command injection risk if input unsanitized"},{pattern:/`[^`]+`/,id:"RB_SMELL005",name:"Backtick Shell Exec",message:"Backtick shell execution — command injection risk"},{pattern:/\bexec\s*\(/,id:"RB_SMELL006",name:"exec() call",message:"exec() replaces the process — ensure this is intentional"},{pattern:/\brescue\s*$|\brescue\s+Exception\b/,id:"RB_SMELL007",name:"Bare rescue",message:"Bare rescue catches all exceptions including fatal ones — be specific"},{pattern:/["'].*#\{.*sql.*\}.*["']/i,id:"RB_SMELL008",name:"SQL String Interpolation",message:"SQL built with string interpolation — use parameterized queries"},{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)/i,id:"RB_SMELL009",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished"},{pattern:/raise\s+NotImplementedError/,id:"RB_SMELL010",name:"Not Implemented",message:"Stub implementation — will raise at runtime"}],this.jsExtensions=new Set([".js",".ts",".jsx",".tsx",".mjs",".cjs"]),this.pyExtensions=new Set([".py",".pyw"]),this.goExtensions=new Set([".go"]),this.rustExtensions=new Set([".rs"]),this.javaExtensions=new Set([".java",".kt"]),this.csharpExtensions=new Set([".cs"]),this.phpExtensions=new Set([".php"]),this.rubyExtensions=new Set([".rb"]),this.aiCodeSmells=[{pattern:/\/\/\s*TODO:?\s*(implement|add|fix|complete|finish)\s*(this|here|later)/i,id:"AI_SMELL001",name:"Placeholder TODO",message:"AI-generated placeholder — likely unfinished implementation"},{pattern:/throw new Error\(['"]Not implemented['"]\)/,id:"AI_SMELL002",name:"Not Implemented",message:"Stub implementation — function body was not generated"},{pattern:/\/\/\s*\.\.\.\s*(rest|remaining|more|other|additional)/i,id:"AI_SMELL003",name:"Truncated Code",message:"AI output was truncated — code is incomplete"},{pattern:/\/\/\s*(your|replace|insert|put)\s+(code|logic|implementation|api[_\s]?key)/i,id:"AI_SMELL004",name:"Template Placeholder",message:"Template placeholder left in code — needs real implementation"},{pattern:/['"]your-api-key-here['"]|['"]sk-[.]{3,}['"]|['"]xxx+['"]/i,id:"AI_SMELL005",name:"Dummy Credential",message:"Placeholder credential — will fail at runtime"},{pattern:/example\.com|test@test\.com|john@doe\.com|foo@bar\.com/i,id:"AI_SMELL006",name:"Example Domain",message:"Example domain/email in production code"},{pattern:/localhost:\d{4}(?!.*(?:dev|test|local|development))/i,id:"AI_SMELL007",name:"Hardcoded Localhost",message:"Hardcoded localhost URL — will fail in production"}],this.deprecatedAPIs=[{pattern:/new Buffer\s*\(/,suggestion:"Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe()",since:"Node 6",name:"new Buffer()",id:"DEPR_API001"},{pattern:/require\s*\(\s*['"]sys['"]\s*\)/,suggestion:'Use require("util") — sys was removed in Node 1.0',since:"Node 1.0",name:'require("sys")',id:"DEPR_API002"},{pattern:/fs\.exists\s*\((?!Sync)/,suggestion:"Use fs.access() or fs.stat() — fs.exists() is deprecated",since:"Node 1.0",name:"fs.exists()",id:"DEPR_API003"},{pattern:/domain\.create\s*\(/,suggestion:"Use async_hooks or try/catch — domain module is deprecated",since:"Node 4",name:"domain.create()",id:"DEPR_API004",fixable:!1},{pattern:/require\s*\(\s*['"]punycode['"]\s*\)/,suggestion:"Use userland punycode package — built-in is deprecated",since:"Node 7",name:'require("punycode")',id:"DEPR_API005",fixable:!1},{pattern:/url\.parse\s*\(/,suggestion:"Use new URL() — url.parse() is legacy",since:"Node 11",name:"url.parse()",id:"DEPR_API006"},{pattern:/querystring\.(parse|stringify)\s*\(/,suggestion:"Use URLSearchParams — querystring is legacy",since:"Node 14",name:"querystring",id:"DEPR_API007",fixable:!1},{pattern:/util\.isArray\s*\(/,suggestion:"Use Array.isArray() — util type checks are deprecated",since:"Node 4",name:"util.isArray()",id:"DEPR_API008"},{pattern:/util\.isFunction\s*\(/,suggestion:'Use typeof fn === "function"',since:"Node 4",name:"util.isFunction()",id:"DEPR_API009"},{pattern:/util\.pump\s*\(/,suggestion:"Use stream.pipeline() — util.pump() was removed",since:"Node 1.0",name:"util.pump()",id:"DEPR_API010",fixable:!1}]}async scan(e){const t=Date.now(),s={phantomImports:[],phantomAPIs:[],aiSmells:[],deprecatedAPIs:[],unresolvedDeps:[],stats:{filesScanned:0,totalIssues:0,scanTime:0}},n=this._loadDeclaredDeps(),i=this._packageJsonPaths&&this._packageJsonPaths.size>0,a=this._loadIgnoreRules();for(const t of e)try{const e=path.extname(t).toLowerCase(),o=this.jsExtensions.has(e),r=this.pyExtensions.has(e),l=this.goExtensions.has(e),c=this.rustExtensions.has(e),d=this.javaExtensions.has(e),p=this.csharpExtensions.has(e),m=this.phpExtensions.has(e),u=this.rubyExtensions.has(e);if(!(o||r||l||c||d||p||m||u))continue;const g=path.relative(this.config.rootPath,t);if(a.some(e=>g.includes(e)||t.includes(e)))continue;const h=fs.readFileSync(t,"utf-8").replace(/\r\n/g,"\n"),f=h.split("\n"),_=new Set;for(let e=0;e<f.length;e++)f[e].includes("thuban-ignore")&&(_.add(e+1),_.add(e+2));const y=this._isPatternDefinitionFile(h);s.stats.filesScanned++,o?(i&&this._checkPhantomImports(g,t,h,f,n,s,_),y||this._checkPhantomAPIs(g,h,f,s,_),this._checkAISmells(g,h,f,s,_),y||this._checkDeprecatedAPIs(g,h,f,s,_),y||this._checkNamedExports(g,t,h,s,_)):r?(this._checkLanguagePatterns(g,h,f,s,_,this.pythonPhantomAPIs,"phantomAPIs"),this._checkLanguagePatterns(g,h,f,s,_,this.pythonDeprecated,"deprecatedAPIs"),this._checkLanguageSmells(g,h,f,s,_,this.pythonSmells)):m?(this._checkLanguagePatterns(g,h,f,s,_,this.phpPhantomAPIs,"phantomAPIs"),this._checkLanguagePatterns(g,h,f,s,_,this.phpDeprecated,"deprecatedAPIs"),this._checkLanguageSmells(g,h,f,s,_,this.phpSmells)):u?(this._checkLanguagePatterns(g,h,f,s,_,this.rubyPhantomAPIs,"phantomAPIs"),this._checkLanguagePatterns(g,h,f,s,_,this.rubyDeprecated,"deprecatedAPIs"),this._checkLanguageSmells(g,h,f,s,_,this.rubySmells)):l?(this._checkLanguagePatterns(g,h,f,s,_,this.goDeprecated,"deprecatedAPIs"),this._checkLanguageSmells(g,h,f,s,_,this.goSmells)):c?(this._checkLanguagePatterns(g,h,f,s,_,this.rustPhantomAPIs,"phantomAPIs"),this._checkLanguagePatterns(g,h,f,s,_,this.rustDeprecated,"deprecatedAPIs"),this._checkLanguageSmells(g,h,f,s,_,this.rustSmells)):d?".kt"===e?(this._checkLanguagePatterns(g,h,f,s,_,this.kotlinPhantomAPIs,"phantomAPIs"),this._checkLanguagePatterns(g,h,f,s,_,this.kotlinDeprecated,"deprecatedAPIs"),this._checkLanguageSmells(g,h,f,s,_,this.kotlinSmells)):this._checkLanguageSmells(g,h,f,s,_,this.javaSmells):p&&this._checkLanguageSmells(g,h,f,s,_,this.csharpSmells)}catch(e){}return s.stats.totalIssues=s.phantomImports.length+s.phantomAPIs.length+s.aiSmells.length+s.deprecatedAPIs.length+s.unresolvedDeps.length,s.stats.scanTime=Date.now()-t,s}_safeRegexTest(e,t,s=1e3){const n=Date.now();try{const i=e.test(t),a=Date.now()-n;return a>s?(console.warn(`[HALLUCINATION-DETECTOR] WARNING: Regex ${e.source.substring(0,50)}... took ${a}ms on input (${t.length} chars) — skipping pattern`),null):i}catch(e){return console.warn("[HALLUCINATION-DETECTOR] Regex error during scan"),null}}_safeRegexExec(e,t,s=1e3){const n=Date.now();try{const i=e.exec(t),a=Date.now()-n;return a>s?(console.warn(`[HALLUCINATION-DETECTOR] WARNING: Regex exec ${e.source.substring(0,50)}... took ${a}ms — skipping pattern`),null):i}catch(e){return console.warn("[HALLUCINATION-DETECTOR] Regex exec error during scan"),null}}_checkLanguagePatterns(e,t,s,n,i,a,o){for(let t=0;t<s.length;t++){if(i.has(t+1))continue;const r=s[t];for(const s of a){const i=this._safeRegexTest(s.pattern,r);if(null!==i&&i){const i={file:e,line:t+1,name:s.name,id:s.id};s.suggestion&&(i.suggestion=s.suggestion),s.since&&(i.since=s.since,i.fix=s.suggestion),"deprecatedAPIs"===o?n.deprecatedAPIs.push(i):n.phantomAPIs.push(i)}}}}_checkLanguageSmells(e,t,s,n,i,a){for(let t=0;t<s.length;t++){if(i.has(t+1))continue;const o=s[t];for(const s of a){const i=this._safeRegexTest(s.pattern,o);null!==i&&i&&n.aiSmells.push({file:e,line:t+1,id:s.id,name:s.name,message:s.message,type:"ai_smell",severity:"medium"})}}}formatReport(e){const t="",s="",n="",i="",a="",o="",r="",l="";let c="";if(c+=`\n${l} ╔══════════════════════════════════════════════╗${t}\n`,c+=`${l} ║${s} THUBAN HALLUCINATION REPORT ${t}${l}║${t}\n`,c+=`${l} ╚══════════════════════════════════════════════╝${t}\n\n`,0===e.stats.totalIssues)return c+=` ${i}${s}No hallucinations detected.${t} ${r}Clean codebase.${t}\n\n`,c;if(e.phantomImports.length>0){c+=` ${n}${s}Phantom Imports (${e.phantomImports.length})${t}\n`,c+=` ${r}Packages that don't exist in package.json or node_modules${t}\n\n`;for(const s of e.phantomImports.slice(0,10))c+=` ${n}✗${t} ${o}${s.file}${t}:${s.line}\n`,c+=` ${a}${s.module}${t} ${r}— ${s.reason}${t}\n`;e.phantomImports.length>10&&(c+=` ${r}... and ${e.phantomImports.length-10} more${t}\n`),c+="\n"}if(e.phantomAPIs.length>0){c+=` ${n}${s}Phantom APIs (${e.phantomAPIs.length})${t}\n`,c+=` ${r}Methods/properties that don't exist on their objects${t}\n\n`;for(const s of e.phantomAPIs.slice(0,10))c+=` ${n}✗${t} ${s.id?`${r}[${s.id}]${t} `:""}${o}${s.file}${t}:${s.line}\n`,c+=` ${a}${s.name}${t} ${r}— ${s.suggestion}${t}\n`,c+=` ${r}Suppress: // thuban-ignore ${s.id||"HALL_API"}${t}\n`;e.phantomAPIs.length>10&&(c+=` ${r}... and ${e.phantomAPIs.length-10} more${t}\n`),c+="\n"}if(e.aiSmells.length>0){c+=` ${a}${s}AI Code Smells (${e.aiSmells.length})${t}\n`,c+=` ${r}Patterns typical of AI-generated code that needs review${t}\n\n`;for(const s of e.aiSmells.slice(0,10))c+=` ${a}!${t} ${o}${s.file}${t}:${s.line}\n`,c+=` ${r}${s.message}${t}\n`;e.aiSmells.length>10&&(c+=` ${r}... and ${e.aiSmells.length-10} more${t}\n`),c+="\n"}if(e.deprecatedAPIs.length>0){c+=` ${a}${s}Deprecated APIs (${e.deprecatedAPIs.length})${t}\n`,c+=` ${r}APIs that LLMs still suggest but are deprecated or removed${t}\n\n`;for(const s of e.deprecatedAPIs.slice(0,10))c+=` ${a}⚠${t} ${o}${s.file}${t}:${s.line}\n`,c+=` ${a}${s.name}${t} ${r}(deprecated since ${s.since})${t}\n`,c+=` ${i}→${t} ${r}${s.suggestion}${t}\n`;e.deprecatedAPIs.length>10&&(c+=` ${r}... and ${e.deprecatedAPIs.length-10} more${t}\n`),c+="\n"}return c+=` ${s}Summary:${t} ${o}${e.stats.filesScanned}${t} files scanned, `,c+=`${e.stats.totalIssues>0?n:i}${e.stats.totalIssues}${t} hallucination issues found `,c+=`${r}(${e.stats.scanTime}ms)${t}\n\n`,c}_loadDeclaredDeps(){const e=new Set;return this._packageJsonPaths=new Map,this._collectPackageJsonDeps(this.config.rootPath,e,0),e}_collectPackageJsonDeps(e,t,s){if(!(s>5))try{const n=path.join(e,"package.json");if(fs.existsSync(n)){const s=JSON.parse(fs.readFileSync(n,"utf-8")),i=new Set;for(const e of Object.keys(s.dependencies||{}))t.add(e),i.add(e);for(const e of Object.keys(s.devDependencies||{}))t.add(e),i.add(e);for(const e of Object.keys(s.peerDependencies||{}))t.add(e),i.add(e);this._packageJsonPaths.set(e,i)}const i=new Set(["node_modules",".git","dist","build","coverage",".next",".cache","vendor"]),a=fs.readdirSync(e,{withFileTypes:!0});for(const n of a)!n.isDirectory()||i.has(n.name)||n.name.startsWith(".")||this._collectPackageJsonDeps(path.join(e,n.name),t,s+1)}catch(e){}}_checkPhantomImports(e,t,s,n,i,a,o=new Set){const r=[/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g,/import\s+.*?from\s+['"]([^'"]+)['"]/g,/import\s*\(\s*['"]([^'"]+)['"]\s*\)/g];for(const l of r){let r;for(;null!==(r=l.exec(s));){const l=r[1];if(l.startsWith(".")||path.isAbsolute(l))continue;if(l.includes("${"))continue;const c=this._findLineNumber(s,r.index),d=n[c-1]||"";if(this._isInsidePattern(d,r[0]))continue;if(/^[@~#$][/\\]/.test(l))continue;const p=l.split("/")[0];if(this.builtins.has(l)||this.builtins.has(p))continue;if(p.startsWith("node:")&&this.builtins.has(p.slice(5)))continue;const m=l.startsWith("@")?l.split("/").slice(0,2).join("/"):p;if(!this._isSelfReference(t,m)&&!i.has(m)){if(this.knownRealPackages.has(m))continue;if(!this._findInNodeModules(t,m)){if(o.has(c))continue;const t=this.phantomPackages.has(l);a.phantomImports.push({file:e,line:c,module:l,reason:t?"Known AI-hallucinated package — does not exist on npm":"Not in package.json and not in node_modules",severity:t?"critical":"high",fixable:!1})}}}}}_checkNamedExports(e,t,s,n,i=new Set){let a;try{a=exportVerifier.verifyFile(t,s)}catch(e){return}for(const t of a)i.has(t.line)||n.phantomImports.push({file:e,line:t.line,module:t.source,reason:t.message,severity:"critical",fixable:!1,source:"export-verifier"})}_checkPhantomAPIs(e,t,s,n,i=new Set){for(const a of this.phantomAPIs){let o;const r=new RegExp(a.pattern.source,a.pattern.flags+(a.pattern.flags.includes("g")?"":"g"));for(;null!==(o=this._safeRegexExec(r,t));){if("."===t[o.index-1])continue;const r=this._findLineNumber(t,o.index);if(i.has(r))continue;const l=s[r-1]||"";this._isInsidePattern(l,o[0])||n.phantomAPIs.push({file:e,line:r,name:a.name,id:a.id,suggestion:a.suggestion,severity:"high",fixable:!0,fixAction:"replace_phantom_api"})}}this._checkDynamicBuiltinCalls(e,t,s,n,i)}_checkDynamicBuiltinCalls(e,t,s,n,i){const a=new Map,o=/(?:const|let|var)\s+(\w+)\s*=\s*require\s*\(\s*['"](?:node:)?(\w+)['"]\s*\)/g;let r;for(;null!==(r=o.exec(t));){const e=r[1],t=r[2];this.builtins.has(t)&&a.set(e,t)}const l=/import\s+(?:\*\s+as\s+)?(\w+)\s+from\s+['"](?:node:)?(\w+)['"]/g;let c;for(;null!==(c=l.exec(t));){const e=c[1],t=c[2];this.builtins.has(t)&&a.set(e,t)}if(0!==a.size){this._builtinMethodCache||(this._builtinMethodCache=new Map);for(const[o,r]of a){if(!this._builtinMethodCache.has(r))try{const e=require(r),t=new Set(Object.keys(e));"object"==typeof e&&null!==e&&Object.getOwnPropertyNames(e).forEach(e=>t.add(e)),this._builtinMethodCache.set(r,t)}catch{this._builtinMethodCache.set(r,null);continue}const a=this._builtinMethodCache.get(r);if(!a)continue;const l=new RegExp(`\\b${o}\\.(\\w+)\\s*\\(`,"g");let c;for(;null!==(c=l.exec(t));){if("."===t[c.index-1])continue;const o=c[1],l=this._findLineNumber(t,c.index);if(i.has(l))continue;const d=s[l-1]||"";if(!this._isInsidePattern(d,c[0])&&!a.has(o)){if(n.phantomAPIs.some(t=>t.file===e&&t.line===l))continue;n.phantomAPIs.push({file:e,line:l,name:`${r}.${o}`,id:"HALL_DYN",suggestion:`'${o}' does not exist on the '${r}' module — this is a hallucinated API`,severity:"critical",fixable:!1})}}}}}_checkAISmells(e,t,s,n,i=new Set){for(const a of this.aiCodeSmells){let o;const r=new RegExp(a.pattern.source,a.pattern.flags+(a.pattern.flags.includes("g")?"":"g"));for(;null!==(o=this._safeRegexExec(r,t));){const r=this._findLineNumber(t,o.index);i.has(r)||n.aiSmells.push({file:e,line:r,id:a.id,name:a.name,message:a.message,severity:"warning",code:s[r-1]?.trim().substring(0,100)})}}}_checkDeprecatedAPIs(e,t,s,n,i=new Set){for(const a of this.deprecatedAPIs){let o;const r=new RegExp(a.pattern.source,a.pattern.flags+(a.pattern.flags.includes("g")?"":"g"));for(;null!==(o=this._safeRegexExec(r,t));){const r=this._findLineNumber(t,o.index);if(i.has(r))continue;const l=s[r-1]||"";this._isInsidePattern(l,o[0])||n.deprecatedAPIs.push({file:e,line:r,name:a.name,id:a.id,suggestion:a.suggestion,since:a.since,severity:"warning",fixable:!0,fixAction:"update_deprecated_api"})}}}_findLineNumber(e,t){let s=1;for(let n=0;n<t&&n<e.length;n++)"\n"===e[n]&&s++;return s}_isPatternDefinitionFile(e){const t=(e.match(/pattern:\s*\//g)||[]).length,s=(e.match(/phantom|hallucin/gi)||[]).length;return t>5&&s>2}_isInsidePattern(e,t){const s=e.trim();return!!/pattern:\s*\//.test(s)||!!(s.startsWith("//")||s.startsWith("*")||s.startsWith("/*"))||!!/(?:name|suggestion|message|description):\s*['"]/.test(s)}_loadIgnoreRules(){const e=[];try{const t=path.join(this.config.rootPath,".thubanrc.json"),s=JSON.parse(fs.readFileSync(t,"utf-8"));s.hallucination?.ignore&&e.push(...s.hallucination.ignore),s.ignore&&e.push(...s.ignore)}catch(e){}return e}_findInNodeModules(e,t){let s=path.dirname(e);const n=this.config.rootPath;for(;s.length>=n.length;){const e=path.join(s,"node_modules",t);try{if(fs.existsSync(e))return!0}catch(e){}const n=path.dirname(s);if(n===s)break;s=n}return!1}_isSelfReference(e,t){let s=path.dirname(e);const n=this.config.rootPath;for(;s.length>=n.length;){try{const e=path.join(s,"package.json");if(fs.existsSync(e)){const n=JSON.parse(fs.readFileSync(e,"utf-8"));if(n.name===t)return!0;if(n.workspaces){const e=Array.isArray(n.workspaces)?n.workspaces:n.workspaces.packages||[];for(const n of e){const e=n.replace(/\/?\*.*$/,""),i=path.join(s,e);try{if(fs.existsSync(i)){const e=fs.readdirSync(i,{withFileTypes:!0});for(const s of e)if(s.isDirectory()){const e=path.join(i,s.name,"package.json");try{if(fs.existsSync(e)&&JSON.parse(fs.readFileSync(e,"utf-8")).name===t)return!0}catch(e){}}}}catch(e){}}}break}}catch(e){}const e=path.dirname(s);if(e===s)break;s=e}return!1}}module.exports=HallucinationDetector;
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),EventEmitter=require("events");class HealthChecker extends EventEmitter{constructor(e={}){super(),this.config={rootPath:e.rootPath||process.cwd(),serverPath:e.serverPath||path.join(e.rootPath||process.cwd(),"server"),checkTimeout:e.checkTimeout||5e3,...e},this.systemChecks=[{id:"senate",name:"Senate",description:"Multi-model orchestration",check:()=>this._checkSenate()},{id:"citadel",name:"Citadel",description:"5-layer safety system",check:()=>this._checkCitadel()},{id:"forge",name:"Forge",description:"Build system",check:()=>this._checkForge()},{id:"ocee",name:"OCEE",description:"Orchestrated continuous execution",check:()=>this._checkOCEE()},{id:"handoff",name:"Handoff",description:"Human-AI collaboration",check:()=>this._checkHandoff()},{id:"shadow_realm",name:"Shadow Realm",description:"Validation sandbox",check:()=>this._checkShadowRealm()},{id:"knowledge",name:"Knowledge Manager",description:"Build tracking and learning",check:()=>this._checkKnowledge()},{id:"server",name:"Express Server",description:"API server health",check:()=>this._checkServer()}]}async checkAll(){console.log("[HEALTH-CHECKER] Running full health check...");const e=Date.now(),s={timestamp:(new Date).toISOString(),duration:0,overall:"healthy",systems:[],healthySystems:[],unhealthySystems:[],summary:{}};for(const e of this.systemChecks)try{const t=await Promise.race([e.check(),this._timeout(this.config.checkTimeout)]),i={id:e.id,name:e.name,description:e.description,status:t.healthy?"healthy":"unhealthy",healthy:t.healthy,details:t.details||{},issues:t.issues||[],lastChecked:(new Date).toISOString()};s.systems.push(i),i.healthy?s.healthySystems.push(e.id):s.unhealthySystems.push(e.id)}catch(t){s.systems.push({id:e.id,name:e.name,description:e.description,status:"error",healthy:!1,error:t.message,lastChecked:(new Date).toISOString()}),s.unhealthySystems.push(e.id)}return 0===s.unhealthySystems.length?s.overall="healthy":s.unhealthySystems.length<=2?s.overall="degraded":s.overall="unhealthy",s.duration=Date.now()-e,s.summary={total:this.systemChecks.length,healthy:s.healthySystems.length,unhealthy:s.unhealthySystems.length},console.log(`[HEALTH-CHECKER] Health check complete: ${s.overall} (${s.summary.healthy}/${s.summary.total} systems healthy)`),this.emit("checkComplete",s),s}async _checkSenate(){const e={healthy:!0,details:{},issues:[]};try{const s=[path.join(this.config.serverPath,"senate.js"),path.join(this.config.serverPath,"senate-v2.js"),path.join(this.config.serverPath,"data","model-registry.json"),path.join(this.config.serverPath,"data","senate-weights-v2.json")];let t=0;for(const e of s)fs.existsSync(e)&&t++;e.details.filesFound=t,e.details.totalFiles=s.length;const i=path.join(this.config.serverPath,"data","model-registry.json");if(fs.existsSync(i)){const s=JSON.parse(fs.readFileSync(i,"utf8"));e.details.providersConfigured=Object.keys(s.providers||{}).length,e.details.modelsRegistered=Object.values(s.providers||{}).reduce((e,s)=>e+(s.models?.length||0),0)}t<2&&(e.healthy=!1,e.issues.push("Core Senate files missing"))}catch(s){e.healthy=!1,e.issues.push(`Senate check failed: ${s.message}`)}return e}async _checkCitadel(){const e={healthy:!0,details:{},issues:[]};try{const s=path.join(this.config.rootPath,"citadel"),t=["enforcer.js","watchers.js","constitution-loader.js","file-guard.js"];let i=0;for(const e of t)fs.existsSync(path.join(s,e))&&i++;e.details.filesFound=i,e.details.totalFiles=t.length;const a=path.join(s,"audit");if(fs.existsSync(a)){const s=fs.readdirSync(a).filter(e=>e.endsWith(".json"));if(e.details.auditFilesCount=s.length,s.length>0){const t=s.sort().pop(),i=path.join(a,t),n=fs.statSync(i);e.details.lastAudit=n.mtime.toISOString();const o=(Date.now()-n.mtime.getTime())/36e5;o>24&&e.issues.push(`No audit activity in ${Math.round(o)} hours`)}}i<3&&(e.healthy=!1,e.issues.push("Core Citadel files missing"))}catch(s){e.healthy=!1,e.issues.push(`Citadel check failed: ${s.message}`)}return e}async _checkForge(){const e={healthy:!0,details:{},issues:[]};try{const s=path.join(this.config.rootPath,"forge"),t=["forge-core.js","task-decomposer.js","intent-matcher.js","diagnostician-v2.js","prescriber.js","forge-loop.js"];let i=0;for(const e of t)fs.existsSync(path.join(s,e))&&i++;e.details.filesFound=i,e.details.totalFiles=t.length,e.details.completeness=Math.round(i/t.length*100)+"%",i<4&&(e.healthy=!1,e.issues.push("Core Forge components missing"))}catch(s){e.healthy=!1,e.issues.push(`Forge check failed: ${s.message}`)}return e}async _checkOCEE(){const e={healthy:!0,details:{},issues:[]};try{const s=path.join(this.config.serverPath,"ocee"),t=["ocee-core.js","persistent-task-queue.js","checkpoint-manager.js","build-session-manager.js","build-graph-generator.js"];let i=0;for(const e of t)fs.existsSync(path.join(s,e))&&i++;e.details.filesFound=i,e.details.totalFiles=t.length;const a=path.join(s,"queue");if(fs.existsSync(a))try{const s=fs.readdirSync(a);e.details.pendingTasks=s.length}catch(s){e.details.pendingTasks="unknown"}i<3&&(e.healthy=!1,e.issues.push("Core OCEE components missing"))}catch(s){e.healthy=!1,e.issues.push(`OCEE check failed: ${s.message}`)}return e}async _checkHandoff(){const e={healthy:!0,details:{},issues:[]};try{const s=path.join(this.config.serverPath,"handoff"),t=["index.js","risk-scorer.js","gate-checker.js","mission-state.js","audit-logger.js","evidence-bundle.js","cost-tracker.js"];let i=0;for(const e of t)fs.existsSync(path.join(s,e))&&i++;e.details.filesFound=i,e.details.totalFiles=t.length,i<5&&(e.healthy=!1,e.issues.push("Core Handoff components missing"))}catch(s){e.healthy=!1,e.issues.push(`Handoff check failed: ${s.message}`)}return e}async _checkShadowRealm(){const e={healthy:!0,details:{},issues:[]};try{const s=path.join(this.config.rootPath,"build-engine","orion-core"),t=["shadow-realm-v2.js","foreman.js","healing-loop.js"];let i=0;for(const e of t)fs.existsSync(path.join(s,e))&&i++;e.details.filesFound=i,e.details.totalFiles=t.length;try{const t=require(path.join(s,"shadow-realm-v2.js")).validateInSandbox('console.log("test");',"test.js");e.details.validationWorking=!0===t.syntaxValid}catch(s){e.details.validationWorking=!1,e.issues.push(`Shadow Realm validation test failed: ${s.message}`)}i<2&&(e.healthy=!1,e.issues.push("Core Shadow Realm components missing"))}catch(s){e.healthy=!1,e.issues.push(`Shadow Realm check failed: ${s.message}`)}return e}async _checkKnowledge(){const e={healthy:!0,details:{},issues:[]};try{const s=path.join(this.config.rootPath,"orion-knowledge.json");if(fs.existsSync(s)){const t=JSON.parse(fs.readFileSync(s,"utf8"));if(e.details.buildsTracked=t.builds?.length||0,e.details.capabilitiesTracked=t.capabilities?.length||0,t.builds&&t.builds.length>0){const s=t.builds[t.builds.length-1];e.details.lastBuild=s.timestamp||s.date}}else e.healthy=!1,e.issues.push("orion-knowledge.json not found")}catch(s){e.healthy=!1,e.issues.push(`Knowledge check failed: ${s.message}`)}return e}async _checkServer(){const e={healthy:!0,details:{},issues:[]};try{const s=[path.join(this.config.serverPath,"package.json"),path.join(this.config.serverPath,"index.js")];let t=0;for(const e of s)fs.existsSync(e)&&t++;e.details.filesFound=t;const i=path.join(this.config.serverPath,"package.json");if(fs.existsSync(i)){const s=JSON.parse(fs.readFileSync(i,"utf8"));e.details.dependencies=Object.keys(s.dependencies||{}).length,e.details.nodeVersion=s.engines?.node||"not specified"}const a=path.join(this.config.serverPath,"node_modules");e.details.nodeModulesInstalled=fs.existsSync(a),e.details.nodeModulesInstalled||e.issues.push("node_modules not installed - run npm install")}catch(s){e.healthy=!1,e.issues.push(`Server check failed: ${s.message}`)}return e}_timeout(e){return new Promise((s,t)=>setTimeout(()=>t(new Error("Health check timeout")),e))}}module.exports=HealthChecker;
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),crypto=require("crypto"),{ComplianceMapper:ComplianceMapper,generateRecommendations:generateRecommendations}=require("./compliance-mapper.js");class InvestorReport{constructor(e={}){this.rootPath=e.rootPath||process.cwd(),this.companyName=e.companyName||this._detectProjectName(),this.generatedAt=new Date,this.reportKey=e.reportKey||null,this.tier=this._validateKey(this.reportKey)}_validateKey(e){if(!e||"string"!=typeof e)return"free";try{const t=e.split(":");if(t.length<3)return"free";const n=t[0],s=t[1],a=t.slice(2).join(":");if(!["snapshot","full"].includes(n))return"free";const r=parseInt(s,10);if(isNaN(r)||Date.now()-r>7776e6)return"free";const i="thuban-investor-salt-2026";return a===crypto.createHmac("sha256",i).update(`thuban-investor-${n}:${s}`).digest("hex").slice(0,16)?n:"free"}catch{return"free"}}static generateKey(e="full"){const t=Date.now().toString();return`${e}:${t}:${crypto.createHmac("sha256","thuban-investor-salt-2026").update(`thuban-investor-${e}:${t}`).digest("hex").slice(0,16)}`}_detectProjectName(){try{return JSON.parse(fs.readFileSync(path.join(this.rootPath,"package.json"),"utf-8")).name||path.basename(this.rootPath)}catch{return path.basename(this.rootPath)}}generate(e){const{scanResults:t={},hallResults:n={},debtCost:s={},ghostResults:a={},aiScoreResults:r={},cloneResults:i={},passportData:o={},velocityResults:l=null,architectureData:d=null,riskValuation:c=null,historyData:m=null,benchmarkData:v=null,crucibleResults:u=null,supplyChainResults:h=null,fileCount:g=0,lineCount:p=0}=e,b=`THB-INV-${Date.now().toString(36).toUpperCase()}`,f=this._calculateOverallScore(e),y=this._scoreToGrade(f),x=this._gradeColor(y);return this._renderHTML({reportId:b,score:f,grade:y,gradeColor:x,scanResults:t,hallResults:n,debtCost:s,ghostResults:a,aiScoreResults:r,cloneResults:i,passportData:o,velocityResults:l,architectureData:d,riskValuation:c,historyData:m,benchmarkData:v,crucibleResults:u,supplyChainResults:h,fileCount:g,lineCount:p,tier:this.tier})}static TEST_FIXTURE_PATTERNS=[/(^|[\/\\])crucible([\/\\]|$)/i,/\.test\.js$/i,/\.spec\.js$/i,/(^|[\/\\])tests([\/\\]|$)/i,/(^|[\/\\])__tests__([\/\\]|$)/i,/(^|[\/\\])fixtures([\/\\]|$)/i,/(^|[\/\\])thuban-videos([\/\\]|$)/i,/(^|[\/\\])regression([\/\\]|$)/i];_isTestFixture(e){return!!e&&(this._testFixturePatterns||InvestorReport.TEST_FIXTURE_PATTERNS).some(t=>t.test(e))}_getTestFixturePatterns(){if(this._testFixturePatterns)return this._testFixturePatterns;const e=[...InvestorReport.TEST_FIXTURE_PATTERNS];try{const t=path.join(this.rootPath,".thubanrc.json"),n=JSON.parse(fs.readFileSync(t,"utf-8")),s=n.investorReport?.testFixtures||n.testFixtures||[];for(const t of s){if("string"!=typeof t||!t.trim())continue;const n=t.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"\0").replace(/\*/g,"[^/\\\\]*").replace(/\u0000/g,".*");try{e.push(new RegExp(n,"i"))}catch{}}}catch{}return this._testFixturePatterns=e,e}_getProductionFindings(e){this._getTestFixturePatterns();const t=e=>this._isTestFixture(e),n=e.hallResults||{},s=e.ghostResults||{},a=e.cloneResults||{},r=e.aiScoreResults||{},i=e.scanResults||{},o=(n.phantomAPIs||[]).filter(e=>!t(e.file)),l=(n.deprecatedAPIs||[]).filter(e=>!t(e.file)),d=(s.ghosts||[]).filter(e=>!t(e.file)),c=(a.clusters||[]).filter(e=>(e.members||[]).filter(e=>!t(e.file)).length>=2),m=(r.highConfidence||[]).filter(e=>!t(e.file)),v=(i.issues||[]).filter(e=>!t(e.file));return{phantomAPIs:o,deprecatedAPIs:l,totalGhosts:d.length,totalClusters:c.length,clusters:c,aiLikelyCount:m.length,scanIssueCount:v.length,scanIssuesList:v}}_calculateOverallScore(e){let t=100;const n=this._getProductionFindings(e);t-=15*n.phantomAPIs.length,t-=5*n.deprecatedAPIs.length;const s=100/Math.max(e.fileCount||0,1);t-=Math.min(n.totalGhosts*s*2,25);const a={high:3,medium:1.5,low:.5},r=(n.clusters||[]).reduce((e,t)=>e+(a[t.severity]??1.5),0);t-=Math.min(r*s,20),t-=Math.min(n.aiLikelyCount*s*1,10);const i={critical:3,error:2,warning:1,info:.15},o=n.scanIssuesList.reduce((e,t)=>e+(i[t.severity]??1),0);t-=Math.min(o*s*.5,20);const l=(e.fileCount||0)>0?10:0;return Math.max(l,Math.min(100,Math.round(t)))}_scoreToGrade(e){return e>=90?"A":e>=80?"B":e>=65?"C":e>=50?"D":"F"}_gradeColor(e){return{A:"#00ff88",B:"#88ff00",C:"#ffd93d",D:"#ff8844",F:"#ff4444"}[e]||"#ff4444"}_investmentVerdict(e){return e>=80?{label:"PASS — Low Risk Investment",color:"#00ff88",bg:"rgba(0,255,136,0.1)",border:"rgba(0,255,136,0.3)"}:e>=65?{label:"CONDITIONAL PASS — Moderate Risk, Remediation Required",color:"#ffd93d",bg:"rgba(255,217,61,0.1)",border:"rgba(255,217,61,0.3)"}:e>=50?{label:"HIGH RISK — Significant Technical Debt",color:"#ff8844",bg:"rgba(255,136,68,0.1)",border:"rgba(255,136,68,0.3)"}:{label:"DO NOT INVEST — Critical Code Quality Issues",color:"#ff4444",bg:"rgba(255,68,68,0.1)",border:"rgba(255,68,68,0.3)"}}_aiDependencyAssessment(e){return e<10?{level:"Minimal",description:"Minimal AI dependency — traditional development team",color:"#00ff88"}:e<30?{level:"Moderate",description:"Moderate AI usage — within normal range for modern development",color:"#ffd93d"}:e<60?{level:"Heavy",description:"Heavy AI dependency — verify team can maintain without AI tools",color:"#ff8844"}:{level:"AI-Dominant",description:"AI-dominant codebase — high bus-factor risk if AI tools become unavailable",color:"#ff4444"}}_buildRemediationEstimate(e){const t=[],n=this._getProductionFindings(e),s=n.phantomAPIs.length,a=n.deprecatedAPIs.length,r=n.totalGhosts,i=n.totalClusters,o=n.aiLikelyCount;if(s>0){const e=2*s;t.push({category:"Hallucinated APIs",issues:s,hours:e,cost80:80*e,cost120:120*e,priority:"Critical"})}if(a>0){const e=Math.ceil(1.5*a);t.push({category:"Deprecated APIs",issues:a,hours:e,cost80:80*e,cost120:120*e,priority:"High"})}if(r>0){const e=Math.ceil(.5*r);t.push({category:"Ghost / Dead Code",issues:r,hours:e,cost80:80*e,cost120:120*e,priority:"Medium"})}if(i>0){const e=3*i;t.push({category:"Code Clones / Duplication",issues:i,hours:e,cost80:80*e,cost120:120*e,priority:"Medium"})}if(o>0){const e=1*o;t.push({category:"AI-Generated Code Review",issues:o,hours:e,cost80:80*e,cost120:120*e,priority:"Low"})}const l=n.scanIssueCount;if(l>0){const e=Math.ceil(.3*l);t.push({category:"Code Quality Issues",issues:l,hours:e,cost80:80*e,cost120:120*e,priority:"Low"})}return t}_assessTeamCompetency(e){const t=e.scanResults||{},n=e.ghostResults||{},s=(e.cloneResults,e.aiScoreResults,e.lineCount,e.fileCount||1);let a=0,r=0;if(t&&"object"==typeof t)for(const[,e]of Object.entries(t))if(e?.issues){r+=e.issues.length;for(const t of e.issues){const e=(t.message||t.rule||"").toLowerCase();(e.includes("error")||e.includes("catch")||e.includes("exception")||e.includes("try"))&&a++}}const i=r>0?1-a/r:1,o=r/s,l=n.wastedPercent||0,d=(e.testFileCount||0)/s,c=e.commentRatio||0,m=[];return i>=.9?m.push({name:"Error Handling Patterns",rating:"Strong",color:"#00ff88"}):i>=.7?m.push({name:"Error Handling Patterns",rating:"Adequate",color:"#ffd93d"}):i>=.4?m.push({name:"Error Handling Patterns",rating:"Needs Improvement",color:"#ff8844"}):m.push({name:"Error Handling Patterns",rating:"Concerning",color:"#ff4444"}),o<=1?m.push({name:"Naming Consistency",rating:"Strong",color:"#00ff88"}):o<=3?m.push({name:"Naming Consistency",rating:"Adequate",color:"#ffd93d"}):o<=6?m.push({name:"Naming Consistency",rating:"Needs Improvement",color:"#ff8844"}):m.push({name:"Naming Consistency",rating:"Concerning",color:"#ff4444"}),l<=3?m.push({name:"Function Size Distribution",rating:"Strong",color:"#00ff88"}):l<=8?m.push({name:"Function Size Distribution",rating:"Adequate",color:"#ffd93d"}):l<=15?m.push({name:"Function Size Distribution",rating:"Needs Improvement",color:"#ff8844"}):m.push({name:"Function Size Distribution",rating:"Concerning",color:"#ff4444"}),d>=.3?m.push({name:"Test Coverage Indicators",rating:"Strong",color:"#00ff88"}):d>=.15?m.push({name:"Test Coverage Indicators",rating:"Adequate",color:"#ffd93d"}):d>=.05?m.push({name:"Test Coverage Indicators",rating:"Needs Improvement",color:"#ff8844"}):m.push({name:"Test Coverage Indicators",rating:"Concerning",color:"#ff4444"}),c>=.15?m.push({name:"Documentation Quality",rating:"Strong",color:"#00ff88"}):c>=.08?m.push({name:"Documentation Quality",rating:"Adequate",color:"#ffd93d"}):c>=.03?m.push({name:"Documentation Quality",rating:"Needs Improvement",color:"#ff8844"}):m.push({name:"Documentation Quality",rating:"Concerning",color:"#ff4444"}),m}_buildExecutiveSummary(e,t){const n=t.aiScoreResults||{},s=this._getProductionFindings(t),a=s.phantomAPIs.length,r=s.totalGhosts,i=n.aiPercentage||0,o=this._buildRemediationEstimate(t),l=o.reduce((e,t)=>e+t.hours,0),d=o.reduce((e,t)=>e+t.cost80,0);let c;c=e>=80?"demonstrates strong engineering practices":e>=65?"demonstrates competent engineering practices with areas requiring attention":e>=50?"shows foundational engineering capability but carries significant technical debt":"exhibits critical code quality deficiencies that pose material risk";let m=[`This codebase ${c} with a trust score of ${e}/100.`];return a>0?m.push(`${a} critical AI-hallucinated API call${a>1?"s":""} require${1===a?"s":""} immediate remediation (estimated ${2*a} dev-hours).`):r>0&&m.push(`${r} dead code function${r>1?"s":""} should be removed to reduce maintenance surface area.`),i>30?m.push(`${i}% of the codebase shows AI-generation signals, indicating elevated dependency on AI tooling.`):e>=65?m.push("The development team shows strong architectural discipline with manageable technical debt."):m.push("The development team would benefit from structured code review processes and automated quality gates."),l>0&&m.push(`Estimated remediation cost to reach investment-grade: &pound;${d.toLocaleString()}.`),m.join(" ")}_buildRiskMatrix(e){const t=this._getProductionFindings(e),n=t.phantomAPIs.length,s=t.deprecatedAPIs.length,a=t.totalGhosts,r=t.totalClusters;let i=0,o=0;for(const e of t.scanIssuesList){const t=(e.message||e.rule||"").toLowerCase();"info"!==e.severity&&"TAINT003"!==e.id&&((t.includes("inject")||t.includes("sql")||t.includes("xss")||t.includes("taint"))&&i++,(t.includes("style")||t.includes("format")||t.includes("indent")||t.includes("naming"))&&o++)}return{criticalLikely:{items:[],count:n+i},criticalUnlikely:{items:[],count:0},moderateLikely:{items:[],count:a+r},moderateUnlikely:{items:[],count:s+o},phantomCount:n,injectionCount:i,ghostCount:a,cloneCount:r,deprecatedCount:s,styleIssueCount:o}}_renderVelocitySection(e,t){const n='<span class="icon">&#128200;</span>';if(!e||!e.available){const t=e?.reason||"git history unavailable";return`\n<div class="section">\n <div class="section-header">\n ${n}\n <h3>Development Velocity &amp; Team Indicators</h3>\n </div>\n <div style="font-size:0.85rem; color:var(--dim); padding:1rem; background:var(--surface); border-radius:8px; border:1px solid var(--border);">\n Git history analysis not available (${this._esc(t)}).\n </div>\n</div>`}if("free"===t)return`\n<div class="section paywall-section">\n <div class="section-header">\n ${n}\n <h3>Development Velocity &amp; Team Indicators</h3>\n </div>\n <div class="paywall-overlay">\n <div class="paywall-message">\n <div style="font-size:2rem;margin-bottom:0.75rem;">&#128274;</div>\n <h4 style="margin-bottom:0.5rem;color:var(--text);">Unlock Team Velocity Analysis</h4>\n <p style="color:var(--dim);font-size:0.85rem;margin-bottom:1rem;">Commit frequency, contributor distribution, and bus factor risk are available with a Snapshot ($99) or Full Audit ($249) report key.</p>\n <div style="font-family:var(--mono);font-size:0.8rem;color:var(--cyan);background:rgba(0,246,255,0.05);padding:0.75rem 1rem;border-radius:8px;border:1px solid rgba(0,246,255,0.15);">\n Purchase at <a href="https://thuban.dev/#investors" style="color:var(--cyan)">thuban.dev</a> &rarr; run with <code>--key=YOUR_KEY</code>\n </div>\n </div>\n </div>\n</div>`;const s=e.metrics,a=e.health,r=e.contributors||[],i=a.busFactorRisk.color,o=a.commitFrequency.color,l=a.ownershipConcentration.color,d=r.slice(0,8),c=r.slice(8),m=c.reduce((e,t)=>e+t.percentage,0),v=["var(--cyan)","var(--green)","var(--purple)","var(--yellow)","var(--orange)"];let u="";d.forEach((e,t)=>{const n=v[t%v.length],s=e.focusAreas.length>0?e.focusAreas.map(e=>e.dir).join(", "):"no directory data";u+=`\n <div style="margin-bottom:8px;">\n <span>${this._esc(e.name)}</span>\n <div class="progress-bar" style="margin-top:4px;height:8px;background:rgba(42,42,90,0.5);border-radius:4px;overflow:hidden;"><div style="height:100%;width:${Math.min(e.percentage,100)}%;background:${n};"></div></div>\n <span style="font-size:0.75rem;color:var(--dim)">${e.percentage}% &mdash; ${this._esc(s)}</span>\n </div>`}),c.length>0&&(u+=`\n <div>\n <span style="color:var(--dim)">${c.length} other${c.length>1?"s":""}</span>\n <div class="progress-bar" style="margin-top:4px;height:8px;background:rgba(42,42,90,0.5);border-radius:4px;overflow:hidden;"><div style="height:100%;width:${Math.min(m,100)}%;background:var(--dim);"></div></div>\n <span style="font-size:0.75rem;color:var(--dim)">${m.toFixed(1)}% combined</span>\n </div>`);let h="";for(const e of r.slice(0,15)){const t=new Date(e.lastCommit).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}),n=e.focusAreas.length>0?e.focusAreas.map(e=>e.dir).join(", "):"—";h+=`<tr>\n <td style="font-family:var(--sans)">${this._esc(e.name)}</td>\n <td style="text-align:center">${e.commits} (${e.percentage}%)</td>\n <td style="text-align:right;color:var(--green)">+${e.linesAdded.toLocaleString()}</td>\n <td style="text-align:right;color:var(--red)">-${e.linesDeleted.toLocaleString()}</td>\n <td>${t}</td>\n <td style="font-family:var(--sans)">${this._esc(n)}</td>\n </tr>`}const g=s.repoAgeYears>=1?`${s.repoAgeYears}y`:`${s.repoAgeDays}d`;return`\n<div class="section">\n <div class="section-header">\n ${n}\n <h3>Development Velocity &amp; Team Indicators</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Derived from local git history analysis (${s.totalCommits.toLocaleString()} commits on the current branch). ${e.metrics.prMergeRateSource.includes("remote detected")?"Remote repository detected; PR merge rate approximated via local merge-commit ratio.":""}\n </p>\n\n <div class="stat-row" style="margin-top:0;">\n <div class="stat">\n <div class="stat-value" style="color:var(--cyan)">${s.totalCommits.toLocaleString()}</div>\n <div class="stat-label">Total Commits</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--green)">${s.totalContributors}</div>\n <div class="stat-label">Contributors</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:${i}">${s.busFactor}</div>\n <div class="stat-label">Bus Factor</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--purple)">${g}</div>\n <div class="stat-label">Repo Age</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--cyan)">${s.commitsPerDay90d}</div>\n <div class="stat-label">Commits / Day (90d)</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--yellow)">${s.prMergeRate}%</div>\n <div class="stat-label">Merge Commit Rate</div>\n </div>\n </div>\n\n <div style="display:grid; grid-template-columns:1fr 1fr; gap:1.5rem; margin-top:1.5rem;">\n <div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:1.25rem 1.5rem;">\n <div style="font-size:0.85rem; font-weight:600; margin-bottom:12px;">Contributor Distribution</div>\n <div style="font-size:0.85rem;">\n ${u}\n </div>\n </div>\n <div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:1.25rem 1.5rem;">\n <div style="font-size:0.85rem; font-weight:600; margin-bottom:12px;">Bus Factor Risk</div>\n <div class="callout ${"var(--red)"===i||"#ff4444"===i?"callout-danger":"callout-warning"}" style="margin-bottom:0.75rem;">\n <strong>Bus factor: ${s.busFactor}</strong> (${s.busFactorOwners.join(", ")}) &mdash; ${a.busFactorRisk.note}\n </div>\n <div style="font-size:0.8rem; color:var(--dim); line-height:1.6;">\n <div><strong style="color:${o}">${a.commitFrequency.label}:</strong> ${a.commitFrequency.note}</div>\n <div style="margin-top:0.5rem;"><strong style="color:${l}">${a.ownershipConcentration.label}:</strong> ${a.ownershipConcentration.note}</div>\n </div>\n </div>\n </div>\n\n <div style="margin-top:1.5rem;">\n <div style="font-size:0.85rem; font-weight:600; margin-bottom:0.75rem;">Contributor Detail</div>\n <table>\n <thead>\n <tr><th>Contributor</th><th style="text-align:center">Commits</th><th style="text-align:right">Lines Added</th><th style="text-align:right">Lines Deleted</th><th>Last Active</th><th>Focus Areas</th></tr>\n </thead>\n <tbody>${h}</tbody>\n </table>\n </div>\n</div>`}_renderCrucibleSection(e){const t='<span class="icon">&#128737;</span>';if(!e)return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Crucible Attack Resistance</h3>\n </div>\n <div style="font-size:0.85rem; color:var(--dim); padding:1rem; background:var(--surface); border-radius:8px; border:1px solid var(--border);">\n Crucible analysis not included — run <code style="font-family:var(--mono); color:var(--cyan);">thuban crucible</code> first to generate adversarial attack-resistance data for this codebase.\n </div>\n</div>`;const n="number"==typeof e.score?e.score:0,s=n>=85?"var(--green)":n>=65?"var(--yellow)":n>=40?"var(--orange)":"var(--red)",a=e.seeds||{},r=e.mutations||{},i=a.byCategory||{},o={sql_injection:"SQL Injection",sqli:"SQL Injection",xss:"Cross-Site Scripting (XSS)",auth_bypass:"Auth Bypass",authbypass:"Auth Bypass",command_injection:"Command Injection",path_traversal:"Path Traversal",ssrf:"SSRF",deserialization:"Insecure Deserialization",hardcoded_secret:"Hardcoded Secrets"};let l="";for(const[e,t]of Object.entries(i)){const n=t.total||0,s=t.detected||0,a=s,r=n-s,i=n>0?Math.round(s/n*100):0,d=i>=85?"var(--green)":i>=60?"var(--yellow)":"var(--red)",c=o[e]||e.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase());l+=`<tr>\n <td style="font-family:var(--sans)">${this._esc(c)}</td>\n <td style="text-align:center">${n}</td>\n <td style="text-align:center; color:var(--green)">${a}</td>\n <td style="text-align:center; color:${r>0?"var(--red)":"var(--dim)"}">${r}</td>\n <td style="text-align:right; color:${d}; font-weight:600">${i}%</td>\n </tr>`}return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Crucible Attack Resistance</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Crucible auto-generates adversarial test cases (boundary attacks, mutation testing) and measures how many the scanner\n correctly detects. This validates the scanner's real-world detection rate — not just static rule coverage.\n </p>\n <div class="stat-row" style="margin-top:0;">\n <div class="stat">\n <div class="stat-value" style="color:${s}">${n}</div>\n <div class="stat-label">Crucible Score</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--cyan)">${a.total||0}</div>\n <div class="stat-label">Patterns Tested</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--green)">${a.detected||0}</div>\n <div class="stat-label">Blocked</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:${(a.missed||0)>0?"var(--red)":"var(--green)"}">${a.missed||0}</div>\n <div class="stat-label">Exploitable</div>\n </div>\n ${r.total?`\n <div class="stat">\n <div class="stat-value" style="color:var(--purple)">${r.killRate??"?"}%</div>\n <div class="stat-label">Mutation Kill Rate</div>\n </div>`:""}\n </div>\n ${Object.keys(i).length>0?`\n <table style="margin-top:1.25rem;">\n <thead>\n <tr>\n <th>Attack Category</th>\n <th style="text-align:center">Tested</th>\n <th style="text-align:center">Blocked</th>\n <th style="text-align:center">Exploitable</th>\n <th style="text-align:right">Detection Rate</th>\n </tr>\n </thead>\n <tbody>${l}</tbody>\n </table>\n `:""}\n ${(a.missed||0)>0?`\n <div class="callout callout-danger">\n <strong>${a.missed} attack pattern${a.missed>1?"s":""} bypassed detection.</strong>\n These represent gaps in the scanner's rule coverage for this codebase's language/framework mix and should be reviewed.\n </div>`:""}\n</div>`}_renderArchitectureSection(e){const t='<span class="icon">&#128506;</span>';if(!e||!e.modules||0===e.modules.length)return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Architecture &amp; Module Map</h3>\n </div>\n <div style="font-size:0.85rem; color:var(--dim); padding:1rem; background:var(--surface); border-radius:8px; border:1px solid var(--border);">\n No modules detected in this codebase.\n </div>\n</div>`;let n="";for(const t of e.modules.slice(0,25)){const e=t.hasSecurityFindings?" &#9888;":"";n+=`<tr>\n <td style="font-family:var(--sans)">${this._esc(t.name)}${e}</td>\n <td style="text-align:center">${t.fileCount}</td>\n <td style="text-align:center">${t.loc.toLocaleString()}</td>\n <td style="text-align:center">${t.avgComplexity}</td>\n <td style="text-align:center; color:${t.findingsCount>0?"var(--yellow)":"var(--dim)"}">${t.findingsCount}</td>\n <td style="text-align:right; color:${t.healthColor}; font-weight:600">${t.healthRating}</td>\n </tr>`}const s=e.securityModules?.length||0;return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Architecture &amp; Module Map</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Auto-detected module structure across ${e.modules.length} module${e.modules.length>1?"s":""}.\n ${s>0?`<span style="color:var(--yellow)">${s} module${s>1?"s contain":" contains"} security-relevant findings.</span>`:"No modules flagged for security-relevant findings."}\n </p>\n <table>\n <thead>\n <tr>\n <th>Module</th>\n <th style="text-align:center">Files</th>\n <th style="text-align:center">LOC</th>\n <th style="text-align:center">Avg Complexity</th>\n <th style="text-align:center">Findings</th>\n <th style="text-align:right">Health</th>\n </tr>\n </thead>\n <tbody>${n}</tbody>\n </table>\n <div style="margin-top:1.25rem;">\n <div style="font-size:0.85rem; font-weight:600; margin-bottom:0.5rem;">Module Dependency Graph</div>\n <pre style="background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:1rem 1.25rem; font-family:var(--mono); font-size:0.7rem; line-height:1.6; overflow-x:auto; white-space:pre; color:var(--text);">${this._esc(e.graph)}</pre>\n </div>\n</div>`}_renderHistorySection(e){const t='<span class="icon">&#128201;</span>';if(!e||e.isFirstScan)return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Historical Trends</h3>\n </div>\n <div style="font-size:0.85rem; color:var(--dim); padding:1rem; background:var(--surface); border-radius:8px; border:1px solid var(--border);">\n First scan — no trend data yet. Run <code style="font-family:var(--mono); color:var(--cyan);">thuban investor-report</code> again after future changes to see score progression over time.\n </div>\n</div>`;const n="improving"===e.direction?"var(--green)":"declining"===e.direction?"var(--red)":"var(--dim)",s="improving"===e.direction?"Improving":"declining"===e.direction?"Declining":"Flat",a="improving"===e.direction?"&#9650;":"declining"===e.direction?"&#9660;":"&#9644;",r=e.series.slice(-12),i=Math.max(...r.map(e=>e.trustScore),100);let o="";for(const e of r){const t=Math.max(e.trustScore/i*100,4),n=new Date(e.date).toLocaleDateString("en-GB",{day:"numeric",month:"short"});o+=`\n <div style="display:flex; flex-direction:column; align-items:center; gap:4px; flex:1;">\n <div style="font-size:0.65rem; color:var(--dim)">${e.trustScore}</div>\n <div style="width:60%; height:${t}px; max-height:80px; background:var(--cyan); border-radius:3px 3px 0 0; opacity:0.7;"></div>\n <div style="font-size:0.6rem; color:var(--dim); writing-mode:vertical-rl; transform:rotate(180deg); height:50px;">${n}</div>\n </div>`}return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Historical Trends</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Trust score progression across ${e.scanCount} scan${e.scanCount>1?"s":""}, tracked locally in <code style="font-family:var(--mono);">.thuban-history.json</code>.\n </p>\n <div class="stat-row" style="margin-top:0;">\n <div class="stat">\n <div class="stat-value" style="color:${n}">${a} ${s}</div>\n <div class="stat-label">Trend Direction</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--cyan)">${e.firstScore}</div>\n <div class="stat-label">First Score</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:var(--cyan)">${e.latestScore}</div>\n <div class="stat-label">Latest Score</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:${e.totalChange>=0?"var(--green)":"var(--red)"}">${e.totalChange>=0?"+":""}${e.totalChange}</div>\n <div class="stat-label">Total Change</div>\n </div>\n <div class="stat">\n <div class="stat-value" style="color:${e.avgMonthlyChange>=0?"var(--green)":"var(--red)"}">${e.avgMonthlyChange>=0?"+":""}${e.avgMonthlyChange}/mo</div>\n <div class="stat-label">Avg Monthly Change</div>\n </div>\n </div>\n <div style="display:flex; align-items:flex-end; gap:4px; margin-top:1.5rem; padding:1rem; background:var(--surface); border:1px solid var(--border); border-radius:12px; min-height:140px;">\n ${o}\n </div>\n</div>`}_renderBenchmarksSection(e){if(!e||!e.metrics)return"";let t="";for(const n of e.metrics){const e=n.percentile>=75?"var(--green)":n.percentile>=50?"var(--yellow)":n.percentile>=25?"var(--orange)":"var(--red)";t+=`\n <div class="benchmark-row">\n <div class="benchmark-label">${this._esc(n.label)}</div>\n <div class="benchmark-track">\n <div class="benchmark-marker" style="left:${Math.min(Math.max(n.percentile,0),100)}%; background:${e}; box-shadow:0 0 8px ${e}"></div>\n </div>\n <div class="benchmark-values">${n.value}${n.unit} <span style="color:${e}">(P${n.percentile})</span></div>\n </div>`}return`\n<div class="section">\n <div class="section-header">\n <span class="icon">&#128200;</span>\n <h3>Benchmarking</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1.25rem;">\n Compared against ${this._esc(e.language)} codebases in the ${this._esc(e.bucket.label)} size range.\n Marker position shows this codebase's percentile rank (P50 = category average, P90 = top decile).\n </p>\n <div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:1.5rem 2rem;">\n ${t}\n </div>\n</div>`}_renderRiskValuationSection(e){const t='<span class="icon">&#128176;</span>';if(!e||!e.hasFindings)return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Risk-Adjusted Valuation Impact</h3>\n </div>\n <div style="font-size:0.85rem; color:var(--green); padding:1rem; background:rgba(0,255,136,0.05); border-radius:8px; border:1px solid rgba(0,255,136,0.15);">\n No significant financial exposure identified from current findings.\n </div>\n</div>`;let n="";for(const t of e.byType){const e="High"===t.probabilityLabel?"var(--red)":"Medium"===t.probabilityLabel?"var(--yellow)":"var(--dim)";n+=`<tr>\n <td style="font-family:var(--sans)">${this._esc(t.label)}</td>\n <td style="text-align:center">${t.count}</td>\n <td style="text-align:center; color:${e}">${t.probabilityLabel}</td>\n <td style="text-align:right">$${t.impactMin.toLocaleString()}–$${t.impactMax.toLocaleString()}</td>\n <td style="text-align:right; color:var(--orange); font-weight:600">$${t.expectedLoss.toLocaleString()}</td>\n </tr>`}const s=(e.roi??0)>=0?"var(--green)":"var(--red)";return`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Risk-Adjusted Valuation Impact</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Financial exposure estimated from industry breach-cost benchmarks (IBM Cost of a Data Breach Report and comparable\n incident-response data). Expected loss = probability of realization &times; impact.\n </p>\n <table>\n <thead>\n <tr>\n <th>Finding Type</th>\n <th style="text-align:center">Count</th>\n <th style="text-align:center">Probability</th>\n <th style="text-align:right">Impact Range</th>\n <th style="text-align:right">Expected Loss</th>\n </tr>\n </thead>\n <tbody>\n ${n}\n <tr class="totals-row">\n <td style="font-family:var(--sans)"><strong>TOTAL</strong></td>\n <td></td>\n <td></td>\n <td style="text-align:right; color:var(--red)">$${e.totalMaxExposure.toLocaleString()} max</td>\n <td style="text-align:right; color:var(--orange)">$${e.totalExpectedLoss.toLocaleString()}</td>\n </tr>\n </tbody>\n </table>\n <div class="cost-box" style="margin-top:1.25rem;">\n <div class="cost-grid">\n <div class="cost-item cost-manual">\n <div class="cost-value">$${e.totalExpectedLoss.toLocaleString()}</div>\n <div class="cost-label">Total expected loss (unmitigated)</div>\n </div>\n <div class="cost-item cost-thuban">\n <div class="cost-value">$${e.costToFix.toLocaleString()}</div>\n <div class="cost-label">Cost to fix (${e.fixHours}h @ $${e.hourlyRate}/hr)</div>\n </div>\n <div class="cost-item cost-saving">\n <div class="cost-value" style="color:${s}">${null!=e.roiMultiple?e.roiMultiple+"x":"N/A"}</div>\n <div class="cost-label">Remediation ROI ${null!=e.roi?`(${e.roi>=0?"+":""}${e.roi}%)`:""}</div>\n </div>\n </div>\n </div>\n</div>`}_renderSupplyChainSection(e,t){const n='<span class="icon">&#128230;</span>';if(!e||!e.summary)return`\n<div class="section">\n <div class="section-header">\n ${n}\n <h3>Dependency Supply Chain &amp; SBOM</h3>\n </div>\n <div style="font-size:0.85rem; color:var(--dim); padding:1rem; background:var(--surface); border-radius:8px; border:1px solid var(--border);">\n Dependency supply chain analysis not available (no supported lockfile detected).\n </div>\n</div>`;if("free"===t)return`\n<div class="section paywall-section">\n <div class="section-header">\n ${n}\n <h3>Dependency Supply Chain &amp; SBOM</h3>\n </div>\n <div class="paywall-overlay">\n <div class="paywall-message">\n <div style="font-size:2rem;margin-bottom:0.75rem;">&#128274;</div>\n <h4 style="margin-bottom:0.5rem;color:var(--text);">Unlock Supply Chain Analysis</h4>\n <p style="color:var(--dim);font-size:0.85rem;margin-bottom:1rem;">CVE exposure, malicious package detection, license compliance, and a full CycloneDX/SPDX SBOM are available with a Snapshot ($99) or Full Audit ($249) report key.</p>\n <div style="font-family:var(--mono);font-size:0.8rem;color:var(--cyan);background:rgba(0,246,255,0.05);padding:0.75rem 1rem;border-radius:8px;border:1px solid rgba(0,246,255,0.15);">\n Purchase at <a href="https://thuban.dev/#investors" style="color:var(--cyan)">thuban.dev</a> &rarr; run with <code>--key=YOUR_KEY</code>\n </div>\n </div>\n </div>\n</div>`;const s=e.summary,a=e.packages||[],r=e=>({CRITICAL:"var(--red)",HIGH:"var(--red)",MEDIUM:"var(--yellow)",LOW:"var(--dim)",UNKNOWN:"var(--dim)"}[e]||"var(--dim)");let i="";const o=a.filter(e=>e.cves.length>0).slice(0,20);for(const e of o)for(const t of e.cves)i+=`<tr>\n <td><code>${this._esc(e.name)}</code></td>\n <td>${this._esc(e.version)}</td>\n <td>${t.fixedVersion?this._esc(t.fixedVersion):"&mdash;"}</td>\n <td>${this._esc(t.id)}</td>\n <td style="color:${r(t.severity)}; font-weight:700">${t.severity}</td>\n </tr>`;let l="";for(const e of a.filter(e=>e.malicious||e.suspectedTyposquat).slice(0,15)){const t=e.malicious?e.maliciousReasons.join("; "):e.suspectedTyposquat;l+=`<tr>\n <td><code>${this._esc(e.name)}</code></td>\n <td>${this._esc(e.version)}</td>\n <td style="color:${e.malicious?"var(--red)":"var(--yellow)"}; font-weight:700">${e.malicious?"MALICIOUS":"SUSPECTED TYPOSQUAT"}</td>\n <td style="font-size:0.75rem;">${this._esc(t)}</td>\n </tr>`}const d={permissive:"var(--green)","weak-copyleft":"var(--yellow)",copyleft:"var(--red)",unlicensed:"var(--red)",unknown:"var(--dim)"},c={permissive:"Permissive","weak-copyleft":"Weak Copyleft",copyleft:"Copyleft (GPL/AGPL)",unlicensed:"Unlicensed",unknown:"Unknown"};let m="";for(const[e,t]of Object.entries(s.licenseBreakdown||{})){if(!t)continue;const n=s.totalPackages?(t/s.totalPackages*100).toFixed(1):"0.0";m+=`<span style="display:inline-block; margin:0.2rem 0.4rem 0.2rem 0; padding:0.2rem 0.6rem; border-radius:4px; font-size:0.75rem; font-family:var(--mono); color:${d[e]||"var(--dim)"}; background:${d[e]||"var(--dim)"}1a; border:1px solid ${d[e]||"var(--dim)"}44;">${c[e]||e}: ${t} (${n}%)</span>`}const v=a.filter(e=>"copyleft"===e.licenseCategory||"weak-copyleft"===e.licenseCategory),u=v.length>0?`\n <div class="callout callout-danger" style="margin-top:0.75rem;">\n <strong>License Risk:</strong> ${v.length} package${v.length>1?"s use":" uses"} copyleft licensing\n (${v.slice(0,6).map(e=>`<code>${this._esc(e.name)}@${this._esc(e.version)}</code> (${this._esc(e.license||"unknown")})`).join(", ")}${v.length>6?`, +${v.length-6} more`:""}).\n If this application is distributed, copyleft obligations may require source disclosure. <strong>Legal review recommended.</strong>\n </div>`:"",h=(e.ecosystemsDetected||[]).join(", ")||"npm",g=new Date(e.generatedAt||Date.now()).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"});return`\n<div class="section">\n <div class="section-header">\n ${n}\n <h3>Dependency Supply Chain &amp; SBOM</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Automated scan of direct and transitive dependencies${e.networkAvailable?"":" (offline mode — CVE/version data unavailable)"} across detected ecosystems (${this._esc(h)}) against the OSV.dev vulnerability database.\n </p>\n <div class="stat-row" style="margin-top:0; margin-bottom:1rem;">\n <div class="stat stat-info"><div class="stat-value">${s.totalDirect}</div><div class="stat-label">Direct Deps</div></div>\n <div class="stat stat-info"><div class="stat-value">${s.totalTransitive}</div><div class="stat-label">Transitive</div></div>\n <div class="stat ${s.totalCVEs>0?"stat-critical":"stat-good"}"><div class="stat-value">${s.totalCVEs}</div><div class="stat-label">Known CVEs</div></div>\n <div class="stat ${s.maliciousCount>0?"stat-critical":"stat-good"}"><div class="stat-value">${s.maliciousCount}</div><div class="stat-label">Malicious</div></div>\n </div>\n\n ${i?`\n <div style="font-size:0.85rem; font-weight:600; margin-bottom:0.5rem;">Vulnerable Dependencies</div>\n <table>\n <thead>\n <tr><th>Package</th><th>Installed</th><th>Patched</th><th>CVE</th><th>Severity</th></tr>\n </thead>\n <tbody>${i}</tbody>\n </table>`:'\n <div style="font-size:0.85rem; color:var(--green); padding:1rem; background:rgba(0,255,136,0.05); border-radius:8px; border:1px solid rgba(0,255,136,0.15); margin-bottom:1rem;">\n No known CVEs found in scanned dependencies.\n </div>'}\n\n ${l?`\n <div style="font-size:0.85rem; font-weight:600; margin:1rem 0 0.5rem;">Malicious / Suspected Typosquat Packages</div>\n <table>\n <thead>\n <tr><th>Package</th><th>Version</th><th>Flag</th><th>Detail</th></tr>\n </thead>\n <tbody>${l}</tbody>\n </table>`:""}\n\n <div style="font-size:0.85rem; font-weight:600; margin:1rem 0 0.5rem;">Software Bill of Materials (SBOM)</div>\n <div style="font-size:0.85rem; color:var(--text);">\n <strong>Total dependencies:</strong> ${s.totalPackages} (direct: ${s.totalDirect}, transitive: ${s.totalTransitive})<br>\n <strong>Outdated packages:</strong> ${s.outdatedCount} (${s.majorVersionsBehindCount} major version${1===s.majorVersionsBehindCount?"":"s"} behind)${s.deprecatedCount>0?` &mdash; ${s.deprecatedCount} deprecated`:""}<br>\n <strong>SBOM formats generated:</strong> CycloneDX 1.5 JSON, SPDX 2.3 JSON (${s.totalPackages} components, generated ${g})<br>\n <strong>License distribution:</strong>\n <div style="margin-top:0.4rem;">${m}</div>\n ${u}\n </div>\n</div>`}_renderComplianceSection(e,t){const n='<span class="icon">&#128220;</span>';if("free"===t)return`\n<div class="section paywall-section">\n <div class="section-header">\n ${n}\n <h3>Compliance &amp; Standards Mapping</h3>\n </div>\n <div class="paywall-overlay">\n <div class="paywall-message">\n <div style="font-size:2rem;margin-bottom:0.75rem;">&#128274;</div>\n <h4 style="margin-bottom:0.5rem;color:var(--text);">Unlock Compliance Mapping</h4>\n <p style="color:var(--dim);font-size:0.85rem;margin-bottom:1rem;">OWASP Top 10, SOC 2, PCI DSS, and ISO 27001 compliance mapping is available with a Snapshot ($99) or Full Audit ($249) report key.</p>\n <div style="font-family:var(--mono);font-size:0.8rem;color:var(--cyan);background:rgba(0,246,255,0.05);padding:0.75rem 1rem;border-radius:8px;border:1px solid rgba(0,246,255,0.15);">\n Purchase at <a href="https://thuban.dev/#investors" style="color:var(--cyan)">thuban.dev</a> &rarr; run with <code>--key=YOUR_KEY</code>\n </div>\n </div>\n </div>\n</div>`;const s=e=>"Fail"===e?{color:"var(--red)",label:"Fail"}:"Partial"===e?{color:"var(--yellow)",label:"Partial"}:{color:"var(--green)",label:"Pass"};let a="",r=0,i=0,o=0;for(const t of Object.values(e))for(const e of t.requirements){const n=s(e.status);"Pass"===e.status?r++:"Fail"===e.status?i++:o++;const l=e.findings.length?this._esc(e.findings.join("; ")):"&mdash;";a+=`<tr>\n <td style="font-family:var(--sans)">${this._esc(t.name)}</td>\n <td style="font-family:var(--sans)">${this._esc(e.id)} &mdash; ${this._esc(e.name)}</td>\n <td style="color:${n.color}; font-weight:700">${n.label}</td>\n <td style="font-size:0.7rem;">${l}</td>\n </tr>`}return`\n<div class="section">\n <div class="section-header">\n ${n}\n <h3>Compliance &amp; Standards Mapping</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Automated mapping of scan findings against major compliance frameworks. A <span style="color:var(--red)">Fail</span> indicates\n critical/high-severity findings tied to that requirement; <span style="color:var(--yellow)">Partial</span> indicates lower-severity\n findings; <span style="color:var(--green)">Pass</span> indicates no mapped findings were detected. This is a preliminary automated\n assessment, not a certified compliance audit.\n </p>\n <div class="stat-row" style="margin-top:0; margin-bottom:1rem;">\n <div class="stat stat-good"><div class="stat-value">${r}</div><div class="stat-label">Pass</div></div>\n <div class="stat stat-warning"><div class="stat-value">${o}</div><div class="stat-label">Partial</div></div>\n <div class="stat stat-critical"><div class="stat-value">${i}</div><div class="stat-label">Fail</div></div>\n </div>\n <table>\n <thead>\n <tr><th>Framework</th><th>Requirement</th><th>Status</th><th>Findings</th></tr>\n </thead>\n <tbody>${a}</tbody>\n </table>\n</div>`}_renderRecommendationsSection(e){const t='<span class="icon">&#9989;</span>',n=(e,t,n,s)=>{if(!t.length)return"";let a="";for(const e of t)a+=`\n <div class="callout" style="background:rgba(0,0,0,0.15); border:1px solid ${n}44; margin-bottom:0.75rem;">\n <div style="display:flex; justify-content:space-between; align-items:baseline; gap:1rem;">\n <strong style="color:${n}; font-size:0.9rem;">${this._esc(e.title)}</strong>\n <span style="font-family:var(--mono); font-size:0.75rem; color:var(--dim); white-space:nowrap;">Est. effort: ${this._esc(e.effort)}</span>\n </div>\n <div style="font-size:0.8rem; color:var(--text); margin-top:0.4rem; line-height:1.5;">${this._esc(e.detail)}</div>\n </div>`;return`\n <div style="margin-bottom:1.5rem;">\n <div style="display:flex; align-items:center; gap:0.5rem; margin-bottom:0.75rem;">\n <span style="background:${n}; color:var(--bg); font-size:0.65rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; padding:0.2rem 0.6rem; border-radius:4px;">${s}</span>\n </div>\n ${a}\n </div>`},s=n(0,e.beforeClose,"var(--red)","Before Close"),a=n(0,e.within30Days,"var(--orange)","Within 30 Days"),r=n(0,e.within90Days,"var(--yellow)","Within 90 Days");let i="";if(e.positive.length){let t="";for(const n of e.positive)t+=`\n <div class="callout" style="background:rgba(0,255,136,0.05); border:1px solid rgba(0,255,136,0.2); margin-bottom:0.75rem;">\n <strong style="color:var(--green); font-size:0.9rem;">&#10003; ${this._esc(n.title)}</strong>\n <div style="font-size:0.8rem; color:var(--text); margin-top:0.4rem; line-height:1.5;">${this._esc(n.detail)}</div>\n </div>`;i=`\n <div>\n <div style="display:flex; align-items:center; gap:0.5rem; margin-bottom:0.75rem;">\n <span style="background:var(--green); color:var(--bg); font-size:0.65rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; padding:0.2rem 0.6rem; border-radius:4px;">Positive</span>\n </div>\n ${t}\n </div>`}return 0!==e.beforeClose.length+e.within30Days.length+e.within90Days.length||e.positive.length?`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Investment Recommendations</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1.25rem;">\n Prioritised, auto-generated recommendations derived from scan findings, with effort estimates for engineering planning.\n </p>\n ${s}\n ${a}\n ${r}\n ${i}\n</div>`:`\n<div class="section">\n <div class="section-header">\n ${t}\n <h3>Investment Recommendations</h3>\n </div>\n <div style="font-size:0.85rem; color:var(--green); padding:1rem; background:rgba(0,255,136,0.05); border-radius:8px; border:1px solid rgba(0,255,136,0.15);">\n No actionable findings to report — codebase meets investment-grade quality standards.\n </div>\n</div>`}_renderHTML(e){const t=this.generatedAt,n=t.toLocaleDateString("en-GB",{day:"numeric",month:"long",year:"numeric"}),s=t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),a=this._getProductionFindings({hallResults:e.hallResults,ghostResults:e.ghostResults,cloneResults:e.cloneResults,aiScoreResults:e.aiScoreResults,scanResults:e.scanResults}),r=a.phantomAPIs.length,i=a.deprecatedAPIs.length,o=a.totalGhosts,l=e.ghostResults.totalWastedLines||0,d=(a.totalClusters,e.cloneResults.totalDuplicateLines,e.aiScoreResults.aiLikelyCount||0),c=e.aiScoreResults.aiPossibleCount||0,m=e.aiScoreResults.aiPercentage||0,v=e.debtCost.totalHoursManual||0,u=e.debtCost.totalCostManual||0,h=e.debtCost.totalHoursThuban||0,g=e.debtCost.totalSaving||0,p=e.debtCost.savingPercent||0,b=this._investmentVerdict(e.score),f=this._aiDependencyAssessment(m),y=this._buildExecutiveSummary(e.score,{hallResults:e.hallResults,ghostResults:e.ghostResults,aiScoreResults:e.aiScoreResults,debtCost:e.debtCost,scanResults:e.scanResults,fileCount:e.fileCount,lineCount:e.lineCount}),x=this._buildRemediationEstimate({hallResults:e.hallResults,ghostResults:e.ghostResults,aiScoreResults:e.aiScoreResults,cloneResults:e.cloneResults,scanResults:e.scanResults}),$=x.reduce((e,t)=>e+t.hours,0),w=x.reduce((e,t)=>e+t.cost80,0),C=x.reduce((e,t)=>e+t.cost120,0),k=x.reduce((e,t)=>e+t.issues,0),R=this._buildRiskMatrix({hallResults:e.hallResults,ghostResults:e.ghostResults,cloneResults:e.cloneResults,scanResults:e.scanResults}),S=this._assessTeamCompetency({scanResults:e.scanResults,ghostResults:e.ghostResults,cloneResults:e.cloneResults,aiScoreResults:e.aiScoreResults,fileCount:e.fileCount,lineCount:e.lineCount,testFileCount:e.passportData?.testFileCount||0,commentRatio:e.passportData?.commentRatio||0}),I=this._renderVelocitySection(e.velocityResults,e.tier),A=this._renderCrucibleSection(e.crucibleResults),_=this._renderArchitectureSection(e.architectureData),z=this._renderHistorySection(e.historyData),T=this._renderBenchmarksSection(e.benchmarkData),P=this._renderRiskValuationSection(e.riskValuation),D=this._renderSupplyChainSection(e.supplyChainResults,e.tier),F={phantomAPIs:a.phantomAPIs,deprecatedAPIs:a.deprecatedAPIs},M={...e.ghostResults,totalGhosts:a.totalGhosts},L={...e.cloneResults,totalClusters:a.totalClusters},E=(new ComplianceMapper).map({scanIssues:a.scanIssuesList,hallResults:F,ghostResults:M,cloneResults:L}),j=generateRecommendations({scanIssues:a.scanIssuesList,hallResults:F,ghostResults:M,cloneResults:L,aiScoreResults:e.aiScoreResults}),N=this._renderComplianceSection(E,e.tier),O=this._renderRecommendationsSection(j);let B="";if(e.hallResults.phantomAPIs){const t=[...e.hallResults.phantomAPIs].sort((e,t)=>this._isTestFixture(e.file)-this._isTestFixture(t.file));for(const e of t.slice(0,8)){const t=this._isTestFixture(e.file);B+=`<tr${t?' style="opacity:0.6"':""}>\n <td class="sev-critical">CRITICAL${t?' <span style="font-size:0.7em; color:var(--dim); font-weight:400;">(test fixture)</span>':""}</td>\n <td>${this._esc(e.file||"")}:${e.line||"?"}</td>\n <td>${this._esc(e.name||e.code||"Phantom API")}</td>\n <td>Will crash at runtime — method does not exist</td>\n </tr>`}}if(e.hallResults.deprecatedAPIs){const t=[...e.hallResults.deprecatedAPIs].sort((e,t)=>this._isTestFixture(e.file)-this._isTestFixture(t.file));for(const e of t.slice(0,5)){const t=this._isTestFixture(e.file);B+=`<tr${t?' style="opacity:0.6"':""}>\n <td class="sev-high">HIGH${t?' <span style="font-size:0.7em; color:var(--dim); font-weight:400;">(test fixture)</span>':""}</td>\n <td>${this._esc(e.file||"")}:${e.line||"?"}</td>\n <td>${this._esc(e.name||e.code||"Deprecated API")}</td>\n <td>Deprecated — will break in future versions</td>\n </tr>`}}let H="";if(e.ghostResults.ghosts){const t=[...e.ghostResults.ghosts].sort((e,t)=>this._isTestFixture(e.file)-this._isTestFixture(t.file));for(const e of t.slice(0,8)){const t=this._isTestFixture(e.file);H+=`<tr${t?' style="opacity:0.6"':""}>\n <td>${this._esc(e.file)}:${e.line}${t?' <span style="font-size:0.7em; color:var(--dim);">(test fixture)</span>':""}</td>\n <td>${this._esc(e.name)}()</td>\n <td>${e.wastedLines} lines</td>\n <td>${e.references} references</td>\n </tr>`}}let q="";for(const e of x){const t="Critical"===e.priority?"var(--red)":"High"===e.priority?"var(--yellow)":"Medium"===e.priority?"var(--cyan)":"var(--dim)";q+=`<tr>\n <td>${this._esc(e.category)}</td>\n <td style="text-align:center">${e.issues}</td>\n <td style="text-align:center">${e.hours}</td>\n <td style="text-align:right">&pound;${e.cost80.toLocaleString()}</td>\n <td style="text-align:right">&pound;${e.cost120.toLocaleString()}</td>\n <td style="color:${t}; font-weight:600">${e.priority}</td>\n </tr>`}let V="";for(const e of S)V+=`<tr>\n <td>${this._esc(e.name)}</td>\n <td style="color:${e.color}; font-weight:600">${e.rating}</td>\n </tr>`;const G=[{label:"Pre-seed typical",min:40,max:55},{label:"Seed typical",min:50,max:65},{label:"Series A typical",min:60,max:75},{label:"Series B typical",min:70,max:80},{label:"Series C+",min:80,max:90}];let U="";for(const t of G)U+=`\n <div class="benchmark-row">\n <div class="benchmark-label">${t.label}</div>\n <div class="benchmark-track">\n <div class="benchmark-range" style="left:${t.min}%; width:${t.max-t.min}%"></div>\n <div class="benchmark-marker" style="left:${e.score}%" title="This codebase: ${e.score}"></div>\n </div>\n <div class="benchmark-values">${t.min}–${t.max}</div>\n </div>`;return`<!DOCTYPE html>\n<html lang="en">\n<head>\n<meta charset="UTF-8">\n<meta name="viewport" content="width=device-width, initial-scale=1.0">\n<title>Thuban Investor Due Diligence Report — ${this._esc(this.companyName)}</title>\n<style>\n @page { size: A4; margin: 15mm; }\n @media print {\n body { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }\n .no-print { display: none !important; }\n .page-break { page-break-before: always; }\n .verdict-banner { break-inside: avoid; }\n }\n\n :root {\n --bg: #0a0a1a;\n --surface: #12122a;\n --border: #2a2a5a;\n --text: #e0e0f0;\n --dim: #8888aa;\n --cyan: #00f6ff;\n --green: #00ff88;\n --yellow: #ffd93d;\n --red: #ff4444;\n --purple: #a855f7;\n --orange: #ff8844;\n --mono: 'JetBrains Mono', 'Cascadia Code', 'Consolas', monospace;\n --sans: 'Segoe UI', system-ui, -apple-system, sans-serif;\n }\n\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n background: var(--bg);\n color: var(--text);\n font-family: var(--sans);\n font-size: 11pt;\n line-height: 1.5;\n max-width: 210mm;\n margin: 0 auto;\n padding: 20mm 15mm;\n }\n\n /* Header */\n .report-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n border-bottom: 2px solid var(--cyan);\n padding-bottom: 1.5rem;\n margin-bottom: 2rem;\n }\n\n .report-header .logo {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n }\n\n .report-header .logo svg { width: 36px; height: 36px; }\n\n .report-header .logo-text {\n font-size: 1.5rem;\n font-weight: 300;\n letter-spacing: 0.3em;\n color: var(--cyan);\n }\n\n .report-header .meta {\n text-align: right;\n font-size: 0.8rem;\n color: var(--dim);\n line-height: 1.8;\n }\n\n .report-title {\n text-align: center;\n margin-bottom: 2rem;\n }\n\n .report-title h1 {\n font-size: 1.8rem;\n font-weight: 700;\n margin-bottom: 0.25rem;\n }\n\n .report-title .subtitle {\n font-size: 0.85rem;\n color: var(--dim);\n text-transform: uppercase;\n letter-spacing: 0.15em;\n margin-bottom: 0.25rem;\n }\n\n .report-title .project-name {\n color: var(--cyan);\n font-size: 1.1rem;\n font-family: var(--mono);\n }\n\n /* Verdict Banner */\n .verdict-banner {\n text-align: center;\n padding: 1.5rem 2rem;\n border-radius: 12px;\n margin-bottom: 2rem;\n font-size: 1.3rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n }\n\n /* Executive Summary */\n .exec-summary {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 12px;\n padding: 1.5rem 2rem;\n margin-bottom: 2rem;\n font-size: 0.9rem;\n line-height: 1.7;\n color: var(--text);\n }\n\n .exec-summary .summary-label {\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n color: var(--dim);\n margin-bottom: 0.5rem;\n font-weight: 600;\n }\n\n /* Score Ring */\n .score-section {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 3rem;\n margin-bottom: 2.5rem;\n padding: 2rem;\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 12px;\n }\n\n .score-ring {\n position: relative;\n width: 140px;\n height: 140px;\n }\n\n .score-ring svg { transform: rotate(-90deg); }\n\n .score-ring .score-value {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n text-align: center;\n }\n\n .score-ring .grade {\n font-size: 2.5rem;\n font-weight: 700;\n font-family: var(--mono);\n line-height: 1;\n }\n\n .score-ring .number {\n font-size: 0.85rem;\n color: var(--dim);\n }\n\n .score-summary { flex: 1; }\n\n .score-summary h2 {\n font-size: 1.3rem;\n margin-bottom: 0.75rem;\n }\n\n .stat-row {\n display: flex;\n gap: 2rem;\n flex-wrap: wrap;\n margin-top: 1rem;\n }\n\n .stat {\n text-align: center;\n min-width: 80px;\n }\n\n .stat .stat-value {\n font-size: 1.5rem;\n font-weight: 700;\n font-family: var(--mono);\n }\n\n .stat .stat-label {\n font-size: 0.7rem;\n color: var(--dim);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n .stat-critical .stat-value { color: var(--red); }\n .stat-warning .stat-value { color: var(--yellow); }\n .stat-good .stat-value { color: var(--green); }\n .stat-info .stat-value { color: var(--cyan); }\n\n /* Sections */\n .section {\n margin-bottom: 2rem;\n }\n\n .section-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 1rem;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--border);\n }\n\n .section-header h3 {\n font-size: 1rem;\n font-weight: 600;\n }\n\n .section-header .icon { font-size: 1.2rem; }\n\n /* Tables */\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.8rem;\n margin-bottom: 1rem;\n }\n\n th {\n text-align: left;\n padding: 0.5rem;\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n font-weight: 600;\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--dim);\n }\n\n td {\n padding: 0.4rem 0.5rem;\n border-bottom: 1px solid rgba(42,42,90,0.3);\n font-family: var(--mono);\n font-size: 0.75rem;\n word-break: break-all;\n }\n\n .sev-critical { color: var(--red); font-weight: 700; }\n .sev-high { color: var(--yellow); font-weight: 600; }\n\n /* Risk Matrix */\n .risk-matrix {\n display: grid;\n grid-template-columns: auto 1fr 1fr;\n grid-template-rows: auto 1fr 1fr;\n gap: 0;\n margin-bottom: 1rem;\n border: 1px solid var(--border);\n border-radius: 12px;\n overflow: hidden;\n }\n\n .risk-matrix .rm-corner {\n background: var(--surface);\n padding: 0.5rem;\n }\n\n .risk-matrix .rm-col-header {\n background: var(--surface);\n padding: 0.6rem 0.75rem;\n text-align: center;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--dim);\n border-bottom: 1px solid var(--border);\n }\n\n .risk-matrix .rm-row-header {\n background: var(--surface);\n padding: 0.6rem 0.75rem;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--dim);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--border);\n }\n\n .risk-matrix .rm-cell {\n padding: 0.75rem;\n font-size: 0.75rem;\n border-right: 1px solid rgba(42,42,90,0.3);\n border-bottom: 1px solid rgba(42,42,90,0.3);\n }\n\n .rm-cell-critical-likely { background: rgba(255,68,68,0.12); }\n .rm-cell-critical-unlikely { background: rgba(255,136,68,0.08); }\n .rm-cell-moderate-likely { background: rgba(255,217,61,0.08); }\n .rm-cell-moderate-unlikely { background: rgba(0,246,255,0.05); }\n\n .rm-cell .rm-count {\n font-family: var(--mono);\n font-size: 1.2rem;\n font-weight: 700;\n margin-bottom: 0.25rem;\n }\n\n .rm-cell .rm-items {\n font-size: 0.7rem;\n color: var(--dim);\n line-height: 1.4;\n }\n\n /* AI Dependency */\n .ai-dep-bar {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 12px;\n padding: 1.5rem 2rem;\n margin-bottom: 1rem;\n }\n\n .ai-dep-meter {\n height: 24px;\n background: rgba(42,42,90,0.5);\n border-radius: 12px;\n position: relative;\n margin: 1rem 0;\n overflow: visible;\n }\n\n .ai-dep-fill {\n height: 100%;\n border-radius: 12px;\n transition: width 0.3s;\n }\n\n .ai-dep-zones {\n display: flex;\n justify-content: space-between;\n font-size: 0.65rem;\n color: var(--dim);\n margin-top: 0.5rem;\n }\n\n .ai-dep-assessment {\n margin-top: 1rem;\n font-size: 0.85rem;\n line-height: 1.6;\n }\n\n /* Cost Box */\n .cost-box {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 12px;\n padding: 1.5rem 2rem;\n margin-bottom: 1rem;\n }\n\n .cost-grid {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n gap: 1.5rem;\n text-align: center;\n }\n\n .cost-item .cost-value {\n font-size: 1.8rem;\n font-weight: 700;\n font-family: var(--mono);\n }\n\n .cost-item .cost-label {\n font-size: 0.75rem;\n color: var(--dim);\n margin-top: 0.25rem;\n }\n\n .cost-manual .cost-value { color: var(--red); }\n .cost-thuban .cost-value { color: var(--cyan); }\n .cost-saving .cost-value { color: var(--green); }\n\n /* Benchmarks */\n .benchmark-row {\n display: flex;\n align-items: center;\n gap: 1rem;\n margin-bottom: 0.75rem;\n }\n\n .benchmark-label {\n width: 130px;\n font-size: 0.75rem;\n color: var(--dim);\n text-align: right;\n flex-shrink: 0;\n }\n\n .benchmark-track {\n flex: 1;\n height: 20px;\n background: rgba(42,42,90,0.4);\n border-radius: 10px;\n position: relative;\n }\n\n .benchmark-range {\n position: absolute;\n top: 3px;\n height: 14px;\n background: rgba(0,246,255,0.15);\n border: 1px solid rgba(0,246,255,0.3);\n border-radius: 7px;\n }\n\n .benchmark-marker {\n position: absolute;\n top: -2px;\n width: 4px;\n height: 24px;\n background: var(--cyan);\n border-radius: 2px;\n box-shadow: 0 0 8px rgba(0,246,255,0.5);\n transform: translateX(-2px);\n }\n\n .benchmark-values {\n width: 50px;\n font-size: 0.7rem;\n color: var(--dim);\n font-family: var(--mono);\n flex-shrink: 0;\n }\n\n /* Team Competency */\n .competency-table td:first-child {\n font-family: var(--sans);\n font-size: 0.8rem;\n word-break: normal;\n }\n\n .competency-table td:last-child {\n text-align: center;\n font-size: 0.8rem;\n width: 140px;\n }\n\n /* Callouts */\n .callout {\n padding: 1rem 1.5rem;\n border-radius: 8px;\n margin-bottom: 1rem;\n font-size: 0.85rem;\n }\n\n .callout-danger {\n background: rgba(255,68,68,0.08);\n border: 1px solid rgba(255,68,68,0.2);\n color: #ffaaaa;\n }\n\n .callout-warning {\n background: rgba(255,217,61,0.08);\n border: 1px solid rgba(255,217,61,0.2);\n color: #ffe088;\n }\n\n /* Paywall Gate */\n .paywall-section { position: relative; }\n .paywall-overlay {\n padding: 3rem 2rem;\n text-align: center;\n background: linear-gradient(135deg, rgba(18,18,42,0.95), rgba(10,10,26,0.98));\n border: 1px dashed var(--border);\n border-radius: 12px;\n }\n .paywall-message { max-width: 420px; margin: 0 auto; }\n .paywall-message h4 { font-size: 1.1rem; }\n .paywall-message code {\n background: rgba(0,246,255,0.1);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.8rem;\n }\n .paywall-message a { text-decoration: none; }\n .paywall-message a:hover { text-decoration: underline; }\n\n /* Confidentiality Footer */\n .confidentiality {\n margin-top: 3rem;\n padding: 1.25rem 1.5rem;\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 8px;\n font-size: 0.7rem;\n color: var(--dim);\n line-height: 1.6;\n text-align: center;\n }\n\n .confidentiality strong {\n color: var(--yellow);\n letter-spacing: 0.1em;\n }\n\n /* Footer */\n .report-footer {\n margin-top: 1.5rem;\n padding-top: 1.5rem;\n border-top: 1px solid var(--border);\n display: flex;\n justify-content: space-between;\n font-size: 0.75rem;\n color: var(--dim);\n }\n\n .report-footer a { color: var(--cyan); text-decoration: none; }\n\n /* Print button */\n .print-btn {\n position: fixed;\n bottom: 2rem;\n right: 2rem;\n background: var(--cyan);\n color: var(--bg);\n border: none;\n padding: 0.75rem 1.5rem;\n border-radius: 8px;\n font-weight: 600;\n font-size: 0.9rem;\n cursor: pointer;\n box-shadow: 0 4px 20px rgba(0,246,255,0.3);\n z-index: 100;\n }\n\n .print-btn:hover { background: #33f8ff; }\n\n /* Totals row */\n .totals-row td {\n font-weight: 700;\n border-top: 2px solid var(--border);\n padding-top: 0.6rem;\n }\n\n /* Responsive */\n @media screen and (max-width: 700px) {\n body { padding: 1rem; }\n .cost-grid { grid-template-columns: 1fr; }\n .stat-row { flex-direction: column; gap: 0.75rem; }\n .score-section { flex-direction: column; gap: 1.5rem; }\n .risk-matrix { grid-template-columns: auto 1fr; }\n .benchmark-label { width: 80px; font-size: 0.65rem; }\n }\n</style>\n</head>\n<body>\n\n<button class="print-btn no-print" onclick="window.print()">Save as PDF</button>\n\n\x3c!-- Header --\x3e\n<div class="report-header">\n <div class="logo">\n <svg viewBox="0 0 32 32" fill="none">\n <polygon points="16,2 30,28 2,28" stroke="#00f6ff" stroke-width="2" fill="none"/>\n <polygon points="16,8 25,25 7,25" stroke="#00f6ff" stroke-width="1" fill="rgba(0,246,255,0.1)"/>\n <circle cx="16" cy="18" r="3" fill="#00f6ff"/>\n </svg>\n <span class="logo-text">THUBAN</span>\n </div>\n <div class="meta">\n Report ID: ${e.reportId}<br>\n Generated: ${n} at ${s}<br>\n Engine: Thuban Code Health v0.3.0<br>\n Classification: Investor Due Diligence\n </div>\n</div>\n\n\x3c!-- Title --\x3e\n<div class="report-title">\n <div class="subtitle">Investor Due Diligence Report</div>\n <h1>Code Health Assessment</h1>\n <div class="project-name">${this._esc(this.companyName)}</div>\n</div>\n\n\x3c!-- Investment Verdict Banner --\x3e\n<div class="verdict-banner" style="background:${b.bg}; border:2px solid ${b.border}; color:${b.color}">\n ${b.label}\n</div>\n\n\x3c!-- Executive Summary --\x3e\n<div class="exec-summary">\n <div class="summary-label">Executive Summary</div>\n ${y}\n</div>\n\n\x3c!-- Score --\x3e\n<div class="score-section">\n <div class="score-ring">\n <svg width="140" height="140" viewBox="0 0 140 140">\n <circle cx="70" cy="70" r="60" fill="none" stroke="${e.gradeColor}22" stroke-width="10"/>\n <circle cx="70" cy="70" r="60" fill="none" stroke="${e.gradeColor}" stroke-width="10"\n stroke-dasharray="${Math.round(3.77*e.score)} 377"\n stroke-linecap="round"/>\n </svg>\n <div class="score-value">\n <div class="grade" style="color:${e.gradeColor}">${e.grade}</div>\n <div class="number">${e.score}/100</div>\n </div>\n </div>\n <div class="score-summary">\n <h2>Trust Score: ${"A"===e.grade?"Excellent":"B"===e.grade?"Good":"C"===e.grade?"Needs Attention":"D"===e.grade?"At Risk":"Critical"}</h2>\n <div class="stat-row">\n <div class="stat stat-info">\n <div class="stat-value">${e.fileCount.toLocaleString()}</div>\n <div class="stat-label">Files Scanned</div>\n </div>\n <div class="stat stat-info">\n <div class="stat-value">${e.lineCount.toLocaleString()}</div>\n <div class="stat-label">Lines of Code</div>\n </div>\n <div class="stat ${r>0?"stat-critical":"stat-good"}">\n <div class="stat-value">${r}</div>\n <div class="stat-label">Hallucinated APIs</div>\n </div>\n <div class="stat ${o>0?"stat-warning":"stat-good"}">\n <div class="stat-value">${o}</div>\n <div class="stat-label">Ghost Functions</div>\n </div>\n <div class="stat ${d>0?"stat-warning":"stat-good"}">\n <div class="stat-value">${m}%</div>\n <div class="stat-label">AI-Generated</div>\n </div>\n </div>\n </div>\n</div>\n\n${r>0?`\n<div class="callout callout-danger">\n <strong>MATERIAL RISK:</strong> ${r} API call${r>1?"s":""} in this codebase reference${1===r?"s":""} methods that do not exist.\n These will throw runtime errors in production. This represents a direct threat to service reliability and customer trust.\n</div>\n`:""}\n\n\x3c!-- Risk Matrix --\x3e\n${"free"===e.tier?'\n<div class="section paywall-section">\n <div class="section-header">\n <span class="icon">&#9888;</span>\n <h3>Risk Matrix</h3>\n </div>\n <div class="paywall-overlay">\n <div class="paywall-message">\n <div style="font-size:2rem;margin-bottom:0.75rem;">&#128274;</div>\n <h4 style="margin-bottom:0.5rem;color:var(--text);">Unlock Full Risk Analysis</h4>\n <p style="color:var(--dim);font-size:0.85rem;margin-bottom:1rem;">Risk Matrix, AI Dependency Assessment, and detailed findings are available with a Snapshot ($99) or Full Audit ($249) report key.</p>\n <div style="font-family:var(--mono);font-size:0.8rem;color:var(--cyan);background:rgba(0,246,255,0.05);padding:0.75rem 1rem;border-radius:8px;border:1px solid rgba(0,246,255,0.15);">\n Purchase at <a href="https://thuban.dev/#investors" style="color:var(--cyan)">thuban.dev</a> &rarr; run with <code>--key=YOUR_KEY</code>\n </div>\n </div>\n </div>\n</div>\n':`\n<div class="section">\n <div class="section-header">\n <span class="icon">&#9888;</span>\n <h3>Risk Matrix</h3>\n </div>\n <div class="risk-matrix">\n <div class="rm-corner"></div>\n <div class="rm-col-header" style="border-left:1px solid var(--border)">Likely</div>\n <div class="rm-col-header">Unlikely</div>\n\n <div class="rm-row-header">Critical</div>\n <div class="rm-cell rm-cell-critical-likely" style="border-left:1px solid rgba(42,42,90,0.3)">\n <div class="rm-count" style="color:var(--red)">${R.phantomCount+R.injectionCount}</div>\n <div class="rm-items">\n ${R.phantomCount>0?`${R.phantomCount} hallucinated API${R.phantomCount>1?"s":""}<br>`:""}\n ${R.injectionCount>0?`${R.injectionCount} injection risk${R.injectionCount>1?"s":""}`:""}\n ${0===R.phantomCount&&0===R.injectionCount?"None detected":""}\n </div>\n </div>\n <div class="rm-cell rm-cell-critical-unlikely">\n <div class="rm-count" style="color:var(--orange)">0</div>\n <div class="rm-items">Complex taint paths<br>(not yet assessed)</div>\n </div>\n\n <div class="rm-row-header" style="border-top:1px solid var(--border)">Moderate</div>\n <div class="rm-cell rm-cell-moderate-likely" style="border-left:1px solid rgba(42,42,90,0.3)">\n <div class="rm-count" style="color:var(--yellow)">${R.ghostCount+R.cloneCount}</div>\n <div class="rm-items">\n ${R.ghostCount>0?`${R.ghostCount} ghost/dead code<br>`:""}\n ${R.cloneCount>0?`${R.cloneCount} code clone${R.cloneCount>1?"s":""}`:""}\n ${0===R.ghostCount&&0===R.cloneCount?"None detected":""}\n </div>\n </div>\n <div class="rm-cell rm-cell-moderate-unlikely">\n <div class="rm-count" style="color:var(--cyan)">${R.deprecatedCount+R.styleIssueCount}</div>\n <div class="rm-items">\n ${R.deprecatedCount>0?`${R.deprecatedCount} deprecated API${R.deprecatedCount>1?"s":""}<br>`:""}\n ${R.styleIssueCount>0?`${R.styleIssueCount} style issue${R.styleIssueCount>1?"s":""}`:""}\n ${0===R.deprecatedCount&&0===R.styleIssueCount?"None detected":""}\n </div>\n </div>\n </div>\n</div>\n`}\n\n\x3c!-- AI Dependency Assessment --\x3e\n${"free"===e.tier?"":`\n<div class="section">\n <div class="section-header">\n <span class="icon">&#129302;</span>\n <h3>AI Dependency Assessment</h3>\n </div>\n <div class="ai-dep-bar">\n <div style="display:flex; justify-content:space-between; align-items:baseline; margin-bottom:0.5rem;">\n <span style="font-size:0.85rem; color:var(--dim)">AI-Generated Code Percentage</span>\n <span style="font-family:var(--mono); font-size:1.2rem; font-weight:700; color:${f.color}">${m}%</span>\n </div>\n <div class="ai-dep-meter">\n <div class="ai-dep-fill" style="width:${Math.min(m,100)}%; background:${f.color}; opacity:0.7"></div>\n </div>\n <div class="ai-dep-zones">\n <span>&lt;10% Minimal</span>\n <span>10-30% Moderate</span>\n <span>30-60% Heavy</span>\n <span>&gt;60% Dominant</span>\n </div>\n <div class="ai-dep-assessment">\n <strong style="color:${f.color}">${f.level}:</strong> ${f.description}\n </div>\n ${d>0?`<div style="margin-top:0.75rem; font-size:0.8rem; color:var(--dim)">\n ${d} function${d>1?"s":""} flagged as high-confidence AI-generated, ${c} flagged as possible.\n These should be reviewed for correctness, edge-case handling, and adequate test coverage.\n </div>`:""}\n </div>\n</div>\n`}\n\n<div class="page-break"></div>\n\n\x3c!-- Remediation Estimate --\x3e\n${"full"!==e.tier?'\n<div class="section paywall-section">\n <div class="section-header">\n <span class="icon">&#128176;</span>\n <h3>Remediation Cost Estimate</h3>\n </div>\n <div class="paywall-overlay">\n <div class="paywall-message">\n <div style="font-size:2rem;margin-bottom:0.75rem;">&#128274;</div>\n <h4 style="margin-bottom:0.5rem;color:var(--text);">Full Audit Required</h4>\n <p style="color:var(--dim);font-size:0.85rem;margin-bottom:1rem;">Remediation cost estimates, team competency analysis, and comparable benchmarks are available with a Full Audit report key ($249).</p>\n <div style="font-family:var(--mono);font-size:0.8rem;color:var(--cyan);background:rgba(0,246,255,0.05);padding:0.75rem 1rem;border-radius:8px;border:1px solid rgba(0,246,255,0.15);">\n Purchase at <a href="https://thuban.dev/#investors" style="color:var(--cyan)">thuban.dev</a> &rarr; run with <code>--key=YOUR_KEY</code>\n </div>\n </div>\n </div>\n</div>\n':`\n<div class="section">\n <div class="section-header">\n <span class="icon">&#128176;</span>\n <h3>Remediation Cost Estimate</h3>\n </div>\n ${x.length>0?`\n <table>\n <thead>\n <tr>\n <th>Category</th>\n <th style="text-align:center">Issues</th>\n <th style="text-align:center">Est. Hours</th>\n <th style="text-align:right">Cost @ &pound;80/hr</th>\n <th style="text-align:right">Cost @ &pound;120/hr</th>\n <th>Priority</th>\n </tr>\n </thead>\n <tbody>\n ${q}\n <tr class="totals-row">\n <td style="font-family:var(--sans)"><strong>TOTAL</strong></td>\n <td style="text-align:center">${k}</td>\n <td style="text-align:center">${$}</td>\n <td style="text-align:right; color:var(--yellow)">&pound;${w.toLocaleString()}</td>\n <td style="text-align:right; color:var(--red)">&pound;${C.toLocaleString()}</td>\n <td></td>\n </tr>\n </tbody>\n </table>\n <div style="font-size:0.8rem; color:var(--dim); margin-top:0.5rem;">\n Estimates based on industry-average remediation times. Actual costs may vary based on team familiarity and codebase complexity.\n Rates shown reflect UK market mid-range (&pound;80/hr) and senior (&pound;120/hr) developer costs.\n </div>\n `:'\n <div style="font-size:0.85rem; color:var(--green); padding:1rem; background:rgba(0,255,136,0.05); border-radius:8px; border:1px solid rgba(0,255,136,0.15);">\n No significant remediation items detected. This codebase meets investment-grade quality standards.\n </div>\n '}\n</div>\n`}\n\n\x3c!-- Team Competency Signals --\x3e\n${"full"!==e.tier?"":`\n<div class="section">\n <div class="section-header">\n <span class="icon">&#128101;</span>\n <h3>Team Competency Signals</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1rem;">\n Derived from automated code analysis patterns. These signals indicate engineering team capability\n based on observable code quality metrics, not individual performance.\n </p>\n <table class="competency-table">\n <thead>\n <tr><th>Signal</th><th style="text-align:center">Assessment</th></tr>\n </thead>\n <tbody>${V}</tbody>\n </table>\n</div>\n`}\n\n\x3c!-- Comparable Benchmarks --\x3e\n${"full"!==e.tier?"":`\n<div class="section">\n <div class="section-header">\n <span class="icon">&#128200;</span>\n <h3>Comparable Benchmarks</h3>\n </div>\n <p style="font-size:0.8rem; color:var(--dim); margin-bottom:1.25rem;">\n How this codebase compares to typical trust scores at each funding stage.\n The <span style="color:var(--cyan)">cyan marker</span> indicates this codebase's score of <strong>${e.score}/100</strong>.\n </p>\n <div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:1.5rem 2rem;">\n ${U}\n </div>\n</div>\n`}\n\n<div class="page-break"></div>\n${A}\n\n${_}\n\n<div class="page-break"></div>\n${I}\n\n${r+i>0&&"free"!==e.tier?`\n<div class="page-break"></div>\n\x3c!-- Hallucination Detail --\x3e\n<div class="section">\n <div class="section-header">\n <span class="icon">&#128302;</span>\n <h3>AI Hallucination Detail</h3>\n </div>\n <p style="font-size:0.85rem; color:var(--dim); margin-bottom:1rem;">\n These API calls reference methods, modules, or endpoints that do not exist in the libraries being used.\n They were likely generated by an AI coding tool and will fail at runtime.\n </p>\n <table>\n <thead>\n <tr><th>Severity</th><th>Location</th><th>API Call</th><th>Impact</th></tr>\n </thead>\n <tbody>${B}</tbody>\n </table>\n</div>\n`:""}\n\n${o>0?`\n\x3c!-- Ghost Code Detail --\x3e\n<div class="section">\n <div class="section-header">\n <span class="icon">&#128123;</span>\n <h3>Ghost Code — Dead Functions</h3>\n </div>\n <p style="font-size:0.85rem; color:var(--dim); margin-bottom:1rem;">\n ${o} function${o>1?"s":""} exist in the codebase but are never called.\n This represents ${l.toLocaleString()} wasted lines of code (${e.ghostResults.wastedPercent||"?"}% of the codebase).\n </p>\n <table>\n <thead>\n <tr><th>Location</th><th>Function</th><th>Size</th><th>References</th></tr>\n </thead>\n <tbody>${H}</tbody>\n </table>\n</div>\n`:""}\n\n\x3c!-- Technical Debt Cost --\x3e\n<div class="section">\n <div class="section-header">\n <span class="icon">&#128200;</span>\n <h3>Technical Debt Cost Analysis</h3>\n </div>\n <div class="cost-box">\n <div class="cost-grid">\n <div class="cost-item cost-manual">\n <div class="cost-value">&pound;${u.toLocaleString()}</div>\n <div class="cost-label">Manual fix cost (${v} dev-hours)</div>\n </div>\n <div class="cost-item cost-thuban">\n <div class="cost-value">${h}h</div>\n <div class="cost-label">Fix time with Thuban auto-fix</div>\n </div>\n <div class="cost-item cost-saving">\n <div class="cost-value">&pound;${g.toLocaleString()}</div>\n <div class="cost-label">Potential saving (${p}%)</div>\n </div>\n </div>\n </div>\n</div>\n\n<div class="page-break"></div>\n${z}\n\n${T}\n\n${P}\n\n<div class="page-break"></div>\n${D}\n\n<div class="page-break"></div>\n${N}\n\n${O}\n\n\x3c!-- Confidentiality Notice --\x3e\n<div class="confidentiality">\n <strong>CONFIDENTIAL</strong><br>\n This report was generated by Thuban Code Health Engine for investment due diligence purposes.\n Distribution should be limited to authorised investment committee members.\n Thuban does not provide investment advice. This report reflects automated code analysis only.\n</div>\n\n\x3c!-- Footer --\x3e\n<div class="report-footer">\n <div>\n <strong>Thuban</strong> — Code Health Engine<br>\n <a href="https://thuban.dev">thuban.dev</a> &nbsp;|&nbsp; A Silverwings product\n </div>\n <div style="text-align:right;">\n Report: ${e.reportId}<br>\n This report was generated automatically.<br>\n For full details, run: <code style="font-family:var(--mono); color:var(--cyan);">npx thuban scan .</code>\n </div>\n</div>\n\n</body>\n</html>`}_esc(e){return String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}save(e,t){const n=t||this.rootPath,s=path.resolve(n),a=path.resolve(this.rootPath);if(!s.startsWith(a+path.sep)&&s!==a)throw new Error(`Output directory must be within the project root: ${a}`);const r=`thuban-investor-report-${this.generatedAt.toISOString().split("T")[0]}.html`,i=path.join(s,r);return fs.writeFileSync(i,e,"utf-8"),i}}module.exports=InvestorReport;
@@ -0,0 +1 @@
1
+ "use strict";const fs=require("fs");function readJsonSafe(e,r=null){try{return JSON.parse(fs.readFileSync(e,"utf-8"))}catch{return r}}module.exports={readJsonSafe:readJsonSafe};
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),os=require("os"),crypto=require("crypto"),{readJsonSafe:readJsonSafe}=require("./json-file-util.js"),THUBAN_DIR=path.join(os.homedir(),".thuban"),MONITOR_DIR=path.join(THUBAN_DIR,"monitor"),CONFIG_FILE=path.join(MONITOR_DIR,"config.json"),RUNS_DIR=path.join(MONITOR_DIR,"runs"),NOTIFICATIONS_FILE=path.join(MONITOR_DIR,"notifications.json");function ensureDir(e){fs.existsSync(e)||fs.mkdirSync(e,{recursive:!0})}function safeReadJson(e,t){return readJsonSafe(e,t)}function atomicWriteSync(e,t){const n=e+".tmp."+process.pid+"."+Date.now();try{fs.writeFileSync(n,t,"utf-8"),fs.renameSync(n,e)}catch(e){try{fs.unlinkSync(n)}catch{}throw e}}class MonitorStore{constructor(){ensureDir(THUBAN_DIR),ensureDir(MONITOR_DIR),ensureDir(RUNS_DIR)}getRepoId(e){return crypto.createHash("sha256").update(path.resolve(e)).digest("hex").substring(0,12)}loadConfig(){return safeReadJson(CONFIG_FILE,{version:1,repos:[]})}saveConfig(e){atomicWriteSync(CONFIG_FILE,JSON.stringify(e,null,2))}upsertRepo(e){const t=this.loadConfig(),n=e.repoId||this.getRepoId(e.repoPath),o={repoId:n,repoPath:path.resolve(e.repoPath),frequency:e.frequency||"daily",intervalMs:e.intervalMs,notification:e.notification||{channels:["inbox"]},createdAt:e.createdAt||(new Date).toISOString(),updatedAt:(new Date).toISOString(),enabled:!1!==e.enabled,lastRunAt:e.lastRunAt||null,nextRunAt:e.nextRunAt||null},r=t.repos.findIndex(e=>e.repoId===n);return r>=0?t.repos[r]={...t.repos[r],...o}:t.repos.push(o),this.saveConfig(t),o}listRepos(){return this.loadConfig().repos||[]}getRepo(e){const t=e?path.resolve(e):null;return this.listRepos().find(n=>n.repoId===e||n.repoPath===t)||null}getRepoRunDir(e){const t=path.join(RUNS_DIR,e);return ensureDir(t),t}saveRun(e,t){const n=this.getRepoRunDir(e),o=path.join(n,`${t.timestamp.replace(/[:.]/g,"-")}.json`);return atomicWriteSync(o,JSON.stringify(t,null,2)),o}listRuns(e){const t=this.getRepoRunDir(e);return fs.readdirSync(t).filter(e=>e.endsWith(".json")).sort().map(e=>safeReadJson(path.join(t,e),null)).filter(Boolean)}getLatestRun(e){const t=this.listRuns(e);return t.length?t[t.length-1]:null}appendNotification(e){const t=safeReadJson(NOTIFICATIONS_FILE,{notifications:[]});t.notifications.push(e),atomicWriteSync(NOTIFICATIONS_FILE,JSON.stringify(t,null,2))}getNotifications(e=20){return safeReadJson(NOTIFICATIONS_FILE,{notifications:[]}).notifications.slice(-e).reverse()}}module.exports=MonitorStore;