thuban 0.4.8 → 0.4.9
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.
- package/README.md +4 -4
- package/{dist/cli.js → cli.js} +0 -0
- package/package.json +12 -12
- package/packages/crucible/README.md +93 -0
- package/packages/scanner/go-ast-analyzer.js +1 -0
- package/packages/scanner/license-manager.js +1 -0
- package/packages/scanner/taint-tracker.js +1 -0
- package/dist/LICENSE +0 -21
- package/dist/README.md +0 -437
- package/dist/package.json +0 -65
- package/dist/packages/scanner/go-ast-analyzer.js +0 -1
- package/dist/packages/scanner/license-manager.js +0 -1
- package/dist/packages/scanner/taint-tracker.js +0 -1
- /package/{dist/packages → packages}/crucible/.golden/golden-master.json +0 -0
- /package/{dist/packages → packages}/crucible/badge-generator.js +0 -0
- /package/{dist/packages → packages}/crucible/banner.js +0 -0
- /package/{dist/packages → packages}/crucible/ci-integration.js +0 -0
- /package/{dist/packages → packages}/crucible/golden-master.js +0 -0
- /package/{dist/packages → packages}/crucible/index.js +0 -0
- /package/{dist/packages → packages}/crucible/kenny-mode.js +0 -0
- /package/{dist/packages → packages}/crucible/leaderboard.js +0 -0
- /package/{dist/packages → packages}/crucible/mutation-engine.js +0 -0
- /package/{dist/packages → packages}/crucible/pattern-learner.js +0 -0
- /package/{dist/packages → packages}/crucible/report-generator.js +0 -0
- /package/{dist/packages → packages}/crucible/rule-loader.js +0 -0
- /package/{dist/packages → packages}/crucible/rules/code-scanner-core.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/command-injection.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/crypto-misuse.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/deserialization.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/env-injection.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/eval-abuse.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/file-upload.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/hallucination.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/hardcoded-secret.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/hardcoded-url.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/insecure-crypto.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/integer-overflow.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/log-injection.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/mass-assignment.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/open-redirect.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/path-traversal.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/prototype-pollution.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/sql-injection.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/ssrf.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/timing-attack.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/unsafe-block.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/xss.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/xxe.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/yaml-deserialization.json +0 -0
- /package/{dist/packages → packages}/crucible/rules/yaml-injection.json +0 -0
- /package/{dist/packages → packages}/crucible/seeding-engine.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-001.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-002.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-003.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-004.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-005.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-006.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-007.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-008.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-009.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-010.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-011.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-012.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-013.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-014.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-015.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-016.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-017.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-018.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-019.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-020.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-021.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-022.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-023.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-024.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-025.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-026.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-027.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-028.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-029.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-030.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-031.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-032.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-033.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-034.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-035.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-036.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-037.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-038.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-039.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-040.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-041.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-042.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-043.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-044.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-045.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-046.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-047.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-048.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-049.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-050.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-051.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/csharp/seed-052.cs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-001.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-002.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-003.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-004.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-005.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-006.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-007.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-008.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-009.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-010.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-011.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-012.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-013.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-014.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-015.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-016.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-017.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-018.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-019.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-020.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-021.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-022.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-023.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-024.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-025.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-026.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-027.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-028.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-029.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-030.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-031.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-032.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-033.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-034.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-035.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-036.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-037.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-038.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-039.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-040.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-041.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-042.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-043.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-044.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-045.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-046.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-047.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-048.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-049.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-050.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-051.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/go/seed-052.go +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-001.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-002.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-003.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-004.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-005.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-006.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-007.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-008.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-009.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-010.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-011.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-012.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-013.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-014.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-015.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-016.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-017.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-018.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-019.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-020.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-021.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-022.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-023.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-024.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-025.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-026.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-027.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-028.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-029.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-030.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-031.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-032.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-033.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-034.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-035.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-036.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-037.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-038.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-039.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-040.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-041.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-042.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-043.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-044.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-045.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-046.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-047.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-048.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-049.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-050.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-051.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/java/seed-052.java +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-001.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-002.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-003.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-004.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-005.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-006.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-007.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-008.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-009.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-010.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-011.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-012.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-013.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-014.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-015.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-016.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-017.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-018.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-019.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-020.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-021.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-022.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-023.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-024.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-025.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-026.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-027.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-028.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-029.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-030.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-031.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-032.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-033.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-034.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-035.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-036.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-037.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-038.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-039.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-040.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-041.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-042.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-043.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-044.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-045.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-046.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-047.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-048.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-049.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-050.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-051.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-052.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-053.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-054.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/js/seed-055.js +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-001.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-002.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-003.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-004.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-005.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-006.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-007.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-008.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-009.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-010.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-011.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-012.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-013.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-014.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-015.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-016.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-017.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-018.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-019.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-020.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-021.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-022.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-023.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-024.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-025.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-026.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-027.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-028.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-029.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-030.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-031.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-032.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-033.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-034.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-035.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-036.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-037.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-038.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-039.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-040.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-041.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-042.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-043.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-044.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-045.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-046.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-047.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-048.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-049.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/kotlin/seed-050.kt +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-001.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-002.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-003.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-004.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-005.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-006.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-007.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-008.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-009.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-010.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-011.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-012.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-013.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-014.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-015.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-016.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-017.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-018.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-019.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-020.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-021.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-022.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-023.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-024.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-025.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-026.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-027.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-028.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-029.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-030.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-031.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-032.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-033.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-034.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-035.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-036.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-037.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-038.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-039.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-040.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-041.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-042.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-043.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-044.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-045.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-046.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-047.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-048.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-049.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/php/seed-050.php +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-001.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-002.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-003.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-004.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-005.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-006.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-007.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-008.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-009.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-010.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-011.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-012.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-013.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-014.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-015.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-016.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-017.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-018.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-019.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-020.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-021 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-021.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-022 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-022.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-023 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-023.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-024 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-024.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-025 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-025.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-026 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-026.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-027 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-027.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-028 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-028.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-029.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-030 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-030.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-031 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-031.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-032.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-033.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-034.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-035.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-036 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-036.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-037 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-037.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-038 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-038.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-039 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-039.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-040 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-040.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-041 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-041.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-042 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-042.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-043 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-043.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-044 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-044.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-045 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-045.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-046 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-046.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-047 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-047.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-048 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-048.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-049 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-049.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-050 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-050.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-051 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-051.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-052 2.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/python/seed-052.py +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-001 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-001.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-002 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-002.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-003 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-003.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-004 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-004.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-005 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-005.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-006 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-006.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-007 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-007.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-008 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-008.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-009 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-009.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-010 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-010.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-011 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-011.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-012 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-012.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-013 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-013.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-014 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-014.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-015 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-015.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-016 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-016.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-017 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-017.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-018 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-018.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-019 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-019.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-020 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-020.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-021 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-021.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-022 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-022.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-023 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-023.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-024 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-024.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-025 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-025.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-026 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-026.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-027 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-027.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-028 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-028.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-029 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-029.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-030 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-030.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-031 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-031.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-032 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-032.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-033 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-033.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-034 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-034.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-035 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-035.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-036 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-036.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-037 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-037.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-038 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-038.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-039 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-039.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-040 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-040.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-041 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-041.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-042 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-042.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-043 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-043.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-044 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-044.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-045 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-045.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-046 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-046.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-047 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-047.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-048 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-048.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-049 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-049.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-050 2.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ruby/seed-050.rb +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-001 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-001.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-002 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-002.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-003 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-003.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-004 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-004.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-005 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-005.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-006 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-006.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-007 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-007.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-008 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-008.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-009 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-009.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-010 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-010.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-011 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-011.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-012 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-012.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-013 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-013.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-014 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-014.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-015 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-015.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-016 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-016.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-017 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-017.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-018 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-018.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-019 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-019.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-020 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-020.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-021 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-021.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-022 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-022.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-023 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-023.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-024 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-024.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-025 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-025.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-026 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-026.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-027 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-027.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-028 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-028.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-029 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-029.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-030 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-030.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-031 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-031.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-032 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-032.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-033 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-033.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-034 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-034.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-035 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-035.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-036 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-036.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-037 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-037.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-038 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-038.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-039 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-039.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-040 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-040.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-041 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-041.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-042 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-042.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-043 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-043.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-044 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-044.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-045 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-045.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-046 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-046.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-047 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-047.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-048 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-048.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-049 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-049.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-050 2.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/rust/seed-050.rs +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-001 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-001.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-002 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-002.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-003 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-003.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-004 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-004.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-005 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-005.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-006 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-006.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-007 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-007.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-008 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-008.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-009 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-009.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-010 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-010.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-011 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-011.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-012 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-012.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-013 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-013.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-014 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-014.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-015 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-015.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-016 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-016.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-017 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-017.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-018 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-018.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-019 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-019.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-020 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-020.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-021 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-021.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-022 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-022.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-023 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-023.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-024 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-024.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-025 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-025.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-026 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-026.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-027 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-027.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-028 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-028.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-029 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-029.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-030 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-030.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-031 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-031.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-032 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-032.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-033 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-033.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-034 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-034.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-035 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-035.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-036 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-036.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-037 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-037.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-038 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-038.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-039 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-039.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-040 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-040.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-041 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-041.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-042 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-042.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-043 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-043.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-044 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-044.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-045 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-045.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-046 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-046.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-047 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-047.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-048 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-048.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-049 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-049.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-050 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-050.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-051 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-051.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-052 2.ts +0 -0
- /package/{dist/packages → packages}/crucible/seeds/ts/seed-052.ts +0 -0
- /package/{dist/packages → packages}/crucible/self-attack.js +0 -0
- /package/{dist/packages → packages}/scanner/ai-confidence-scorer.js +0 -0
- /package/{dist/packages → packages}/scanner/alert-manager.js +0 -0
- /package/{dist/packages → packages}/scanner/ast-analyzer.js +0 -0
- /package/{dist/packages → packages}/scanner/baseline-manager.js +0 -0
- /package/{dist/packages → packages}/scanner/cfg-analyzer.js +0 -0
- /package/{dist/packages → packages}/scanner/code-scanner.js +0 -0
- /package/{dist/packages → packages}/scanner/codebase-passport.js +0 -0
- /package/{dist/packages → packages}/scanner/copy-paste-detector.js +0 -0
- /package/{dist/packages → packages}/scanner/dependency-graph.js +0 -0
- /package/{dist/packages → packages}/scanner/drift-detector.js +0 -0
- /package/{dist/packages → packages}/scanner/executive-report.js +0 -0
- /package/{dist/packages → packages}/scanner/export-verifier.js +0 -0
- /package/{dist/packages → packages}/scanner/feedback-client.js +0 -0
- /package/{dist/packages → packages}/scanner/file-collector.js +0 -0
- /package/{dist/packages → packages}/scanner/file-watcher.js +0 -0
- /package/{dist/packages → packages}/scanner/ghost-code-detector.js +0 -0
- /package/{dist/packages → packages}/scanner/hallucination-detector.js +0 -0
- /package/{dist/packages → packages}/scanner/health-checker.js +0 -0
- /package/{dist/packages → packages}/scanner/html-report.js +0 -0
- /package/{dist/packages → packages}/scanner/index.js +0 -0
- /package/{dist/packages → packages}/scanner/investor-report.js +0 -0
- /package/{dist/packages → packages}/scanner/master-health-checker.js +0 -0
- /package/{dist/packages → packages}/scanner/monitor-notifier.js +0 -0
- /package/{dist/packages → packages}/scanner/monitor-service.js +0 -0
- /package/{dist/packages → packages}/scanner/monitor-store.js +0 -0
- /package/{dist/packages → packages}/scanner/pre-commit-gate.js +0 -0
- /package/{dist/packages → packages}/scanner/python-ast-analyzer.js +0 -0
- /package/{dist/packages → packages}/scanner/python_ast_helper.py +0 -0
- /package/{dist/packages → packages}/scanner/read-file.js +0 -0
- /package/{dist/packages → packages}/scanner/scan-diff.js +0 -0
- /package/{dist/packages → packages}/scanner/scan-runner.js +0 -0
- /package/{dist/packages → packages}/scanner/secret-scanner.js +0 -0
- /package/{dist/packages → packages}/scanner/sentinel-core.js +0 -0
- /package/{dist/packages → packages}/scanner/sentinel-knowledge.js +0 -0
- /package/{dist/packages → packages}/scanner/slack-notifier.js +0 -0
- /package/{dist/packages → packages}/scanner/support-bot.js +0 -0
- /package/{dist/packages → packages}/scanner/support-knowledge.js +0 -0
- /package/{dist/packages → packages}/scanner/tech-debt-analyzer.js +0 -0
- /package/{dist/packages → packages}/scanner/tech-debt-cost.js +0 -0
- /package/{dist/packages → packages}/scanner/widget-generator.js +0 -0
package/dist/README.md
DELETED
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
# Thuban -- Code Intelligence Scanner
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/thuban)
|
|
4
|
-
[](LICENSE)
|
|
5
|
-
[](#testing)
|
|
6
|
-
[](#testing)
|
|
7
|
-
|
|
8
|
-
AI Code Verification — Catch what AI gets wrong.
|
|
9
|
-
|
|
10
|
-
Static analysis, security scanning, dead code detection, clone detection, AI-generated code scoring, dependency analysis, and mutation testing for 12 languages. One command. Zero runtime dependencies beyond `@babel/parser`.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## Quick Start
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install -g thuban
|
|
18
|
-
thuban scan .
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Or run without installing:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npx thuban scan .
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
JSON output for CI pipelines:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
thuban scan . --json
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Feature Highlights
|
|
36
|
-
|
|
37
|
-
### Security Analysis
|
|
38
|
-
|
|
39
|
-
84 detection rules across multiple categories. Cross-file taint tracking follows user input from sources (`req.query`, `req.body`, `req.params`, `process.argv`, `process.env`) through assignment, concatenation, and template interpolation to dangerous SQL and XSS sinks -- across file boundaries via `require()`, `import`, destructured imports, and re-exports.
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
thuban scan src/ --json
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### OWASP Top 10 & CWE Compliance
|
|
46
|
-
|
|
47
|
-
All security rules (SEC001--SEC019, RUST001--RUST002) map to [OWASP Top 10 2021](https://owasp.org/Top10/) categories and [CWE](https://cwe.mitre.org/) identifiers. Every finding includes machine-readable `owasp` and `cwe` fields in JSON output, enabling direct integration with compliance dashboards and vulnerability management systems.
|
|
48
|
-
|
|
49
|
-
| OWASP 2021 Category | Rules | CWEs |
|
|
50
|
-
|-----------------------------------------|----------------------------------------|-----------------------------------|
|
|
51
|
-
| A01 Broken Access Control | SEC005, SEC013, SEC014 | CWE-22, CWE-942, CWE-601 |
|
|
52
|
-
| A02 Cryptographic Failures | SEC006, SEC007, SEC008, SEC016 | CWE-798, CWE-327, CWE-330, CWE-208 |
|
|
53
|
-
| A03 Injection | SEC001, SEC002, SEC003, SEC004, SEC009, SEC011, SEC018, SEC019 | CWE-95, CWE-79, CWE-89, CWE-78, CWE-1321 |
|
|
54
|
-
| A04 Insecure Design | SEC015 | CWE-209 |
|
|
55
|
-
| A05 Security Misconfiguration | SEC017 | CWE-611 |
|
|
56
|
-
| A06 Vulnerable Components | RUST001, RUST002 | CWE-908, CWE-477 |
|
|
57
|
-
| A08 Software and Data Integrity | SEC012 | CWE-502 |
|
|
58
|
-
| A10 SSRF | SEC010 | CWE-918 |
|
|
59
|
-
|
|
60
|
-
### Control Flow Graph Analysis
|
|
61
|
-
|
|
62
|
-
Detects unreachable code, infinite loops, and dead branches through AST-based control flow graph construction.
|
|
63
|
-
|
|
64
|
-
### Clone Detection
|
|
65
|
-
|
|
66
|
-
Multi-language code clone detection with AST normalization. Finds duplicated logic across your codebase.
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
thuban clones src/
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### AI-Generated Code Scoring
|
|
73
|
-
|
|
74
|
-
Scores files for likelihood of AI generation based on structural patterns, naming conventions, and code smells common in LLM output.
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
thuban aiscore src/
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Dependency Analysis
|
|
81
|
-
|
|
82
|
-
Maps dependency graphs, detects circular imports, and identifies unused or phantom dependencies.
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
thuban deps .
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Mutation Testing (Crucible)
|
|
89
|
-
|
|
90
|
-
Built-in mutation testing engine. 515 seed files generate 1,030 mutations. Validates that your test suite catches real bugs.
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
thuban crucible --mode kenny # standard mode
|
|
94
|
-
thuban crucible --mode hell # maximum mutation density
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Ghost Code Detection
|
|
98
|
-
|
|
99
|
-
Finds dead exports, unused functions, and unreachable modules.
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
thuban ghosts src/
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Auto-Fix
|
|
106
|
-
|
|
107
|
-
Automatically applies safe fixes for supported rule violations.
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
thuban fix src/
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### HTML Dashboard
|
|
114
|
-
|
|
115
|
-
Generates a visual HTML report with charts, trends, and drill-down by category.
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
thuban dashboard .
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Executive Reports
|
|
122
|
-
|
|
123
|
-
PDF-ready executive summary with risk scores, trend data, and remediation priorities.
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
thuban executive .
|
|
127
|
-
thuban pdf .
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Baseline Scanning
|
|
131
|
-
|
|
132
|
-
Establish a baseline and track only new issues introduced after that point.
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
thuban baseline . # save current state
|
|
136
|
-
thuban scan . --baseline # report only new issues
|
|
137
|
-
thuban compare . # compare current scan to baseline
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Pre-Commit Gate
|
|
141
|
-
|
|
142
|
-
Block commits that introduce issues above a configurable threshold.
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
thuban gate .
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Inline Suppression
|
|
149
|
-
|
|
150
|
-
Suppress specific rules on a per-line basis:
|
|
151
|
-
|
|
152
|
-
```javascript
|
|
153
|
-
const query = "SELECT * FROM " + input; // thuban-ignore SEC001
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
```python
|
|
157
|
-
password = "admin123" # thuban-ignore SEC005
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Suppress all rules on a line:
|
|
161
|
-
|
|
162
|
-
```javascript
|
|
163
|
-
eval(code); // thuban-ignore
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## Supported Languages
|
|
169
|
-
|
|
170
|
-
| Language | Extension(s) | AST Engine |
|
|
171
|
-
|------------|----------------------|----------------|
|
|
172
|
-
| JavaScript | `.js`, `.mjs`, `.cjs`| Babel |
|
|
173
|
-
| TypeScript | `.ts` | Babel |
|
|
174
|
-
| JSX | `.jsx` | Babel |
|
|
175
|
-
| TSX | `.tsx` | Babel |
|
|
176
|
-
| Python | `.py` | Python `ast` |
|
|
177
|
-
| Go | `.go` | `go/parser` |
|
|
178
|
-
| Rust | `.rs` | Pattern-based |
|
|
179
|
-
| Ruby | `.rb` | Pattern-based |
|
|
180
|
-
| Java | `.java` | Pattern-based |
|
|
181
|
-
| C# | `.cs` | Pattern-based |
|
|
182
|
-
| Kotlin | `.kt` | Pattern-based |
|
|
183
|
-
| PHP | `.php` | Pattern-based |
|
|
184
|
-
|
|
185
|
-
Three AST engines provide deep analysis: Babel for JavaScript/TypeScript/JSX/TSX, Python `ast` for Python, and Go `go/parser` for Go. Remaining languages use pattern-based detection.
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Detection Rules
|
|
190
|
-
|
|
191
|
-
84 rules organized by category:
|
|
192
|
-
|
|
193
|
-
| Category | Rule IDs | Description |
|
|
194
|
-
|-------------|-----------------------|--------------------------------------------------|
|
|
195
|
-
| Security | SEC001--SEC019 | SQL injection, XSS, hardcoded secrets, eval, command injection, path traversal, insecure crypto, SSRF, prototype pollution, and more |
|
|
196
|
-
| Security | RUST001--RUST002 | Rust-specific unsafe patterns |
|
|
197
|
-
| Quality | QUAL001--QUAL004 | Code quality, naming, structure |
|
|
198
|
-
| Performance | PERF001 | Performance anti-patterns |
|
|
199
|
-
| AST | AST001--AST005 | Phantom imports, deprecated APIs, unused variables, hallucinated APIs, empty catch blocks |
|
|
200
|
-
| AST | AST011--AST014 | Advanced AST patterns |
|
|
201
|
-
| Taint | TAINT001--TAINT002 | Cross-file taint tracking for SQLi and XSS |
|
|
202
|
-
| CFG | CFG001--CFG005 | Unreachable code, infinite loops, dead branches |
|
|
203
|
-
| Nesting | NEST001 | Excessive nesting depth |
|
|
204
|
-
| Complexity | CMPLX001--CMPLX002 | Cyclomatic and cognitive complexity |
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## CLI Commands
|
|
209
|
-
|
|
210
|
-
28 commands grouped by function:
|
|
211
|
-
|
|
212
|
-
### Core Scanning
|
|
213
|
-
|
|
214
|
-
| Command | Description |
|
|
215
|
-
|---------------|--------------------------------------------------|
|
|
216
|
-
| `scan [path]` | Scan a codebase for issues |
|
|
217
|
-
| `diff [path]` | Scan only git-changed files |
|
|
218
|
-
| `deps [path]` | Map dependencies and detect circular imports |
|
|
219
|
-
| `health [path]`| Run health check on codebase |
|
|
220
|
-
| `report [path]`| Full scan + deps + drift combined report |
|
|
221
|
-
|
|
222
|
-
### Detection
|
|
223
|
-
|
|
224
|
-
| Command | Description |
|
|
225
|
-
|----------------------|--------------------------------------------|
|
|
226
|
-
| `hallucinate [path]` | Detect AI hallucinations and phantom imports|
|
|
227
|
-
| `ghosts [path]` | Detect dead code and unused exports |
|
|
228
|
-
| `aiscore [path]` | Score files for AI-generated code patterns |
|
|
229
|
-
| `clones [path]` | Detect code clones across the codebase |
|
|
230
|
-
| `drift [path]` | Detect drift from Mother Code annotations |
|
|
231
|
-
| `debt [path]` | Analyze technical debt |
|
|
232
|
-
| `cost [path]` | Calculate technical debt cost |
|
|
233
|
-
|
|
234
|
-
### Remediation
|
|
235
|
-
|
|
236
|
-
| Command | Description |
|
|
237
|
-
|---------------|--------------------------------------------------|
|
|
238
|
-
| `fix [path]` | Auto-fix supported rule violations |
|
|
239
|
-
| `inject [path]`| Inject Mother Code DNA widget into files |
|
|
240
|
-
| `gate [path]` | Pre-commit quality gate |
|
|
241
|
-
|
|
242
|
-
### Reporting
|
|
243
|
-
|
|
244
|
-
| Command | Description |
|
|
245
|
-
|--------------------|-----------------------------------------------|
|
|
246
|
-
| `dashboard [path]` | Generate visual HTML dashboard |
|
|
247
|
-
| `executive [path]` | Generate executive summary report |
|
|
248
|
-
| `pdf [path]` | Generate PDF-ready report |
|
|
249
|
-
| `passport [path]` | Generate codebase passport |
|
|
250
|
-
|
|
251
|
-
### Monitoring
|
|
252
|
-
|
|
253
|
-
| Command | Description |
|
|
254
|
-
|------------------|-------------------------------------------------|
|
|
255
|
-
| `watch [path]` | Live sentinel -- continuous file monitoring |
|
|
256
|
-
| `monitor [path]` | Recurring scans with history and alerts |
|
|
257
|
-
| `history [path]` | View recurring scan history |
|
|
258
|
-
| `trend [path]` | Show issue trends across scans |
|
|
259
|
-
|
|
260
|
-
### Baseline and Comparison
|
|
261
|
-
|
|
262
|
-
| Command | Description |
|
|
263
|
-
|------------------|-------------------------------------------------|
|
|
264
|
-
| `baseline [path]`| Save current scan state as baseline |
|
|
265
|
-
| `compare [path]` | Compare current scan against baseline |
|
|
266
|
-
|
|
267
|
-
### Licensing
|
|
268
|
-
|
|
269
|
-
| Command | Description |
|
|
270
|
-
|------------|------------------------------------------------------|
|
|
271
|
-
| `activate` | Activate a license key |
|
|
272
|
-
| `status` | Show current license status |
|
|
273
|
-
| `upgrade` | Upgrade license tier |
|
|
274
|
-
|
|
275
|
-
### Mutation Testing
|
|
276
|
-
|
|
277
|
-
| Command | Description |
|
|
278
|
-
|------------|------------------------------------------------------|
|
|
279
|
-
| `crucible` | Run the Crucible mutation testing engine |
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
## Configuration
|
|
284
|
-
|
|
285
|
-
### `.thubanrc.json`
|
|
286
|
-
|
|
287
|
-
Place a `.thubanrc.json` in your project root to configure scan behavior:
|
|
288
|
-
|
|
289
|
-
```json
|
|
290
|
-
{
|
|
291
|
-
"$schema": "https://thuban.dev/schema/thubanrc.json",
|
|
292
|
-
"minScore": 0,
|
|
293
|
-
"ignore": [
|
|
294
|
-
"node_modules",
|
|
295
|
-
"dist",
|
|
296
|
-
".git",
|
|
297
|
-
"coverage"
|
|
298
|
-
],
|
|
299
|
-
"hallucination": {
|
|
300
|
-
"enabled": true,
|
|
301
|
-
"ignore": []
|
|
302
|
-
},
|
|
303
|
-
"motherCode": {
|
|
304
|
-
"enabled": true,
|
|
305
|
-
"autoInject": false
|
|
306
|
-
},
|
|
307
|
-
"report": {
|
|
308
|
-
"format": "html",
|
|
309
|
-
"outputDir": "."
|
|
310
|
-
},
|
|
311
|
-
"ci": {
|
|
312
|
-
"failOnGrade": "F",
|
|
313
|
-
"postComment": true
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
### `.thubanignore`
|
|
319
|
-
|
|
320
|
-
Exclude files and directories from scanning, one glob pattern per line:
|
|
321
|
-
|
|
322
|
-
```
|
|
323
|
-
packages/crucible/seeds/**
|
|
324
|
-
tests/regression/fixtures/**
|
|
325
|
-
vendor/**
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
## JSON Output
|
|
331
|
-
|
|
332
|
-
All scan commands support `--json` for machine-readable output:
|
|
333
|
-
|
|
334
|
-
```bash
|
|
335
|
-
thuban scan src/ --json
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
```json
|
|
339
|
-
{
|
|
340
|
-
"version": "0.4.5",
|
|
341
|
-
"timestamp": "2026-07-04T12:00:00.000Z",
|
|
342
|
-
"files": 42,
|
|
343
|
-
"issues": [
|
|
344
|
-
{
|
|
345
|
-
"file": "src/api/handler.js",
|
|
346
|
-
"line": 17,
|
|
347
|
-
"rule": "SEC001",
|
|
348
|
-
"severity": "critical",
|
|
349
|
-
"category": "security",
|
|
350
|
-
"message": "Potential SQL injection: unsanitized input in query string",
|
|
351
|
-
"fix": "Use parameterized queries instead of string concatenation"
|
|
352
|
-
}
|
|
353
|
-
],
|
|
354
|
-
"summary": {
|
|
355
|
-
"critical": 1,
|
|
356
|
-
"warning": 3,
|
|
357
|
-
"info": 5,
|
|
358
|
-
"score": 72,
|
|
359
|
-
"grade": "C"
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
## Performance
|
|
367
|
-
|
|
368
|
-
| Metric | Value |
|
|
369
|
-
|----------------|--------------------|
|
|
370
|
-
| Throughput | ~23,000 lines/sec |
|
|
371
|
-
| Test suite | 746 tests |
|
|
372
|
-
| Code coverage | 91.2% |
|
|
373
|
-
| Dependencies | 1 (`@babel/parser`) |
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
## Tiers
|
|
378
|
-
|
|
379
|
-
| Tier | Limit | Features |
|
|
380
|
-
|------------|-----------|---------------------------------------------------|
|
|
381
|
-
| Free | 100 files | Core scanning, all 84 rules, JSON output |
|
|
382
|
-
| Pro | Unlimited | Recurring scans, history, trends, notifications |
|
|
383
|
-
| Team | Unlimited | Dashboard, executive reports, baseline management |
|
|
384
|
-
| Enterprise | Unlimited | Custom rules, priority support, SSO |
|
|
385
|
-
|
|
386
|
-
Activate a license:
|
|
387
|
-
|
|
388
|
-
```bash
|
|
389
|
-
thuban activate <license-key>
|
|
390
|
-
thuban status
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
## CI Integration
|
|
396
|
-
|
|
397
|
-
### GitHub Actions
|
|
398
|
-
|
|
399
|
-
```yaml
|
|
400
|
-
- name: Thuban Scan
|
|
401
|
-
run: npx thuban scan . --json --baseline
|
|
402
|
-
env:
|
|
403
|
-
THUBAN_LICENSE: ${{ secrets.THUBAN_LICENSE }}
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
### Pre-Commit Hook
|
|
407
|
-
|
|
408
|
-
```bash
|
|
409
|
-
thuban gate . --fail-on critical
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
---
|
|
413
|
-
|
|
414
|
-
## Requirements
|
|
415
|
-
|
|
416
|
-
- Node.js >= 16.0.0
|
|
417
|
-
|
|
418
|
-
---
|
|
419
|
-
|
|
420
|
-
## Contributing
|
|
421
|
-
|
|
422
|
-
1. Fork the repository
|
|
423
|
-
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
424
|
-
3. Run the test suite (`npm test`)
|
|
425
|
-
4. Submit a pull request
|
|
426
|
-
|
|
427
|
-
Issues and feature requests: [github.com/SilverwingsBenefitsGit/thuban/issues](https://github.com/SilverwingsBenefitsGit/thuban/issues)
|
|
428
|
-
|
|
429
|
-
---
|
|
430
|
-
|
|
431
|
-
## License
|
|
432
|
-
|
|
433
|
-
[MIT](LICENSE)
|
|
434
|
-
|
|
435
|
-
---
|
|
436
|
-
|
|
437
|
-
[thuban.dev](https://thuban.dev)
|
package/dist/package.json
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "thuban",
|
|
3
|
-
"version": "0.4.8",
|
|
4
|
-
"description": "The safety layer for AI-coded software. Detect hallucinated APIs, ghost code, tech debt, and architecture drift. One command. Minimal dependencies.",
|
|
5
|
-
"bin": {
|
|
6
|
-
"thuban": "dist/cli.js"
|
|
7
|
-
},
|
|
8
|
-
"scripts": {
|
|
9
|
-
"scan": "node cli.js scan",
|
|
10
|
-
"test": "node build.js && node --test tests/build-integrity.test.js tests/crlf-safety.test.js tests/windows-paths.test.js tests/npm-publish-smoke.test.js",
|
|
11
|
-
"test:all": "node --test tests/*.test.js packages/scanner/*.test.js packages/crucible/*.test.js",
|
|
12
|
-
"test:build": "node build.js && node --test tests/build-integrity.test.js tests/npm-publish-smoke.test.js",
|
|
13
|
-
"build": "node build.js",
|
|
14
|
-
"prepublishOnly": "npm run build && node --test tests/build-integrity.test.js tests/npm-publish-smoke.test.js"
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"code-quality",
|
|
18
|
-
"static-analysis",
|
|
19
|
-
"ai-hallucination",
|
|
20
|
-
"hallucination-detection",
|
|
21
|
-
"ghost-code",
|
|
22
|
-
"tech-debt",
|
|
23
|
-
"ai-code-review",
|
|
24
|
-
"code-health",
|
|
25
|
-
"pre-commit",
|
|
26
|
-
"copilot",
|
|
27
|
-
"cursor",
|
|
28
|
-
"ai-safety",
|
|
29
|
-
"developer-tools",
|
|
30
|
-
"devtools",
|
|
31
|
-
"linter",
|
|
32
|
-
"code-scanner"
|
|
33
|
-
],
|
|
34
|
-
"author": "Silverwings Benefits <hello@thuban.dev>",
|
|
35
|
-
"license": "SEE LICENSE IN LICENSE",
|
|
36
|
-
"homepage": "https://thuban.dev",
|
|
37
|
-
"repository": {
|
|
38
|
-
"type": "git",
|
|
39
|
-
"url": "git+https://github.com/SilverwingsBenefitsGit/thuban.git"
|
|
40
|
-
},
|
|
41
|
-
"bugs": {
|
|
42
|
-
"url": "https://github.com/SilverwingsBenefitsGit/thuban/issues"
|
|
43
|
-
},
|
|
44
|
-
"engines": {
|
|
45
|
-
"node": ">=16.0.0"
|
|
46
|
-
},
|
|
47
|
-
"files": [
|
|
48
|
-
"dist/cli.js",
|
|
49
|
-
"dist/packages/scanner/*.js",
|
|
50
|
-
"dist/packages/scanner/python_ast_helper.py",
|
|
51
|
-
"dist/packages/crucible/*.js",
|
|
52
|
-
"dist/packages/crucible/seeds/**",
|
|
53
|
-
"dist/packages/crucible/.golden/",
|
|
54
|
-
"dist/packages/crucible/rules/**",
|
|
55
|
-
"dist/README.md",
|
|
56
|
-
"dist/LICENSE",
|
|
57
|
-
"dist/package.json"
|
|
58
|
-
],
|
|
59
|
-
"dependencies": {
|
|
60
|
-
"@babel/parser": "^7.29.7"
|
|
61
|
-
},
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"terser": "^5.48.0"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const{execFileSync:execFileSync}=require("child_process"),path=require("path"),HELPER_SCRIPT=path.join(__dirname,"go_ast_helper.go"),PROBE_TIMEOUT_MS=3e3,EXEC_TIMEOUT_MS=8e3,MAX_BUFFER=2097152;let cachedGoBin;function resolveGoBin(){if(void 0!==cachedGoBin)return cachedGoBin;try{execFileSync("go",["version"],{stdio:"pipe",timeout:3e3}),cachedGoBin="go"}catch(e){cachedGoBin=null}return cachedGoBin}function _resetGoBinCache(){cachedGoBin=void 0}function snippet(e,n){return!n||n<1||n>e.length?"":e[n-1].trim().substring(0,100)}const RULES_BY_TYPE={unused_import:{id:"AST031",severity:"info",category:"quality",name:"Unused Import (Go AST)"},unused_variable:{id:"AST032",severity:"info",category:"quality",name:"Ineffectual Assignment (Go AST)"},high_complexity:{id:"AST033",severity:"warning",category:"quality",name:"High Cyclomatic Complexity (Go AST)"},dead_code:{id:"AST034",severity:"warning",category:"quality",name:"Unreachable Code (Go AST)"},unchecked_error:{id:"AST035",severity:"warning",category:"security",name:"Unchecked Error (Go AST)"},goroutine_leak:{id:"AST036",severity:"warning",category:"quality",name:"Goroutine Leak (Go AST)"},defer_in_loop:{id:"AST037",severity:"warning",category:"quality",name:"Defer Inside Loop (Go AST)"}};function toIssue(e,n,i){const t=RULES_BY_TYPE[i.type];return t?{file:e,line:i.line||0,category:t.category,type:i.type,severity:t.severity,id:t.id,name:t.name,message:i.message,code:snippet(n,i.line),source:"go-ast"}:null}function analyze(e,n){const i=resolveGoBin();if(!i)return[];let t,o;try{t=execFileSync(i,["run",HELPER_SCRIPT],{input:n,encoding:"utf8",timeout:8e3,maxBuffer:2097152,windowsHide:!0})}catch(e){return[]}try{o=JSON.parse(t)}catch(e){return[]}if(!o||!0!==o.ok||!Array.isArray(o.issues))return[];const r=n.split("\n"),a=[];for(const n of o.issues){const i=toIssue(e,r,n);i&&a.push(i)}return a}module.exports={analyze:analyze,_internal:{resolveGoBin:resolveGoBin,_resetGoBinCache:_resetGoBinCache,RULES_BY_TYPE:RULES_BY_TYPE}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const fs=require("fs"),path=require("path"),os=require("os"),crypto=require("crypto"),TRIAL_HMAC_SECRET_DEFAULT="thuban-trial-silverwings-2026",THUBAN_DIR=path.join(os.homedir(),".thuban"),USAGE_FILE=path.join(THUBAN_DIR,"usage.json"),LICENSE_FILE=path.join(THUBAN_DIR,"license.json"),ED25519_PUBLIC_KEY_DER_B64="MCowBQYDK2VwAyEAyytegj0i6LHfXajJXodgEW6kAS9HxkWok+H3gGEy1lA=";function _trialBase64urlDecode(e){const t=e+"===".slice((e.length+3)%4);return Buffer.from(t.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString("utf-8")}function _trialHmac8(e){const t=process.env.TRIAL_HMAC_SECRET||TRIAL_HMAC_SECRET_DEFAULT;return crypto.createHmac("sha256",t).update(e).digest("hex").substring(0,8)}function validateTrialKey(e){const t=e&&e.match(/^THUBAN-TRIAL-([A-Za-z0-9_-]+)-([A-Fa-f0-9]{8})$/);if(!t)return null;const s=t[1],r=t[2],a=_trialHmac8(`THUBAN-TRIAL-${s}`);if(r.toLowerCase()!==a.toLowerCase())return null;let i;try{i=JSON.parse(_trialBase64urlDecode(s))}catch(e){return null}if(!i||!i.x||!i.e)return null;const n=Math.floor(Date.now()/1e3),o=n>i.x,c=Math.max(0,Math.ceil((i.x-n)/86400));return{valid:!o,expired:o,email:i.e,name:i.n,invitedBy:i.i,expiresAt:new Date(1e3*i.x).toISOString(),daysRemaining:c,tier:"trial"}}const TIERS={free:{name:"Free",price:"$0/forever",maxFiles:100,maxProjects:3,scansPerMonth:200,showFullDetails:!0,showDashboard:!0,showAutoFix:!1,showCIAction:!1,showVSCode:!0,showMCP:!1,teaserIssues:1/0,maxHallucinationDetail:1/0},pro:{name:"Pro",price:"£29/month",maxFiles:1/0,maxProjects:1/0,scansPerMonth:1/0,showFullDetails:!0,showDashboard:!0,showAutoFix:!0,showCIAction:!1,showVSCode:!0,showMCP:!0,teaserIssues:1/0,maxHallucinationDetail:1/0},team:{name:"Team",price:"£99/month",maxFiles:1/0,maxProjects:1/0,scansPerMonth:1/0,showFullDetails:!0,showDashboard:!0,showAutoFix:!0,showCIAction:!0,showVSCode:!0,showMCP:!0,teaserIssues:1/0,maxHallucinationDetail:1/0},enterprise:{name:"Enterprise",price:"£299/month",maxFiles:1/0,maxProjects:1/0,scansPerMonth:1/0,showFullDetails:!0,showDashboard:!0,showAutoFix:!0,showCIAction:!0,showVSCode:!0,showMCP:!0,showSSO:!0,showAuditLogs:!0,showSLA:!0,teaserIssues:1/0,maxHallucinationDetail:1/0},trial:{name:"Trial",price:"Free (14 days)",maxFiles:1/0,maxProjects:1/0,scansPerMonth:1/0,showFullDetails:!0,showDashboard:!0,showAutoFix:!0,showCIAction:!0,showVSCode:!0,showMCP:!0,teaserIssues:1/0,maxHallucinationDetail:1/0}};class LicenseManager{constructor(){this._ensureDir(),this.machineId=this._getMachineId(),this.usage=this._loadUsage(),this.license=this._loadLicense()}getTier(){if("true"===process.env.THUBAN_DEV_MODE&&!__filename.includes("node_modules"))return"enterprise";if(!this.license||!this.license.key)return"free";if(this.license.key.startsWith("THUBAN-TRIAL-")){const e=validateTrialKey(this.license.key);return e?e.expired?(this._trialExpired=!0,"free"):(this._trialInfo=e,"trial"):"free"}return this._validateKey(this.license.key)&&this.license.tier||"free"}getTierConfig(){return"true"!==process.env.THUBAN_DEV_MODE||__filename.includes("node_modules")?TIERS[this.getTier()]||TIERS.free:TIERS.pro}canScan(){if("true"===process.env.THUBAN_DEV_MODE&&!__filename.includes("node_modules"))return{allowed:!0,remaining:1/0,devMode:!0};const e=this.getTierConfig();if(e.scansPerMonth===1/0)return{allowed:!0,remaining:1/0};const t=this._currentMonth(),s=this.usage.scans?.[t]||0,r=Math.max(0,e.scansPerMonth-s);return{allowed:r>0,remaining:r,limit:e.scansPerMonth,used:s,resetsOn:this._nextMonthDate()}}recordScan(){if("true"===process.env.THUBAN_DEV_MODE&&!__filename.includes("node_modules"))return;const e=this._currentMonth();this.usage.scans||(this.usage.scans={}),this.usage.scans[e]=(this.usage.scans[e]||0)+1,this.usage.lastScan=(new Date).toISOString(),this.usage.totalScans=(this.usage.totalScans||0)+1,this._saveUsage()}activate(e){if(e&&e.startsWith("THUBAN-TRIAL-")){const t=validateTrialKey(e);return t?t.expired?{success:!1,error:`Trial key expired on ${new Date(t.expiresAt).toLocaleDateString("en-GB")}. Upgrade at thuban.dev/pricing`}:(this.license={key:e,tier:"trial",activatedAt:(new Date).toISOString(),machineId:this.machineId,trialExpiresAt:t.expiresAt,trialEmail:t.email,trialName:t.name},this._saveLicense(),{success:!0,tier:"trial",tierName:"Trial (Pro features)",daysRemaining:t.daysRemaining,expiresAt:t.expiresAt}):{success:!1,error:"Invalid trial key format or signature"}}const t=this._validateKey(e);return t?(this.license={key:e,tier:t.tier,activatedAt:(new Date).toISOString(),machineId:this.machineId},this._saveLicense(),{success:!0,tier:t.tier,tierName:TIERS[t.tier]?.name||t.tier}):{success:!1,error:"Invalid license key format"}}deactivate(){return this.license={},this._saveLicense(),{success:!0}}getStatus(){const e=this.getTier(),t=this.getTierConfig(),s=this.canScan();let r=!1;return r="true"===process.env.THUBAN_DEV_MODE&&!__filename.includes("node_modules"),{tier:e,tierName:t.name,machineId:this.machineId.substring(0,8)+"...",licensed:"free"!==e,devMode:r,scansUsed:r?0:s.used||0,scansRemaining:s.remaining,scansLimit:r?1/0:s.limit||t.scansPerMonth,totalScans:this.usage.totalScans||0,..."trial"===e&&this._trialInfo?{trialDaysRemaining:this._trialInfo.daysRemaining,trialExpiresAt:this._trialInfo.expiresAt,trialName:this._trialInfo.name,trialEmail:this._trialInfo.email}:{},...this._trialExpired?{trialExpired:!0}:{},features:{fullDetails:t.showFullDetails,dashboard:t.showDashboard,autoFix:t.showAutoFix,ciAction:t.showCIAction,scheduledScans:"free"!==e&&"trial"!==e}}}canUseProFeature(e="This feature"){const t=this.getTier();return"free"===t?{allowed:!1,message:`${e} is available on Thuban Pro and above.`}:{allowed:!0,tier:t}}_ensureDir(){try{fs.existsSync(THUBAN_DIR)||fs.mkdirSync(THUBAN_DIR,{recursive:!0})}catch(e){}}_getMachineId(){const e=[os.hostname(),os.userInfo().username,os.platform(),os.arch()].join("|");try{const t=os.networkInterfaces(),s=Object.values(t).flat().filter(e=>!e.internal&&e.mac&&"00:00:00:00:00:00"!==e.mac).map(e=>e.mac).sort();if(s.length>0)return crypto.createHash("sha256").update(e+"|"+s[0]).digest("hex")}catch(e){}return crypto.createHash("sha256").update(e).digest("hex")}_loadUsage(){try{return JSON.parse(fs.readFileSync(USAGE_FILE,"utf-8"))}catch(e){return{scans:{},totalScans:0}}}_atomicWriteSync(e,t){const s=e+".tmp."+process.pid+"."+Date.now();try{fs.writeFileSync(s,t,"utf-8"),fs.renameSync(s,e)}catch(e){try{fs.unlinkSync(s)}catch{}}}_saveUsage(){try{this._atomicWriteSync(USAGE_FILE,JSON.stringify(this.usage,null,2))}catch(e){}}_loadLicense(){try{return JSON.parse(fs.readFileSync(LICENSE_FILE,"utf-8"))}catch(e){return{}}}_saveLicense(){try{this._atomicWriteSync(LICENSE_FILE,JSON.stringify(this.license,null,2))}catch(e){}}_validateKey(e){if(!e||"string"!=typeof e)return null;const t=e.match(/^THUBAN-(FREE|PRO|TEAM|ENT)-([A-Za-z0-9]{16})-([A-Fa-f0-9]{8,})$/);if(!t)return null;const s=t[1],r=t[2],a=t[3],i={FREE:"free",PRO:"pro",TEAM:"team",ENT:"enterprise"};try{const e=crypto.createPublicKey({key:Buffer.from(ED25519_PUBLIC_KEY_DER_B64,"base64"),format:"der",type:"spki"}),t=Buffer.from(`THUBAN-${s}-${r}`),n=Buffer.from(a,"hex");if(crypto.verify(null,t,e,n))return{tier:i[s]||"free",valid:!0,method:"ed25519"}}catch(e){}return null}_currentMonth(){const e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}`}_nextMonthDate(){const e=new Date;return new Date(e.getFullYear(),e.getMonth()+1,1).toISOString().split("T")[0]}static generateKey(e="PRO"){const t=process.env.THUBAN_SIGNING_PRIVATE_KEY;if(!t)throw new Error("THUBAN_SIGNING_PRIVATE_KEY environment variable is required to generate license keys. This keeps the signing key out of source control and off end-user machines.");const s=crypto.createPrivateKey({key:Buffer.from(t,"base64"),format:"der",type:"pkcs8"}),r=crypto.randomBytes(8).toString("hex"),a=Buffer.from(`THUBAN-${e}-${r}`);return`THUBAN-${e}-${r}-${crypto.sign(null,a,s).toString("hex")}`}}module.exports=LicenseManager,module.exports.validateTrialKey=validateTrialKey;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const parser=require("@babel/parser"),path=require("path"),fs=require("fs"),{joinLogicalStatements:joinLogicalStatements,extractBalanced:extractBalanced,splitTopLevelArgs:splitTopLevelArgs,isDynamicPyString:isDynamicPyString}=require("./ast-analyzer")._internal,BABEL_PLUGINS=["estree","typescript","jsx","classProperties","decorators-legacy"],MAX_TAINT_FILE_SIZE=2e4,MAX_FIXPOINT_ITERATIONS=10;function walk(e,t){if(e&&"object"==typeof e&&"string"==typeof e.type){t(e);for(const n in e){if("loc"===n||"range"===n||"start"===n||"end"===n)continue;const i=e[n];if(Array.isArray(i))for(const e of i)e&&"object"==typeof e&&"string"==typeof e.type&&walk(e,t);else i&&"object"==typeof i&&"string"==typeof i.type&&walk(i,t)}}}function lineOf(e){return e&&e.loc?e.loc.start.line:0}function snippet(e,t){return!t||t<1||t>e.length?"":e[t-1].trim().substring(0,100)}function mkTaintIssue(e,t,n,i){const r={file:e,line:t,category:"security",type:i.type,severity:i.severity||"critical",id:i.id,name:i.name,message:i.message,code:snippet(n,t),source:"taint",taintPath:i.taintPath};return i.crossFile&&(r.crossFile=!0,r.sourceFile=i.sourceFile),r}function fileTooLargeIssue(e,t){return{file:e,line:0,category:"quality",type:"file_too_large",severity:"info",id:"TAINT003",name:"Taint Analysis Skipped",message:`File too large (${t} chars) - taint analysis skipped (cap: 20000 chars)`,code:"",source:"taint"}}const SANITIZER_FUNCS=new Set(["parseInt","parseFloat","Number","Boolean","encodeURIComponent","encodeURI","escape","sanitize","sanitizeHtml","stripTags","escapeHtml","htmlEscape","htmlEncode","xssFilter","filterXSS","DOMPurify","purify","clean","validator"]),SANITIZER_MEMBER=new Set(["sanitize","escape","escapeHtml","stripTags","clean","escapeLiteral","escapeIdentifier","escapeId"]),SANITIZER_RECEIVER_NAMES=new Set(["dompurify","sanitizehtml","sanitize-html","html","xss","validator","bleach","markupsafe","purify","sqlstring","sanitizer","striptags","xssfilters","insane","mysql","mysql2","connection","conn","db","pool","pg","knex"]);function hasKnownSanitizerReceiver(e){let t=e,n=0;for(;t&&n++<20;){if("Identifier"===t.type)return SANITIZER_RECEIVER_NAMES.has(t.name.toLowerCase());if("MemberExpression"!==t.type)return!1;t=t.object}return!1}const JS_SOURCE_PATH_PATTERNS=[{re:/^req\.(params|query|body|headers)(\.|$)/,severity:"critical"},{re:/^request\.(params|query|body|headers)(\.|$)/,severity:"critical"},{re:/^process\.argv/,severity:"critical"},{re:/^process\.env/,severity:"warning"},{re:/^document\.location/,severity:"critical"},{re:/^window\.location/,severity:"critical"},{re:/^location\.(search|hash|href)/,severity:"critical"}];function memberChainToPath(e){const t=[];let n=e,i=0;for(;n&&i++<20;){if("Identifier"===n.type){t.unshift(n.name);break}if("ThisExpression"===n.type){t.unshift("this");break}if("MemberExpression"!==n.type)return null;n.computed||"Identifier"!==n.property.type?t.unshift("*"):t.unshift(n.property.name),n=n.object}return t.length?t.join("."):null}function jsSourceSeverity(e){if(!e)return null;if("CallExpression"===e.type&&"Identifier"===e.callee.type&&"prompt"===e.callee.name)return"critical";if("NewExpression"===e.type&&"Identifier"===e.callee.type&&("URLSearchParams"===e.callee.name||"FormData"===e.callee.name))return"critical";const t=memberChainToPath(e);if(t)for(const e of JS_SOURCE_PATH_PATTERNS)if(e.re.test(t))return e.severity;return null}function isJSSourceExpr(e){return null!==jsSourceSeverity(e)}function describeJSSource(e){return memberChainToPath(e)||("CallExpression"===e.type&&"Identifier"===e.callee.type&&"prompt"===e.callee.name?"prompt()":"NewExpression"===e.type&&"Identifier"===e.callee.type?`new ${e.callee.name}()`:"tainted source")}function isSanitizerCall(e){return!(!e||"CallExpression"!==e.type)&&(!("Identifier"!==e.callee.type||!SANITIZER_FUNCS.has(e.callee.name))||!("MemberExpression"!==e.callee.type||"Identifier"!==e.callee.property.type||!SANITIZER_MEMBER.has(e.callee.property.name))&&hasKnownSanitizerReceiver(e.callee.object))}function isNumericCoercionCall(e){return!(!e||"CallExpression"!==e.type||"Identifier"!==e.callee.type||"parseInt"!==e.callee.name&&"parseFloat"!==e.callee.name&&"Number"!==e.callee.name)}function isTaintedExpr(e,t,n){if(n=n||0,!e||n>12)return!1;if("Identifier"===e.type)return t.has(e.name);if("CallExpression"===e.type){if(isSanitizerCall(e))return!1;if(isJSSourceExpr(e))return!0;if("MemberExpression"===e.callee.type&&isTaintedExpr(e.callee.object,t,n+1))return!0;for(const i of e.arguments)if(isTaintedExpr(i,t,n+1))return!0;return!1}return"MemberExpression"===e.type?!!isJSSourceExpr(e)||isTaintedExpr(e.object,t,n+1):"NewExpression"===e.type?isJSSourceExpr(e):"BinaryExpression"===e.type&&"+"===e.operator?isTaintedExpr(e.left,t,n+1)||isTaintedExpr(e.right,t,n+1):"TemplateLiteral"===e.type?(e.expressions||[]).some(e=>isTaintedExpr(e,t,n+1)):"AssignmentExpression"===e.type?isTaintedExpr(e.right,t,n+1):"ConditionalExpression"===e.type?isTaintedExpr(e.consequent,t,n+1)||isTaintedExpr(e.alternate,t,n+1):"LogicalExpression"===e.type?isTaintedExpr(e.left,t,n+1)||isTaintedExpr(e.right,t,n+1):!("SequenceExpression"!==e.type||!e.expressions.length)&&isTaintedExpr(e.expressions[e.expressions.length-1],t,n+1)}function isDynamicTaintedBuild(e,t){return!!e&&("TemplateLiteral"===e.type?(e.expressions||[]).some(e=>isTaintedExpr(e,t)):"BinaryExpression"===e.type&&"+"===e.operator&&(isTaintedExpr(e.left,t)||isTaintedExpr(e.right,t)))}function collectFunctionReturnNodes(e){const t=[];return e.body&&"BlockStatement"===e.body.type?function n(i){if(i&&"object"==typeof i&&"string"==typeof i.type&&(i===e||"FunctionDeclaration"!==i.type&&"FunctionExpression"!==i.type&&"ArrowFunctionExpression"!==i.type)){"ReturnStatement"===i.type&&i.argument&&t.push(i.argument);for(const e in i){if("loc"===e||"range"===e||"start"===e||"end"===e)continue;const t=i[e];if(Array.isArray(t))for(const e of t)e&&"object"==typeof e&&"string"==typeof e.type&&n(e);else t&&"object"==typeof t&&"string"==typeof t.type&&n(t)}}}(e.body):e.body&&t.push(e.body),t}function findTaintOrigin(e,t){let n=null;return walk(e,e=>{if(!n)if("Identifier"===e.type&&t.has(e.name))n=t.get(e.name);else{const t=jsSourceSeverity(e);t&&(n={desc:describeJSSource(e),line:lineOf(e),severity:t})}}),n}function collectTaintedVars(e,t){const n=new Set,i=new Map,r=new Set,a=new Map;if(t)for(const[e,r]of t)n.add(e),i.set(e,r);let s=!0,o=0;function l(e){return!(!e||"CallExpression"!==e.type||"Identifier"!==e.callee.type||!r.has(e.callee.name))}for(;s&&o<10;)s=!1,o++,walk(e,e=>{if("FunctionDeclaration"!==e.type&&"FunctionExpression"!==e.type&&"ArrowFunctionExpression"!==e.type)return;const t=e.id&&e.id.name;if(t&&!r.has(t))for(const o of collectFunctionReturnNodes(e))if(isTaintedExpr(o,n)||l(o)){r.add(t),a.set(t,findTaintOrigin(o,i)||(l(o)?a.get(o.callee.name):null)||{desc:describeJSSource(o),line:lineOf(o),severity:jsSourceSeverity(o)||"critical"}),s=!0;break}}),walk(e,e=>{let t=null,r=null;if("VariableDeclarator"===e.type&&e.init&&"Identifier"===e.id.type?(t=e.id.name,r=e.init):"AssignmentExpression"===e.type&&"="===e.operator&&"Identifier"===e.left.type&&(t=e.left.name,r=e.right),t&&r&&n.has(t)&&(isSanitizerCall(r)||isNumericCoercionCall(r)))return n.delete(t),i.delete(t),void(s=!0);if(!t||n.has(t))return;const o=l(r);if(isTaintedExpr(r,n)||o){n.add(t),s=!0;const l=findTaintOrigin(r,i)||(o?a.get(r.callee.name):null)||{desc:describeJSSource(r),line:lineOf(e),severity:jsSourceSeverity(r)||"critical"};i.set(t,l)}});return{taintedVars:n,origins:i}}const SQL_METHODS=new Set(["query","execute","raw","where"]);function parseJS(e){try{return parser.parse(e,{sourceType:"unambiguous",plugins:BABEL_PLUGINS,allowReturnOutsideFunction:!0,allowImportExportEverywhere:!0,allowAwaitOutsideFunction:!0,allowSuperOutsideMethod:!0,allowUndeclaredExports:!0,errorRecovery:!1}).program}catch(e){return null}}function analyzeJSTaint(e,t,n){const i=[],r=t.split("\n"),a=parseJS(t);if(!a)return i;const{taintedVars:s,origins:o}=collectTaintedVars(a,n),l=new Set;function c(t,n){const a=lineOf(t),s=`${a}:${n.id}`;if(l.has(s))return;l.add(s);const c=findTaintOrigin(t,o);c&&(n=Object.assign({},n,{severity:c.severity||"critical"}),c.crossFile&&(n=Object.assign({},n,{crossFile:!0,sourceFile:c.sourceFile}))),i.push(mkTaintIssue(e,a,r,n))}function p(e){const t=findTaintOrigin(e,o);if(t)return`${t.crossFile?`${t.sourceFile}: `:""}${t.desc} (line ${t.line}) -> sink (line ${lineOf(e)})`}return walk(a,e=>{if("CallExpression"===e.type&&"MemberExpression"===e.callee.type&&"Identifier"===e.callee.property.type&&SQL_METHODS.has(e.callee.property.name)){const t=e.arguments[0];t&&(isDynamicTaintedBuild(t,s)||isTaintedExpr(t,s))&&c(e,{type:"sql_injection",id:"TAINT001",name:"Tainted SQL Injection",message:`Tainted user input flows into .${e.callee.property.name}() without sanitization - SQL injection risk`,taintPath:p(e)})}if("AssignmentExpression"!==e.type||"MemberExpression"!==e.left.type||"Identifier"!==e.left.property.type||"innerHTML"!==e.left.property.name&&"outerHTML"!==e.left.property.name||(isTaintedExpr(e.right,s)||isDynamicTaintedBuild(e.right,s))&&c(e,{type:"xss",id:"TAINT002",name:"Tainted XSS via "+e.left.property.name,message:`Tainted user input flows into ${e.left.property.name} without sanitization - XSS risk`,taintPath:p(e)}),"CallExpression"===e.type&&"MemberExpression"===e.callee.type&&"Identifier"===e.callee.object.type&&"document"===e.callee.object.name&&"Identifier"===e.callee.property.type&&("write"===e.callee.property.name||"writeln"===e.callee.property.name)){const t=e.arguments[0];t&&(isTaintedExpr(t,s)||isDynamicTaintedBuild(t,s))&&c(e,{type:"xss",id:"TAINT002",name:`Tainted XSS via document.${e.callee.property.name}()`,message:`Tainted user input flows into document.${e.callee.property.name}() without sanitization - XSS risk`,taintPath:p(e)})}if("JSXAttribute"===e.type&&e.name&&"dangerouslySetInnerHTML"===e.name.name&&e.value&&"JSXExpressionContainer"===e.value.type){const t=e.value.expression;if(t&&"ObjectExpression"===t.type){const n=t.properties.find(e=>e.key&&("__html"===e.key.name||"__html"===e.key.value));n&&(isTaintedExpr(n.value,s)||isDynamicTaintedBuild(n.value,s))&&c(e,{type:"xss",id:"TAINT002",name:"Tainted XSS via dangerouslySetInnerHTML",message:"Tainted user input flows into dangerouslySetInnerHTML without sanitization - XSS risk",taintPath:p(e)})}}if("CallExpression"===e.type&&"MemberExpression"===e.callee.type&&"Identifier"===e.callee.object.type&&/^res(ponse)?$/.test(e.callee.object.name)&&"Identifier"===e.callee.property.type&&("send"===e.callee.property.name||"write"===e.callee.property.name)){const t=e.arguments[0];t&&"ObjectExpression"!==t.type&&"ArrayExpression"!==t.type&&(isTaintedExpr(t,s)||isDynamicTaintedBuild(t,s))&&c(e,{type:"xss",id:"TAINT002",name:`Reflected XSS via ${e.callee.object.name}.${e.callee.property.name}()`,message:`Tainted user input is reflected via ${e.callee.object.name}.${e.callee.property.name}() without sanitization - reflected XSS risk`,taintPath:p(e)})}}),i}const PY_SOURCE_PATTERNS=[/\brequest\.args\b/,/\brequest\.form\b/,/\brequest\.json\b/,/\brequest\.data\b/,/\brequest\.GET\b/,/\brequest\.POST\b/,/\bsys\.argv\b/,/\bos\.environ\b/,/\binput\s*\(/],PY_SANITIZER_WRAP_RE=/^\s*(int|float|re\.escape|html\.escape|escape|markupsafe\.escape|bleach\.clean)\s*\(/;function describePySource(e){for(const t of PY_SOURCE_PATTERNS){const n=e.match(t);if(n)return n[0]}return"tainted source"}function isPySourceText(e){return PY_SOURCE_PATTERNS.some(t=>t.test(e))}function isDynamicPyText(e){return isDynamicPyString(e)}function collectPyTaintedVars(e){const t=new Set,n=new Map;let i=!0,r=0;const a=/^\s*([A-Za-z_]\w*)\s*=(?!=)\s*([\s\S]+?)\s*$/;for(;i&&r<10;){i=!1,r++;for(const r of e){const e=r.text.split("\n")[0].match(a)||r.text.match(a);if(!e)continue;const s=e[1],o=r.text.slice(r.text.indexOf("=")+1);if(PY_SANITIZER_WRAP_RE.test(o.trim())){t.has(s)&&(t.delete(s),n.delete(s),i=!0);continue}if(t.has(s))continue;let l=!1,c=null;if(isPySourceText(o))l=!0,c=describePySource(o);else for(const e of t)if(new RegExp("\\b"+e+"\\b").test(o)){l=!0,c=n.has(e)?n.get(e).desc:e;break}l&&(t.add(s),n.set(s,{desc:c,line:r.startLine}),i=!0)}}return{taintedVars:t,origins:n}}function textReferencesTaint(e,t){if(isPySourceText(e))return!0;for(const n of t)if(new RegExp("\\b"+n+"\\b").test(e))return!0;return!1}function analyzePythonTaint(e,t){const n=[],i=t.split("\n"),r=joinLogicalStatements(t),{taintedVars:a,origins:s}=collectPyTaintedVars(r),o=new Set;function l(t,r){const a=`${t}:${r.id}`;o.has(a)||(o.add(a),n.push(mkTaintIssue(e,t,i,r)))}function c(e,t){for(const n of a)if(new RegExp("\\b"+n+"\\b").test(e)&&s.has(n)){const e=s.get(n);return`${e.desc} (line ${e.line}) -> sink (line ${t})`}if(isPySourceText(e))return`${describePySource(e)} -> sink (line ${t})`}for(const e of r){const t=e.text,n=e.startLine,i=t.match(/\b(?:cursor|db|conn|connection)\.execute\s*\(/);if(i){const e=t.indexOf("(",i.index),r=extractBalanced(t,e),s=splitTopLevelArgs(r)[0]||"";isDynamicPyText(s)&&textReferencesTaint(s,a)&&l(n,{type:"sql_injection",id:"TAINT001",name:"Tainted SQL Injection",message:"Tainted user input flows into .execute() without sanitization - SQL injection risk",taintPath:c(s,n)})}const r=t.match(/\.(raw|extra)\s*\(|\bRawSQL\s*\(/);if(r){const e=t.indexOf("(",r.index),i=extractBalanced(t,e),s=splitTopLevelArgs(i)[0]||"";(isDynamicPyText(s)||isPySourceText(s))&&textReferencesTaint(s,a)&&l(n,{type:"sql_injection",id:"TAINT001",name:"Tainted SQL Injection (Django)",message:"Tainted user input flows into raw SQL construct without sanitization - SQL injection risk",taintPath:c(s,n)})}const s=t.match(/\btext\s*\(/);if(s){const e=t.indexOf("(",s.index),i=extractBalanced(t,e);isDynamicPyText(i)&&textReferencesTaint(i,a)&&l(n,{type:"sql_injection",id:"TAINT001",name:"Tainted SQL Injection (SQLAlchemy text())",message:"Tainted user input flows into SQLAlchemy text() without sanitization - SQL injection risk",taintPath:c(i,n)})}const o=t.match(/\bmark_safe\s*\(/);if(o){const e=t.indexOf("(",o.index),i=extractBalanced(t,e);textReferencesTaint(i,a)&&l(n,{type:"xss",id:"TAINT002",name:"Tainted XSS via mark_safe()",message:"Tainted user input flows into mark_safe() without sanitization - XSS risk",taintPath:c(i,n)})}const p=t.match(/\{\{\s*([A-Za-z_][\w.]*)[^}]*\|\s*safe\b/);p&&textReferencesTaint(p[1],a)&&l(n,{type:"xss",id:"TAINT002",name:"Tainted XSS via Jinja2 |safe filter",message:"Tainted user input is rendered with the |safe filter without sanitization - XSS risk",taintPath:c(p[1],n)})}return n}const JS_RESOLVE_EXTS=["",".js",".jsx",".ts",".tsx",".mjs",".cjs",path.sep+"index.js",path.sep+"index.ts",path.sep+"index.jsx",path.sep+"index.tsx"];function resolveImportPath(e,t,n){if(!t||!t.startsWith(".")&&!path.isAbsolute(t))return null;const i=path.dirname(e),r=path.isAbsolute(t)?t:path.resolve(i,t);for(const e of JS_RESOLVE_EXTS){const t=r+e;if(n(t))return t}return null}function defaultFileExists(e){try{return fs.statSync(e).isFile()}catch(e){return!1}}function extractImportBindings(e){const t=[];return walk(e,e=>{if("ImportDeclaration"===e.type&&e.source&&"string"==typeof e.source.value){const n=e.source.value;for(const i of e.specifiers||[])if("ImportDefaultSpecifier"===i.type)t.push({localName:i.local.name,importedName:"default",source:n});else if("ImportNamespaceSpecifier"===i.type)t.push({localName:i.local.name,importedName:"*",source:n});else if("ImportSpecifier"===i.type){const e=i.imported&&(i.imported.name||i.imported.value);t.push({localName:i.local.name,importedName:e||i.local.name,source:n})}}if("VariableDeclarator"===e.type&&e.init){const n=unwrapRequireCall(e.init);if(n)if("Identifier"===e.id.type)t.push({localName:e.id.name,importedName:"*",source:n});else if("ObjectPattern"===e.id.type)for(const i of e.id.properties)if("ObjectProperty"===i.type||"Property"===i.type){const e=i.key&&(i.key.name||i.key.value),r=i.value&&"Identifier"===i.value.type?i.value.name:e;e&&r&&t.push({localName:r,importedName:e,source:n})}}if("AssignmentExpression"===e.type&&"="===e.operator&&"Identifier"===e.left.type){const n=unwrapRequireCall(e.right);n&&t.push({localName:e.left.name,importedName:"*",source:n})}if("CallExpression"===e.type&&"MemberExpression"===e.callee.type&&"Identifier"===e.callee.property.type&&"then"===e.callee.property.name&&"ImportExpression"===e.callee.object.type&&e.callee.object.source&&"string"==typeof e.callee.object.source.value){const n=e.callee.object.source.value,i=e.arguments[0];i&&("ArrowFunctionExpression"===i.type||"FunctionExpression"===i.type)&&i.params[0]&&"Identifier"===i.params[0].type&&t.push({localName:i.params[0].name,importedName:"*",source:n})}}),t}function unwrapRequireCall(e){if(!e||"CallExpression"!==e.type)return null;if("Identifier"!==e.callee.type||"require"!==e.callee.name)return null;const t=e.arguments[0];return t&&"string"==typeof t.value?t.value:null}function extractReExports(e){const t=[];return walk(e,e=>{if("ExportNamedDeclaration"===e.type&&e.source&&"string"==typeof e.source.value){const n=e.source.value;for(const i of e.specifiers||[]){const e=i.local&&(i.local.name||i.local.value),r=i.exported&&(i.exported.name||i.exported.value);e&&r&&t.push({importedName:e,exportedName:r,source:n})}}if("ExportAllDeclaration"===e.type&&e.source&&"string"==typeof e.source.value&&t.push({importedName:"*",exportedName:"*",source:e.source.value}),"AssignmentExpression"===e.type&&"="===e.operator&&"MemberExpression"===e.left.type&&"module.exports"===memberChainToPath(e.left)){const n=unwrapRequireCall(e.right);n&&t.push({importedName:"*",exportedName:"*",source:n})}}),t}function extractLocalExports(e){const t=[];return walk(e,e=>{if("AssignmentExpression"===e.type&&"="===e.operator&&"MemberExpression"===e.left.type&&!e.left.computed&&"Identifier"===e.left.property.type){const n=memberChainToPath(e.left.object);"module.exports"!==n&&"exports"!==n||t.push({exportedName:e.left.property.name,localName:null,inlineNode:e.right})}if("AssignmentExpression"===e.type&&"="===e.operator&&"MemberExpression"===e.left.type&&"module.exports"===memberChainToPath(e.left)&&"ObjectExpression"===e.right.type)for(const n of e.right.properties){if("ObjectProperty"!==n.type&&"Property"!==n.type)continue;const e=n.key&&(n.key.name||n.key.value);e&&(n.value&&"Identifier"===n.value.type?t.push({exportedName:e,localName:n.value.name,inlineNode:null}):t.push({exportedName:e,localName:null,inlineNode:n.value}))}if("ExportNamedDeclaration"===e.type&&e.declaration){const n=e.declaration;if("VariableDeclaration"===n.type)for(const e of n.declarations)"Identifier"===e.id.type&&t.push({exportedName:e.id.name,localName:e.id.name,inlineNode:e.init||null});else"FunctionDeclaration"!==n.type&&"ClassDeclaration"!==n.type||!n.id||t.push({exportedName:n.id.name,localName:n.id.name,inlineNode:null})}if("ExportNamedDeclaration"===e.type&&!e.source)for(const n of e.specifiers||[]){const e=n.local&&(n.local.name||n.local.value),i=n.exported&&(n.exported.name||n.exported.value);e&&i&&t.push({exportedName:i,localName:e,inlineNode:null})}if("ExportDefaultDeclaration"===e.type){const n=e.declaration;n&&("FunctionDeclaration"===n.type||"ClassDeclaration"===n.type)&&n.id?t.push({exportedName:"default",localName:n.id.name,inlineNode:null}):n&&"Identifier"===n.type?t.push({exportedName:"default",localName:n.name,inlineNode:null}):t.push({exportedName:"default",localName:null,inlineNode:n})}}),t}function buildExportTaintMap(e,t){const n=(t=t||{}).readFile||(e=>fs.readFileSync(e,"utf8").replace(/\r\n/g,"\n")),i=t.fileExists||defaultFileExists,r=t.parsedCache||null,a=new Map;for(const t of e){const e=path.extname(t).toLowerCase();if(!JS_EXTS.has(e))continue;let i;try{i=n(t)}catch(e){continue}if(r&&r.set(t,{content:i,ast:null}),i.length>2e4)continue;const s=parseJS(i);r&&(r.get(t).ast=s),s&&a.set(t,{ast:s,content:i})}const s=new Map;for(const e of a.keys())s.set(e,new Map);const o=Math.max(10,a.size+1);let l=!0,c=0;for(;l&&c<o;){l=!1,c++;for(const[e,{ast:t}]of a){const n=s.get(e),r=extractImportBindings(t),a=new Map;for(const t of r){const n=resolveImportPath(e,t.source,i);if(!n||!s.has(n))continue;const r=s.get(n);if("*"===t.importedName)for(const[,e]of r)a.has(t.localName)||a.set(t.localName,e);else r.has(t.importedName)&&a.set(t.localName,r.get(t.importedName))}const{taintedVars:o,origins:c}=collectTaintedVars(t,a),p=extractLocalExports(t);for(const t of p){if(n.has(t.exportedName))continue;let i=null;if(t.localName&&o.has(t.localName)?i=c.get(t.localName)||{desc:t.localName,line:0}:t.inlineNode&&(isTaintedExpr(t.inlineNode,o)||isDynamicTaintedBuild(t.inlineNode,o))&&(i=findTaintOrigin(t.inlineNode,c)||{desc:describeJSSource(t.inlineNode),line:lineOf(t.inlineNode)}),i){const r=i.crossFile?i.sourceFile:e;n.set(t.exportedName,{desc:i.desc,line:i.line,sourceFile:r,crossFile:!0}),l=!0}}const u=extractReExports(t);for(const t of u){const r=resolveImportPath(e,t.source,i);if(!r||!s.has(r))continue;const a=s.get(r);if("*"===t.importedName)for(const[e,t]of a)n.has(e)||(n.set(e,t),l=!0);else a.has(t.importedName)&&!n.has(t.exportedName)&&(n.set(t.exportedName,a.get(t.importedName)),l=!0)}}}return s}function buildImportSeeds(e,t,n,i){const r=new Map,a=extractImportBindings(t);for(const t of a){const a=resolveImportPath(e,t.source,i);if(!a||!n.has(a))continue;const s=n.get(a);if("*"===t.importedName)for(const[,e]of s)r.has(t.localName)||r.set(t.localName,e);else s.has(t.importedName)&&r.set(t.localName,s.get(t.importedName))}return r}function analyzeProject(e,t){const n=(t=t||{}).readFile||(e=>fs.readFileSync(e,"utf8").replace(/\r\n/g,"\n")),i=t.fileExists||defaultFileExists,r=new Map,a=buildExportTaintMap(e,{readFile:n,fileExists:i,parsedCache:r}),s=[];for(const t of e){const e=path.extname(t).toLowerCase(),o=r.get(t);let l;if(o)l=o.content;else try{l=n(t)}catch(e){continue}if(l.length>2e4)(JS_EXTS.has(e)||PY_EXTS.has(e))&&s.push(fileTooLargeIssue(t,l.length));else try{if(JS_EXTS.has(e)){const e=o?o.ast:parseJS(l);if(!e)continue;const n=buildImportSeeds(t,e,a,i);s.push(...analyzeJSTaint(t,l,n.size?n:void 0))}else PY_EXTS.has(e)&&s.push(...analyzePythonTaint(t,l))}catch(e){}}return s}const JS_EXTS=new Set([".js",".jsx",".ts",".tsx",".mjs",".cjs"]),PY_EXTS=new Set([".py",".pyw"]);function analyze(e,t){if(t.length>2e4)return[fileTooLargeIssue(e,t.length)];const n=path.extname(e).toLowerCase();try{if(JS_EXTS.has(n))return analyzeJSTaint(e,t);if(PY_EXTS.has(n))return analyzePythonTaint(e,t)}catch(e){return[]}return[]}module.exports={analyze:analyze,analyzeProject:analyzeProject,analyzeJSTaint:analyzeJSTaint,analyzePythonTaint:analyzePythonTaint,buildExportTaintMap:buildExportTaintMap,buildImportSeeds:buildImportSeeds,resolveImportPath:resolveImportPath,_internal:{walk:walk,isTaintedExpr:isTaintedExpr,isJSSourceExpr:isJSSourceExpr,isSanitizerCall:isSanitizerCall,collectTaintedVars:collectTaintedVars,memberChainToPath:memberChainToPath,isPySourceText:isPySourceText,isDynamicPyText:isDynamicPyText,collectPyTaintedVars:collectPyTaintedVars,resolveImportPath:resolveImportPath,extractImportBindings:extractImportBindings,extractReExports:extractReExports,extractLocalExports:extractLocalExports,parseJS:parseJS}};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|