@dailephd/my-dev-kit-lab 0.4.5 → 0.4.6

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 (231) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +37 -3
  3. package/dist/scripts/cli.js +9 -0
  4. package/dist/src/audits/core/typescriptJavaScriptAnalyzer.js +30 -12
  5. package/dist/src/cli/help.js +300 -0
  6. package/dist/src/cli/index.js +2 -0
  7. package/dist/src/cli/runLabCli.js +229 -0
  8. package/dist/src/commands/runAuditCommand.js +132 -0
  9. package/dist/src/commands/runControlledExperimentCommand.js +7 -3
  10. package/dist/{scripts/experiments/describeExperiment.js → src/commands/runExperimentDescribeCommand.js} +14 -10
  11. package/dist/{scripts/experiments/listExperiments.js → src/commands/runExperimentListCommand.js} +3 -6
  12. package/dist/{scripts/experiments/runExperiment.js → src/commands/runExperimentRunCommand.js} +80 -22
  13. package/dist/src/commands/runFinalDemoCommand.js +2 -3
  14. package/dist/src/commands/runSecurityValidationCommand.js +271 -0
  15. package/dist/src/runtime/index.js +3 -0
  16. package/dist/src/runtime/labExecutionContext.js +22 -0
  17. package/dist/src/runtime/packageResource.js +22 -0
  18. package/dist/src/runtime/packageRoot.js +37 -0
  19. package/dist/src/securityValidation/packageChecks/requiredPackageContents.js +14 -1
  20. package/package.json +7 -7
  21. package/dist/scripts/audits/runAudit.js +0 -135
  22. package/dist/scripts/build-gallery.js +0 -3
  23. package/dist/scripts/capture-demo-report.js +0 -3
  24. package/dist/scripts/evaluate-token-savings.js +0 -2
  25. package/dist/scripts/generate-experiment-plots.js +0 -3
  26. package/dist/scripts/generate-prompt-variants.js +0 -2
  27. package/dist/scripts/render-experiment-report.js +0 -2
  28. package/dist/scripts/report-context-integrity-smoke.js +0 -70
  29. package/dist/scripts/run-agent-prompt.js +0 -2
  30. package/dist/scripts/run-controlled-experiment.js +0 -2
  31. package/dist/scripts/run-lab-demo.js +0 -5
  32. package/dist/scripts/run-visualization-demos.js +0 -3
  33. package/dist/scripts/security/resolveToolRoot.js +0 -16
  34. package/dist/scripts/security/runCodeql.js +0 -58
  35. package/dist/scripts/security/runDependencyChecks.js +0 -58
  36. package/dist/scripts/security/runFuzzSmoke.js +0 -29
  37. package/dist/scripts/security/runPackageChecks.js +0 -57
  38. package/dist/scripts/security/runSemgrep.js +0 -64
  39. package/dist/scripts/security/validate.js +0 -266
  40. package/dist/scripts/verify-benchmarks.js +0 -202
  41. package/examples/demo-report-input.json +0 -78
  42. package/examples/lab-demo-cases.json +0 -35
  43. package/examples/real-agent-campaign-cases.json +0 -118
  44. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/debug/res/xml/ambiguous_backup_rules.xml +0 -4
  45. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/ambiguous_backup_rules.xml +0 -4
  46. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/backup_rules.xml +0 -5
  47. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/broad_backup_rules.xml +0 -4
  48. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/data_extraction_rules.xml +0 -10
  49. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/unsupported_domain_rules.xml +0 -4
  50. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-b/src/main/res/xml/malformed_backup_rules.xml +0 -4
  51. package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-b/src/main/res/xml/unsupported_root.xml +0 -4
  52. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/debug/res/xml/ambiguous_config.xml +0 -4
  53. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/ambiguous_config.xml +0 -4
  54. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/base_cleartext_false.xml +0 -8
  55. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/broad_and_duplicate_domains.xml +0 -8
  56. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/empty_domain.xml +0 -6
  57. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/malformed_pin.xml +0 -11
  58. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/network_security_config.xml +0 -26
  59. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-b/src/main/res/xml/malformed_network_security_config.xml +0 -6
  60. package/tests/fixtures/android/advanced-security-fixtures/network-security/module-b/src/main/res/xml/unsupported_root.xml +0 -4
  61. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-dynamic.gradle +0 -7
  62. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-false.gradle +0 -9
  63. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-true.gradle +0 -13
  64. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/kotlin-release-debuggable-false.gradle.kts +0 -7
  65. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/kotlin-release-debuggable-true.gradle.kts +0 -10
  66. package/tests/fixtures/android/advanced-security-fixtures/release-configuration/missing-release-build-type.gradle.kts +0 -7
  67. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/debug/res/xml/network_security_config.xml +0 -8
  68. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/main/res/xml/backup_rules.xml +0 -4
  69. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/main/res/xml/network_security_config.xml +0 -8
  70. package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-b/src/main/res/xml/malformed_network_security_config.xml +0 -7
  71. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/SampleActivity.java +0 -8
  72. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/SampleActivity.kt +0 -9
  73. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/build.gradle +0 -11
  74. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/build.gradle.kts +0 -11
  75. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/google-services.json +0 -16
  76. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/local.properties +0 -3
  77. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates-bounds/module/binary.properties +0 -0
  78. package/tests/fixtures/android/advanced-security-fixtures/secret-candidates-bounds/module/oversized.json +0 -1
  79. package/tests/fixtures/android/advanced-security-fixtures/signing-configuration/app/fake-release-keystore.jks +0 -1
  80. package/tests/fixtures/android/advanced-security-fixtures/signing-configuration/build/generated-fake.keystore +0 -1
  81. package/tests/fixtures/android/compose-app/app/build.gradle.kts +0 -21
  82. package/tests/fixtures/android/compose-app/app/src/main/AndroidManifest.xml +0 -22
  83. package/tests/fixtures/android/compose-app/app/src/main/java/com/example/composeapp/MainActivity.kt +0 -11
  84. package/tests/fixtures/android/compose-app/build.gradle.kts +0 -4
  85. package/tests/fixtures/android/compose-app/gradle/wrapper/gradle-wrapper.properties +0 -4
  86. package/tests/fixtures/android/compose-app/settings.gradle.kts +0 -2
  87. package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/build.gradle.kts +0 -3
  88. package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/gradle/libs.versions.toml +0 -5
  89. package/tests/fixtures/android/gradle-metadata-fixtures/comment-safety.gradle.kts +0 -21
  90. package/tests/fixtures/android/gradle-metadata-fixtures/dynamic-values.gradle.kts +0 -17
  91. package/tests/fixtures/android/gradle-metadata-fixtures/groovy-literal.gradle +0 -23
  92. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-malformed.properties +0 -4
  93. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-missing-url.properties +0 -3
  94. package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-with-checksum.properties +0 -5
  95. package/tests/fixtures/android/java-app/app/build.gradle +0 -16
  96. package/tests/fixtures/android/java-app/app/src/main/AndroidManifest.xml +0 -19
  97. package/tests/fixtures/android/java-app/app/src/main/java/com/example/javaapp/MainActivity.java +0 -4
  98. package/tests/fixtures/android/java-app/build.gradle +0 -3
  99. package/tests/fixtures/android/java-app/gradle/wrapper/gradle-wrapper.properties +0 -4
  100. package/tests/fixtures/android/java-app/settings.gradle +0 -2
  101. package/tests/fixtures/android/library/build.gradle.kts +0 -3
  102. package/tests/fixtures/android/library/gradle/wrapper/gradle-wrapper.properties +0 -4
  103. package/tests/fixtures/android/library/mylibrary/build.gradle.kts +0 -13
  104. package/tests/fixtures/android/library/mylibrary/src/main/AndroidManifest.xml +0 -2
  105. package/tests/fixtures/android/library/settings.gradle.kts +0 -2
  106. package/tests/fixtures/android/manifest-audit-fixtures/incomplete-intent-filter.xml +0 -14
  107. package/tests/fixtures/android/manifest-audit-fixtures/malformed-exported.xml +0 -10
  108. package/tests/fixtures/android/manifest-audit-fixtures/malformed.xml +0 -5
  109. package/tests/fixtures/android/manifest-audit-fixtures/missing-application.xml +0 -7
  110. package/tests/fixtures/android/manifest-audit-fixtures/missing-component-name.xml +0 -11
  111. package/tests/fixtures/android/manifest-audit-fixtures/permission-coverage.xml +0 -29
  112. package/tests/fixtures/android/manifest-audit-fixtures/risky-components.xml +0 -62
  113. package/tests/fixtures/android/manifest-audit-fixtures/risky-deep-links.xml +0 -45
  114. package/tests/fixtures/android/manifest-audit-fixtures/unresolved-placeholder.xml +0 -14
  115. package/tests/fixtures/android/manifest-audit-fixtures/unusual-namespace-prefix.xml +0 -11
  116. package/tests/fixtures/android/multi-module/app/build.gradle.kts +0 -22
  117. package/tests/fixtures/android/multi-module/app/src/androidTest/java/com/example/multimodule/app/ExampleInstrumentedTest.kt +0 -3
  118. package/tests/fixtures/android/multi-module/app/src/main/AndroidManifest.xml +0 -11
  119. package/tests/fixtures/android/multi-module/app/src/test/java/com/example/multimodule/app/ExampleUnitTest.kt +0 -3
  120. package/tests/fixtures/android/multi-module/build.gradle.kts +0 -5
  121. package/tests/fixtures/android/multi-module/core/build.gradle.kts +0 -14
  122. package/tests/fixtures/android/multi-module/core/src/main/AndroidManifest.xml +0 -2
  123. package/tests/fixtures/android/multi-module/feature-login/build.gradle.kts +0 -18
  124. package/tests/fixtures/android/multi-module/feature-login/src/main/AndroidManifest.xml +0 -2
  125. package/tests/fixtures/android/multi-module/gradle/libs.versions.toml +0 -8
  126. package/tests/fixtures/android/multi-module/gradle/wrapper/gradle-wrapper.properties +0 -4
  127. package/tests/fixtures/android/multi-module/settings.gradle.kts +0 -4
  128. package/tests/fixtures/android/non-android-gradle/build.gradle.kts +0 -3
  129. package/tests/fixtures/android/non-android-gradle/core/build.gradle.kts +0 -3
  130. package/tests/fixtures/android/non-android-gradle/core/src/main/java/com/example/core/Core.java +0 -4
  131. package/tests/fixtures/android/non-android-gradle/gradle/wrapper/gradle-wrapper.properties +0 -4
  132. package/tests/fixtures/android/non-android-gradle/settings.gradle.kts +0 -2
  133. package/tests/fixtures/android/partial/app/build.gradle.kts +0 -7
  134. package/tests/fixtures/android/partial/settings.gradle.kts +0 -2
  135. package/tests/fixtures/android/xml-view-app/app/build.gradle.kts +0 -17
  136. package/tests/fixtures/android/xml-view-app/app/src/main/AndroidManifest.xml +0 -31
  137. package/tests/fixtures/android/xml-view-app/app/src/main/kotlin/com/example/xmlviewapp/MainActivity.kt +0 -7
  138. package/tests/fixtures/android/xml-view-app/app/src/main/res/layout/activity_main.xml +0 -4
  139. package/tests/fixtures/android/xml-view-app/build.gradle.kts +0 -4
  140. package/tests/fixtures/android/xml-view-app/gradle/wrapper/gradle-wrapper.properties +0 -4
  141. package/tests/fixtures/android/xml-view-app/settings.gradle.kts +0 -2
  142. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/README.md +0 -16
  143. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/build.gradle.kts +0 -4
  144. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/java/com/example/Widget.java +0 -7
  145. package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/kotlin/com/example/Gadget.kt +0 -7
  146. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/README.md +0 -10
  147. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/build/Main.class +0 -1
  148. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/dist/index.js +0 -1
  149. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/generated/schema.ts +0 -1
  150. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/src/index.ts +0 -3
  151. package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/vendor/lib.py +0 -2
  152. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/README.md +0 -10
  153. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/build.gradle.kts +0 -8
  154. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/settings.gradle.kts +0 -1
  155. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/java/com/example/FooService.java +0 -7
  156. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/kotlin/com/example/BarService.kt +0 -7
  157. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/java/com/example/FooServiceTest.java +0 -8
  158. package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/kotlin/com/example/BarServiceTest.kt +0 -8
  159. package/tests/fixtures/audits/mixed-language/mixed-python-ts/README.md +0 -8
  160. package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/app.py +0 -7
  161. package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/index.ts +0 -3
  162. package/tests/fixtures/audits/mixed-language/mixed-python-ts/tests/test_app.py +0 -5
  163. package/tests/fixtures/audits/mixed-language/mixed-ts-js/README.md +0 -7
  164. package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/helper.js +0 -5
  165. package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/index.ts +0 -3
  166. package/tests/fixtures/audits/mixed-language/mixed-ts-js/tests/index.sample.ts +0 -5
  167. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/README.md +0 -10
  168. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/build.gradle.kts +0 -4
  169. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/pytests/test_app.py +0 -5
  170. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/app.py +0 -2
  171. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/helper.js +0 -5
  172. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/index.ts +0 -3
  173. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/java/com/example/Multiplier.java +0 -7
  174. package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/kotlin/com/example/Divider.kt +0 -7
  175. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/derived/run-integrity-evidence.json +0 -99
  176. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-audit.json +0 -1585
  177. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-capsule.json +0 -11455
  178. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/00-request.txt +0 -1
  179. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/architecture-context-packet.txt +0 -82
  180. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/behavior-model.txt +0 -104
  181. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/final-report.txt +0 -41
  182. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-context-packet.txt +0 -114
  183. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-report.txt +0 -92
  184. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/judge-report.txt +0 -34
  185. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/pseudocode-packet.txt +0 -244
  186. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/request-brief.txt +0 -40
  187. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-context-packet.txt +0 -93
  188. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-implementation-report.txt +0 -69
  189. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-strategy-packet.txt +0 -354
  190. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/verification-report.txt +0 -85
  191. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/derived/run-integrity-evidence.json +0 -98
  192. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-audit.json +0 -1169
  193. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-request.json +0 -29
  194. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-audit.json +0 -1494
  195. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-capsule.json +0 -11364
  196. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-request.json +0 -33
  197. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/test-request.json +0 -74
  198. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/architecture-context-retrieval-report.txt +0 -58
  199. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/implementation-context-retrieval-report.txt +0 -75
  200. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/test-context-retrieval-report.txt +0 -84
  201. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/run.json +0 -62
  202. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/my-dev-kit-version.txt +0 -1
  203. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/orchestrator-version.txt +0 -1
  204. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/corrected-replay-manifest.json +0 -19
  205. package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/failed-run-manifest.json +0 -56
  206. package/tests/fixtures/fake-adversarial-cli.js +0 -152
  207. package/tests/fixtures/fake-my-dev-kit-cli.js +0 -83
  208. package/tests/fixtures/full-workflow-library/complete-v1.0.0.json +0 -24
  209. package/tests/fixtures/full-workflow-library/future-minor-v1.1.0-additive.json +0 -25
  210. package/tests/fixtures/stage-context-expectations/complete-v1.0.0.json +0 -230
  211. package/tests/fixtures/stage-context-expectations/future-minor-v1.1.0-additive.json +0 -232
  212. package/tests/fixtures/stage-context-expectations/invalid/malformed-json.txt +0 -1
  213. package/tests/fixtures/stage-context-expectations/invalid/non-object-root.json +0 -1
  214. package/tests/fixtures/stage-context-expectations/minimal-v1.0.0.json +0 -18
  215. package/tests/fixtures/upstream-artifacts/invalid/malformed-json.txt +0 -1
  216. package/tests/fixtures/upstream-artifacts/invalid/non-object-root.json +0 -1
  217. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/complete-v1.0.0.json +0 -504
  218. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/future-minor-v1.1.0-additive.json +0 -955
  219. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/complete-v1.0.0.json +0 -190
  220. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/future-minor-v1.1.0-additive.json +0 -327
  221. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/PROVENANCE.txt +0 -18
  222. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/context-capsule/complete-v1.0.0.json +0 -556
  223. package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/retrieval-audit-record/complete-v1.0.0.json +0 -238
  224. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/PROVENANCE.txt +0 -13
  225. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/context-capsule.json +0 -7874
  226. package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/retrieval-audit-record.json +0 -1076
  227. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/complete-v1.0.0.json +0 -160
  228. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/future-minor-v1.1.0-additive.json +0 -186
  229. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/PROVENANCE.txt +0 -31
  230. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/ready-pass-final-pass.json +0 -132
  231. package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/refresh-required-need-context.json +0 -146
@@ -0,0 +1,271 @@
1
+ import path from "node:path";
2
+ import { runSecurityValidation } from "../securityValidation/validate/runSecurityValidation.js";
3
+ import { resolveValidationTarget, reportFilenamePrefix } from "../securityValidation/validate/resolveTarget.js";
4
+ import { buildSecurityReportFromSummary } from "../securityValidation/report/buildSecurityReport.js";
5
+ import { renderTextReport } from "../securityValidation/report/renderSecurityReport.js";
6
+ import { writeSecurityReportFiles } from "../securityValidation/report/writeSecurityReportFiles.js";
7
+ import { parseSecurityValidateArgs, normalizeSecurityValidateConfig, applyProfileDefaultChecksIfApplicable } from "../securityValidation/validate/cliOptions.js";
8
+ import { resolveAttackProfile } from "../securityValidation/attackScenarios/attackProfile.js";
9
+ import { findingsBreachFailOnThreshold } from "../securityValidation/validate/verdict.js";
10
+ import { validateAndroidTarget } from "../mobile/android/validate/validateAndroidTarget.js";
11
+ import { toAndroidReportModel } from "../mobile/android/report/model.js";
12
+ import { renderAndroidTextReport } from "../mobile/android/report/renderAndroidReport.js";
13
+ import { writeAndroidReportFiles } from "../mobile/android/report/writeAndroidReportFiles.js";
14
+ import { createLabExecutionContext } from "../runtime/index.js";
15
+ // ---------------------------------------------------------------------------
16
+ // v0.4.6 Batch 4 -- reusable security-validation command owner.
17
+ //
18
+ // Extracted from scripts/security/validate.ts (formerly a top-level script
19
+ // with inline try/catch + process.exit()) so both the contributor npm script
20
+ // and the installed CLI router (src/cli/) call the same argument-parsing/
21
+ // target-resolution/report-writing/exit-mapping path. Mirrors the audit
22
+ // command extraction in src/commands/runAuditCommand.ts (Batch 3). Detector/
23
+ // verdict/severity policy, the Android validator, and the classic check
24
+ // pipeline are untouched -- this module only owns CLI wiring.
25
+ // ---------------------------------------------------------------------------
26
+ export const SECURITY_VALIDATE_USAGE = "Usage: my-dev-kit-lab security validate [--target <path>] [--out <dir>] [--report-prefix <name>] " +
27
+ "[--checks deps,package,static,cli-adversarial,fuzz,boundary,subprocess,secrets,network] " +
28
+ "[--profile node-cli-package|local-tool|npm-package|android] [--format text,json] [--fail-on blocker|high|medium|low] " +
29
+ "[--android-gradle-operations wrapper-version,tasks,assemble-debug,unit-test-debug,lint-debug] " +
30
+ "[--android-external-tools semgrep,osv,android-lint,dependency-check] " +
31
+ "[--android-external-network deny|allow-requested]\n" +
32
+ "\n" +
33
+ "Android profile:\n" +
34
+ " --profile android performs static, read-only Android project detection, manifest parsing,\n" +
35
+ " permission/exported-component/intent-filter/deep-link audits, static Gradle metadata\n" +
36
+ " extraction, and (as of v0.4.1 Batch 8) eleven internal advanced security checks (network\n" +
37
+ " security config, backup/release configuration, hardcoded secrets, signing configuration,\n" +
38
+ " WebView, FileProvider, sensitive storage/logging, clipboard, and Firebase/Google services).\n" +
39
+ " Gradle and external tools are never executed by default.\n" +
40
+ " --android-gradle-operations explicitly opts into running ONLY the listed allowlisted Gradle\n" +
41
+ " operations (wrapper-version, tasks, assemble-debug, unit-test-debug, lint-debug) via the\n" +
42
+ " project's own Gradle wrapper. Arbitrary Gradle tasks cannot be passed. This option is only\n" +
43
+ " valid together with --profile android.\n" +
44
+ " --android-external-tools explicitly opts into running ONLY the listed allowlisted optional\n" +
45
+ " external security tools (semgrep, osv, android-lint, dependency-check). No arbitrary tool\n" +
46
+ " names, commands, or arguments can be passed. This option is only valid together with\n" +
47
+ " --profile android.\n" +
48
+ " --android-external-network controls whether a requested tool may use network access.\n" +
49
+ " Defaults to deny (osv is skipped unless supported offline data is available; semgrep,\n" +
50
+ " android-lint, and dependency-check always run offline/no-update regardless of this flag).\n" +
51
+ " allow-requested authorizes network only for an explicitly requested tool whose Batch 7\n" +
52
+ " contract supports it (currently only osv). This option is only valid together with\n" +
53
+ " --profile android.\n" +
54
+ " Example: my-dev-kit-lab security validate --target \"<android-project-path>\" --profile android\n" +
55
+ " Example: my-dev-kit-lab security validate --target \"<android-project-path>\" --profile android --android-gradle-operations wrapper-version,tasks\n" +
56
+ " Example: my-dev-kit-lab security validate --target \"<android-project-path>\" --profile android --android-external-tools semgrep,android-lint\n" +
57
+ " Example: my-dev-kit-lab security validate --target \"<android-project-path>\" --profile android --android-external-tools osv --android-external-network allow-requested";
58
+ export async function runSecurityValidationCommandFromArgs(argv, options = {}) {
59
+ const context = options.context ?? createLabExecutionContext();
60
+ const toolRoot = context.packageRoot;
61
+ const defaultOutRoot = options.defaultOutRoot ?? toolRoot;
62
+ // Help deliberately wins over every other argument. It must remain a
63
+ // no-work path: no target/default resolution, option normalization, report
64
+ // directory creation, validation orchestration, or subprocess execution.
65
+ if (argv.includes("--help") || argv.includes("-h")) {
66
+ console.log(SECURITY_VALIDATE_USAGE);
67
+ return 0;
68
+ }
69
+ let args;
70
+ let config;
71
+ try {
72
+ args = parseSecurityValidateArgs(argv);
73
+ config = normalizeSecurityValidateConfig(args, defaultOutRoot);
74
+ // v0.2.2 Batch 5: --profile with no --checks uses that profile's declared
75
+ // default checks. No-op unless the user passed --profile without --checks
76
+ // (see applyProfileDefaultChecksIfApplicable's guard) -- the true no-flag
77
+ // case and any explicit --checks case are always unaffected. Skipped for
78
+ // "android": that profile does not use the classic --checks pipeline.
79
+ if (config.profile !== "android") {
80
+ config = applyProfileDefaultChecksIfApplicable(config, resolveAttackProfile(config.profile).defaultCheckIds);
81
+ }
82
+ }
83
+ catch (err) {
84
+ const msg = err instanceof Error ? err.message : String(err);
85
+ console.error(`\nERROR: ${msg}`);
86
+ console.error(SECURITY_VALIDATE_USAGE);
87
+ return 2;
88
+ }
89
+ // Resolve and validate target early so we can fail fast with a clean error.
90
+ let target;
91
+ try {
92
+ target = resolveValidationTarget(args.target, toolRoot);
93
+ }
94
+ catch (err) {
95
+ const msg = err instanceof Error ? err.message : String(err);
96
+ console.error(`\nERROR: ${msg}`);
97
+ console.error(SECURITY_VALIDATE_USAGE);
98
+ return 1;
99
+ }
100
+ console.log("=".repeat(60));
101
+ console.log("my-dev-kit-lab security:validate");
102
+ console.log("=".repeat(60));
103
+ console.log(`Tool root : ${toolRoot}`);
104
+ if (!target.isSelf) {
105
+ console.log(`Target : ${target.targetRoot}`);
106
+ if (target.packageName)
107
+ console.log(`Package : ${target.packageName}${target.packageVersion ? `@${target.packageVersion}` : ""}`);
108
+ }
109
+ else {
110
+ console.log(`Mode : self-validation`);
111
+ }
112
+ console.log(`Profile : ${config.profile}`);
113
+ // ---------------------------------------------------------------------------
114
+ // v0.4.0 Batch 5 -- Android profile path.
115
+ //
116
+ // A separate orchestrator (not the classic check-group/attack-scenario
117
+ // pipeline below) because the Android check/finding/status vocabulary
118
+ // established in Batches 1-4 does not fit SecurityCheckId/SecurityCheckResult.
119
+ // Same command, same --profile flag, same reports/security/ output root.
120
+ // ---------------------------------------------------------------------------
121
+ if (config.profile === "android") {
122
+ if (config.androidGradleOperationIds.length > 0) {
123
+ console.log(`Gradle ops : ${config.androidGradleOperationIds.join(", ")} (explicitly requested — will execute via the target's Gradle wrapper)`);
124
+ }
125
+ else {
126
+ console.log(`Gradle ops : (none requested — static-only validation, zero Gradle process execution)`);
127
+ }
128
+ // v0.4.1 Batch 8 -- external tools remain explicit opt-in, mirroring Gradle
129
+ // operations exactly. "allow-requested" (the CLI-facing value) maps to the
130
+ // Batch 7 dispatcher's "allow-for-requested-tool" network policy value.
131
+ const externalNetworkPolicy = config.androidExternalNetworkPolicy === "allow-requested" ? "allow-for-requested-tool" : "deny";
132
+ if (config.androidExternalToolIds.length > 0) {
133
+ console.log(`External : ${config.androidExternalToolIds.join(", ")} (explicitly requested — network policy: ${config.androidExternalNetworkPolicy})`);
134
+ }
135
+ else {
136
+ console.log(`External : (none requested — zero external-tool process execution)`);
137
+ }
138
+ console.log("");
139
+ const reportsDir = config.out;
140
+ let result;
141
+ try {
142
+ result = await validateAndroidTarget({
143
+ toolRoot,
144
+ targetPath: args.target,
145
+ requestedGradleOperationIds: config.androidGradleOperationIds,
146
+ requestedExternalToolIds: config.androidExternalToolIds,
147
+ externalNetworkPolicy: externalNetworkPolicy,
148
+ externalToolArtifactRoot: path.join(reportsDir, "external-tools")
149
+ });
150
+ }
151
+ catch (err) {
152
+ const msg = err instanceof Error ? err.message : String(err);
153
+ console.error(`\nERROR: Android validation failed to run: ${msg}`);
154
+ return 3;
155
+ }
156
+ const reportModel = toAndroidReportModel(result, {
157
+ profile: config.profile,
158
+ requestedGradleOperations: config.androidGradleOperationIds,
159
+ requestedExternalTools: config.androidExternalToolIds,
160
+ externalNetworkPolicy: config.androidExternalNetworkPolicy
161
+ });
162
+ const textReport = renderAndroidTextReport(reportModel);
163
+ const prefix = args.reportPrefix ??
164
+ reportFilenamePrefix({
165
+ isSelf: result.target.local.isSelf,
166
+ packageName: result.target.local.packageName,
167
+ packageVersion: result.target.local.packageVersion,
168
+ targetRoot: result.target.local.targetRoot
169
+ });
170
+ let writtenPaths;
171
+ try {
172
+ ({ writtenPaths } = writeAndroidReportFiles({ outDir: reportsDir, prefix, report: reportModel, formats: config.formats }));
173
+ }
174
+ catch (err) {
175
+ const msg = err instanceof Error ? err.message : String(err);
176
+ console.error(`\nERROR: Failed to write Android report files: ${msg}`);
177
+ console.error("Validation completed but the report could not be written. The in-memory result was not persisted.");
178
+ return 4;
179
+ }
180
+ console.log(textReport);
181
+ console.log(`\nReports written:`);
182
+ for (const p of writtenPaths) {
183
+ console.log(` ${p}`);
184
+ }
185
+ const blockerExists = result.verdict === "not-ready-security-blocker-remains";
186
+ const inconclusive = result.verdict === "inconclusive-audit-environment-incomplete";
187
+ if (blockerExists) {
188
+ console.error("\nExit 1 — security blocker remains.");
189
+ return 1;
190
+ }
191
+ else if (inconclusive) {
192
+ console.warn("\nExit 2 — android environment incomplete.");
193
+ return 2;
194
+ }
195
+ else {
196
+ console.log("\nExit 0 — validation completed.");
197
+ return 0;
198
+ }
199
+ }
200
+ // ---------------------------------------------------------------------------
201
+ // Classic check-group/attack-scenario pipeline (unchanged from prior versions).
202
+ // ---------------------------------------------------------------------------
203
+ if (!config.checksWereDefault) {
204
+ console.log(`Checks : ${config.checks.join(", ")}`);
205
+ }
206
+ if (config.plannedChecksRequested.length > 0) {
207
+ console.log(`Note : ${config.plannedChecksRequested.join(", ")} are routed through the attack-scenario framework rather than the classic check-group runners. Review the attack-scenario section in the report for their concrete results.`);
208
+ }
209
+ console.log("");
210
+ const summary = await runSecurityValidation({
211
+ cwd: toolRoot,
212
+ targetPath: args.target,
213
+ fuzzIterations: parseInt(process.env["FUZZ_ITERATIONS"] ?? "50", 10),
214
+ fuzzSeed: parseInt(process.env["FUZZ_SEED"] ?? "0xDEADBEEF", 16),
215
+ // Full selection (implemented + planned/attack-scenario ids) -- the runner
216
+ // gates both implemented check groups and attack-scenario checks off the
217
+ // same selectedChecks set.
218
+ selectedChecks: config.checks,
219
+ profile: config.profile
220
+ });
221
+ // v0.2.2 Batch 5: --fail-on breach is additive to (never a substitute for)
222
+ // the existing verdict-based exit decision below -- it can only escalate
223
+ // exit 0 to exit 1 (e.g. --fail-on medium/low catching minor/informational
224
+ // findings the verdict policy doesn't already treat as blocking), never
225
+ // downgrade an existing blocker.
226
+ const failOnBreached = findingsBreachFailOnThreshold(summary.findings, config.failOnThreshold);
227
+ // Build report object
228
+ const report = buildSecurityReportFromSummary(summary, {
229
+ profile: config.profile,
230
+ selectedChecks: config.checks,
231
+ failOnThreshold: config.failOnThreshold,
232
+ formats: config.formats,
233
+ failOnBreached
234
+ });
235
+ const textReport = renderTextReport(report);
236
+ // Determine output directory
237
+ const reportsDir = config.out;
238
+ // Determine report filename prefix
239
+ const prefix = args.reportPrefix ?? reportFilenamePrefix(target);
240
+ const { writtenPaths } = writeSecurityReportFiles({
241
+ outDir: reportsDir,
242
+ prefix,
243
+ report,
244
+ formats: config.formats
245
+ });
246
+ // Print report to stdout
247
+ console.log(textReport);
248
+ console.log(`\nReports written:`);
249
+ for (const p of writtenPaths) {
250
+ console.log(` ${p}`);
251
+ }
252
+ // Exit code based on verdict, escalated (never downgraded) by --fail-on.
253
+ const blockerExists = summary.verdict === "not-ready-security-blocker-remains";
254
+ const inconclusive = summary.verdict === "inconclusive-audit-environment-incomplete";
255
+ if (blockerExists) {
256
+ console.error("\nExit 1 — security blocker remains.");
257
+ return 1;
258
+ }
259
+ else if (inconclusive) {
260
+ console.warn("\nExit 2 — audit environment incomplete.");
261
+ return 2;
262
+ }
263
+ else if (failOnBreached) {
264
+ console.error(`\nExit 1 — --fail-on ${config.failOnThreshold} threshold breached.`);
265
+ return 1;
266
+ }
267
+ else {
268
+ console.log("\nExit 0 — validation completed.");
269
+ return 0;
270
+ }
271
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./packageRoot.js";
2
+ export * from "./labExecutionContext.js";
3
+ export * from "./packageResource.js";
@@ -0,0 +1,22 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ import { discoverPackageRoot } from "./packageRoot.js";
4
+ const DEFAULT_WORKSPACE_DIR_NAME = ".my-dev-kit-lab";
5
+ export function createLabExecutionContext(options = {}) {
6
+ const invocationCwd = path.resolve(options.invocationCwd ?? process.cwd());
7
+ const packageRoot = path.resolve(options.packageRoot ?? discoverPackageRoot());
8
+ const workspaceRoot = resolveWorkspaceRoot(options.workspaceRoot, invocationCwd);
9
+ const resourceRoot = packageRoot;
10
+ return Object.freeze({
11
+ invocationCwd,
12
+ packageRoot,
13
+ workspaceRoot,
14
+ resourceRoot
15
+ });
16
+ }
17
+ function resolveWorkspaceRoot(explicitWorkspaceRoot, invocationCwd) {
18
+ if (!explicitWorkspaceRoot) {
19
+ return path.join(os.homedir(), DEFAULT_WORKSPACE_DIR_NAME);
20
+ }
21
+ return path.resolve(path.isAbsolute(explicitWorkspaceRoot) ? explicitWorkspaceRoot : path.resolve(invocationCwd, explicitWorkspaceRoot));
22
+ }
@@ -0,0 +1,22 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { resolveWithinRoot } from "../core/pathSafety.js";
4
+ /**
5
+ * Safely resolves a package-relative path (e.g. "benchmarks/contracts/foo.json")
6
+ * against resourceRoot. Rejects empty/absolute/traversal inputs and missing files
7
+ * so command owners never depend on process.cwd() to find bundled resources.
8
+ */
9
+ export function resolvePackageResource(contextOrResourceRoot, resourceRelativePath) {
10
+ const resourceRoot = typeof contextOrResourceRoot === "string" ? contextOrResourceRoot : contextOrResourceRoot.resourceRoot;
11
+ if (!resourceRelativePath || resourceRelativePath.trim().length === 0) {
12
+ throw new Error("Package resource path must not be empty.");
13
+ }
14
+ if (path.isAbsolute(resourceRelativePath)) {
15
+ throw new Error(`Package resource path must be relative, not absolute: ${resourceRelativePath}`);
16
+ }
17
+ const resolvedPath = resolveWithinRoot(resourceRoot, resourceRelativePath);
18
+ if (!existsSync(resolvedPath)) {
19
+ throw new Error(`Required package resource not found: ${resourceRelativePath} (resolved: ${resolvedPath})`);
20
+ }
21
+ return resolvedPath;
22
+ }
@@ -0,0 +1,37 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const PACKAGE_NAME = "@dailephd/my-dev-kit-lab";
5
+ /**
6
+ * Walks upward from the executing module's location (not process.cwd()) until it
7
+ * finds the package.json that declares PACKAGE_NAME, so this resolves correctly
8
+ * from a source checkout, compiled dist output, or an installed node_modules copy.
9
+ */
10
+ export function discoverPackageRoot(startDir) {
11
+ const start = path.resolve(startDir ?? path.dirname(fileURLToPath(import.meta.url)));
12
+ let current = start;
13
+ while (true) {
14
+ const candidatePackageJson = path.join(current, "package.json");
15
+ if (existsSync(candidatePackageJson)) {
16
+ const name = readPackageName(candidatePackageJson);
17
+ if (name === PACKAGE_NAME) {
18
+ return current;
19
+ }
20
+ }
21
+ const parent = path.dirname(current);
22
+ if (parent === current) {
23
+ break;
24
+ }
25
+ current = parent;
26
+ }
27
+ throw new Error(`Unable to locate the "${PACKAGE_NAME}" package root by walking up from ${start}.`);
28
+ }
29
+ function readPackageName(packageJsonPath) {
30
+ try {
31
+ const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
32
+ return typeof parsed.name === "string" ? parsed.name : undefined;
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
@@ -2,9 +2,22 @@ export const REQUIRED_PACKAGE_CONTENTS = [
2
2
  "CHANGELOG.md",
3
3
  "LICENSE",
4
4
  "README.md",
5
+ "package.json",
6
+ // Public bin target (installed CLI router entrypoint).
7
+ "dist/scripts/cli.js",
8
+ // Legacy final-demo bin-target compatibility (pre-v0.4.6 package.json bin).
5
9
  "dist/scripts/run-final-demo.js",
10
+ // Compiled runtime the installed CLI router and its shared command owners
11
+ // depend on.
6
12
  "dist/src/index.js",
7
- "package.json",
13
+ "dist/src/cli/runLabCli.js",
14
+ "dist/src/runtime/labExecutionContext.js",
15
+ "dist/src/runtime/packageRoot.js",
16
+ "dist/src/runtime/packageResource.js",
17
+ // Bundled runtime resources public installed commands read by default
18
+ // (experiment run/controlled, demo final, legacy final-demo invocation).
19
+ "benchmarks/contracts/benchmark-project-profiles.json",
20
+ "examples/token-savings-cases.json",
8
21
  ];
9
22
  function normalizeTarballPath(file) {
10
23
  const normalized = file.replace(/\\/g, "/");
package/package.json CHANGED
@@ -1,20 +1,19 @@
1
1
  {
2
2
  "name": "@dailephd/my-dev-kit-lab",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "type": "module",
5
5
  "description": "Evidence, benchmark, and evaluation companion for my-dev-kit.",
6
6
  "bin": {
7
- "my-dev-kit-lab": "dist/scripts/run-final-demo.js"
7
+ "my-dev-kit-lab": "dist/scripts/cli.js"
8
8
  },
9
9
  "files": [
10
10
  "CHANGELOG.md",
11
- "dist/scripts/",
12
- "!dist/scripts/docs/",
11
+ "dist/scripts/cli.js",
12
+ "dist/scripts/run-final-demo.js",
13
13
  "dist/src/",
14
14
  "benchmarks/",
15
15
  "docs/METRICS.md",
16
- "examples/",
17
- "tests/fixtures/"
16
+ "examples/token-savings-cases.json"
18
17
  ],
19
18
  "repository": {
20
19
  "type": "git",
@@ -72,6 +71,7 @@
72
71
  "test:plots": "vitest run tests/plots tests/commands/generateExperimentPlotsCommand.spec.ts",
73
72
  "test:visualization-demos": "vitest run tests/visualizationDemos tests/commands/runVisualizationDemosCommand.spec.ts",
74
73
  "verify:benchmarks": "tsx scripts/verify-benchmarks.ts",
74
+ "verify:packed-package": "node scripts/verify-packed-package.mjs",
75
75
  "docs:check": "node scripts/check-docs.mjs",
76
76
  "verify": "npm run build && npm run verify:benchmarks",
77
77
  "security:deps": "tsx scripts/security/runDependencyChecks.ts",
@@ -95,6 +95,6 @@
95
95
  "vite": "7.3.6"
96
96
  },
97
97
  "engines": {
98
- "node": ">=20"
98
+ "node": ">=24"
99
99
  }
100
100
  }
@@ -1,135 +0,0 @@
1
- #!/usr/bin/env node
2
- import { parseAuditArgs, normalizeAuditConfig } from "../../src/audits/core/auditConfig.js";
3
- import { resolveAuditTarget } from "../../src/audits/core/auditTarget.js";
4
- import { runAudit } from "../../src/audits/core/auditRunner.js";
5
- import { AUDIT_EXIT_CODES } from "../../src/audits/core/auditExitCode.js";
6
- import { resolveToolRoot } from "../security/resolveToolRoot.js";
7
- import { buildAuditReportModel } from "../../src/audits/report/auditReportModel.js";
8
- import { writeAuditReports } from "../../src/audits/report/writeAuditReports.js";
9
- // ---------------------------------------------------------------------------
10
- // v0.3.0 Batch 5 -- npm run audit entrypoint.
11
- //
12
- // Thin wiring only: parse args -> normalize config -> resolve target ->
13
- // runAudit() -> buildAuditReportModel() -> writeAuditReports() -> print a
14
- // concise console summary -> set process.exitCode. All report-shaping logic
15
- // (the former inline buildJsonReport()/renderMinimalTextSummary()/
16
- // summarizeInventory()/summarizeSourceOfTruth() functions from Batch 1/2)
17
- // now lives in src/audits/report/ -- see auditReportModel.ts,
18
- // renderAuditJsonReport.ts, renderAuditTextReport.ts, writeAuditReports.ts.
19
- // Mirrors the structure of scripts/security/validate.ts.
20
- // ---------------------------------------------------------------------------
21
- const USAGE = "Usage: npm run audit -- [--target <path>] [--types code-rot,security] " +
22
- "[--include docs,tests,package,architecture,cli] [--format text,json] " +
23
- "[--fail-on blocker|high|medium|low|none] [--out <path>] [--android]\n" +
24
- "\n" +
25
- " --android opts into Batch 2's programmatic Android security integration.\n" +
26
- " Requires --types to include \"security\" (e.g. --types security or --types\n" +
27
- " code-rot,security). Runs the same static, read-only, nineteen-check\n" +
28
- " Android validation security:validate --profile android performs --\n" +
29
- " detection, manifest parsing, and internal advanced security checks --\n" +
30
- " through the existing security adapter, never a subprocess. Confirmed\n" +
31
- " findings are mapped into the normal issue collection; CandidateEvidence\n" +
32
- " remains a separate, bounded summary and is never treated as a confirmed\n" +
33
- " issue. Starts zero Gradle operations, zero external tools, and zero\n" +
34
- " network operations by default; --android does not expose any of those.\n" +
35
- " Example: npm run audit -- --target \"<android-project-path>\" --types security --android --format text,json --fail-on none";
36
- const rawArgs = process.argv.slice(2);
37
- const toolRoot = resolveToolRoot(import.meta.url);
38
- // Help deliberately wins over every other argument, mirroring
39
- // scripts/security/validate.ts -- no config normalization, target
40
- // resolution, audit execution, or report write.
41
- if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
42
- console.log(USAGE);
43
- process.exitCode = 0;
44
- process.exit(0);
45
- }
46
- let config;
47
- try {
48
- const args = parseAuditArgs(rawArgs);
49
- config = normalizeAuditConfig(args, toolRoot);
50
- }
51
- catch (err) {
52
- const msg = err instanceof Error ? err.message : String(err);
53
- console.error(`\nERROR: ${msg}`);
54
- console.error(USAGE);
55
- process.exitCode = AUDIT_EXIT_CODES.FATAL_ERROR;
56
- process.exit(AUDIT_EXIT_CODES.FATAL_ERROR);
57
- }
58
- let target;
59
- try {
60
- target = resolveAuditTarget(config.targetPathArg, toolRoot);
61
- }
62
- catch (err) {
63
- const msg = err instanceof Error ? err.message : String(err);
64
- console.error(`\nERROR: ${msg}`);
65
- console.error(USAGE);
66
- process.exitCode = AUDIT_EXIT_CODES.FATAL_ERROR;
67
- process.exit(AUDIT_EXIT_CODES.FATAL_ERROR);
68
- }
69
- console.log("=".repeat(60));
70
- console.log("my-dev-kit-lab audit");
71
- console.log("=".repeat(60));
72
- console.log(`Tool root : ${toolRoot}`);
73
- if (!target.isSelf) {
74
- console.log(`Target : ${target.rootPath}`);
75
- }
76
- else {
77
- console.log(`Mode : self-audit`);
78
- }
79
- console.log(`Types : ${config.types.join(", ")}`);
80
- console.log(`Include : ${config.include.join(", ")}`);
81
- console.log("");
82
- let result;
83
- try {
84
- result = await runAudit({ config, toolRoot, target });
85
- }
86
- catch (err) {
87
- const msg = err instanceof Error ? err.message : String(err);
88
- console.error(`\nERROR: audit runtime failure: ${msg}`);
89
- process.exitCode = AUDIT_EXIT_CODES.FATAL_ERROR;
90
- process.exit(AUDIT_EXIT_CODES.FATAL_ERROR);
91
- }
92
- const model = buildAuditReportModel(result, { target });
93
- const { writtenPaths } = writeAuditReports({ model, config, outDir: config.out });
94
- console.log(`Issues found : ${model.summary.totalIssues}`);
95
- console.log(` blocker=${model.summary.issuesBySeverity.blocker} high=${model.summary.issuesBySeverity.high} medium=${model.summary.issuesBySeverity.medium} low=${model.summary.issuesBySeverity.low} info=${model.summary.issuesBySeverity.info}`);
96
- console.log(`Skipped detectors : ${model.summary.skippedDetectorCount}`);
97
- if (model.summary.detectorErrorCount > 0) {
98
- console.log(`Detector errors : ${model.summary.detectorErrorCount}`);
99
- for (const e of model.detectorErrors) {
100
- console.log(` [${e.id}] ${e.message}`);
101
- }
102
- }
103
- if (model.summary.noDetectorsRegistered && !model.securitySummary.ran) {
104
- console.log(`Note: no code-rot detectors are registered for this run's --types/--include selection -- this run collected inventory/source-of-truth data only.`);
105
- }
106
- if (model.securitySummary.ran) {
107
- console.log(`\nSecurity validation: verdict=${model.securitySummary.verdictLabel} checks=${model.securitySummary.totalChecks} findings(blocker=${model.securitySummary.findingCounts.blocker} major=${model.securitySummary.findingCounts.major} minor=${model.securitySummary.findingCounts.minor} info=${model.securitySummary.findingCounts.informational})`);
108
- if (model.securitySummary.reportPaths.text) {
109
- console.log(` Full report: ${model.securitySummary.reportPaths.text}`);
110
- }
111
- }
112
- if (model.androidSecurity.summary.requested) {
113
- const android = model.androidSecurity.summary;
114
- console.log(`\nAndroid security validation: status=${android.status} applicable=${android.applicable ?? "n/a"} verdict=${android.verdict ?? "(unknown)"} checks=${android.totalChecks} confirmed=${android.confirmedFindingCount} mappedIssues=${android.mappedIssueCount} candidates=${android.candidateSummary.totalCount}`);
115
- if (android.reportPaths.text) {
116
- console.log(` Full report: ${android.reportPaths.text}`);
117
- }
118
- }
119
- console.log(`\nInventory: ${model.inventory.totalScannedFileCount} file(s) scanned, ${model.inventory.skippedFileCount} skipped`);
120
- console.log(` source=${model.inventory.filesByCategory.source} tests=${model.inventory.filesByCategory.tests} docs=${model.inventory.filesByCategory.docs} package=${model.inventory.filesByCategory.package} config=${model.inventory.filesByCategory.config} scripts=${model.inventory.filesByCategory.scripts} ci=${model.inventory.filesByCategory.ci}`);
121
- console.log(`Source of truth: package=${model.sourceOfTruth.packageName ?? "(none)"}@${model.sourceOfTruth.packageVersion ?? "?"} readme=${model.sourceOfTruth.hasReadme} changelog=${model.sourceOfTruth.hasChangelog} ciWorkflows=${model.sourceOfTruth.ciWorkflowCount}`);
122
- console.log(`Source facts: ${model.sourceFacts.totalFilesAnalyzed} file(s) analyzed (parsed=${model.sourceFacts.filesByParseStatus.parsed} file-level-only=${model.sourceFacts.filesByParseStatus["file-level-only"]} unsupported=${model.sourceFacts.filesByParseStatus.unsupported})`);
123
- if (writtenPaths.length > 0) {
124
- console.log(`\nReports written:`);
125
- for (const p of writtenPaths) {
126
- console.log(` ${p}`);
127
- }
128
- }
129
- console.log(`\nHighest severity: ${model.summary.highestSeverity ?? "(none)"}`);
130
- console.log(`Verdict: ${model.summary.finalVerdictLabel}`);
131
- console.log(`Exit reason: ${model.exit.reason}`);
132
- console.log(model.exit.code === AUDIT_EXIT_CODES.SUCCESS
133
- ? `Exit 0 -- audit completed.`
134
- : `Exit 1 -- fail-on threshold breached.`);
135
- process.exitCode = model.exit.code;
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- import { runBuildGalleryCommand } from "../src/commands/buildGalleryCommand.js";
3
- process.exitCode = await runBuildGalleryCommand(process.argv.slice(2));
@@ -1,3 +0,0 @@
1
- import { runCaptureDemoReportCommand } from "../src/commands/captureDemoReport.js";
2
- const exitCode = await runCaptureDemoReportCommand(process.argv.slice(2));
3
- process.exitCode = exitCode;
@@ -1,2 +0,0 @@
1
- import { runEvaluateTokenSavingsCommand } from "../src/commands/evaluateTokenSavings.js";
2
- process.exitCode = await runEvaluateTokenSavingsCommand(process.argv.slice(2));
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- import { runGenerateExperimentPlotsCommand } from "../src/commands/generateExperimentPlotsCommand.js";
3
- process.exitCode = await runGenerateExperimentPlotsCommand(process.argv.slice(2));
@@ -1,2 +0,0 @@
1
- import { runGeneratePromptVariantsCommand } from "../src/commands/generatePromptVariants.js";
2
- process.exitCode = await runGeneratePromptVariantsCommand(process.argv.slice(2));
@@ -1,2 +0,0 @@
1
- import { runRenderExperimentReportCommand } from "../src/commands/renderExperimentReportCommand.js";
2
- process.exitCode = await runRenderExperimentReportCommand(process.argv.slice(2));