@dailephd/my-dev-kit-lab 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +11 -8
  2. package/dist/scripts/security/validate.js +8 -18
  3. package/dist/src/audits/codeRot/detectors/deadCodeCandidateDetector.js +96 -0
  4. package/dist/src/audits/codeRot/detectors/docsCodeMismatchDetector.js +202 -4
  5. package/dist/src/audits/codeRot/detectors/duplicateImplementationDetector.js +19 -1
  6. package/dist/src/audits/codeRot/detectors/testRotDetector.js +126 -0
  7. package/dist/src/audits/codeRot/utils/jvmSourceFactsUtils.js +153 -0
  8. package/dist/src/audits/core/collectSourceFacts.js +21 -10
  9. package/dist/src/audits/core/javaAnalyzer.js +282 -0
  10. package/dist/src/audits/core/jvmProjectMetadata.js +106 -0
  11. package/dist/src/audits/core/kotlinAnalyzer.js +280 -0
  12. package/dist/src/audits/core/languageAnalyzerRegistry.js +9 -3
  13. package/dist/src/audits/core/projectInventory.js +41 -0
  14. package/dist/src/audits/security/securityAuditAdapter.js +15 -12
  15. package/dist/src/securityValidation/report/writeSecurityReportFiles.js +28 -0
  16. package/package.json +97 -97
  17. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/README.md +16 -0
  18. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/build.gradle.kts +4 -0
  19. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/java/com/example/Widget.java +7 -0
  20. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/kotlin/com/example/Gadget.kt +7 -0
  21. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/README.md +10 -0
  22. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/build/Main.class +1 -0
  23. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/dist/index.js +1 -0
  24. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/generated/schema.ts +1 -0
  25. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/src/index.ts +3 -0
  26. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/vendor/lib.py +2 -0
  27. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/README.md +10 -0
  28. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/build.gradle.kts +8 -0
  29. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/settings.gradle.kts +1 -0
  30. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/java/com/example/FooService.java +7 -0
  31. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/kotlin/com/example/BarService.kt +7 -0
  32. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/java/com/example/FooServiceTest.java +8 -0
  33. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/kotlin/com/example/BarServiceTest.kt +8 -0
  34. package/tests/fixtures/audits/mixed-language/mixed-python-ts/README.md +8 -0
  35. package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/app.py +7 -0
  36. package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/index.ts +3 -0
  37. package/tests/fixtures/audits/mixed-language/mixed-python-ts/tests/test_app.py +5 -0
  38. package/tests/fixtures/audits/mixed-language/mixed-ts-js/README.md +7 -0
  39. package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/helper.js +5 -0
  40. package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/index.ts +3 -0
  41. package/tests/fixtures/audits/mixed-language/mixed-ts-js/tests/index.sample.ts +5 -0
  42. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/README.md +10 -0
  43. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/build.gradle.kts +4 -0
  44. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/pytests/test_app.py +5 -0
  45. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/app.py +2 -0
  46. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/helper.js +5 -0
  47. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/index.ts +3 -0
  48. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/java/com/example/Multiplier.java +7 -0
  49. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/kotlin/com/example/Divider.kt +7 -0
@@ -1,5 +1,7 @@
1
1
  import { TYPESCRIPT_JAVASCRIPT_ANALYZER } from "./typescriptJavaScriptAnalyzer.js";
2
2
  import { PYTHON_ANALYZER } from "./pythonAnalyzer.js";
3
+ import { JAVA_ANALYZER } from "./javaAnalyzer.js";
4
+ import { KOTLIN_ANALYZER } from "./kotlinAnalyzer.js";
3
5
  // Validates a list has no duplicate analyzer ids. Later batches call this
4
6
  // when assembling their own registries; Batch 2's empty default trivially
5
7
  // passes.
@@ -27,10 +29,14 @@ export function selectLanguageAnalyzer(registry, language, extension) {
27
29
  return null;
28
30
  }
29
31
  // v0.3.1 Batch 3 -- registers the TypeScript/JavaScript analyzer. v0.3.2
30
- // Batch 1 adds the Python analyzer alongside it. Java and Kotlin remain
31
- // fallback-only (no analyzer registered for them) -- see
32
- // collectSourceFacts.ts's fallback policy.
32
+ // Batch 1 adds the Python analyzer alongside it. v0.3.3 Batch 1 adds Java
33
+ // and Kotlin (see javaAnalyzer.ts/kotlinAnalyzer.ts) -- no other language
34
+ // remains fallback-only by design change here; any language not in this
35
+ // list still degrades through collectSourceFacts.ts's existing fallback
36
+ // policy unchanged.
33
37
  export const DEFAULT_LANGUAGE_ANALYZER_REGISTRY = createLanguageAnalyzerRegistry([
34
38
  TYPESCRIPT_JAVASCRIPT_ANALYZER,
35
39
  PYTHON_ANALYZER,
40
+ JAVA_ANALYZER,
41
+ KOTLIN_ANALYZER,
36
42
  ]);
@@ -384,6 +384,25 @@ function isPythonTestFile(relativePath, basename) {
384
384
  return true;
385
385
  return /^test_.*\.py$/.test(basename) || /^.*_test\.py$/.test(basename);
386
386
  }
387
+ // v0.3.3 Batch 1 -- conservative JVM (Java/Kotlin) test naming/source-set
388
+ // conventions. Gated to .java/.kt so this can never reclassify an unrelated
389
+ // file. "tests/**/*.java" and "tests/**/*.kt" are already covered by the
390
+ // generic, extension-agnostic check above; this adds the Gradle/Maven
391
+ // standard "src/test/{java,kotlin}" source-set layout, the singular "test/"
392
+ // directory convention (same style as isPythonTestFile's "test/" check
393
+ // above), and the "*Test(s).java" / "*Test(s).kt" / "*Spec.kt" filename
394
+ // conventions.
395
+ function isJvmTestFile(relativePath, basename, extension) {
396
+ if (relativePath.includes("src/test/java/") || relativePath.includes("src/test/kotlin/"))
397
+ return true;
398
+ if (relativePath.startsWith("test/") || relativePath.includes("/test/"))
399
+ return true;
400
+ if (extension === ".java")
401
+ return /Tests?\.java$/.test(basename);
402
+ if (extension === ".kt")
403
+ return /Tests?\.kt$/.test(basename) || /Spec\.kt$/.test(basename);
404
+ return false;
405
+ }
387
406
  function isTestFile(relativePath, basename, extension) {
388
407
  if (relativePath.startsWith("tests/") || relativePath.includes("/tests/"))
389
408
  return true;
@@ -391,6 +410,8 @@ function isTestFile(relativePath, basename, extension) {
391
410
  return true;
392
411
  if (extension === ".py" && isPythonTestFile(relativePath, basename))
393
412
  return true;
413
+ if ((extension === ".java" || extension === ".kt") && isJvmTestFile(relativePath, basename, extension))
414
+ return true;
394
415
  return false;
395
416
  }
396
417
  // v0.3.2 Batch 1 -- recognized Python project/config metadata filenames.
@@ -405,6 +426,24 @@ const PYTHON_PROJECT_METADATA_FILE_NAMES = new Set([
405
426
  "tox.ini",
406
427
  "pytest.ini",
407
428
  ]);
429
+ // v0.3.3 Batch 1 -- recognized JVM (Gradle/Maven) project/build metadata
430
+ // filenames. Same narrow, basename-only convention as
431
+ // PYTHON_PROJECT_METADATA_FILE_NAMES above: does not match arbitrary *.xml/
432
+ // *.properties files, only these exact names. `build.gradle.kts` and
433
+ // `settings.gradle.kts` matter in particular: without this, a Gradle Kotlin
434
+ // DSL build script would otherwise fall through to the generic
435
+ // KNOWN_SOURCE_EXTENSIONS ".kts" -> "source" classification below and be fed
436
+ // to the Kotlin source-facts analyzer as if it were application code.
437
+ const JVM_PROJECT_METADATA_FILE_NAMES = new Set([
438
+ "build.gradle",
439
+ "build.gradle.kts",
440
+ "settings.gradle",
441
+ "settings.gradle.kts",
442
+ "pom.xml",
443
+ "gradle.properties",
444
+ "gradlew",
445
+ "gradlew.bat",
446
+ ]);
408
447
  function isConfigFile(relativePath, basename, extension) {
409
448
  if (/^tsconfig(\..+)?\.json$/.test(basename))
410
449
  return true;
@@ -420,6 +459,8 @@ function isConfigFile(relativePath, basename, extension) {
420
459
  // here for the same "project metadata, not source" reasoning.
421
460
  if (basename === "setup.py" || PYTHON_PROJECT_METADATA_FILE_NAMES.has(basename))
422
461
  return true;
462
+ if (JVM_PROJECT_METADATA_FILE_NAMES.has(basename))
463
+ return true;
423
464
  // Root-level dotfile configs (e.g. .prettierrc, .babelrc) not already
424
465
  // covered above -- deliberately conservative (root-only, not recursive)
425
466
  // to avoid misclassifying dotfiles inside fixture/benchmark projects.
@@ -1,9 +1,8 @@
1
- import fs from "node:fs";
2
1
  import path from "node:path";
3
2
  import { runSecurityValidation } from "../../securityValidation/validate/runSecurityValidation.js";
4
3
  import { reportFilenamePrefix } from "../../securityValidation/validate/resolveTarget.js";
5
- import { renderJsonReport, renderTextReport } from "../../securityValidation/report/renderSecurityReport.js";
6
4
  import { buildSecurityReportFromSummary } from "../../securityValidation/report/buildSecurityReport.js";
5
+ import { writeSecurityReportFiles } from "../../securityValidation/report/writeSecurityReportFiles.js";
7
6
  import { DEFAULT_SECURITY_CHECKS, DEFAULT_SECURITY_PROFILE } from "../../securityValidation/validate/cliOptions.js";
8
7
  import { verdictToHumanLabel } from "../../securityValidation/validate/verdict.js";
9
8
  import { mapSecurityFindingToAuditIssue } from "./mapSecurityFindingToAuditIssue.js";
@@ -23,23 +22,21 @@ export async function runSecurityAuditAdapter(options) {
23
22
  selectedChecks: [...DEFAULT_SECURITY_CHECKS],
24
23
  formats: ["text", "json"],
25
24
  });
26
- // Always under my-dev-kit-lab's own reports/ tree (toolRoot), never under
27
- // the audited target's root — matches the target-safety guarantee
28
- // AuditTarget.safeReportOutputRoot already documents for code-rot reports.
29
25
  const reportDir = path.join(toolRoot, "reports", "security");
30
- if (!fs.existsSync(reportDir)) {
31
- fs.mkdirSync(reportDir, { recursive: true });
32
- }
33
26
  const prefix = reportFilenamePrefix({
34
27
  isSelf: summary.isSelf,
35
28
  packageName: summary.packageName,
36
29
  packageVersion: summary.packageVersion,
37
30
  targetRoot: summary.targetRoot,
38
31
  });
39
- const textPath = path.join(reportDir, `${prefix}-security-validation.txt`);
40
- const jsonPath = path.join(reportDir, `${prefix}-security-validation.json`);
41
- fs.writeFileSync(textPath, renderTextReport(report), "utf8");
42
- fs.writeFileSync(jsonPath, renderJsonReport(report), "utf8");
32
+ const runSuffix = buildRunScopedReportSuffix(summary.startedAt, summary.finishedAt);
33
+ const { textPath, jsonPath } = writeSecurityReportFiles({
34
+ outDir: reportDir,
35
+ prefix,
36
+ report,
37
+ formats: ["text", "json"],
38
+ reportPathSuffix: runSuffix,
39
+ });
43
40
  const findingCounts = {
44
41
  blocker: summary.findings.filter((f) => f.severity === "blocker").length,
45
42
  major: summary.findings.filter((f) => f.severity === "major").length,
@@ -65,3 +62,9 @@ export async function runSecurityAuditAdapter(options) {
65
62
  };
66
63
  return { issues, summary: securitySummary };
67
64
  }
65
+ function buildRunScopedReportSuffix(startedAt, finishedAt) {
66
+ return `${sanitizeTimestamp(startedAt)}-${sanitizeTimestamp(finishedAt)}-${process.pid}`;
67
+ }
68
+ function sanitizeTimestamp(value) {
69
+ return value.replace(/[^0-9]/g, "").slice(0, 14) || "run";
70
+ }
@@ -0,0 +1,28 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { renderJsonReport, renderTextReport } from "./renderSecurityReport.js";
4
+ export function writeSecurityReportFiles(options) {
5
+ const reportDir = options.outDir;
6
+ if (!fs.existsSync(reportDir)) {
7
+ fs.mkdirSync(reportDir, { recursive: true });
8
+ }
9
+ const basename = options.reportPathSuffix
10
+ ? `${options.prefix}-${options.reportPathSuffix}-security-validation`
11
+ : `${options.prefix}-security-validation`;
12
+ const textPath = options.formats.includes("text")
13
+ ? path.join(reportDir, `${basename}.txt`)
14
+ : null;
15
+ const jsonPath = options.formats.includes("json")
16
+ ? path.join(reportDir, `${basename}.json`)
17
+ : null;
18
+ const writtenPaths = [];
19
+ if (textPath) {
20
+ fs.writeFileSync(textPath, renderTextReport(options.report), "utf8");
21
+ writtenPaths.push(textPath);
22
+ }
23
+ if (jsonPath) {
24
+ fs.writeFileSync(jsonPath, renderJsonReport(options.report), "utf8");
25
+ writtenPaths.push(jsonPath);
26
+ }
27
+ return { textPath, jsonPath, writtenPaths };
28
+ }
package/package.json CHANGED
@@ -1,97 +1,97 @@
1
- {
2
- "name": "@dailephd/my-dev-kit-lab",
3
- "version": "0.3.2",
4
- "type": "module",
5
- "description": "Evidence, benchmark, and evaluation companion for my-dev-kit.",
6
- "bin": {
7
- "my-dev-kit-lab": "dist/scripts/run-final-demo.js"
8
- },
9
- "files": [
10
- "dist/scripts/",
11
- "!dist/scripts/docs/",
12
- "dist/src/",
13
- "benchmarks/",
14
- "docs/METRICS.md",
15
- "examples/",
16
- "tests/fixtures/"
17
- ],
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/dailephd/my-dev-kit-lab.git"
21
- },
22
- "homepage": "https://github.com/dailephd/my-dev-kit-lab#readme",
23
- "bugs": {
24
- "url": "https://github.com/dailephd/my-dev-kit-lab/issues"
25
- },
26
- "publishConfig": {
27
- "access": "public"
28
- },
29
- "funding": [
30
- "https://github.com/sponsors/dailephd",
31
- "https://paypal.me/daile88"
32
- ],
33
- "keywords": [
34
- "benchmark",
35
- "evaluation",
36
- "reporting",
37
- "graph-retrieval",
38
- "codex",
39
- "claude"
40
- ],
41
- "author": "Dai Le",
42
- "license": "MIT",
43
- "scripts": {
44
- "build": "node scripts/clean-dist.mjs && tsc -p tsconfig.json",
45
- "typecheck": "tsc --noEmit",
46
- "test": "vitest run",
47
- "test:benchmarks": "vitest run tests/benchmarks tests/scripts",
48
- "test:report": "vitest run tests/report tests/commands",
49
- "test:screenshot": "vitest run tests/screenshot",
50
- "test:evaluation": "vitest run tests/core tests/evaluation tests/commands",
51
- "test:gallery": "vitest run tests/gallery",
52
- "test:demo": "vitest run tests/commands/runLabDemo.spec.ts tests/integration/runLabDemoCommand.spec.ts",
53
- "test:integration": "vitest run tests/integration",
54
- "test:e2e": "vitest run tests/e2e",
55
- "test:agents": "vitest run tests/agents tests/commands/runAgentPromptCommand.spec.ts tests/integration/runAgentPromptFake.spec.ts",
56
- "test:experiments": "vitest run tests/evaluation/buildExperimentMatrix.spec.ts tests/evaluation/classifyAgentRunOutcome.spec.ts tests/evaluation/parseAgentAnswer.spec.ts tests/evaluation/scoreCorrectness.spec.ts tests/evaluation/compareExperimentRuns.spec.ts tests/evaluation/runControlledExperiment.spec.ts tests/commands/runControlledExperimentCommand.spec.ts tests/integration/runControlledExperimentFake.spec.ts",
57
- "capture-demo-report": "tsx scripts/capture-demo-report.ts",
58
- "evaluate-token-savings": "tsx scripts/evaluate-token-savings.ts",
59
- "generate-experiment-plots": "tsx scripts/generate-experiment-plots.ts",
60
- "generate-prompt-variants": "tsx scripts/generate-prompt-variants.ts",
61
- "build-gallery": "tsx scripts/build-gallery.ts",
62
- "lab-demo": "tsx scripts/run-lab-demo.ts",
63
- "render-experiment-report": "tsx scripts/render-experiment-report.ts",
64
- "experiment:list": "tsx scripts/experiments/listExperiments.ts",
65
- "experiment:describe": "tsx scripts/experiments/describeExperiment.ts",
66
- "experiment:run": "tsx scripts/experiments/runExperiment.ts",
67
- "run-final-demo": "tsx scripts/run-final-demo.ts",
68
- "run-agent-prompt": "tsx scripts/run-agent-prompt.ts",
69
- "run-controlled-experiment": "tsx scripts/run-controlled-experiment.ts",
70
- "run-visualization-demos": "tsx scripts/run-visualization-demos.ts",
71
- "test:plots": "vitest run tests/plots tests/commands/generateExperimentPlotsCommand.spec.ts",
72
- "test:visualization-demos": "vitest run tests/visualizationDemos tests/commands/runVisualizationDemosCommand.spec.ts",
73
- "verify:benchmarks": "tsx scripts/verify-benchmarks.ts",
74
- "verify": "npm run build && npm run test && npm run test:benchmarks && npm run test:report && npm run test:screenshot && npm run test:evaluation && npm run test:agents && npm run test:experiments && npm run test:plots && npm run test:visualization-demos && npm run test:gallery && npm run test:demo && npm run test:integration && npm run test:e2e && npm run verify:benchmarks",
75
- "security:deps": "tsx scripts/security/runDependencyChecks.ts",
76
- "security:package": "tsx scripts/security/runPackageChecks.ts",
77
- "security:codeql": "tsx scripts/security/runCodeql.ts",
78
- "security:semgrep": "tsx scripts/security/runSemgrep.ts",
79
- "test:security": "vitest run tests/security/",
80
- "test:fuzz:smoke": "tsx scripts/security/runFuzzSmoke.ts",
81
- "security:validate": "tsx scripts/security/validate.ts",
82
- "audit": "tsx scripts/audits/runAudit.ts"
83
- },
84
- "devDependencies": {
85
- "@types/node": "^24.0.0",
86
- "playwright": "^1.54.1",
87
- "tsx": "^4.20.3",
88
- "typescript": "^5.8.3",
89
- "vitest": "^3.2.4"
90
- },
91
- "overrides": {
92
- "vite": "7.3.6"
93
- },
94
- "engines": {
95
- "node": ">=20"
96
- }
97
- }
1
+ {
2
+ "name": "@dailephd/my-dev-kit-lab",
3
+ "version": "0.3.4",
4
+ "type": "module",
5
+ "description": "Evidence, benchmark, and evaluation companion for my-dev-kit.",
6
+ "bin": {
7
+ "my-dev-kit-lab": "dist/scripts/run-final-demo.js"
8
+ },
9
+ "files": [
10
+ "dist/scripts/",
11
+ "!dist/scripts/docs/",
12
+ "dist/src/",
13
+ "benchmarks/",
14
+ "docs/METRICS.md",
15
+ "examples/",
16
+ "tests/fixtures/"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/dailephd/my-dev-kit-lab.git"
21
+ },
22
+ "homepage": "https://github.com/dailephd/my-dev-kit-lab#readme",
23
+ "bugs": {
24
+ "url": "https://github.com/dailephd/my-dev-kit-lab/issues"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "funding": [
30
+ "https://github.com/sponsors/dailephd",
31
+ "https://paypal.me/daile88"
32
+ ],
33
+ "keywords": [
34
+ "benchmark",
35
+ "evaluation",
36
+ "reporting",
37
+ "graph-retrieval",
38
+ "codex",
39
+ "claude"
40
+ ],
41
+ "author": "Dai Le",
42
+ "license": "MIT",
43
+ "scripts": {
44
+ "build": "node scripts/clean-dist.mjs && tsc -p tsconfig.json",
45
+ "typecheck": "tsc --noEmit",
46
+ "test": "vitest run",
47
+ "test:benchmarks": "vitest run tests/benchmarks tests/scripts",
48
+ "test:report": "vitest run tests/report tests/commands",
49
+ "test:screenshot": "vitest run tests/screenshot",
50
+ "test:evaluation": "vitest run tests/core tests/evaluation tests/commands",
51
+ "test:gallery": "vitest run tests/gallery",
52
+ "test:demo": "vitest run tests/commands/runLabDemo.spec.ts tests/integration/runLabDemoCommand.spec.ts",
53
+ "test:integration": "vitest run tests/integration",
54
+ "test:e2e": "vitest run tests/e2e",
55
+ "test:agents": "vitest run tests/agents tests/commands/runAgentPromptCommand.spec.ts tests/integration/runAgentPromptFake.spec.ts",
56
+ "test:experiments": "vitest run tests/evaluation/buildExperimentMatrix.spec.ts tests/evaluation/classifyAgentRunOutcome.spec.ts tests/evaluation/parseAgentAnswer.spec.ts tests/evaluation/scoreCorrectness.spec.ts tests/evaluation/compareExperimentRuns.spec.ts tests/evaluation/runControlledExperiment.spec.ts tests/commands/runControlledExperimentCommand.spec.ts tests/integration/runControlledExperimentFake.spec.ts",
57
+ "capture-demo-report": "tsx scripts/capture-demo-report.ts",
58
+ "evaluate-token-savings": "tsx scripts/evaluate-token-savings.ts",
59
+ "generate-experiment-plots": "tsx scripts/generate-experiment-plots.ts",
60
+ "generate-prompt-variants": "tsx scripts/generate-prompt-variants.ts",
61
+ "build-gallery": "tsx scripts/build-gallery.ts",
62
+ "lab-demo": "tsx scripts/run-lab-demo.ts",
63
+ "render-experiment-report": "tsx scripts/render-experiment-report.ts",
64
+ "experiment:list": "tsx scripts/experiments/listExperiments.ts",
65
+ "experiment:describe": "tsx scripts/experiments/describeExperiment.ts",
66
+ "experiment:run": "tsx scripts/experiments/runExperiment.ts",
67
+ "run-final-demo": "tsx scripts/run-final-demo.ts",
68
+ "run-agent-prompt": "tsx scripts/run-agent-prompt.ts",
69
+ "run-controlled-experiment": "tsx scripts/run-controlled-experiment.ts",
70
+ "run-visualization-demos": "tsx scripts/run-visualization-demos.ts",
71
+ "test:plots": "vitest run tests/plots tests/commands/generateExperimentPlotsCommand.spec.ts",
72
+ "test:visualization-demos": "vitest run tests/visualizationDemos tests/commands/runVisualizationDemosCommand.spec.ts",
73
+ "verify:benchmarks": "tsx scripts/verify-benchmarks.ts",
74
+ "verify": "npm run build && npm run test && npm run test:benchmarks && npm run test:report && npm run test:screenshot && npm run test:evaluation && npm run test:agents && npm run test:experiments && npm run test:plots && npm run test:visualization-demos && npm run test:gallery && npm run test:demo && npm run test:integration && npm run test:e2e && npm run verify:benchmarks",
75
+ "security:deps": "tsx scripts/security/runDependencyChecks.ts",
76
+ "security:package": "tsx scripts/security/runPackageChecks.ts",
77
+ "security:codeql": "tsx scripts/security/runCodeql.ts",
78
+ "security:semgrep": "tsx scripts/security/runSemgrep.ts",
79
+ "test:security": "vitest run tests/security/",
80
+ "test:fuzz:smoke": "tsx scripts/security/runFuzzSmoke.ts",
81
+ "security:validate": "tsx scripts/security/validate.ts",
82
+ "audit": "tsx scripts/audits/runAudit.ts"
83
+ },
84
+ "devDependencies": {
85
+ "@types/node": "^24.0.0",
86
+ "playwright": "^1.54.1",
87
+ "tsx": "^4.20.3",
88
+ "typescript": "^5.8.3",
89
+ "vitest": "^3.2.4"
90
+ },
91
+ "overrides": {
92
+ "vite": "7.3.6"
93
+ },
94
+ "engines": {
95
+ "node": ">=20"
96
+ }
97
+ }
@@ -0,0 +1,16 @@
1
+ # mixed-docs-claims fixture
2
+
3
+ Current: this fixture ships `com.example.Widget` (Java) and `com.example.Gadget`
4
+ (Kotlin), matching the classes actually present under `src/main/java` and
5
+ `src/main/kotlin` -- these are current, accurate claims about this fixture's
6
+ own source.
7
+
8
+ Planned (not yet implemented): Android-specific validation of this project's
9
+ JVM sources is planned for a later `v0.4.x` release track.
10
+
11
+ Out of scope: this fixture's `build.gradle.kts` is never executed by Gradle,
12
+ and `pom.xml`-style Maven execution is not performed against this project --
13
+ static classification only.
14
+
15
+ Future (not yet implemented): a combined `quality`, `project`, or `all`
16
+ audit type covering this fixture does not exist yet.
@@ -0,0 +1,4 @@
1
+ plugins {
2
+ id("java")
3
+ kotlin("jvm") version "1.9.0"
4
+ }
@@ -0,0 +1,7 @@
1
+ package com.example;
2
+
3
+ public class Widget {
4
+ public String label() {
5
+ return "widget";
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ package com.example
2
+
3
+ class Gadget {
4
+ fun label(): String {
5
+ return "gadget"
6
+ }
7
+ }
@@ -0,0 +1,10 @@
1
+ # mixed-generated-vendor fixture
2
+
3
+ Current: a single real source file (`src/index.ts`) alongside
4
+ `generated/schema.ts`, `dist/index.js`, `build/Main.class`, and
5
+ `vendor/lib.py` -- files that live under path segments the existing
6
+ `projectInventory.ts` policy already classifies as generated/build-output/
7
+ vendor. Used to prove those files do not pollute source-facts collection
8
+ (role stays generated/build-output/vendor, not source/test) and are excluded
9
+ from `SourceFactsSnapshot.files` the same way `sourceFacts.test.ts`'s
10
+ existing vendor/generated test already proves for a single language.
@@ -0,0 +1 @@
1
+ module.exports = { identity: (v) => v };
@@ -0,0 +1 @@
1
+ export type GeneratedSchema = { id: string };
@@ -0,0 +1,3 @@
1
+ export function identity<T>(value: T): T {
2
+ return value;
3
+ }
@@ -0,0 +1,2 @@
1
+ def vendored():
2
+ return "vendored"
@@ -0,0 +1,10 @@
1
+ # mixed-java-kotlin fixture
2
+
3
+ Current: a conventional Gradle Kotlin DSL JVM project layout with one Java
4
+ class (`src/main/java/com/example/FooService.java`), one Kotlin class
5
+ (`src/main/kotlin/com/example/BarService.kt`), and matching test classes
6
+ under `src/test/java` and `src/test/kotlin`. `build.gradle.kts` and
7
+ `settings.gradle.kts` are present to prove Gradle Kotlin DSL build scripts
8
+ are classified as config, not Kotlin source. Used to prove Java and Kotlin
9
+ source facts coexist in one JVM-style project without disrupting each
10
+ other's declarations or role classification.
@@ -0,0 +1,8 @@
1
+ plugins {
2
+ id("java")
3
+ kotlin("jvm") version "1.9.0"
4
+ }
5
+
6
+ repositories {
7
+ mavenCentral()
8
+ }
@@ -0,0 +1 @@
1
+ rootProject.name = "mixed-java-kotlin-fixture"
@@ -0,0 +1,7 @@
1
+ package com.example;
2
+
3
+ public class FooService {
4
+ public String greet(String name) {
5
+ return "Hello, " + name;
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ package com.example
2
+
3
+ class BarService {
4
+ fun greet(name: String): String {
5
+ return "Hello, $name"
6
+ }
7
+ }
@@ -0,0 +1,8 @@
1
+ package com.example;
2
+
3
+ public class FooServiceTest {
4
+ public void testGreet() {
5
+ FooService service = new FooService();
6
+ assert service.greet("world").equals("Hello, world");
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ package com.example
2
+
3
+ class BarServiceTest {
4
+ fun testGreet() {
5
+ val service = BarService()
6
+ assert(service.greet("world") == "Hello, world")
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ # mixed-python-ts fixture
2
+
3
+ Current: a Python module (`src/app.py`) and a TypeScript module
4
+ (`src/index.ts`) that both declare an equivalent `add` function/declaration,
5
+ plus one Python test file. Used to prove Python and TypeScript source facts
6
+ coexist without schema or ordering drift, and that a duplicate-name
7
+ declaration across languages is not merged into a single cross-language
8
+ candidate.
@@ -0,0 +1,7 @@
1
+ def add(a, b):
2
+ return a + b
3
+
4
+
5
+ class Calculator:
6
+ def compute(self, a, b):
7
+ return add(a, b)
@@ -0,0 +1,3 @@
1
+ export function add(a: number, b: number): number {
2
+ return a + b;
3
+ }
@@ -0,0 +1,5 @@
1
+ from src.app import add
2
+
3
+
4
+ def test_add():
5
+ assert add(1, 2) == 3
@@ -0,0 +1,7 @@
1
+ # mixed-ts-js fixture
2
+
3
+ Current: a minimal TypeScript entrypoint (`src/index.ts`) calling a plain
4
+ JavaScript helper (`src/helper.js`), with one test file. Used by
5
+ `tests/audits/mixedLanguageSourceFacts.test.ts` to prove TypeScript and
6
+ JavaScript files coexist in a single source-facts collection without schema
7
+ or ordering drift.
@@ -0,0 +1,5 @@
1
+ function greet(name) {
2
+ return "Hello, " + name;
3
+ }
4
+
5
+ module.exports = { greet };
@@ -0,0 +1,3 @@
1
+ export function main(name: string): string {
2
+ return `Hello, ${name}`;
3
+ }
@@ -0,0 +1,5 @@
1
+ import { main } from "../src/index.js";
2
+
3
+ test("main returns a greeting", () => {
4
+ expect(main("world")).toContain("world");
5
+ });
@@ -0,0 +1,10 @@
1
+ # mixed-ts-python-jvm fixture
2
+
3
+ Current: TypeScript, JavaScript, Python, Java, and Kotlin source files
4
+ coexisting in one target, plus a `build.gradle.kts` JVM metadata file. Used
5
+ to prove all currently-supported language families (v0.3.3 baseline) can be
6
+ collected together without crashing, without cross-language schema drift,
7
+ and without one analyzer's output disturbing another's.
8
+
9
+ Planned (not implemented): Android-specific source-set validation and
10
+ manual pentest coverage are out of scope for this fixture and for v0.3.4.
@@ -0,0 +1,4 @@
1
+ plugins {
2
+ id("java")
3
+ kotlin("jvm") version "1.9.0"
4
+ }
@@ -0,0 +1,5 @@
1
+ from src.app import multiply
2
+
3
+
4
+ def test_multiply():
5
+ assert multiply(2, 3) == 6
@@ -0,0 +1,2 @@
1
+ def multiply(a, b):
2
+ return a * b
@@ -0,0 +1,5 @@
1
+ function double(x) {
2
+ return x * 2;
3
+ }
4
+
5
+ module.exports = { double };
@@ -0,0 +1,3 @@
1
+ export function multiply(a: number, b: number): number {
2
+ return a * b;
3
+ }
@@ -0,0 +1,7 @@
1
+ package com.example;
2
+
3
+ public class Multiplier {
4
+ public int multiply(int a, int b) {
5
+ return a * b;
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ package com.example
2
+
3
+ class Divider {
4
+ fun divide(a: Int, b: Int): Int {
5
+ return a / b
6
+ }
7
+ }