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,426 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Thuban Python AST Helper
4
+
5
+ Reads Python source from stdin, parses it with the built-in `ast` module,
6
+ and prints a single-line JSON report to stdout describing:
7
+
8
+ - unused_import Imported names never referenced anywhere in the file
9
+ - unused_variable Local variables assigned in a function but never read
10
+ - high_complexity Functions whose McCabe cyclomatic complexity exceeds
11
+ COMPLEXITY_THRESHOLD
12
+ - dead_code Statements that are unreachable because they follow
13
+ an unconditional return/raise/break/continue in the
14
+ same block
15
+ - bare_except `except:` clauses with no exception type
16
+ - mutable_default_arg Function parameters defaulting to a mutable literal
17
+ (list/dict/set) or list()/dict()/set() call
18
+
19
+ This script is invoked by packages/scanner/python-ast-analyzer.js as a
20
+ subprocess (one call per Python file). It must never raise past main() -
21
+ on any parse failure it prints {"ok": false, "error": "..."} and exits 0,
22
+ so the caller can treat AST analysis as a best-effort supplement.
23
+
24
+ Output contract (stdout, single JSON object):
25
+ {"ok": true, "issues": [{"type": str, "line": int, "name": str|null, "message": str}, ...]}
26
+ {"ok": false, "error": str}
27
+ """
28
+
29
+ import ast
30
+ import json
31
+ import sys
32
+
33
+ COMPLEXITY_THRESHOLD = 10
34
+
35
+ TERMINATOR_TYPES = (ast.Return, ast.Raise, ast.Continue, ast.Break)
36
+
37
+
38
+ # ─────────────────────────────────────────────────────────────────────────
39
+ # Unused imports
40
+ # ─────────────────────────────────────────────────────────────────────────
41
+
42
+ class _UnusedImportChecker:
43
+ def __init__(self, tree):
44
+ self.tree = tree
45
+ self.imports = [] # [{'name', 'line', 'source'}]
46
+ self.used_names = set()
47
+ self.dunder_all_names = set()
48
+
49
+ def collect(self):
50
+ for node in ast.walk(self.tree):
51
+ if isinstance(node, ast.Import):
52
+ for alias in node.names:
53
+ if alias.name == '*':
54
+ continue
55
+ bound = alias.asname or alias.name.split('.')[0]
56
+ self.imports.append({'name': bound, 'line': node.lineno, 'source': ''})
57
+ elif isinstance(node, ast.ImportFrom):
58
+ if node.module == '__future__':
59
+ continue
60
+ for alias in node.names:
61
+ if alias.name == '*':
62
+ continue
63
+ bound = alias.asname or alias.name
64
+ self.imports.append({'name': bound, 'line': node.lineno, 'source': node.module or ''})
65
+ elif isinstance(node, ast.Name) and isinstance(node.ctx, ast.Load):
66
+ self.used_names.add(node.id)
67
+ elif isinstance(node, ast.Assign):
68
+ for target in node.targets:
69
+ if isinstance(target, ast.Name) and target.id == '__all__' and \
70
+ isinstance(node.value, (ast.List, ast.Tuple, ast.Set)):
71
+ for elt in node.value.elts:
72
+ if isinstance(elt, ast.Constant) and isinstance(elt.value, str):
73
+ self.dunder_all_names.add(elt.value)
74
+
75
+ def unused(self):
76
+ issues = []
77
+ seen = set()
78
+ for imp in self.imports:
79
+ name = imp['name']
80
+ if name.startswith('_'):
81
+ continue
82
+ if name in self.used_names or name in self.dunder_all_names:
83
+ continue
84
+ key = (name, imp['line'])
85
+ if key in seen:
86
+ continue
87
+ seen.add(key)
88
+ source_suffix = " from '%s'" % imp['source'] if imp['source'] else ''
89
+ issues.append({
90
+ 'type': 'unused_import',
91
+ 'line': imp['line'],
92
+ 'name': name,
93
+ 'message': "Unused import: '%s'%s" % (name, source_suffix),
94
+ })
95
+ return issues
96
+
97
+
98
+ # ─────────────────────────────────────────────────────────────────────────
99
+ # Per-function analysis: complexity, unused locals, mutable defaults
100
+ # ─────────────────────────────────────────────────────────────────────────
101
+
102
+ class _ComplexityVisitor(ast.NodeVisitor):
103
+ """Counts McCabe decision points within a single function's own body,
104
+ stopping at nested function/lambda boundaries (those are analyzed
105
+ independently when ast.walk() reaches them on its own)."""
106
+
107
+ def __init__(self):
108
+ self.complexity = 1
109
+
110
+ def visit_If(self, node):
111
+ self.complexity += 1
112
+ self.generic_visit(node)
113
+
114
+ def visit_For(self, node):
115
+ self.complexity += 1
116
+ self.generic_visit(node)
117
+
118
+ def visit_AsyncFor(self, node):
119
+ self.complexity += 1
120
+ self.generic_visit(node)
121
+
122
+ def visit_While(self, node):
123
+ self.complexity += 1
124
+ self.generic_visit(node)
125
+
126
+ def visit_IfExp(self, node):
127
+ self.complexity += 1
128
+ self.generic_visit(node)
129
+
130
+ def visit_ExceptHandler(self, node):
131
+ self.complexity += 1
132
+ self.generic_visit(node)
133
+
134
+ def visit_BoolOp(self, node):
135
+ self.complexity += max(len(node.values) - 1, 0)
136
+ self.generic_visit(node)
137
+
138
+ def visit_comprehension(self, node):
139
+ self.complexity += len(node.ifs)
140
+ self.generic_visit(node)
141
+
142
+ # Nested scopes get their own complexity computation - don't descend.
143
+ def visit_FunctionDef(self, node):
144
+ pass
145
+
146
+ def visit_AsyncFunctionDef(self, node):
147
+ pass
148
+
149
+ def visit_Lambda(self, node):
150
+ pass
151
+
152
+
153
+ def _compute_complexity(fn):
154
+ visitor = _ComplexityVisitor()
155
+ for stmt in fn.body:
156
+ visitor.visit(stmt)
157
+ return visitor.complexity
158
+
159
+
160
+ def _is_mutable_default(default):
161
+ if isinstance(default, (ast.List, ast.Dict, ast.Set)):
162
+ return True
163
+ if isinstance(default, ast.Call) and isinstance(default.func, ast.Name):
164
+ return default.func.id in ('list', 'dict', 'set')
165
+ return False
166
+
167
+
168
+ def _mutable_defaults(fn):
169
+ issues = []
170
+ args = fn.args
171
+ positional = list(getattr(args, 'posonlyargs', [])) + list(args.args)
172
+ if args.defaults:
173
+ for arg, default in zip(reversed(positional), reversed(args.defaults)):
174
+ if _is_mutable_default(default):
175
+ issues.append({
176
+ 'type': 'mutable_default_arg',
177
+ 'line': default.lineno,
178
+ 'name': arg.arg,
179
+ 'message': "Mutable default argument '%s' in function '%s' - shared across all calls" % (arg.arg, fn.name),
180
+ })
181
+ for arg, default in zip(args.kwonlyargs, args.kw_defaults or []):
182
+ if default is not None and _is_mutable_default(default):
183
+ issues.append({
184
+ 'type': 'mutable_default_arg',
185
+ 'line': default.lineno,
186
+ 'name': arg.arg,
187
+ 'message': "Mutable default argument '%s' in function '%s' - shared across all calls" % (arg.arg, fn.name),
188
+ })
189
+ return issues
190
+
191
+
192
+ class _LocalAssignCollector(ast.NodeVisitor):
193
+ """Collects simple (single-Name-target) local assignments made directly
194
+ within a function's own body - not inside nested function/lambda
195
+ scopes, which own their own locals."""
196
+
197
+ def __init__(self):
198
+ self.assigned = {} # name -> first assignment line
199
+ self.declared_global_nonlocal = set()
200
+
201
+ def visit_Assign(self, node):
202
+ if len(node.targets) == 1 and isinstance(node.targets[0], ast.Name):
203
+ name = node.targets[0].id
204
+ self.assigned.setdefault(name, node.lineno)
205
+ self.generic_visit(node)
206
+
207
+ def visit_AnnAssign(self, node):
208
+ if isinstance(node.target, ast.Name) and node.value is not None:
209
+ self.assigned.setdefault(node.target.id, node.lineno)
210
+ self.generic_visit(node)
211
+
212
+ def visit_For(self, node):
213
+ if isinstance(node.target, ast.Name):
214
+ self.assigned.setdefault(node.target.id, node.lineno)
215
+ self.generic_visit(node)
216
+
217
+ def visit_With(self, node):
218
+ for item in node.items:
219
+ if item.optional_vars is not None and isinstance(item.optional_vars, ast.Name):
220
+ self.assigned.setdefault(item.optional_vars.id, node.lineno)
221
+ self.generic_visit(node)
222
+
223
+ def visit_Global(self, node):
224
+ self.declared_global_nonlocal.update(node.names)
225
+
226
+ def visit_Nonlocal(self, node):
227
+ self.declared_global_nonlocal.update(node.names)
228
+
229
+ def visit_FunctionDef(self, node):
230
+ pass
231
+
232
+ def visit_AsyncFunctionDef(self, node):
233
+ pass
234
+
235
+ def visit_Lambda(self, node):
236
+ pass
237
+
238
+
239
+ class _LoadNameCollector(ast.NodeVisitor):
240
+ """Collects every Name read (Load context) anywhere within a subtree,
241
+ INCLUDING nested functions/lambdas - a variable captured by a closure
242
+ still counts as used."""
243
+
244
+ def __init__(self):
245
+ self.loaded = set()
246
+
247
+ def visit_Name(self, node):
248
+ if isinstance(node.ctx, ast.Load):
249
+ self.loaded.add(node.id)
250
+ self.generic_visit(node)
251
+
252
+
253
+ def _unused_locals(fn):
254
+ assign_collector = _LocalAssignCollector()
255
+ for stmt in fn.body:
256
+ assign_collector.visit(stmt)
257
+
258
+ load_collector = _LoadNameCollector()
259
+ load_collector.visit(fn)
260
+
261
+ issues = []
262
+ for name, line in assign_collector.assigned.items():
263
+ if name.startswith('_'):
264
+ continue
265
+ if name in assign_collector.declared_global_nonlocal:
266
+ continue
267
+ if name in load_collector.loaded:
268
+ continue
269
+ issues.append({
270
+ 'type': 'unused_variable',
271
+ 'line': line,
272
+ 'name': name,
273
+ 'message': "Variable '%s' is assigned but never used" % name,
274
+ })
275
+ return issues
276
+
277
+
278
+ # ─────────────────────────────────────────────────────────────────────────
279
+ # Dead code (unreachable statements)
280
+ # ─────────────────────────────────────────────────────────────────────────
281
+
282
+ def _check_block(stmts, issues):
283
+ for i, stmt in enumerate(stmts):
284
+ if isinstance(stmt, TERMINATOR_TYPES):
285
+ if i + 1 < len(stmts):
286
+ nxt = stmts[i + 1]
287
+ kind = type(stmt).__name__.lower()
288
+ issues.append({
289
+ 'type': 'dead_code',
290
+ 'line': nxt.lineno,
291
+ 'name': None,
292
+ 'message': "Unreachable code after '%s' statement" % kind,
293
+ })
294
+ break # only report the first unreachable run per block
295
+
296
+
297
+ class _DeadCodeVisitor(ast.NodeVisitor):
298
+ def __init__(self):
299
+ self.issues = []
300
+
301
+ def visit_Module(self, node):
302
+ _check_block(node.body, self.issues)
303
+ self.generic_visit(node)
304
+
305
+ def visit_FunctionDef(self, node):
306
+ _check_block(node.body, self.issues)
307
+ self.generic_visit(node)
308
+
309
+ def visit_AsyncFunctionDef(self, node):
310
+ _check_block(node.body, self.issues)
311
+ self.generic_visit(node)
312
+
313
+ def visit_If(self, node):
314
+ _check_block(node.body, self.issues)
315
+ _check_block(node.orelse, self.issues)
316
+ self.generic_visit(node)
317
+
318
+ def visit_For(self, node):
319
+ _check_block(node.body, self.issues)
320
+ _check_block(node.orelse, self.issues)
321
+ self.generic_visit(node)
322
+
323
+ def visit_AsyncFor(self, node):
324
+ _check_block(node.body, self.issues)
325
+ _check_block(node.orelse, self.issues)
326
+ self.generic_visit(node)
327
+
328
+ def visit_While(self, node):
329
+ _check_block(node.body, self.issues)
330
+ _check_block(node.orelse, self.issues)
331
+ self.generic_visit(node)
332
+
333
+ def visit_Try(self, node):
334
+ _check_block(node.body, self.issues)
335
+ for handler in node.handlers:
336
+ _check_block(handler.body, self.issues)
337
+ _check_block(node.orelse, self.issues)
338
+ _check_block(node.finalbody, self.issues)
339
+ self.generic_visit(node)
340
+
341
+ def visit_With(self, node):
342
+ _check_block(node.body, self.issues)
343
+ self.generic_visit(node)
344
+
345
+ def visit_AsyncWith(self, node):
346
+ _check_block(node.body, self.issues)
347
+ self.generic_visit(node)
348
+
349
+
350
+ # ─────────────────────────────────────────────────────────────────────────
351
+ # Suspicious patterns: bare except
352
+ # ─────────────────────────────────────────────────────────────────────────
353
+
354
+ def _find_bare_except(tree):
355
+ issues = []
356
+ for node in ast.walk(tree):
357
+ if isinstance(node, ast.ExceptHandler) and node.type is None:
358
+ issues.append({
359
+ 'type': 'bare_except',
360
+ 'line': node.lineno,
361
+ 'name': None,
362
+ 'message': "Bare 'except:' catches all exceptions including SystemExit/KeyboardInterrupt - catch specific exception types instead",
363
+ })
364
+ return issues
365
+
366
+
367
+ # ─────────────────────────────────────────────────────────────────────────
368
+ # Entry point
369
+ # ─────────────────────────────────────────────────────────────────────────
370
+
371
+ def main():
372
+ source = sys.stdin.read()
373
+
374
+ try:
375
+ tree = ast.parse(source)
376
+ except SyntaxError as e:
377
+ print(json.dumps({'ok': False, 'error': 'SyntaxError: %s' % e}))
378
+ return
379
+ except Exception as e: # pragma: no cover - defensive
380
+ print(json.dumps({'ok': False, 'error': str(e)}))
381
+ return
382
+
383
+ issues = []
384
+
385
+ try:
386
+ importer = _UnusedImportChecker(tree)
387
+ importer.collect()
388
+ issues.extend(importer.unused())
389
+ except Exception:
390
+ pass
391
+
392
+ try:
393
+ for node in ast.walk(tree):
394
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
395
+ issues.extend(_mutable_defaults(node))
396
+ complexity = _compute_complexity(node)
397
+ if complexity > COMPLEXITY_THRESHOLD:
398
+ issues.append({
399
+ 'type': 'high_complexity',
400
+ 'line': node.lineno,
401
+ 'name': node.name,
402
+ 'message': "Function '%s' has cyclomatic complexity %d (threshold %d)" % (
403
+ node.name, complexity, COMPLEXITY_THRESHOLD),
404
+ })
405
+ issues.extend(_unused_locals(node))
406
+ except Exception:
407
+ pass
408
+
409
+ try:
410
+ dead_code_visitor = _DeadCodeVisitor()
411
+ dead_code_visitor.visit(tree)
412
+ issues.extend(dead_code_visitor.issues)
413
+ except Exception:
414
+ pass
415
+
416
+ try:
417
+ issues.extend(_find_bare_except(tree))
418
+ except Exception:
419
+ pass
420
+
421
+ issues.sort(key=lambda i: i.get('line') or 0)
422
+ print(json.dumps({'ok': True, 'issues': issues}))
423
+
424
+
425
+ if __name__ == '__main__':
426
+ main()
@@ -0,0 +1 @@
1
+ "use strict";const RISK_PROFILES={sqlInjection:{label:"SQL Injection",probability:.35,probabilityLabel:"High",impactMin:12e5,impactMax:32e5,source:"IBM Cost of a Data Breach — breach involving injection/database compromise"},xss:{label:"Cross-Site Scripting (XSS)",probability:.25,probabilityLabel:"Medium",impactMin:3e5,impactMax:9e5,source:"Industry incident-response data — client-side compromise / session hijack"},authBypass:{label:"Authentication Bypass",probability:.3,probabilityLabel:"High",impactMin:5e5,impactMax:15e5,source:"Account takeover remediation + notification cost benchmarks"},hardcodedSecret:{label:"Hardcoded Secret / Credential",probability:.2,probabilityLabel:"Medium",impactMin:2e5,impactMax:8e5,source:"Credential leak incident response + key rotation cost"},hallucinatedApi:{label:"Hallucinated / Phantom API Call",probability:.55,probabilityLabel:"High",impactMin:1e4,impactMax:5e4,source:"Production incident / outage cost for runtime crash"},deprecatedApi:{label:"Deprecated API Usage",probability:.15,probabilityLabel:"Low",impactMin:5e3,impactMax:25e3,source:"Future breakage remediation cost"},injectionGeneric:{label:"Injection / Taint Risk (Generic)",probability:.25,probabilityLabel:"Medium",impactMin:4e5,impactMax:12e5,source:"IBM Cost of a Data Breach — generic injection-class vulnerability"},ghostCode:{label:"Ghost / Dead Code",probability:.05,probabilityLabel:"Low",impactMin:1e3,impactMax:8e3,source:"Maintenance overhead / accidental re-activation risk"},codeClone:{label:"Code Clone / Duplication",probability:.08,probabilityLabel:"Low",impactMin:2e3,impactMax:15e3,source:"Divergent-fix maintenance risk (bug fixed in one clone, not others)"},qualityGeneric:{label:"Code Quality Issue (Generic)",probability:.05,probabilityLabel:"Low",impactMin:500,impactMax:5e3,source:"General defect / maintenance cost"}},DEV_HOURLY_RATE=150;function classifyIssue(e){const i=`${e.message||""} ${e.name||""} ${e.id||""}`.toLowerCase(),t=(e.category||"").toLowerCase();return"info"===e.severity?null:i.includes("sql")&&i.includes("inject")?"sqlInjection":i.includes("xss")||i.includes("cross-site")?"xss":i.includes("auth")&&(i.includes("bypass")||i.includes("missing")||i.includes("weak"))?"authBypass":i.includes("secret")||i.includes("hardcoded")||i.includes("credential")||i.includes("api key")||i.includes("apikey")||"secret"===t||"secret-history"===t?"hardcodedSecret":i.includes("inject")||i.includes("taint")||"security"===t?"injectionGeneric":"quality"===t||"style"===t?"qualityGeneric":null}const FIX_HOURS_BY_TYPE={sqlInjection:3,xss:2,authBypass:4,hardcodedSecret:1,hallucinatedApi:2,deprecatedApi:1.5,injectionGeneric:2.5,ghostCode:.5,codeClone:3,qualityGeneric:.3};function calculateRiskValuation(e={}){const i=e.scanResults||{},t=e.hallResults||{},a=e.ghostResults||{},o=e.cloneResults||{},c={},n=(e,i=1)=>{c[e]||(c[e]=0),c[e]+=i};for(const e of i.issues||[]){const i=classifyIssue(e);i&&n(i)}const s=(t.phantomAPIs||[]).length,l=(t.deprecatedAPIs||[]).length;s>0&&n("hallucinatedApi",s),l>0&&n("deprecatedApi",l);const r=a.totalGhosts||0;r>0&&n("ghostCode",r);const u=o.totalClusters||0;u>0&&n("codeClone",u);const d=[];let p=0,b=0,y=0;for(const[e,i]of Object.entries(c)){if(i<=0)continue;const t=RISK_PROFILES[e];if(!t)continue;const a=i*t.impactMax,o=i*t.impactMin,c=(t.impactMin+t.impactMax)/2,n=i*t.probability*c,s=i*(FIX_HOURS_BY_TYPE[e]||1),l=150*s;p+=a,b+=n,y+=s,d.push({typeKey:e,label:t.label,count:i,probability:t.probability,probabilityLabel:t.probabilityLabel,impactMin:o,impactMax:a,expectedLoss:Math.round(n),fixHours:Math.round(10*s)/10,fixCost:Math.round(l),source:t.source})}d.sort((e,i)=>i.expectedLoss-e.expectedLoss);const h=Math.round(150*y);p=Math.round(p),b=Math.round(b);let m=null,M=null;return h>0&&(m=Math.round((b-h)/h*100),M=Math.round(b/h*10)/10),{byType:d,totalMaxExposure:p,totalExpectedLoss:b,costToFix:h,fixHours:Math.round(10*y)/10,hourlyRate:150,roi:m,roiMultiple:M,hasFindings:d.length>0}}module.exports={calculateRiskValuation:calculateRiskValuation,RISK_PROFILES:RISK_PROFILES,DEV_HOURLY_RATE:150};
@@ -0,0 +1 @@
1
+ "use strict";const fs=require("fs"),path=require("path"),HISTORY_FILENAME=".thuban-history.json",MAX_ENTRIES=500;function historyPath(e){return path.join(path.resolve(e),HISTORY_FILENAME)}function loadHistory(e){const t=historyPath(e);if(!fs.existsSync(t))return{entries:[]};try{const e=JSON.parse(fs.readFileSync(t,"utf-8"));return Array.isArray(e)?{entries:e}:{entries:Array.isArray(e.entries)?e.entries:[]}}catch{return{entries:[]}}}function recordScan(e,t){const r=historyPath(e),n=loadHistory(e),s={date:(new Date).toISOString(),trustScore:"number"==typeof t.trustScore?t.trustScore:null,crucibleScore:"number"==typeof t.crucibleScore?t.crucibleScore:null,findingsByType:t.findingsByType||{}};n.entries.push(s),n.entries.length>500&&(n.entries=n.entries.slice(n.entries.length-500));try{fs.writeFileSync(r,JSON.stringify({_version:"1.0.0",entries:n.entries},null,2),"utf-8")}catch{}return n.entries}function analyzeTrend(e){const t=(e||[]).filter(e=>"number"==typeof e.trustScore);if(0===t.length)return{hasHistory:!1,isFirstScan:!0,scanCount:0,direction:null,avgMonthlyChange:null,firstScore:null,latestScore:null,totalChange:null,series:[]};if(1===t.length)return{hasHistory:!0,isFirstScan:!0,scanCount:1,direction:null,avgMonthlyChange:null,firstScore:t[0].trustScore,latestScore:t[0].trustScore,totalChange:0,series:t};const r=t[0],n=t[t.length-1],s=n.trustScore-r.trustScore,i=new Date(r.date).getTime(),o=new Date(n.date).getTime(),a=Math.max((o-i)/2592e6,1/30),c=Math.round(s/a*10)/10;let l;return l=Math.abs(s)<2?"flat":s>0?"improving":"declining",{hasHistory:!0,isFirstScan:!1,scanCount:t.length,direction:l,avgMonthlyChange:c,firstScore:r.trustScore,latestScore:n.trustScore,totalChange:Math.round(10*s)/10,series:t}}function recordAndAnalyze(e,t){const r=loadHistory(e).entries,n=analyzeTrend(r),s=analyzeTrend(recordScan(e,t));return s.wasFirstScanBeforeThis=0===r.filter(e=>"number"==typeof e.trustScore).length,s.priorLatestScore=n.latestScore,s}module.exports={recordScan:recordScan,loadHistory:loadHistory,analyzeTrend:analyzeTrend,recordAndAnalyze:recordAndAnalyze,HISTORY_FILENAME:HISTORY_FILENAME};
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),crypto=require("crypto"),EventEmitter=require("events"),{execFileSync:execFileSync}=require("child_process"),GENERATED_OUTPUT_PATTERN=/^thuban-(sbom-(cyclonedx|spdx)|investor-report|scan-results|passport)-.*\.(json|html)$/i,LOCKFILE_NAMES=new Set(["package-lock.json","npm-shrinkwrap.json","yarn.lock","pnpm-lock.yaml","composer.lock","Cargo.lock","Gemfile.lock","poetry.lock","Pipfile.lock","go.sum"]);class SecretScanner extends EventEmitter{constructor(e={}){super();const t=new Set(["rootPath","ignorePatterns","maxFileSize","entropyThreshold","minEntropyLength","includeGitHistory"]),i={};for(const s of Object.keys(e))t.has(s)&&(i[s]=e[s]);this.config={rootPath:i.rootPath||process.cwd(),ignorePatterns:i.ignorePatterns||["node_modules/**",".git/**","dist/**",".next/**","coverage/**"],maxFileSize:i.maxFileSize||1048576,entropyThreshold:i.entropyThreshold||4.2,minEntropyLength:i.minEntropyLength||20,includeGitHistory:void 0===i.includeGitHistory||i.includeGitHistory},this.scanExtensions=new Set([".env",".js",".jsx",".ts",".tsx",".py",".json",".yaml",".yml",".toml",".ini",".conf",".config",".properties",".sh",".bash",".zsh"]),this.ignoredDirectories=["node_modules",".git","dist",".next","coverage",".venv","venv","__pycache__"],this.safeLinePatterns=[/process\.env\./i,/process\.env\[/i,/os\.environ/i,/sample/i,/placeholder/i,/dummy/i,/mock/i,/example/i,/replace[_-\s]?me/i,/replace[_-\s]?with/i,/local-dev-token/i,/changeme/i,/your[_-\s]?key/i,/your[_-\s]?(secret|token|password)/i,/<secret>/i,/<token>/i,/x{8,}/i],this.secretPatterns=[{id:"SECRET001",type:"Stripe Secret Key",severity:"critical",recommendation:"Move this key to a cloud secret manager and load it via environment variables.",pattern:/\bsk_(live|test)_[0-9a-zA-Z]{16,}\b/gi},{id:"SECRET002",type:"Stripe Publishable Key",severity:"high",recommendation:"Verify this publishable key is intended to be public; if not, move it to managed secrets.",pattern:/\bpk_(live|test)_[0-9a-zA-Z]{16,}\b/gi},{id:"SECRET003",type:"AWS Access Key",severity:"critical",recommendation:"Rotate the AWS credential immediately and store replacements in a cloud secret manager.",pattern:/\b(AKIA|ASIA|AGPA|AIDA|AROA|AIPA)[A-Z0-9]{16}\b/g},{id:"SECRET004",type:"GitHub Token",severity:"critical",recommendation:"Revoke the GitHub token and replace it with a managed secret or GitHub App credential.",pattern:/\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/g},{id:"SECRET005",type:"Slack Token",severity:"critical",recommendation:"Rotate the Slack token and move it into a cloud secret manager.",pattern:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{id:"SECRET006",type:"Twilio Credential",severity:"critical",recommendation:"Rotate the Twilio credential and store it in managed secrets.",pattern:/\b(SK|AC)[0-9a-fA-F]{32}\b/g},{id:"SECRET007",type:"Google API Key",severity:"critical",recommendation:"Restrict and rotate the Google API key, then move it to a cloud secret manager.",pattern:/\bAIza[0-9A-Za-z\-_]{35}\b/g},{id:"SECRET007B",type:"OpenAI Project Key",severity:"critical",recommendation:"Rotate the OpenAI project key and move it to a cloud secret manager.",pattern:/\bsk-proj-[A-Za-z0-9\-_]{20,}\b/g},{id:"SECRET007C",type:"Cartesia API Key",severity:"critical",recommendation:"Rotate the Cartesia API key and move it to a cloud secret manager.",pattern:/\bsk_car_[A-Za-z0-9]{16,}\b/g},{id:"SECRET008",type:"JWT Token",severity:"high",recommendation:"Do not hardcode JWTs; issue them dynamically and store signing secrets in managed secrets.",pattern:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9._-]{8,}\.[A-Za-z0-9._-]{8,}\b/g},{id:"SECRET009",type:"Bearer Token",severity:"high",recommendation:"Move bearer tokens to a cloud secret manager and inject them at runtime.",pattern:/\bBearer\s+[A-Za-z0-9\-._~+/]+=*\b/g},{id:"SECRET010",type:"Private Key",severity:"critical",recommendation:"Remove the private key from source control, rotate it, and store it in a secret manager.",pattern:/-----BEGIN (RSA |DSA |EC |OPENSSH |PGP )?PRIVATE KEY-----/g},{id:"SECRET011",type:"Database Connection String with Password",severity:"critical",recommendation:"Move the connection string to managed secrets and avoid embedding passwords in code or config.",pattern:/\b(?:postgres(?:ql)?|mysql|mssql|mongodb(?:\+srv)?|redis):\/\/[^:\s]+:[^@\s]+@[^'"`\s]+\b/gi},{id:"SECRET012",type:"Webhook Secret",severity:"high",recommendation:"Store webhook secrets in a cloud secret manager and inject them via environment variables.",pattern:/\b(?:whsec_[A-Za-z0-9]+|webhook[_-]?secret[_:=\s'"]+[A-Za-z0-9_\-]{12,})\b/gi},{id:"SECRET013",type:"Hardcoded Password or Secret Assignment",severity:"high",recommendation:"Replace hardcoded credentials with environment variables backed by a cloud secret manager.",pattern:/\b(?:password|passwd|pwd|secret|client_secret|api[_-]?secret|signing[_-]?secret)\b\s*[:=]\s*['"`][^'"`\s][^'"`]{5,}['"`]/gi},{id:"SECRET014",type:"Hardcoded API Key Assignment",severity:"high",recommendation:"Move API keys to a cloud secret manager and reference them through environment variables.",pattern:/\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|token)\b\s*[:=]\s*['"`][A-Za-z0-9_\-./+=]{12,}['"`]/gi},{id:"SECRET015",type:".env File Present",severity:"medium",recommendation:"Ensure .env files are excluded from git and move production secrets to a cloud secret manager.",filePattern:/(^|[\\/])\.env(\.[^\\/]+)?$/i},{id:"SECRET016",type:"LiveKit API Secret",severity:"critical",recommendation:"Rotate the LiveKit API secret and store it in managed secrets.",pattern:/\b(?:LIVEKIT_API_SECRET|livekit[_-]?api[_-]?secret)\b\s*[:=]\s*['"`]?([A-Za-z0-9]{24,})['"`]?/gi}]}async scanAll(){const e=Date.now(),t=await this._discoverFiles(this.config.rootPath),i=[];for(const e of t)i.push(...await this.scanFile(e));return this.config.includeGitHistory&&i.push(...this.scanGitHistory()),{filesScanned:t.length,issues:i,summary:this._summarizeIssues(i),duration:Date.now()-e}}async scanFiles(e){const t=[];for(const i of e)t.push(...await this.scanFile(i));return this.config.includeGitHistory&&t.push(...this.scanGitHistory()),{filesScanned:e.length,issues:t,summary:this._summarizeIssues(t)}}async scanFile(e){const t=[],i=path.relative(this.config.rootPath,e).replace(/\\/g,"/");try{if(fs.statSync(e).size>this.config.maxFileSize)return t;const s=path.basename(e),n=fs.readFileSync(e,"utf8").split(/\r?\n/);for(const r of this.secretPatterns)if(r.filePattern&&r.filePattern.test(e)){if(this._shouldSkipLine(s,i,r))continue;this._isGitIgnored(i)||t.push(this._createIssue({file:e,line:1,type:r.type,severity:r.severity,recommendation:"Add this file to .gitignore and move any production secrets to a cloud secret manager.",id:r.id,match:s,category:"secret"}))}else if(r.pattern)for(let s=0;s<n.length;s++){const o=n[s];if(this._shouldSkipLine(o,i,r))continue;let a;for(r.pattern.lastIndex=0;null!==(a=r.pattern.exec(o));){const i=a[1]||a[0];this._isLikelyPlaceholder(i)||t.push(this._createIssue({file:e,line:s+1,column:a.index,type:r.type,severity:r.severity,recommendation:r.recommendation,id:r.id,match:a[0],category:"secret"}))}}return t.push(...this._scanEntropy(e,n,i)),this._dedupeIssues(t)}catch(t){return[{file:e,line:1,category:"secret",severity:"medium",id:"SECRET_SCAN_ERROR",type:"Secret Scan Error",recommendation:"Verify file permissions and encoding, then rerun the scan.",message:"Failed to scan file for secrets: "+("ENOENT"===t.code?"File not found":"EACCES"===t.code?"Permission denied":"Scan error")}]}}scanGitHistory(){try{const e=execFileSync("git",["log","-p","--all","--full-history","--","."],{cwd:this.config.rootPath,encoding:"utf8",maxBuffer:20971520}),t=[],i=e.split(/\r?\n/);let s=null,n=null;for(const e of i){if(e.startsWith("commit ")){s=e.replace("commit ","").trim();continue}if(e.startsWith("+++ b/")){n=e.replace("+++ b/","").trim();continue}if(!e.startsWith("+")||e.startsWith("+++"))continue;const i=e.slice(1);if(!this._shouldSkipLine(i,n||""))for(const e of this.secretPatterns){if(!e.pattern)continue;let r;for(e.pattern.lastIndex=0;null!==(r=e.pattern.exec(i));){const o=r[1]||r[0];this._isLikelyPlaceholder(o)||t.push({file:n||"unknown",line:null,category:"secret-history",severity:"medium"===e.severity?"high":e.severity,id:`${e.id}_HISTORY`,type:`${e.type} in Git History`,recommendation:"Purge the secret from git history, rotate it, and move it to a cloud secret manager.",message:`Potential secret remains in git history (${s||"unknown commit"})`,commit:s,code:i.trim().slice(0,140)})}}}return this._dedupeIssues(t)}catch(e){return[]}}_scanEntropy(e,t,i){const s=[],n=/['"`]([A-Za-z0-9+/=_\-]{20,})['"`]/g;for(let r=0;r<t.length;r++){const o=t[r];if(this._shouldSkipLine(o,i))continue;let a;for(n.lastIndex=0;null!==(a=n.exec(o));){const t=a[1];if(t.length<this.config.minEntropyLength)continue;if(!/[A-Z]/.test(t)||!/[a-z]/.test(t)||!/[0-9]/.test(t))continue;const i=this._calculateEntropy(t);i>=this.config.entropyThreshold&&s.push(this._createIssue({file:e,line:r+1,column:a.index,type:"High Entropy Secret Candidate",severity:"medium",recommendation:"Review this value, move it to a cloud secret manager if it is a credential, and reference it via environment variables.",id:"SECRET_ENTROPY",match:t,category:"secret",extraMessage:`High-entropy string detected (entropy ${i.toFixed(2)})`}))}}return s}_createIssue({file:e,line:t,column:i,type:s,severity:n,recommendation:r,id:o,match:a,category:c,extraMessage:l}){return{file:e,line:t,column:i,category:c,severity:n,id:o,type:s,recommendation:r,message:l||`${s} detected`,code:"string"==typeof a?a.slice(0,140):""}}async _discoverFiles(e,t=[]){let i=[];try{i=fs.readdirSync(e,{withFileTypes:!0})}catch{return t}for(const s of i){const i=path.join(e,s.name),n=path.relative(this.config.rootPath,i).replace(/\\/g,"/");if(this._shouldIgnore(n))continue;if(s.isDirectory()){await this._discoverFiles(i,t);continue}if(!s.isFile())continue;if(GENERATED_OUTPUT_PATTERN.test(s.name))continue;if(LOCKFILE_NAMES.has(s.name))continue;const r=path.extname(s.name).toLowerCase();(this.scanExtensions.has(r)||s.name.startsWith(".env"))&&t.push(i)}return t}_shouldIgnore(e){const t=e.replace(/\\/g,"/"),i=this.ignoredDirectories;for(const e of i)if(t===e||t.startsWith(`${e}/`)||t.includes(`/${e}/`))return!0;return this.config.ignorePatterns.some(e=>{const i=e.replace(/\\/g,"/"),s=i.replace(/\./g,"\\.").replace(/\*\*/g,".*").replace(/\*/g,"[^/]*");return new RegExp(`^${s}$`).test(t)||t.startsWith(i.replace("/**",""))})}_shouldSkipLine(e,t,i=null){if(!e||!e.trim())return!0;const s=(t||"").replace(/\\/g,"/").toLowerCase();return!!(s.includes("__tests__")||s.includes("/test/")||s.includes("/tests/")||s.endsWith(".spec.js")||s.endsWith(".test.js")||s.endsWith(".spec.ts")||s.endsWith(".test.ts")||s.endsWith(".example")||s.endsWith(".env.example"))||(!i||"SECRET015"!==i.id)&&this.safeLinePatterns.some(t=>t.test(e))}_calculateEntropy(e){const t=new Map;for(const i of e)t.set(i,(t.get(i)||0)+1);let i=0;for(const s of t.values()){const t=s/e.length;i-=t*Math.log2(t)}return i}_isLikelyPlaceholder(e){return!!e&&[/replace[_-\s]?me/i,/replace[_-\s]?with/i,/example/i,/dummy/i,/placeholder/i,/changeme/i,/your[_-\s]?(key|secret|token|password)/i,/local-dev-token/i,/x{8,}/i].some(t=>t.test(e))}_isGitIgnored(e){try{return execFileSync("git",["check-ignore",e],{cwd:this.config.rootPath,stdio:"ignore"}),!0}catch{return!1}}_dedupeIssues(e){const t=new Set;return e.filter(e=>{const i=crypto.createHash("sha1").update(JSON.stringify([e.file,e.line,e.id,e.code,e.commit||""])).digest("hex");return!t.has(i)&&(t.add(i),!0)})}_summarizeIssues(e){return{total:e.length,bySeverity:{critical:e.filter(e=>"critical"===e.severity).length,high:e.filter(e=>"high"===e.severity).length,medium:e.filter(e=>"medium"===e.severity).length},byType:e.reduce((e,t)=>(e[t.type]=(e[t.type]||0)+1,e),{})}}}module.exports=SecretScanner;
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),EventEmitter=require("events");let FileWatcher,CodeScanner,DriftDetector,HealthChecker,AlertManager,SecretScanner;class SentinelCore extends EventEmitter{constructor(e={}){super();const t={...e};delete t.__proto__,delete t.constructor,delete t.prototype,this.config={rootPath:t.rootPath||process.cwd(),watchPatterns:t.watchPatterns||["**/*.js","**/*.ts","**/*.json"],ignorePatterns:t.ignorePatterns||["node_modules/**",".git/**","dist/**",".orion/snapshots/**"],scanIntervalHours:t.scanIntervalHours||6,dailyReportHour:t.dailyReportHour||8,weeklyReportDay:t.weeklyReportDay||1,enableRealtime:!1!==t.enableRealtime,enableScheduled:!1!==t.enableScheduled,alertThreshold:t.alertThreshold||"warning"},this.state={isRunning:!1,lastFullScan:null,lastHealthCheck:null,lastDriftCheck:null,filesWatched:0,issuesFound:[],metrics:{totalScans:0,issuesDetected:0,issuesResolved:0,averageScanTime:0}},this.components={fileWatcher:null,codeScanner:null,driftDetector:null,healthChecker:null,alertManager:null},this.scheduledJobs=[]}async initialize(){console.log("[SENTINEL] Initializing Sentinel Core...");try{return FileWatcher=require("./file-watcher.js"),CodeScanner=require("./code-scanner.js"),DriftDetector=require("./drift-detector.js"),HealthChecker=require("./health-checker.js"),AlertManager=require("./alert-manager.js"),SecretScanner=require("./secret-scanner.js"),this.components.fileWatcher=new FileWatcher(this.config),this.components.codeScanner=new CodeScanner(this.config),this.components.driftDetector=new DriftDetector(this.config),this.components.healthChecker=new HealthChecker(this.config),this.components.alertManager=new AlertManager(this.config),this.components.secretScanner=new SecretScanner(this.config),this._setupEventHandlers(),console.log("[SENTINEL] All components initialized"),{success:!0}}catch(e){return console.error("[SENTINEL] Initialization failed"),{success:!1,error:"Initialization failed"}}}async start(){if(this.state.isRunning)return console.log("[SENTINEL] Already running"),{success:!0,message:"Already running"};console.log("[SENTINEL] Starting Sentinel monitoring...");try{this.config.enableRealtime&&this.components.fileWatcher&&(await this.components.fileWatcher.start(),this.state.filesWatched=this.components.fileWatcher.getWatchedCount()),this.config.enableScheduled&&this._setupScheduledJobs(),await this.runHealthCheck();const e=await this.runFullScan();return this.state.isRunning=!0,this.emit("started",{timestamp:(new Date).toISOString()}),console.log("[SENTINEL] Monitoring active"),console.log(`[SENTINEL] Watching ${this.state.filesWatched} files`),console.log(`[SENTINEL] Initial scan found ${e.issues?.length||0} issues`),{success:!0,filesWatched:this.state.filesWatched,initialIssues:e.issues?.length||0}}catch(e){return console.error("[SENTINEL] Start failed"),{success:!1,error:"Start failed"}}}async stop(){return this.state.isRunning?(console.log("[SENTINEL] Stopping Sentinel monitoring..."),this.components.fileWatcher&&await this.components.fileWatcher.stop(),this.scheduledJobs.forEach(e=>clearInterval(e)),this.scheduledJobs=[],this.state.isRunning=!1,this.emit("stopped",{timestamp:(new Date).toISOString()}),console.log("[SENTINEL] Monitoring stopped"),{success:!0}):{success:!0,message:"Not running"}}async runFullScan(e={}){const t=Date.now();console.log("[SENTINEL] Starting full codebase scan...");const s={timestamp:(new Date).toISOString(),duration:0,filesScanned:0,issues:[],summary:{}};try{if(!this.components.codeScanner)throw new Error("Code scanner not initialized");const e=await this.components.codeScanner.scanAll();if(s.filesScanned=e.filesScanned||0,s.issues.push(...e.issues||[]),this.components.secretScanner){const e=await this.components.secretScanner.scanAll();s.filesScanned+=e.filesScanned||0,s.issues.push(...e.issues||[])}if(this.components.driftDetector){const e=await this.components.driftDetector.detectAll();s.issues.push(...e.issues||[]),this.state.lastDriftCheck=(new Date).toISOString()}return s.duration=Date.now()-t,this.state.lastFullScan=s.timestamp,this.state.metrics.totalScans++,this.state.metrics.issuesDetected+=s.issues.length,this.state.metrics.averageScanTime=(this.state.metrics.averageScanTime*(this.state.metrics.totalScans-1)+s.duration)/this.state.metrics.totalScans,s.summary=this._generateScanSummary(s.issues),this.state.issuesFound=s.issues,await this._processIssues(s.issues),console.log(`[SENTINEL] Scan complete: ${s.filesScanned} files, ${s.issues.length} issues, ${s.duration}ms`),this.emit("scanComplete",s),s}catch(e){return console.error("[SENTINEL] Full scan failed"),s.error="Scan failed",s}}async runQuickScan(e){if(!this.components.codeScanner)return{success:!1,error:"Code scanner not initialized"};console.log(`[SENTINEL] Quick scan on ${e.length} files...`);const t=await this.components.codeScanner.scanFiles(e);return t.issues&&t.issues.length>0&&await this._processIssues(t.issues),t}async runHealthCheck(){if(console.log("[SENTINEL] Running health check..."),!this.components.healthChecker)return{success:!1,error:"Health checker not initialized"};const e=await this.components.healthChecker.checkAll();return this.state.lastHealthCheck=(new Date).toISOString(),e.unhealthySystems&&e.unhealthySystems.length>0&&await(this.components.alertManager?.sendAlert({level:"warning",title:"System Health Issues Detected",message:`${e.unhealthySystems.length} systems are unhealthy`,details:e.unhealthySystems})),this.emit("healthCheck",e),e}async generateDailyDigest(){console.log("[SENTINEL] Generating daily digest...");const e={date:(new Date).toISOString().split("T")[0],timestamp:(new Date).toISOString(),summary:{issuesFound:this.state.issuesFound.length,criticalIssues:this.state.issuesFound.filter(e=>"critical"===e.severity).length,warningIssues:this.state.issuesFound.filter(e=>"warning"===e.severity).length,filesWatched:this.state.filesWatched,lastScan:this.state.lastFullScan,lastHealthCheck:this.state.lastHealthCheck},topIssues:this.state.issuesFound.sort((e,t)=>this._severityScore(t.severity)-this._severityScore(e.severity)).slice(0,10),metrics:this.state.metrics,recommendations:this._generateRecommendations()};return this.components.alertManager&&await this.components.alertManager.sendDigest(e),this.emit("dailyDigest",e),e}async generateWeeklyReport(){console.log("[SENTINEL] Generating weekly report...");const e={weekOf:(new Date).toISOString().split("T")[0],timestamp:(new Date).toISOString(),summary:this.state.metrics,issuesTrend:this._calculateTrend(),codeQuality:await this._assessCodeQuality(),technicalDebt:await this._assessTechnicalDebt(),recommendations:this._generateRecommendations(),fullIssueList:this.state.issuesFound};return this.components.alertManager&&await this.components.alertManager.sendWeeklyReport(e),this.emit("weeklyReport",e),e}getStatus(){return{isRunning:this.state.isRunning,config:this.config,state:{...this.state,componentsLoaded:{fileWatcher:!!this.components.fileWatcher,codeScanner:!!this.components.codeScanner,driftDetector:!!this.components.driftDetector,healthChecker:!!this.components.healthChecker,alertManager:!!this.components.alertManager}},uptime:this.state.isRunning?Date.now()-new Date(this.state.lastFullScan).getTime():0}}_setupEventHandlers(){this.components.fileWatcher&&(this.components.fileWatcher.on("change",async e=>{console.log(`[SENTINEL] File changed: ${e.filePath}`),await this.runQuickScan([e.filePath])}),this.components.fileWatcher.on("error",e=>{console.error("[SENTINEL] File watcher error:",e)})),this.components.codeScanner&&this.components.codeScanner.on("issueFound",async e=>{await this._processIssues([e])})}_setupScheduledJobs(){const e=60*this.config.scanIntervalHours*60*1e3;this.scheduledJobs.push(setInterval(()=>this.runFullScan(),e)),this.scheduledJobs.push(setInterval(()=>this.runHealthCheck(),36e5)),this.scheduledJobs.push(setInterval(()=>{const e=new Date;e.getHours()===this.config.dailyReportHour&&e.getMinutes()<5&&this.generateDailyDigest()},36e5)),this.scheduledJobs.push(setInterval(()=>{const e=new Date;e.getDay()===this.config.weeklyReportDay&&e.getHours()===this.config.dailyReportHour&&e.getMinutes()<5&&this.generateWeeklyReport()},36e5)),console.log(`[SENTINEL] Scheduled jobs: scan every ${this.config.scanIntervalHours}h, daily digest at ${this.config.dailyReportHour}:00`)}async _processIssues(e){for(const t of e)this._meetsThreshold(t.severity)&&this.components.alertManager&&await this.components.alertManager.sendAlert({level:t.severity,title:`[${t.category}] ${t.title||t.message}`,message:t.message,file:t.file,line:t.line,details:t})}_meetsThreshold(e){const t=["info","warning","error","critical"];return t.indexOf(e)>=t.indexOf(this.config.alertThreshold)}_severityScore(e){return{info:1,warning:2,error:3,critical:4}[e]||0}_generateScanSummary(e){return{total:e.length,bySeverity:{critical:e.filter(e=>"critical"===e.severity).length,error:e.filter(e=>"error"===e.severity).length,warning:e.filter(e=>"warning"===e.severity).length,info:e.filter(e=>"info"===e.severity).length},byCategory:e.reduce((e,t)=>(e[t.category]=(e[t.category]||0)+1,e),{})}}_generateRecommendations(){const e=[],t=this.state.issuesFound,s=t.filter(e=>"security"===e.category);s.length>0&&e.push({priority:"high",category:"security",message:`Address ${s.length} security issues before deploying`,issues:s.slice(0,5)});const n=t.filter(e=>"quality"===e.category);n.length>10&&e.push({priority:"medium",category:"quality",message:`Consider refactoring - ${n.length} quality issues detected`,issues:n.slice(0,5)});const i=t.filter(e=>"drift"===e.category);return i.length>0&&e.push({priority:"medium",category:"drift",message:`${i.length} files have drifted from their declared contracts`,issues:i.slice(0,5)}),e}_calculateTrend(){return{direction:"stable",change:0,note:"Trend analysis requires historical data"}}async _assessCodeQuality(){return{score:75,grade:"B",factors:{complexity:70,maintainability:80,documentation:65,testCoverage:40}}}async _assessTechnicalDebt(){return{estimatedHours:40,categories:{refactoring:20,documentation:10,testing:10},priorityItems:[]}}}function createSentinel(e={}){return new SentinelCore(e)}async function main(){const e=createSentinel({rootPath:path.resolve(__dirname,".."),enableRealtime:!0,enableScheduled:!1}),t=await e.initialize();t.success||(console.error("Failed to initialize Sentinel:",t.error),process.exit(1)),await e.start(),console.log("Sentinel status:",e.getStatus()),process.on("SIGINT",async()=>{console.log("\nShutting down Sentinel..."),await e.stop(),process.exit(0)})}require.main===module&&main().catch(console.error),module.exports={SentinelCore:SentinelCore,createSentinel:createSentinel};
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),https=require("https"),crypto=require("crypto"),{readJsonSafe:readJsonSafe}=require("./json-file-util.js"),PERMISSIVE_LICENSES=new Set(["MIT","ISC","BSD-2-Clause","BSD-3-Clause","BSD-3-Clause-Clear","BSD-4-Clause","0BSD","Apache-2.0","Unlicense","CC0-1.0","Python-2.0","Zlib","WTFPL","Artistic-2.0","PostgreSQL","blessing","CC-BY-4.0","CC-BY-3.0","OFL-1.1"]),WEAK_COPYLEFT_LICENSES=new Set(["LGPL-2.0","LGPL-2.0-only","LGPL-2.0-or-later","LGPL-2.1","LGPL-2.1-only","LGPL-2.1-or-later","LGPL-3.0","LGPL-3.0-only","LGPL-3.0-or-later","MPL-1.1","MPL-2.0","EPL-1.0","EPL-2.0","CDDL-1.0","CDDL-1.1"]),STRONG_COPYLEFT_LICENSES=new Set(["GPL-1.0","GPL-1.0-only","GPL-1.0-or-later","GPL-2.0","GPL-2.0-only","GPL-2.0-or-later","GPL-3.0","GPL-3.0-only","GPL-3.0-or-later","AGPL-1.0","AGPL-1.0-only","AGPL-1.0-or-later","AGPL-3.0","AGPL-3.0-only","AGPL-3.0-or-later","SSPL-1.0","OSL-3.0"]),UNLICENSED_MARKERS=new Set(["UNLICENSED","UNLICENCED","NONE","NOASSERTION","PROPRIETARY"]);function classifyLicense(e){if(!e||"string"!=typeof e||!e.trim())return"unknown";const t=e.trim();if(UNLICENSED_MARKERS.has(t.toUpperCase()))return"unlicensed";if(/see license in/i.test(t))return"unlicensed";const n=t.replace(/[()]/g," ").split(/\s+(?:OR|AND|WITH)\s+/i).map(e=>e.trim()).filter(Boolean);let s="unknown";const o={unknown:0,permissive:1,"weak-copyleft":2,copyleft:3,unlicensed:3};for(const e of n){let t;t=STRONG_COPYLEFT_LICENSES.has(e)?"copyleft":WEAK_COPYLEFT_LICENSES.has(e)?"weak-copyleft":PERMISSIVE_LICENSES.has(e)?"permissive":UNLICENSED_MARKERS.has(e.toUpperCase())?"unlicensed":"unknown",o[t]>o[s]&&(s=t)}return s}function httpsRequestJSON(e,{method:t="GET",body:n=null,headers:s={},timeout:o=1e4}={}){return new Promise(r=>{let i;try{i=new URL(e)}catch{return r({ok:!1,status:0,error:"invalid URL",data:null})}const a=n?JSON.stringify(n):null,c={hostname:i.hostname,port:443,path:i.pathname+i.search,method:t,headers:Object.assign(a?{"Content-Type":"application/json","Content-Length":Buffer.byteLength(a)}:{},{"User-Agent":"thuban-supply-chain-scanner"},s),timeout:o},l=https.request(c,e=>{let t="";e.on("data",e=>{t+=e}),e.on("end",()=>{if(e.statusCode<200||e.statusCode>=300)return r({ok:!1,status:e.statusCode,error:`HTTP ${e.statusCode}`,data:null});try{r({ok:!0,status:e.statusCode,data:JSON.parse(t)})}catch(t){r({ok:!1,status:e.statusCode,error:`JSON parse error: ${t.message}`,data:null})}})});l.on("timeout",()=>{l.destroy(),r({ok:!1,status:0,error:"timeout",data:null})}),l.on("error",e=>r({ok:!1,status:0,error:e.message,data:null})),a&&l.write(a),l.end()})}async function withConcurrency(e,t,n){const s=new Array(e.length);let o=0;async function r(){for(;o<e.length;){const t=o++;s[t]=await n(e[t],t)}}const i=[];for(let n=0;n<Math.min(t,Math.max(e.length,1));n++)i.push(r());return await Promise.all(i),s}function chunk(e,t){const n=[];for(let s=0;s<e.length;s+=t)n.push(e.slice(s,s+t));return n}function parseSemver(e){if(!e||"string"!=typeof e)return null;const t=e.trim().replace(/^[\^~=vV]+/,""),n=/^(\d+)\.(\d+)\.(\d+)/.exec(t);return n?{major:parseInt(n[1],10),minor:parseInt(n[2],10),patch:parseInt(n[3],10)}:null}function compareSemver(e,t){const n=parseSemver(e),s=parseSemver(t);return n&&s?n.major!==s.major?n.major-s.major:n.minor!==s.minor?n.minor-s.minor:n.patch-s.patch:0}const KNOWN_MALICIOUS_NPM=new Map([["event-stream",{versions:["3.3.6"],reason:"Injected flatmap-stream dependency harvesting Copay wallet credentials (2018)"}],["flatmap-stream",{versions:["0.1.1"],reason:"Malicious payload injected into event-stream dependency chain (2018)"}],["eslint-scope",{versions:["3.7.2"],reason:"Compromised npm account published version stealing npm tokens (2018)"}],["rc",{versions:["1.3.9"],reason:"Supply-chain compromise injecting crypto-clipper malware (Sept 2025 npm incident)"}],["coa",{versions:["2.0.3","2.0.4","2.1.1","2.1.3","3.0.1","3.1.3"],reason:"Compromised maintainer account published credential-stealing payload"}],["ua-parser-js",{versions:["0.7.29","0.8.0","1.0.0"],reason:"Compromised maintainer account published cryptominer/password-stealer (Oct 2021)"}],["node-ipc",{versions:["10.1.1","10.1.2","9.2.2"],reason:'"Protestware" — destructive file-wiping payload targeting Russian/Belarusian IPs (2022)'}],["colors",{versions:["1.4.1"],reason:"Maintainer sabotage — infinite loop / non-ASCII spam payload (Jan 2022)"}],["faker",{versions:["6.6.6"],reason:"Maintainer sabotage — corrupted package output (Jan 2022)"}]]),KNOWN_MALICIOUS_PYPI=new Map([["requests-darwin-lite",{versions:null,reason:"Typosquat of requests exfiltrating credentials"}],["python3-dateutil",{versions:null,reason:"Typosquat of python-dateutil dropping malicious payload (2019)"}],["jeIlyfish",{versions:null,reason:"Typosquat of jellyfish (2019 PyPI typosquat campaign)"}]]),POPULAR_NPM_PACKAGES=["react","react-dom","lodash","express","axios","chalk","commander","debug","request","moment","webpack","babel","eslint","jest","typescript","next","vue","angular","jquery","underscore","async","colors","yargs","inquirer","mongoose","redis","mysql","pg","socket.io","bcrypt","jsonwebtoken","dotenv","cors","body-parser","nodemon","prettier","rimraf","glob","semver","uuid","node-fetch","form-data","qs","minimist","tar","ini","ansi-styles","strip-ansi"];function levenshtein(e,t){if(e===t)return 0;const n=e.length,s=t.length;if(0===n)return s;if(0===s)return n;const o=new Array(s+1);for(let e=0;e<=s;e++)o[e]=e;for(let r=1;r<=n;r++){let n=o[0];o[0]=r;for(let i=1;i<=s;i++){const s=o[i];o[i]=e[r-1]===t[i-1]?n:1+Math.min(n,o[i],o[i-1]),n=s}}return o[s]}const KNOWN_LEGITIMATE_PACKAGES=new Set(["esquery","acorn","espree","estree","eslint-visitor-keys"]);function suspectedTyposquat(e,t){if("npm"!==t)return null;if(e.startsWith("@"))return null;const n=e;if(POPULAR_NPM_PACKAGES.includes(n))return null;if(KNOWN_LEGITIMATE_PACKAGES.has(n))return null;for(const e of POPULAR_NPM_PACKAGES){const t=levenshtein(n,e);if(0!==t&&(t<=(Math.min(n.length,e.length)>=8?2:1)&&Math.abs(n.length-e.length)<=2))return`Name closely resembles popular package "${e}" (edit distance ${t}) — verify this is the intended dependency`}return null}const OSV_ECOSYSTEM_MAP={npm:"npm",pypi:"PyPI",go:"Go",cargo:"crates.io"};async function osvBatchQuery(e,{timeout:t=15e3}={}){const n=new Map;if(0===e.length)return n;const s=chunk(e,500);for(const e of s){const s=e.map(e=>({package:{name:e.name,ecosystem:OSV_ECOSYSTEM_MAP[e.ecosystem]||e.ecosystem},version:e.version})),o=await httpsRequestJSON("https://api.osv.dev/v1/querybatch",{method:"POST",body:{queries:s},timeout:t});o.ok&&o.data&&Array.isArray(o.data.results)&&o.data.results.forEach((t,s)=>{const o=e[s],r=`${o.ecosystem}:${o.name}@${o.version}`;n.set(r,(t.vulns||[]).map(e=>e.id))})}return n}async function osvResolveIds(e,{concurrency:t=10,timeout:n=1e4}={}){const s=[...new Set(e)],o=new Map;return await withConcurrency(s,t,async e=>{const t=await httpsRequestJSON(`https://api.osv.dev/v1/vulns/${encodeURIComponent(e)}`,{timeout:n});t.ok&&t.data&&o.set(e,t.data)}),o}function osvSeverityLabel(e){const t=e?.database_specific?.severity;if(t){const e=String(t).toUpperCase();if("MODERATE"===e)return"MEDIUM";if(["CRITICAL","HIGH","MEDIUM","LOW"].includes(e))return e}const n=(e?.severity||[]).find(e=>/CVSS/i.test(e.type));if(n&&"string"==typeof n.score){const e=/\/A:(N|L|H)/.exec(n.score)||/\/C:(N|L|H)/.exec(n.score);if(e){if("H"===e[1])return"HIGH";if("L"===e[1])return"MEDIUM"}}return"UNKNOWN"}function osvFixedVersion(e,t,n){const s=OSV_ECOSYSTEM_MAP[t]||t;for(const t of e.affected||[])if(t.package&&t.package.ecosystem===s&&t.package.name===n)for(const e of t.ranges||[]){if("SEMVER"!==e.type&&"ECOSYSTEM"!==e.type)continue;const t=(e.events||[]).filter(e=>e.fixed);if(t.length)return t[t.length-1].fixed}return null}const registryCache=new Map;function npmRegistryLookup(e){const t=`npm:${e}`;if(registryCache.has(t))return registryCache.get(t);const n=(async()=>{const t=await httpsRequestJSON(`https://registry.npmjs.org/${encodeURIComponent(e).replace("%40","@")}`,{timeout:1e4});if(!t.ok||!t.data)return null;const n=t.data,s=n["dist-tags"]?.latest||null,o=s?n.versions?.[s]:null;return{latest:s,license:o?.license?.type||o?.license||n.license?.type||n.license||null,deprecated:!!o?.deprecated}})();return registryCache.set(t,n),n}function pypiRegistryLookup(e){const t=`pypi:${e}`;if(registryCache.has(t))return registryCache.get(t);const n=(async()=>{const t=await httpsRequestJSON(`https://pypi.org/pypi/${encodeURIComponent(e)}/json`,{timeout:1e4});if(!t.ok||!t.data)return null;const n=t.data.info||{};let s=n.license&&n.license.trim()?n.license.trim():null;if(!s||s.length>100){const e=(n.classifiers||[]).find(e=>e.startsWith("License :: OSI Approved ::"));e?s=e.split("::").pop().trim():s&&s.length>100&&(s=null)}return{latest:n.version||null,license:s,deprecated:!1}})();return registryCache.set(t,n),n}function cratesRegistryLookup(e){const t=`cargo:${e}`;if(registryCache.has(t))return registryCache.get(t);const n=(async()=>{const t=await httpsRequestJSON(`https://crates.io/api/v1/crates/${encodeURIComponent(e)}`,{timeout:1e4,headers:{"User-Agent":"thuban-supply-chain-scanner (https://thuban.dev)"}});if(!t.ok||!t.data||!t.data.crate)return null;const n=t.data.versions||[],s=n.find(e=>e.num===t.data.crate.max_stable_version)||n[0];return{latest:t.data.crate.max_stable_version||null,license:s?.license||null,deprecated:!!s?.yanked}})();return registryCache.set(t,n),n}function goProxyLookup(e){const t=`go:${e}`;if(registryCache.has(t))return registryCache.get(t);const n=(async()=>{const t=e.split("/").map(e=>e.replace(/[A-Z]/g,e=>"!"+e.toLowerCase())).join("/"),n=await httpsRequestJSON(`https://proxy.golang.org/${t}/@latest`,{timeout:1e4});return n.ok&&n.data?{latest:n.data.Version||null,license:null,deprecated:!1}:null})();return registryCache.set(t,n),n}function registryLookup(e,t){return"npm"===e?npmRegistryLookup(t):"pypi"===e?pypiRegistryLookup(t):"cargo"===e?cratesRegistryLookup(t):"go"===e?goProxyLookup(t):Promise.resolve(null)}function readJSONSafe(e){return readJsonSafe(e,null)}function readTextSafe(e){try{return fs.readFileSync(e,"utf-8")}catch{return null}}function integrityToHex(e){if(!e||"string"!=typeof e)return null;const t=/^sha(?:256|384|512)-([A-Za-z0-9+/=]+)$/.exec(e.split(" ")[0]);if(!t)return null;try{return Buffer.from(t[1],"base64").toString("hex")}catch{return null}}function integrityAlgo(e){return e?e.startsWith("sha512-")?"SHA-512":e.startsWith("sha384-")?"SHA-384":e.startsWith("sha256-")?"SHA-256":null:null}function parseNpmProject(e,t){const n=readJSONSafe(path.join(e,"package.json"));if(!n)return[];const s=new Set([...Object.keys(n.dependencies||{}),...Object.keys(n.devDependencies||{}),...Object.keys(n.optionalDependencies||{}),...Object.keys(n.peerDependencies||{})]),o=new Set(Object.keys(n.devDependencies||{})),r=readJSONSafe(path.join(e,"package-lock.json")),i=[];if(r&&r.lockfileVersion>=2&&r.packages)for(const[e,t]of Object.entries(r.packages)){if(""===e||!e.includes("node_modules/"))continue;if(!t||!t.version)continue;const n=e.lastIndexOf("node_modules/"),r=e.slice(n+13),a=1===(e.match(/node_modules\//g)||[]).length&&s.has(r);i.push({name:r,version:t.version,ecosystem:"npm",direct:a,dev:!!t.dev||a&&o.has(r),license:t.license||null,resolved:t.resolved||null,integrity:t.integrity||null})}else if(r&&r.dependencies){const e=(t,n)=>{for(const[o,r]of Object.entries(t||{}))i.push({name:o,version:r.version,ecosystem:"npm",direct:0===n&&s.has(o),dev:!!r.dev,license:null,resolved:r.resolved||null,integrity:r.integrity||null}),r.dependencies&&e(r.dependencies,n+1)};e(r.dependencies,0)}else if(!t){for(const[e,t]of Object.entries(n.dependencies||{}))i.push({name:e,version:t.replace(/^[\^~]/,""),versionRange:t,ecosystem:"npm",direct:!0,dev:!1,license:null,unresolved:!0});for(const[e,t]of Object.entries(n.devDependencies||{}))i.push({name:e,version:t.replace(/^[\^~]/,""),versionRange:t,ecosystem:"npm",direct:!0,dev:!0,license:null,unresolved:!0})}const a=new Map;for(const e of i){const t=`${e.name}@${e.version}`,n=a.get(t);(!n||e.direct&&!n.direct)&&a.set(t,e)}return[...a.values()]}function parseYarnLock(e,t,n){const s=readTextSafe(path.join(e,"yarn.lock"));if(!s)return[];const o=[],r=s.split(/\n\n+/);for(const e of r){const s=e.split("\n"),r=s[0];if(!r||r.startsWith("#")||!r.includes(":"))continue;const i=s.find(e=>/^\s+version\s+"?/.test(e));if(!i)continue;const a=/"([^"]+)"/.exec(i)||/version\s+(\S+)/.exec(i);if(!a)continue;const c=a[1],l=s.find(e=>/^\s+resolved\s+/.test(e)),u=l?(/"([^"]+)"/.exec(l)||[])[1]:null,p=s.find(e=>/^\s+integrity\s+/.test(e)),d=p?p.replace(/^\s*integrity\s+/,"").trim():null,m=r.replace(/:$/,"").split(",").map(e=>e.trim().replace(/^"|"$/g,"")),h=new Set;for(const e of m){const t=e.lastIndexOf("@"),n=t>0?e.slice(0,t):e;h.add(n)}for(const e of h)o.push({name:e,version:c,ecosystem:"npm",direct:t.has(e),dev:n.has(e),license:null,resolved:u,integrity:d})}return o}function parsePnpmLock(e,t,n){const s=readTextSafe(path.join(e,"pnpm-lock.yaml"));if(!s)return[];const o=[],r=s.split("\n");let i=!1;for(const e of r){if(/^packages:\s*$/.test(e)){i=!0;continue}if(i&&/^\S/.test(e)&&(i=!1),!i)continue;const s=/^\s{2}'?\/?((?:@[^/]+\/)?[^@'\s]+)@([^'\s:]+)'?:/.exec(e);if(!s)continue;const[,r,a]=s;o.push({name:r,version:a.split("(")[0],ecosystem:"npm",direct:t.has(r),dev:n.has(r),license:null,resolved:null,integrity:null})}const a=new Map;for(const e of o)a.set(`${e.name}@${e.version}`,e);return[...a.values()]}function parseRequirementsTxt(e){const t=readTextSafe(path.join(e,"requirements.txt"));if(!t)return[];const n=[];for(const e of t.split("\n")){const t=e.split("#")[0].trim();if(!t||t.startsWith("-"))continue;const s=/^([A-Za-z0-9._-]+)\s*(==|>=|<=|~=|!=)?\s*([A-Za-z0-9.*+!-]*)/.exec(t);if(!s)continue;const[,o,r,i]=s;n.push({name:o,version:"=="===r&&i?i:i||null,ecosystem:"pypi",direct:!0,dev:!1,license:null,unresolved:"=="!==r})}return n}function parsePipfileLock(e){const t=readJSONSafe(path.join(e,"Pipfile.lock"));if(!t)return[];const n=[],s=[["default",!1],["develop",!0]];for(const[e,o]of s)for(const[s,r]of Object.entries(t[e]||{})){const e=(r.version||"").replace(/^==/,"");e&&n.push({name:s,version:e,ecosystem:"pypi",direct:!0,dev:o,license:null,integrity:(r.hashes||[])[0]||null})}return n}function parseGoModDirects(e){const t=readTextSafe(path.join(e,"go.mod")),n=new Set;if(!t)return n;const s=/require\s*\(([\s\S]*?)\)/.exec(t),o=s?s[1].split("\n"):[],r=t.split("\n").filter(e=>/^require\s+\S/.test(e.trim()));for(const e of[...o,...r]){const t=e.replace(/^require\s+/,"").trim();if(!t||t.includes("// indirect"))continue;const s=/^(\S+)\s+(\S+)/.exec(t);s&&n.add(s[1])}return n}function parseGoSum(e){const t=readTextSafe(path.join(e,"go.sum"));if(!t)return[];const n=parseGoModDirects(e),s=new Map;for(const e of t.split("\n")){const t=e.trim().split(/\s+/);if(t.length<2)continue;const[o,r]=t;if(r.endsWith("/go.mod"))continue;const i=r.replace(/^v/,"");s.set(`${o}@${i}`,{name:o,version:i,ecosystem:"go",direct:n.has(o),dev:!1,license:null})}return[...s.values()]}function parseCargoTomlDirects(e){const t=readTextSafe(path.join(e,"Cargo.toml")),n=new Set;if(!t)return n;let s=!1;for(const e of t.split("\n")){const t=e.trim();if(/^\[(dependencies|dev-dependencies|build-dependencies)\]/.test(t)){s=!0;continue}if(/^\[/.test(t)){s=!1;continue}if(!s||!t||t.startsWith("#"))continue;const o=/^([A-Za-z0-9_-]+)\s*=/.exec(t);o&&n.add(o[1])}return n}function parseCargoLock(e){const t=readTextSafe(path.join(e,"Cargo.lock"));if(!t)return[];const n=parseCargoTomlDirects(e),s=[],o=t.split("[[package]]").slice(1);for(const e of o){const t=/name\s*=\s*"([^"]+)"/.exec(e),o=/version\s*=\s*"([^"]+)"/.exec(e),r=/checksum\s*=\s*"([^"]+)"/.exec(e);t&&o&&s.push({name:t[1],version:o[1],ecosystem:"cargo",direct:n.has(t[1]),dev:!1,license:null,integrity:r?r[1]:null})}return s}function toPurl(e,t,n){return`pkg:${{npm:"npm",pypi:"pypi",go:"golang",cargo:"cargo"}[e]||e}/${t.startsWith("@")?t.replace("@","%40"):t}@${n}`}class SupplyChainAnalyzer{constructor(e={}){this.rootPath=e.rootPath||process.cwd(),this.offline=!!e.offline,this.concurrency=e.concurrency||20,this.timeoutMs=e.timeoutMs||15e3}detectEcosystems(){const e=e=>fs.existsSync(path.join(this.rootPath,e));return{npm:e("package.json"),pypi:e("requirements.txt")||e("Pipfile.lock"),go:e("go.sum"),cargo:e("Cargo.lock")}}collectPackages(){const e=[],t=readJSONSafe(path.join(this.rootPath,"package.json"));if(fs.existsSync(path.join(this.rootPath,"package.json"))){const n=fs.existsSync(path.join(this.rootPath,"package-lock.json")),s=fs.existsSync(path.join(this.rootPath,"yarn.lock")),o=fs.existsSync(path.join(this.rootPath,"pnpm-lock.yaml")),r=parseNpmProject(this.rootPath,!n&&(s||o));if(e.push(...r),!n&&t){const n=new Set([...Object.keys(t.dependencies||{}),...Object.keys(t.devDependencies||{})]),r=new Set(Object.keys(t.devDependencies||{}));s?e.push(...parseYarnLock(this.rootPath,n,r)):o&&e.push(...parsePnpmLock(this.rootPath,n,r))}}return fs.existsSync(path.join(this.rootPath,"Pipfile.lock"))?e.push(...parsePipfileLock(this.rootPath)):fs.existsSync(path.join(this.rootPath,"requirements.txt"))&&e.push(...parseRequirementsTxt(this.rootPath)),fs.existsSync(path.join(this.rootPath,"go.sum"))&&e.push(...parseGoSum(this.rootPath)),fs.existsSync(path.join(this.rootPath,"Cargo.lock"))&&e.push(...parseCargoLock(this.rootPath)),e}async analyze(){const e=this.collectPackages(),t=e.filter(e=>e.version&&!e.unresolved);let n=new Map,s=new Map,o=!0;if(!this.offline&&t.length>0)try{n=await osvBatchQuery(t.map(e=>({name:e.name,version:e.version,ecosystem:e.ecosystem})),{timeout:this.timeoutMs});const e=[...n.values()].flat();s=await osvResolveIds(e,{concurrency:this.concurrency,timeout:this.timeoutMs})}catch{o=!1}else t.length>0&&(o=!1);const r=new Map;for(const t of e)r.set(`${t.ecosystem}:${t.name}`,{ecosystem:t.ecosystem,name:t.name});const i=new Map;this.offline||await withConcurrency([...r.values()],this.concurrency,async({ecosystem:e,name:t})=>{try{const n=await registryLookup(e,t);n&&i.set(`${e}:${t}`,n)}catch{}});const a=[];for(const t of e){const e=`${t.ecosystem}:${t.name}`,o=i.get(e),r=t.license||o?.license||null,c=classifyLicense(r),l=`${t.ecosystem}:${t.name}@${t.version}`,u=n.get(l)||[],p=[],d=[];for(const e of u){const n=s.get(e);/^MAL-/.test(e)?d.push(n?.summary||`Flagged malicious by OSV (${e})`):n?p.push({id:e,severity:osvSeverityLabel(n),summary:n.summary||null,fixedVersion:osvFixedVersion(n,t.ecosystem,t.name),aliases:n.aliases||[]}):p.push({id:e,severity:"UNKNOWN",summary:null,fixedVersion:null,aliases:[]})}const m="npm"===t.ecosystem?KNOWN_MALICIOUS_NPM.get(t.name):"pypi"===t.ecosystem?KNOWN_MALICIOUS_PYPI.get(t.name):null;!m||m.versions&&!m.versions.includes(t.version)||d.push(m.reason);const h=0===d.length?suspectedTyposquat(t.name,t.ecosystem):null,f=o?.latest||null,y=!!(f&&t.version&&compareSemver(t.version,f)<0),g=parseSemver(t.version)?.major,v=parseSemver(f)?.major,S=y&&"number"==typeof g&&"number"==typeof v?Math.max(0,v-g):0,C=p.reduce((e,t)=>{const n={CRITICAL:4,HIGH:3,MEDIUM:2,LOW:1,UNKNOWN:0};return(n[t.severity]||0)>(n[e]||0)?t.severity:e},"UNKNOWN");let P="none";d.length>0||"CRITICAL"===C?P="critical":"HIGH"===C?P="high":"MEDIUM"===C?P="medium":"LOW"===C||p.length>0?P="low":"copyleft"===c?P="medium":("unlicensed"===c||h)&&(P="low"),a.push({name:t.name,version:t.version,ecosystem:t.ecosystem,direct:!!t.direct,dev:!!t.dev,license:r,licenseCategory:c,latestVersion:f,outdated:y,majorVersionsBehind:S,deprecated:!!o?.deprecated,cves:p,malicious:d.length>0,maliciousReasons:d,suspectedTyposquat:h,riskLevel:P,resolved:t.resolved||null,integrity:t.integrity||null,purl:toPurl(t.ecosystem,t.name,t.version)})}a.sort((e,t)=>{const n={critical:4,high:3,medium:2,low:1,none:0};return n[t.riskLevel]-n[e.riskLevel]||e.name.localeCompare(t.name)});const c=this._buildSummary(a,o);return{generatedAt:(new Date).toISOString(),rootPath:this.rootPath,ecosystemsDetected:Object.entries(this.detectEcosystems()).filter(([,e])=>e).map(([e])=>e),networkAvailable:o,packages:a,summary:c}}_buildSummary(e,t){const n=e.filter(e=>e.direct),s=e.filter(e=>!e.direct),o=e.flatMap(e=>e.cves.map(t=>({...t,package:e.name,version:e.version}))),r={CRITICAL:0,HIGH:0,MEDIUM:0,LOW:0,UNKNOWN:0};for(const e of o)r[e.severity]=(r[e.severity]||0)+1;const i={permissive:0,"weak-copyleft":0,copyleft:0,unlicensed:0,unknown:0};for(const t of e)i[t.licenseCategory]=(i[t.licenseCategory]||0)+1;const a=e.filter(e=>e.malicious),c=e.filter(e=>!e.malicious&&e.suspectedTyposquat),l=e.filter(e=>e.outdated),u=e.filter(e=>e.deprecated),p=e.filter(e=>"copyleft"===e.licenseCategory||"weak-copyleft"===e.licenseCategory),d=e.filter(e=>"unlicensed"===e.licenseCategory||"unknown"===e.licenseCategory);return{totalDirect:n.length,totalTransitive:s.length,totalPackages:e.length,totalCVEs:o.length,criticalCVEs:r.CRITICAL,highCVEs:r.HIGH,mediumCVEs:r.MEDIUM,lowCVEs:r.LOW,unknownSeverityCVEs:r.UNKNOWN,maliciousCount:a.length,suspectedTyposquatCount:c.length,outdatedCount:l.length,majorVersionsBehindCount:l.filter(e=>e.majorVersionsBehind>0).length,deprecatedCount:u.length,licenseBreakdown:i,copyleftCount:p.length,unlicensedCount:d.length,networkAvailable:t}}generateCycloneDX(e,t={}){const n=t.componentName||path.basename(this.rootPath),s=t.componentVersion||"0.0.0",o=`urn:uuid:${crypto.randomUUID()}`,r=e.packages.map(e=>{const t=integrityAlgo(e.integrity),n=integrityToHex(e.integrity),s={type:"library","bom-ref":e.purl,name:e.name,version:e.version,purl:e.purl,scope:e.dev?"excluded":"required"};return e.license&&"unknown"!==e.licenseCategory?s.licenses=[{license:{id:e.license}}]:e.license&&(s.licenses=[{license:{name:e.license}}]),t&&n&&(s.hashes=[{alg:t,content:n}]),(e.cves.length>0||e.malicious)&&(s.properties=[{name:"thuban:riskLevel",value:e.riskLevel},{name:"thuban:cveCount",value:String(e.cves.length)},{name:"thuban:malicious",value:String(e.malicious)}]),s}),i=[];for(const t of e.packages)for(const e of t.cves)i.push({id:e.id,source:{name:"OSV"},ratings:[{source:{name:"OSV"},severity:e.severity.toLowerCase()}],description:e.summary||void 0,affects:[{ref:t.purl}],...e.fixedVersion?{recommendation:`Upgrade to ${e.fixedVersion} or later`}:{}});return{bomFormat:"CycloneDX",specVersion:"1.5",serialNumber:o,version:1,metadata:{timestamp:e.generatedAt,tools:[{vendor:"Thuban",name:"Thuban Supply Chain Scanner",version:"1.0.0"}],component:{type:"application",name:n,version:s}},components:r,...i.length>0?{vulnerabilities:i}:{}}}generateSPDX(e,t={}){const n=t.componentName||path.basename(this.rootPath),s=`https://thuban.dev/spdx/${crypto.randomUUID()}`,o=e=>e.license&&/^[A-Za-z0-9.+-]+$/.test(e.license)?e.license:"NOASSERTION",r=e.packages.map((e,t)=>({SPDXID:`SPDXRef-Package-${t}-${e.name.replace(/[^A-Za-z0-9.-]/g,"-")}`,name:e.name,versionInfo:e.version,downloadLocation:e.resolved||"NOASSERTION",licenseConcluded:o(e),licenseDeclared:o(e),copyrightText:"NOASSERTION",externalRefs:[{referenceCategory:"PACKAGE-MANAGER",referenceType:"purl",referenceLocator:e.purl}]})),i=r.map(e=>({spdxElementId:"SPDXRef-DOCUMENT",relationshipType:"DESCRIBES",relatedSpdxElement:e.SPDXID}));return{spdxVersion:"SPDX-2.3",dataLicense:"CC0-1.0",SPDXID:"SPDXRef-DOCUMENT",name:`${n}-sbom`,documentNamespace:s,creationInfo:{created:e.generatedAt,creators:["Tool: Thuban-Supply-Chain-Scanner-1.0.0"]},packages:r,relationships:i}}}module.exports={SupplyChainAnalyzer:SupplyChainAnalyzer,classifyLicense:classifyLicense,toPurl:toPurl,suspectedTyposquat:suspectedTyposquat};
@@ -0,0 +1 @@
1
+ const fs=require("fs"),path=require("path"),os=require("os"),https=require("https"),{execSync:execSync}=require("child_process"),readline=require("readline"),KB=require("./support-knowledge.js"),C={reset:"",bold:"",red:"",green:"",yellow:"",blue:"",cyan:"",gray:""};function ok(e){return` ${C.green}✓${C.reset} ${e}`}function warn(e){return` ${C.yellow}⚠${C.reset} ${e}`}function fail(e){return` ${C.red}✗${C.reset} ${e}`}function safeExec(e){try{return execSync(e,{encoding:"utf8",timeout:1e4,stdio:["pipe","pipe","pipe"]}).trim()}catch{return null}}function parseSemver(e){const o=(e||"").match(/(\d+)\.(\d+)\.(\d+)/);return o?{major:Number(o[1]),minor:Number(o[2]),patch:Number(o[3])}:null}function countFiles(e){try{return fs.readdirSync(e).filter(o=>{try{return fs.statSync(path.join(e,o)).isFile()}catch{return!1}}).length}catch{return-1}}function wordOverlap(e,o){const s=new Set(e.toLowerCase().split(/\s+/).filter(Boolean)),t=new Set(o.toLowerCase().split(/\s+/).filter(Boolean));if(0===s.size||0===t.size)return 0;let n=0;for(const e of s)t.has(e)&&n++;return n/Math.max(s.size,t.size)}class SupportBot{constructor(e={}){this.rootPath=e.rootPath||process.cwd(),this.verbose=e.verbose||!1,this.smart=e.smart||!1,this._thubanVersion=null}async semanticQuery(e){const o=process.env.OPENAI_API_KEY,s=process.env.PINECONE_API_KEY;if(!o||!s){try{const o=await this._httpPost("europe-west2-orion-os-479912.cloudfunctions.net","/thuban-api/support/query",{},{query:e,topK:3});if(o.data&&o.data.results)return o.data.results}catch{}return null}try{const t=await this._httpPost("api.openai.com","/v1/embeddings",{Authorization:`Bearer ${o}`},{model:"text-embedding-3-small",input:e});if(!t.data||!t.data.data)return null;const n=t.data.data[0].embedding,r=await this._httpPost("thuban-kb-es8yjbx.svc.aped-4627-b74a.pinecone.io","/query",{"Api-Key":s},{vector:n,topK:3,includeMetadata:!0});return r.data&&r.data.matches?r.data.matches.map(e=>({score:e.score,type:e.metadata.type,...e.metadata})):null}catch(e){return this.verbose&&console.error(`${C.gray} Semantic search error: ${e.message}${C.reset}`),null}}_httpPost(e,o,s,t){return new Promise((n,r)=>{const a=JSON.stringify(t),i=https.request({hostname:e,path:o,method:"POST",timeout:1e4,headers:{...s,"Content-Type":"application/json","Content-Length":Buffer.byteLength(a)}},e=>{let o="";e.on("data",e=>o+=e),e.on("end",()=>{try{n({status:e.statusCode,data:JSON.parse(o)})}catch{n({status:e.statusCode,data:o})}})});i.on("error",r),i.on("timeout",()=>{i.destroy(),r(new Error("timeout"))}),i.write(a),i.end()})}async diagnose(){const e=[],o=[],s=[],t={},n=safeExec("node --version"),r=parseSemver(n);t.nodeVersion=n||"unknown",r&&r.major>=16?e.push(ok(`Node.js ${n} (requires >= 16)`)):r?s.push(fail(`Node.js ${n} — version 16+ required`)):s.push(fail("Node.js not found"));const a=safeExec("npm --version");t.npmVersion=a||"unknown",a?e.push(ok(`npm v${a}`)):o.push(warn("npm not found — install via Node.js installer"));const i=safeExec("git --version"),c=i?i.replace(/^git version\s*/,""):null;t.gitVersion=c||"unknown",c?e.push(ok(`Git v${c}`)):o.push(warn("Git not found — some features require Git"));const l=this._readThubanVersion();t.thubanVersion=l||"unknown",l?e.push(ok(`Thuban v${l}`)):o.push(warn("Could not determine Thuban version")),this._thubanVersion=l;const u=os.platform(),d=os.arch(),p=os.release();t.os=u,t.arch=d,t.release=p;const g=this._formatOS(u,p,d);e.push(ok(`OS: ${g}`));try{fs.accessSync(this.rootPath,fs.constants.R_OK),e.push(ok("Target path exists and is readable"))}catch{s.push(fail(`Target path not readable: ${this.rootPath}`))}const h=countFiles(this.rootPath);h>=0&&(0===h?o.push(warn("Target directory is empty")):this.verbose&&e.push(ok(`${h} file(s) in target directory`))),fs.existsSync(path.join(this.rootPath,"package.json"))?e.push(ok("package.json found")):s.push(fail("No package.json found in target directory")),this._hasCodeFiles(this.rootPath)||o.push(warn("No .js or .ts files found in target directory"));const f=this._checkDiskSpace();!1===f.ok?o.push(warn(`Low disk space: ${f.free} available`)):f.free&&this.verbose&&e.push(ok(`Disk space: ${f.free} available`)),/\s/.test(this.rootPath)&&o.push(warn("Path contains spaces — may cause issues with some commands"));try{fs.accessSync(this.rootPath,fs.constants.W_OK),this.verbose&&e.push(ok("Write permissions on target directory"))}catch{o.push(warn("No write permissions on target directory"))}const $={passed:e,warnings:o,failed:s,systemInfo:t};return this._printDiagnosticReport($),$}_printDiagnosticReport(e){console.log(""),console.log(` ${C.bold}THUBAN SYSTEM DIAGNOSTIC${C.reset}`),console.log(` ${C.gray}────────────────────────${C.reset}`),console.log("");for(const o of e.passed)console.log(o);for(const o of e.warnings)console.log(o);for(const o of e.failed)console.log(o);console.log("");const o=[];e.passed.length&&o.push(`${C.green}${e.passed.length} passed${C.reset}`),e.warnings.length&&o.push(`${C.yellow}${e.warnings.length} warning${1!==e.warnings.length?"s":""}${C.reset}`),e.failed.length&&o.push(`${C.red}${e.failed.length} failed${C.reset}`),console.log(` ${o.join(", ")}`),console.log("")}query(e){return this._queryLocal(e)}async queryAsync(e){const o=this._queryLocal(e);if(o.confidence>=.7)return o;if(this.smart){const o=await this.semanticQuery(e);if(o&&o.length>0&&o[0].score>.35){const e=o[0];return{type:e.type||"faq",data:{question:e.question||e.title||e.name||"",answer:e.answer||e.fix||e.description||"",category:e.category||"general",source:"pinecone",score:e.score,alternatives:o.slice(1).map(e=>({type:e.type,title:e.question||e.title||e.name||"",score:e.score}))},confidence:Math.min(e.score+.3,1)}}}return o}_queryLocal(e){if(!e||"string"!=typeof e)return{type:"none",data:null,confidence:0};const o=e.trim().toLowerCase();if(!o)return{type:"none",data:null,confidence:0};if(KB.patterns&&Array.isArray(KB.patterns))for(const e of KB.patterns)if(e.regex&&new RegExp(e.regex,"i").test(o))return{type:e.type||"troubleshooting",data:e,confidence:1};let s=null,t=0;if(KB.faq&&Array.isArray(KB.faq))for(const e of KB.faq){const n=e.keywords||[];let r=0;for(const e of n)if(o===e.toLowerCase()){r=1;break}if(r<1)for(const e of n)(o.includes(e.toLowerCase())||e.toLowerCase().includes(o))&&(r=Math.max(r,.7));r<.7&&e.question&&wordOverlap(o,e.question)>.5&&(r=Math.max(r,.5)),r>t&&(t=r,s=e)}let n=null,r=0;if(KB.errors&&Array.isArray(KB.errors))for(const e of KB.errors){const s=(e.code||"").toLowerCase(),t=(e.message||"").toLowerCase();if(s&&o.includes(s)){n=e,r=1;break}if(t&&o.includes(t)&&(n=e,r=Math.max(r,.7)),e.keywords)for(const s of e.keywords)o.includes(s.toLowerCase())&&(r=Math.max(r,.5),n=e)}let a=null,i=0;if(KB.commands&&Array.isArray(KB.commands))for(const e of KB.commands){const s=(e.name||"").toLowerCase();if(s&&o.includes(s)){a=e,i=o===s?1:.7;break}if(e.aliases)for(const s of e.aliases)o.includes(s.toLowerCase())&&(a=e,i=.7)}const c=[{type:"faq",data:s,confidence:t},{type:"error",data:n,confidence:r},{type:"command",data:a,confidence:i}].filter(e=>null!==e.data);return c.sort((e,o)=>o.confidence-e.confidence),c.length>0&&c[0].confidence>0?c[0]:{type:"none",data:{suggestions:(KB.faq||[]).slice(0,3).map(e=>({question:e.question,keywords:e.keywords}))},confidence:0}}async startInteractive(){const e=this._readThubanVersion()||"0.0.0",o=readline.createInterface({input:process.stdin,output:process.stdout});console.log(""),console.log(` ${C.cyan}╔══════════════════════════════════════╗${C.reset}`),console.log(` ${C.cyan}║${C.reset} ${C.bold}THUBAN Support Assistant${C.reset} ${C.cyan}║${C.reset}`),console.log(` ${C.cyan}║${C.reset} v${e} · Type 'help' or 'exit' ${C.cyan}║${C.reset}`),console.log(` ${C.cyan}╚══════════════════════════════════════╝${C.reset}`),console.log(""),console.log(` ${C.bold}Quick actions:${C.reset}`),console.log(` ${C.cyan}[1]${C.reset} Run system diagnostic`),console.log(` ${C.cyan}[2]${C.reset} Installation help`),console.log(` ${C.cyan}[3]${C.reset} Scan not working`),console.log(` ${C.cyan}[4]${C.reset} Understanding results`),console.log(` ${C.cyan}[5]${C.reset} Monitor/watch mode guide`),console.log(` ${C.cyan}[6]${C.reset} Commands reference`),console.log(` ${C.cyan}[7]${C.reset} Report a bug (thuban feedback)`),console.log("");const s={1:"diagnose",2:"installation",3:"scan-not-working",4:"understanding-results",5:"monitor-mode",6:"commands",7:"report-bug"},t=()=>new Promise(e=>{o.question(` ${C.bold}You:${C.reset} `,o=>{e(o?o.trim():"")})}),n=()=>new Promise(e=>{o.question(`\n ${C.gray}Did this help? (y/n/more):${C.reset} `,o=>{e(o?o.trim().toLowerCase():"")})});let r=!0;for(;r;){const e=await t();if(!e)continue;const o=e.toLowerCase();if("exit"===o||"quit"===o){console.log(`\n ${C.cyan}Goodbye! Run 'thuban support' anytime.${C.reset}\n`),r=!1;break}if("help"===o){this._printHelp();continue}if("diagnose"===o||"1"===o){await this.diagnose();continue}if(s[o]&&"1"!==o){const e=s[o];if("report-bug"===e){console.log(`\n ${C.cyan}To report a bug, run:${C.reset}`),console.log(" thuban feedback 'describe your issue'\n");continue}this._handleSlugQuery(e);const t=await n();this._handleFollowUp(t,e);continue}const a=this.query(e);if(this._printQueryResult(a),a.confidence<.5)console.log(`\n ${C.yellow}I couldn't find an exact match. Try:${C.reset}`),console.log(` • ${C.cyan}thuban support --diagnose${C.reset} (run diagnostics)`),console.log(` • ${C.cyan}thuban feedback 'describe your issue'${C.reset} (report to the team)`);else{const e=await n();this._handleFollowUp(e,null)}}o.close()}_readThubanVersion(){const e=[path.join(__dirname,"package.json"),path.join(__dirname,"..","package.json"),path.join(__dirname,"..","..","package.json")];for(const o of e)try{const e=fs.readFileSync(o,"utf8"),s=JSON.parse(e);if(s.version)return s.version}catch{}return null}_formatOS(e,o,s){return`${{win32:"Windows",darwin:"macOS",linux:"Linux",freebsd:"FreeBSD"}[e]||e} ${o} (${s})`}_hasCodeFiles(e){try{return fs.readdirSync(e).some(e=>/\.(js|ts|jsx|tsx|mjs|cjs)$/.test(e))}catch{return!1}}_checkDiskSpace(){const e="win32"===os.platform();try{if(e){const e=safeExec(`wmic logicaldisk where "DeviceID='${(path.parse(this.rootPath).root||"C:\\").charAt(0)}:'" get FreeSpace /format:value`);if(e){const o=e.match(/FreeSpace=(\d+)/);if(o){const e=parseInt(o[1],10);return{ok:e>536870912,free:`${(e/1073741824).toFixed(1)} GB`}}}}else{const e=safeExec(`df -h "${this.rootPath}" 2>/dev/null`);if(e){const o=e.split("\n");if(o.length>=2){return{ok:!0,free:o[1].split(/\s+/)[3]||"unknown"}}}}}catch{}return{ok:null,free:null}}_printHelp(){console.log(""),console.log(` ${C.bold}Available commands:${C.reset}`),console.log(` ${C.cyan}help${C.reset} — Show this help message`),console.log(` ${C.cyan}diagnose${C.reset} — Run full system diagnostic`),console.log(` ${C.cyan}1-7${C.reset} — Quick action shortcuts`),console.log(` ${C.cyan}exit${C.reset} — Exit the support assistant`),console.log(""),console.log(` ${C.bold}Or type any question:${C.reset}`),console.log(' "How do I scan a project?"'),console.log(' "What does error E001 mean?"'),console.log(' "scan command options"'),console.log("")}_handleSlugQuery(e){if(KB.troubleshooting&&Array.isArray(KB.troubleshooting)){const o=KB.troubleshooting.find(o=>o.slug===e);if(o){if(console.log(""),console.log(` ${C.bold}${o.title||o.slug}${C.reset}`),console.log(` ${C.gray}${"─".repeat(40)}${C.reset}`),o.summary&&console.log(`\n ${o.summary}`),o.steps&&o.steps.length>0){console.log("");for(let e=0;e<o.steps.length;e++){const s=o.steps[e];console.log(` ${C.cyan}${e+1}.${C.reset} ${s.description||s.text||""}`),s.fix&&console.log(` ${C.gray}→ ${s.fix}${C.reset}`)}}return void console.log("")}}const o=this.query(e);this._printQueryResult(o)}_printQueryResult(e){if(console.log(""),"none"===e.type){if(e.data&&e.data.suggestions&&e.data.suggestions.length>0){console.log(` ${C.yellow}No exact match found. Did you mean:${C.reset}`);for(const o of e.data.suggestions)console.log(` • ${o.question||o.keywords?.join(", ")||"(untitled)"}`)}else console.log(` ${C.yellow}No results found.${C.reset}`);return void console.log("")}const o=e.data;switch(e.type){case"faq":console.log(` ${C.bold}${o.question||"FAQ"}${C.reset}`),o.answer&&console.log(` ${o.answer}`),o.example&&console.log(`\n ${C.gray}Example:${C.reset} ${o.example}`);break;case"error":console.log(` ${C.bold}${C.red}Error: ${o.code||"Unknown"}${C.reset}`),o.message&&console.log(` ${o.message}`),o.cause&&console.log(`\n ${C.yellow}Cause:${C.reset} ${o.cause}`),o.fix&&console.log(` ${C.green}Fix:${C.reset} ${o.fix}`);break;case"command":if(console.log(` ${C.bold}${C.cyan}${o.name||"Command"}${C.reset}`),o.description&&console.log(` ${o.description}`),o.usage&&console.log(`\n ${C.gray}Usage:${C.reset} ${o.usage}`),o.options&&Array.isArray(o.options)){console.log(`\n ${C.bold}Options:${C.reset}`);for(const e of o.options)console.log(` ${C.cyan}${e.flag||e.name}${C.reset} ${e.description||""}`)}break;case"troubleshooting":if(console.log(` ${C.bold}${o.title||o.slug||"Troubleshooting"}${C.reset}`),o.response&&console.log(` ${o.response}`),o.steps&&Array.isArray(o.steps))for(const e of o.steps)console.log(` • ${e}`);break;default:console.log(` ${C.gray}(${e.type})${C.reset} ${JSON.stringify(o)}`)}e.confidence<1&&e.confidence>=.5&&console.log(`\n ${C.gray}(confidence: ${Math.round(100*e.confidence)}% — results may be approximate)${C.reset}`),console.log("")}_handleFollowUp(e,o){if(e)switch(e){case"y":case"yes":console.log(`\n ${C.green}Great! Anything else?${C.reset}\n`);break;case"n":case"no":console.log(`\n ${C.yellow}Sorry about that. Try describing your issue differently,`),console.log(` or run '${C.cyan}thuban feedback${C.reset}' to report it.${C.reset}\n`);break;case"more":this._showRelatedEntries(o)}}_showRelatedEntries(e){if(!KB.faq||!Array.isArray(KB.faq))return void console.log(`\n ${C.gray}No additional entries available.${C.reset}\n`);const o=KB.faq.filter(o=>o.slug!==e).slice(0,5);if(0!==o.length){console.log(`\n ${C.bold}Related topics:${C.reset}`);for(const e of o)console.log(` • ${e.question||e.keywords?.join(", ")||e.slug||"(untitled)"}`);console.log("")}else console.log(`\n ${C.gray}No additional entries available.${C.reset}\n`)}}module.exports=SupportBot;