@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.
- package/CHANGELOG.md +16 -0
- package/README.md +37 -3
- package/dist/scripts/cli.js +9 -0
- package/dist/src/audits/core/typescriptJavaScriptAnalyzer.js +30 -12
- package/dist/src/cli/help.js +300 -0
- package/dist/src/cli/index.js +2 -0
- package/dist/src/cli/runLabCli.js +229 -0
- package/dist/src/commands/runAuditCommand.js +132 -0
- package/dist/src/commands/runControlledExperimentCommand.js +7 -3
- package/dist/{scripts/experiments/describeExperiment.js → src/commands/runExperimentDescribeCommand.js} +14 -10
- package/dist/{scripts/experiments/listExperiments.js → src/commands/runExperimentListCommand.js} +3 -6
- package/dist/{scripts/experiments/runExperiment.js → src/commands/runExperimentRunCommand.js} +80 -22
- package/dist/src/commands/runFinalDemoCommand.js +2 -3
- package/dist/src/commands/runSecurityValidationCommand.js +271 -0
- package/dist/src/runtime/index.js +3 -0
- package/dist/src/runtime/labExecutionContext.js +22 -0
- package/dist/src/runtime/packageResource.js +22 -0
- package/dist/src/runtime/packageRoot.js +37 -0
- package/dist/src/securityValidation/packageChecks/requiredPackageContents.js +14 -1
- package/package.json +7 -7
- package/dist/scripts/audits/runAudit.js +0 -135
- package/dist/scripts/build-gallery.js +0 -3
- package/dist/scripts/capture-demo-report.js +0 -3
- package/dist/scripts/evaluate-token-savings.js +0 -2
- package/dist/scripts/generate-experiment-plots.js +0 -3
- package/dist/scripts/generate-prompt-variants.js +0 -2
- package/dist/scripts/render-experiment-report.js +0 -2
- package/dist/scripts/report-context-integrity-smoke.js +0 -70
- package/dist/scripts/run-agent-prompt.js +0 -2
- package/dist/scripts/run-controlled-experiment.js +0 -2
- package/dist/scripts/run-lab-demo.js +0 -5
- package/dist/scripts/run-visualization-demos.js +0 -3
- package/dist/scripts/security/resolveToolRoot.js +0 -16
- package/dist/scripts/security/runCodeql.js +0 -58
- package/dist/scripts/security/runDependencyChecks.js +0 -58
- package/dist/scripts/security/runFuzzSmoke.js +0 -29
- package/dist/scripts/security/runPackageChecks.js +0 -57
- package/dist/scripts/security/runSemgrep.js +0 -64
- package/dist/scripts/security/validate.js +0 -266
- package/dist/scripts/verify-benchmarks.js +0 -202
- package/examples/demo-report-input.json +0 -78
- package/examples/lab-demo-cases.json +0 -35
- package/examples/real-agent-campaign-cases.json +0 -118
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/debug/res/xml/ambiguous_backup_rules.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/ambiguous_backup_rules.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/backup_rules.xml +0 -5
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/broad_backup_rules.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/data_extraction_rules.xml +0 -10
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-a/src/main/res/xml/unsupported_domain_rules.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-b/src/main/res/xml/malformed_backup_rules.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/backup-configuration/module-b/src/main/res/xml/unsupported_root.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/debug/res/xml/ambiguous_config.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/ambiguous_config.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/base_cleartext_false.xml +0 -8
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/broad_and_duplicate_domains.xml +0 -8
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/empty_domain.xml +0 -6
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/malformed_pin.xml +0 -11
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-a/src/main/res/xml/network_security_config.xml +0 -26
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-b/src/main/res/xml/malformed_network_security_config.xml +0 -6
- package/tests/fixtures/android/advanced-security-fixtures/network-security/module-b/src/main/res/xml/unsupported_root.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-dynamic.gradle +0 -7
- package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-false.gradle +0 -9
- package/tests/fixtures/android/advanced-security-fixtures/release-configuration/groovy-release-debuggable-true.gradle +0 -13
- package/tests/fixtures/android/advanced-security-fixtures/release-configuration/kotlin-release-debuggable-false.gradle.kts +0 -7
- package/tests/fixtures/android/advanced-security-fixtures/release-configuration/kotlin-release-debuggable-true.gradle.kts +0 -10
- package/tests/fixtures/android/advanced-security-fixtures/release-configuration/missing-release-build-type.gradle.kts +0 -7
- package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/debug/res/xml/network_security_config.xml +0 -8
- package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/main/res/xml/backup_rules.xml +0 -4
- package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-a/src/main/res/xml/network_security_config.xml +0 -8
- package/tests/fixtures/android/advanced-security-fixtures/resource-resolution/module-b/src/main/res/xml/malformed_network_security_config.xml +0 -7
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/SampleActivity.java +0 -8
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/SampleActivity.kt +0 -9
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/build.gradle +0 -11
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/build.gradle.kts +0 -11
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/google-services.json +0 -16
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates/local.properties +0 -3
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates-bounds/module/binary.properties +0 -0
- package/tests/fixtures/android/advanced-security-fixtures/secret-candidates-bounds/module/oversized.json +0 -1
- package/tests/fixtures/android/advanced-security-fixtures/signing-configuration/app/fake-release-keystore.jks +0 -1
- package/tests/fixtures/android/advanced-security-fixtures/signing-configuration/build/generated-fake.keystore +0 -1
- package/tests/fixtures/android/compose-app/app/build.gradle.kts +0 -21
- package/tests/fixtures/android/compose-app/app/src/main/AndroidManifest.xml +0 -22
- package/tests/fixtures/android/compose-app/app/src/main/java/com/example/composeapp/MainActivity.kt +0 -11
- package/tests/fixtures/android/compose-app/build.gradle.kts +0 -4
- package/tests/fixtures/android/compose-app/gradle/wrapper/gradle-wrapper.properties +0 -4
- package/tests/fixtures/android/compose-app/settings.gradle.kts +0 -2
- package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/build.gradle.kts +0 -3
- package/tests/fixtures/android/gradle-metadata-fixtures/catalog-only-plugin/gradle/libs.versions.toml +0 -5
- package/tests/fixtures/android/gradle-metadata-fixtures/comment-safety.gradle.kts +0 -21
- package/tests/fixtures/android/gradle-metadata-fixtures/dynamic-values.gradle.kts +0 -17
- package/tests/fixtures/android/gradle-metadata-fixtures/groovy-literal.gradle +0 -23
- package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-malformed.properties +0 -4
- package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-missing-url.properties +0 -3
- package/tests/fixtures/android/gradle-metadata-fixtures/wrapper-with-checksum.properties +0 -5
- package/tests/fixtures/android/java-app/app/build.gradle +0 -16
- package/tests/fixtures/android/java-app/app/src/main/AndroidManifest.xml +0 -19
- package/tests/fixtures/android/java-app/app/src/main/java/com/example/javaapp/MainActivity.java +0 -4
- package/tests/fixtures/android/java-app/build.gradle +0 -3
- package/tests/fixtures/android/java-app/gradle/wrapper/gradle-wrapper.properties +0 -4
- package/tests/fixtures/android/java-app/settings.gradle +0 -2
- package/tests/fixtures/android/library/build.gradle.kts +0 -3
- package/tests/fixtures/android/library/gradle/wrapper/gradle-wrapper.properties +0 -4
- package/tests/fixtures/android/library/mylibrary/build.gradle.kts +0 -13
- package/tests/fixtures/android/library/mylibrary/src/main/AndroidManifest.xml +0 -2
- package/tests/fixtures/android/library/settings.gradle.kts +0 -2
- package/tests/fixtures/android/manifest-audit-fixtures/incomplete-intent-filter.xml +0 -14
- package/tests/fixtures/android/manifest-audit-fixtures/malformed-exported.xml +0 -10
- package/tests/fixtures/android/manifest-audit-fixtures/malformed.xml +0 -5
- package/tests/fixtures/android/manifest-audit-fixtures/missing-application.xml +0 -7
- package/tests/fixtures/android/manifest-audit-fixtures/missing-component-name.xml +0 -11
- package/tests/fixtures/android/manifest-audit-fixtures/permission-coverage.xml +0 -29
- package/tests/fixtures/android/manifest-audit-fixtures/risky-components.xml +0 -62
- package/tests/fixtures/android/manifest-audit-fixtures/risky-deep-links.xml +0 -45
- package/tests/fixtures/android/manifest-audit-fixtures/unresolved-placeholder.xml +0 -14
- package/tests/fixtures/android/manifest-audit-fixtures/unusual-namespace-prefix.xml +0 -11
- package/tests/fixtures/android/multi-module/app/build.gradle.kts +0 -22
- package/tests/fixtures/android/multi-module/app/src/androidTest/java/com/example/multimodule/app/ExampleInstrumentedTest.kt +0 -3
- package/tests/fixtures/android/multi-module/app/src/main/AndroidManifest.xml +0 -11
- package/tests/fixtures/android/multi-module/app/src/test/java/com/example/multimodule/app/ExampleUnitTest.kt +0 -3
- package/tests/fixtures/android/multi-module/build.gradle.kts +0 -5
- package/tests/fixtures/android/multi-module/core/build.gradle.kts +0 -14
- package/tests/fixtures/android/multi-module/core/src/main/AndroidManifest.xml +0 -2
- package/tests/fixtures/android/multi-module/feature-login/build.gradle.kts +0 -18
- package/tests/fixtures/android/multi-module/feature-login/src/main/AndroidManifest.xml +0 -2
- package/tests/fixtures/android/multi-module/gradle/libs.versions.toml +0 -8
- package/tests/fixtures/android/multi-module/gradle/wrapper/gradle-wrapper.properties +0 -4
- package/tests/fixtures/android/multi-module/settings.gradle.kts +0 -4
- package/tests/fixtures/android/non-android-gradle/build.gradle.kts +0 -3
- package/tests/fixtures/android/non-android-gradle/core/build.gradle.kts +0 -3
- package/tests/fixtures/android/non-android-gradle/core/src/main/java/com/example/core/Core.java +0 -4
- package/tests/fixtures/android/non-android-gradle/gradle/wrapper/gradle-wrapper.properties +0 -4
- package/tests/fixtures/android/non-android-gradle/settings.gradle.kts +0 -2
- package/tests/fixtures/android/partial/app/build.gradle.kts +0 -7
- package/tests/fixtures/android/partial/settings.gradle.kts +0 -2
- package/tests/fixtures/android/xml-view-app/app/build.gradle.kts +0 -17
- package/tests/fixtures/android/xml-view-app/app/src/main/AndroidManifest.xml +0 -31
- package/tests/fixtures/android/xml-view-app/app/src/main/kotlin/com/example/xmlviewapp/MainActivity.kt +0 -7
- package/tests/fixtures/android/xml-view-app/app/src/main/res/layout/activity_main.xml +0 -4
- package/tests/fixtures/android/xml-view-app/build.gradle.kts +0 -4
- package/tests/fixtures/android/xml-view-app/gradle/wrapper/gradle-wrapper.properties +0 -4
- package/tests/fixtures/android/xml-view-app/settings.gradle.kts +0 -2
- package/tests/fixtures/audits/mixed-language/mixed-docs-claims/README.md +0 -16
- package/tests/fixtures/audits/mixed-language/mixed-docs-claims/build.gradle.kts +0 -4
- package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/java/com/example/Widget.java +0 -7
- package/tests/fixtures/audits/mixed-language/mixed-docs-claims/src/main/kotlin/com/example/Gadget.kt +0 -7
- package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/README.md +0 -10
- package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/build/Main.class +0 -1
- package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/dist/index.js +0 -1
- package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/generated/schema.ts +0 -1
- package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/src/index.ts +0 -3
- package/tests/fixtures/audits/mixed-language/mixed-generated-vendor/vendor/lib.py +0 -2
- package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/README.md +0 -10
- package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/build.gradle.kts +0 -8
- package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/settings.gradle.kts +0 -1
- package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/java/com/example/FooService.java +0 -7
- package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/main/kotlin/com/example/BarService.kt +0 -7
- package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/java/com/example/FooServiceTest.java +0 -8
- package/tests/fixtures/audits/mixed-language/mixed-java-kotlin/src/test/kotlin/com/example/BarServiceTest.kt +0 -8
- package/tests/fixtures/audits/mixed-language/mixed-python-ts/README.md +0 -8
- package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/app.py +0 -7
- package/tests/fixtures/audits/mixed-language/mixed-python-ts/src/index.ts +0 -3
- package/tests/fixtures/audits/mixed-language/mixed-python-ts/tests/test_app.py +0 -5
- package/tests/fixtures/audits/mixed-language/mixed-ts-js/README.md +0 -7
- package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/helper.js +0 -5
- package/tests/fixtures/audits/mixed-language/mixed-ts-js/src/index.ts +0 -3
- package/tests/fixtures/audits/mixed-language/mixed-ts-js/tests/index.sample.ts +0 -5
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/README.md +0 -10
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/build.gradle.kts +0 -4
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/pytests/test_app.py +0 -5
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/app.py +0 -2
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/helper.js +0 -5
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/index.ts +0 -3
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/java/com/example/Multiplier.java +0 -7
- package/tests/fixtures/audits/mixed-language/mixed-ts-python-jvm/src/main/kotlin/com/example/Divider.kt +0 -7
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/derived/run-integrity-evidence.json +0 -99
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-audit.json +0 -1585
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/corrected-replay/producer/implementation-capsule.json +0 -11455
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/00-request.txt +0 -1
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/architecture-context-packet.txt +0 -82
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/behavior-model.txt +0 -104
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/final-report.txt +0 -41
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-context-packet.txt +0 -114
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/implementation-report.txt +0 -92
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/judge-report.txt +0 -34
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/pseudocode-packet.txt +0 -244
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/request-brief.txt +0 -40
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-context-packet.txt +0 -93
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-implementation-report.txt +0 -69
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/test-strategy-packet.txt +0 -354
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/artifacts/verification-report.txt +0 -85
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/derived/run-integrity-evidence.json +0 -98
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-audit.json +0 -1169
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/architecture-request.json +0 -29
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-audit.json +0 -1494
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-capsule.json +0 -11364
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/implementation-request.json +0 -33
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/producer/test-request.json +0 -74
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/architecture-context-retrieval-report.txt +0 -58
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/implementation-context-retrieval-report.txt +0 -75
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/reports/test-context-retrieval-report.txt +0 -84
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/run.json +0 -62
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/my-dev-kit-version.txt +0 -1
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/failed-run/tool-versions/orchestrator-version.txt +0 -1
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/corrected-replay-manifest.json +0 -19
- package/tests/fixtures/ecosystem/context-integrity/v0.4.5/manifests/failed-run-manifest.json +0 -56
- package/tests/fixtures/fake-adversarial-cli.js +0 -152
- package/tests/fixtures/fake-my-dev-kit-cli.js +0 -83
- package/tests/fixtures/full-workflow-library/complete-v1.0.0.json +0 -24
- package/tests/fixtures/full-workflow-library/future-minor-v1.1.0-additive.json +0 -25
- package/tests/fixtures/stage-context-expectations/complete-v1.0.0.json +0 -230
- package/tests/fixtures/stage-context-expectations/future-minor-v1.1.0-additive.json +0 -232
- package/tests/fixtures/stage-context-expectations/invalid/malformed-json.txt +0 -1
- package/tests/fixtures/stage-context-expectations/invalid/non-object-root.json +0 -1
- package/tests/fixtures/stage-context-expectations/minimal-v1.0.0.json +0 -18
- package/tests/fixtures/upstream-artifacts/invalid/malformed-json.txt +0 -1
- package/tests/fixtures/upstream-artifacts/invalid/non-object-root.json +0 -1
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/complete-v1.0.0.json +0 -504
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/context-capsule/future-minor-v1.1.0-additive.json +0 -955
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/complete-v1.0.0.json +0 -190
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.2/retrieval-audit-record/future-minor-v1.1.0-additive.json +0 -327
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/PROVENANCE.txt +0 -18
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/context-capsule/complete-v1.0.0.json +0 -556
- package/tests/fixtures/upstream-artifacts/my-dev-kit/1.10.4/retrieval-audit-record/complete-v1.0.0.json +0 -238
- package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/PROVENANCE.txt +0 -13
- package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/context-capsule.json +0 -7874
- package/tests/fixtures/upstream-artifacts/my-dev-kit-1.10.2-identity/retrieval-audit-record.json +0 -1076
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/complete-v1.0.0.json +0 -160
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.1/workflow-instruction-packet/future-minor-v1.1.0-additive.json +0 -186
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/PROVENANCE.txt +0 -31
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/ready-pass-final-pass.json +0 -132
- package/tests/fixtures/upstream-artifacts/my-dev-kit-orchestrator/1.2.3/run-integrity/refresh-required-need-context.json +0 -146
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { runFinalDemoCommand } from "../commands/runFinalDemoCommand.js";
|
|
4
|
+
import { runAuditCommandFromArgs } from "../commands/runAuditCommand.js";
|
|
5
|
+
import { runSecurityValidationCommandFromArgs } from "../commands/runSecurityValidationCommand.js";
|
|
6
|
+
import { runControlledExperimentCommand } from "../commands/runControlledExperimentCommand.js";
|
|
7
|
+
import { runExperimentListCommandFromArgs } from "../commands/runExperimentListCommand.js";
|
|
8
|
+
import { runExperimentDescribeCommandFromArgs } from "../commands/runExperimentDescribeCommand.js";
|
|
9
|
+
import { runExperimentRunCommandFromArgs } from "../commands/runExperimentRunCommand.js";
|
|
10
|
+
import { runRenderExperimentReportCommand } from "../commands/renderExperimentReportCommand.js";
|
|
11
|
+
import { runGenerateExperimentPlotsCommand } from "../commands/generateExperimentPlotsCommand.js";
|
|
12
|
+
import { runBuildGalleryCommand } from "../commands/buildGalleryCommand.js";
|
|
13
|
+
import { createLabExecutionContext, discoverPackageRoot } from "../runtime/index.js";
|
|
14
|
+
import { renderDemoHelp, renderExperimentControlledHelp, renderExperimentDescribeHelp, renderExperimentHelp, renderExperimentListHelp, renderExperimentRunHelp, renderFinalDemoHelp, renderGalleryBuildHelp, renderGalleryHelp, renderPlotsGenerateHelp, renderPlotsHelp, renderReportHelp, renderReportRenderHelp, renderSecurityHelp, renderTopLevelHelp, renderUnknownCommandError } from "./help.js";
|
|
15
|
+
export const CLI_USAGE_EXIT_CODE = 2;
|
|
16
|
+
/**
|
|
17
|
+
* Recognized legacy final-demo flag tokens (mirrors parseRunFinalDemoArgs in
|
|
18
|
+
* src/commands/runFinalDemoCommand.ts). Used only to detect the historical
|
|
19
|
+
* direct invocation form; the legacy argument list itself is delegated to the
|
|
20
|
+
* existing final-demo parser unchanged, never reinterpreted here.
|
|
21
|
+
*/
|
|
22
|
+
const LEGACY_FINAL_DEMO_FLAGS = new Set([
|
|
23
|
+
"--cases",
|
|
24
|
+
"--out",
|
|
25
|
+
"--kit-command",
|
|
26
|
+
"--agents",
|
|
27
|
+
"--strategies",
|
|
28
|
+
"--complexities",
|
|
29
|
+
"--case",
|
|
30
|
+
"--benchmark-project",
|
|
31
|
+
"--max-runs",
|
|
32
|
+
"--screenshot",
|
|
33
|
+
"--no-screenshot",
|
|
34
|
+
"--include-real-agents",
|
|
35
|
+
"--continue-on-failure",
|
|
36
|
+
"--no-continue-on-failure",
|
|
37
|
+
"--timeout-ms"
|
|
38
|
+
]);
|
|
39
|
+
const DEFAULT_WRITERS = {
|
|
40
|
+
stdout: (message) => {
|
|
41
|
+
console.log(message);
|
|
42
|
+
},
|
|
43
|
+
stderr: (message) => {
|
|
44
|
+
console.error(message);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
export async function runLabCli(argv, options = {}) {
|
|
48
|
+
const writers = options.writers ?? DEFAULT_WRITERS;
|
|
49
|
+
const globalOptions = parseGlobalOptions(argv);
|
|
50
|
+
if (!globalOptions.ok) {
|
|
51
|
+
writers.stderr(globalOptions.error);
|
|
52
|
+
return CLI_USAGE_EXIT_CODE;
|
|
53
|
+
}
|
|
54
|
+
const remaining = globalOptions.remaining;
|
|
55
|
+
const context = createLabExecutionContext(globalOptions.workspaceRoot !== undefined ? { workspaceRoot: globalOptions.workspaceRoot } : {});
|
|
56
|
+
const [command, ...rest] = remaining;
|
|
57
|
+
if (remaining.length === 0 || command === "--help" || command === "-h") {
|
|
58
|
+
writers.stdout(renderTopLevelHelp());
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
if (command === "--version" || command === "-V") {
|
|
62
|
+
writers.stdout(readPackageVersion());
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
if (command === "security") {
|
|
66
|
+
return runSecurityFamily(rest, writers, context);
|
|
67
|
+
}
|
|
68
|
+
if (command === "audit") {
|
|
69
|
+
return runAuditCommandFromArgs(rest, { context, defaultOutRoot: context.workspaceRoot });
|
|
70
|
+
}
|
|
71
|
+
if (command === "experiment") {
|
|
72
|
+
return runExperimentFamily(rest, writers, context);
|
|
73
|
+
}
|
|
74
|
+
if (command === "report") {
|
|
75
|
+
return runReportFamily(rest, writers);
|
|
76
|
+
}
|
|
77
|
+
if (command === "plots") {
|
|
78
|
+
return runPlotsFamily(rest, writers);
|
|
79
|
+
}
|
|
80
|
+
if (command === "gallery") {
|
|
81
|
+
return runGalleryFamily(rest, writers);
|
|
82
|
+
}
|
|
83
|
+
if (command === "demo") {
|
|
84
|
+
return runDemoCommand(rest, writers);
|
|
85
|
+
}
|
|
86
|
+
if (LEGACY_FINAL_DEMO_FLAGS.has(command)) {
|
|
87
|
+
return runFinalDemoCommand(remaining);
|
|
88
|
+
}
|
|
89
|
+
writers.stderr(renderUnknownCommandError(command));
|
|
90
|
+
return CLI_USAGE_EXIT_CODE;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Only recognizes a leading "--workspace <path>" pair (must be argv[0]).
|
|
94
|
+
* A --workspace token appearing anywhere else is left untouched for normal
|
|
95
|
+
* command/legacy routing to handle (or reject), per the batch requirement
|
|
96
|
+
* that global options must precede the command.
|
|
97
|
+
*/
|
|
98
|
+
function parseGlobalOptions(argv) {
|
|
99
|
+
if (argv[0] !== "--workspace") {
|
|
100
|
+
return { ok: true, remaining: argv };
|
|
101
|
+
}
|
|
102
|
+
const value = argv[1];
|
|
103
|
+
if (value === undefined) {
|
|
104
|
+
return { ok: false, error: "Missing value for --workspace. Expected a path after --workspace." };
|
|
105
|
+
}
|
|
106
|
+
return { ok: true, workspaceRoot: value, remaining: argv.slice(2) };
|
|
107
|
+
}
|
|
108
|
+
async function runDemoCommand(argv, writers) {
|
|
109
|
+
const [subcommand, ...rest] = argv;
|
|
110
|
+
if (argv.length === 0 || subcommand === "--help" || subcommand === "-h") {
|
|
111
|
+
writers.stdout(renderDemoHelp());
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
if (subcommand === "final") {
|
|
115
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
116
|
+
writers.stdout(renderFinalDemoHelp());
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
return runFinalDemoCommand(rest);
|
|
120
|
+
}
|
|
121
|
+
writers.stderr(renderUnknownCommandError(`demo ${subcommand}`));
|
|
122
|
+
return CLI_USAGE_EXIT_CODE;
|
|
123
|
+
}
|
|
124
|
+
async function runSecurityFamily(argv, writers, context) {
|
|
125
|
+
const [subcommand, ...rest] = argv;
|
|
126
|
+
if (argv.length === 0 || subcommand === "--help" || subcommand === "-h") {
|
|
127
|
+
writers.stdout(renderSecurityHelp());
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
if (subcommand === "validate") {
|
|
131
|
+
return runSecurityValidationCommandFromArgs(rest, { context, defaultOutRoot: context.workspaceRoot });
|
|
132
|
+
}
|
|
133
|
+
writers.stderr(renderUnknownCommandError(`security ${subcommand}`));
|
|
134
|
+
return CLI_USAGE_EXIT_CODE;
|
|
135
|
+
}
|
|
136
|
+
async function runExperimentFamily(argv, writers, context) {
|
|
137
|
+
const [subcommand, ...rest] = argv;
|
|
138
|
+
if (argv.length === 0 || subcommand === "--help" || subcommand === "-h") {
|
|
139
|
+
writers.stdout(renderExperimentHelp());
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
if (subcommand === "list") {
|
|
143
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
144
|
+
writers.stdout(renderExperimentListHelp());
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
return runExperimentListCommandFromArgs(rest);
|
|
148
|
+
}
|
|
149
|
+
if (subcommand === "describe") {
|
|
150
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
151
|
+
writers.stdout(renderExperimentDescribeHelp());
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
return runExperimentDescribeCommandFromArgs(rest);
|
|
155
|
+
}
|
|
156
|
+
if (subcommand === "run") {
|
|
157
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
158
|
+
writers.stdout(renderExperimentRunHelp());
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
return runExperimentRunCommandFromArgs(rest, { context, installedDefaultOutputRoot: context.workspaceRoot });
|
|
162
|
+
}
|
|
163
|
+
if (subcommand === "controlled") {
|
|
164
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
165
|
+
writers.stdout(renderExperimentControlledHelp());
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
return runControlledExperimentCommand(rest);
|
|
169
|
+
}
|
|
170
|
+
writers.stderr(renderUnknownCommandError(`experiment ${subcommand}`));
|
|
171
|
+
return CLI_USAGE_EXIT_CODE;
|
|
172
|
+
}
|
|
173
|
+
async function runReportFamily(argv, writers) {
|
|
174
|
+
const [subcommand, ...rest] = argv;
|
|
175
|
+
if (argv.length === 0 || subcommand === "--help" || subcommand === "-h") {
|
|
176
|
+
writers.stdout(renderReportHelp());
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
if (subcommand === "render") {
|
|
180
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
181
|
+
writers.stdout(renderReportRenderHelp());
|
|
182
|
+
return 0;
|
|
183
|
+
}
|
|
184
|
+
return runRenderExperimentReportCommand(rest);
|
|
185
|
+
}
|
|
186
|
+
writers.stderr(renderUnknownCommandError(`report ${subcommand}`));
|
|
187
|
+
return CLI_USAGE_EXIT_CODE;
|
|
188
|
+
}
|
|
189
|
+
async function runPlotsFamily(argv, writers) {
|
|
190
|
+
const [subcommand, ...rest] = argv;
|
|
191
|
+
if (argv.length === 0 || subcommand === "--help" || subcommand === "-h") {
|
|
192
|
+
writers.stdout(renderPlotsHelp());
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
if (subcommand === "generate") {
|
|
196
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
197
|
+
writers.stdout(renderPlotsGenerateHelp());
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
return runGenerateExperimentPlotsCommand(rest);
|
|
201
|
+
}
|
|
202
|
+
writers.stderr(renderUnknownCommandError(`plots ${subcommand}`));
|
|
203
|
+
return CLI_USAGE_EXIT_CODE;
|
|
204
|
+
}
|
|
205
|
+
async function runGalleryFamily(argv, writers) {
|
|
206
|
+
const [subcommand, ...rest] = argv;
|
|
207
|
+
if (argv.length === 0 || subcommand === "--help" || subcommand === "-h") {
|
|
208
|
+
writers.stdout(renderGalleryHelp());
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
if (subcommand === "build") {
|
|
212
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
213
|
+
writers.stdout(renderGalleryBuildHelp());
|
|
214
|
+
return 0;
|
|
215
|
+
}
|
|
216
|
+
return runBuildGalleryCommand(rest);
|
|
217
|
+
}
|
|
218
|
+
writers.stderr(renderUnknownCommandError(`gallery ${subcommand}`));
|
|
219
|
+
return CLI_USAGE_EXIT_CODE;
|
|
220
|
+
}
|
|
221
|
+
function readPackageVersion() {
|
|
222
|
+
const packageRoot = discoverPackageRoot();
|
|
223
|
+
const packageJsonPath = path.join(packageRoot, "package.json");
|
|
224
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
225
|
+
if (typeof parsed.version !== "string" || parsed.version.length === 0) {
|
|
226
|
+
throw new Error(`Unable to read a valid version from ${packageJsonPath}`);
|
|
227
|
+
}
|
|
228
|
+
return parsed.version;
|
|
229
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { parseAuditArgs, normalizeAuditConfig } from "../audits/core/auditConfig.js";
|
|
2
|
+
import { resolveAuditTarget } from "../audits/core/auditTarget.js";
|
|
3
|
+
import { runAudit } from "../audits/core/auditRunner.js";
|
|
4
|
+
import { AUDIT_EXIT_CODES } from "../audits/core/auditExitCode.js";
|
|
5
|
+
import { buildAuditReportModel } from "../audits/report/auditReportModel.js";
|
|
6
|
+
import { writeAuditReports } from "../audits/report/writeAuditReports.js";
|
|
7
|
+
import { createLabExecutionContext } from "../runtime/index.js";
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// v0.4.6 Batch 3 -- reusable audit command owner.
|
|
10
|
+
//
|
|
11
|
+
// Extracted from scripts/audits/runAudit.ts (formerly a top-level script
|
|
12
|
+
// with inline try/catch + process.exit()) so both the contributor npm
|
|
13
|
+
// script and the installed CLI router (src/cli/) can call the same
|
|
14
|
+
// argument-parsing/target-resolution/report-writing path instead of
|
|
15
|
+
// maintaining two implementations. Detector/severity/report-schema policy
|
|
16
|
+
// is untouched -- this module only owns CLI argument handling, target
|
|
17
|
+
// resolution, the runAudit() call, report writing, and exit-code mapping.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
export const AUDIT_USAGE = "Usage: my-dev-kit-lab audit [--target <path>] [--types code-rot,security] " +
|
|
20
|
+
"[--include docs,tests,package,architecture,cli] [--format text,json] " +
|
|
21
|
+
"[--fail-on blocker|high|medium|low|none] [--out <path>] [--android]\n" +
|
|
22
|
+
"\n" +
|
|
23
|
+
" --android opts into Batch 2's programmatic Android security integration.\n" +
|
|
24
|
+
" Requires --types to include \"security\" (e.g. --types security or --types\n" +
|
|
25
|
+
" code-rot,security). Runs the same static, read-only, nineteen-check\n" +
|
|
26
|
+
" Android validation security:validate --profile android performs --\n" +
|
|
27
|
+
" detection, manifest parsing, and internal advanced security checks --\n" +
|
|
28
|
+
" through the existing security adapter, never a subprocess. Confirmed\n" +
|
|
29
|
+
" findings are mapped into the normal issue collection; CandidateEvidence\n" +
|
|
30
|
+
" remains a separate, bounded summary and is never treated as a confirmed\n" +
|
|
31
|
+
" issue. Starts zero Gradle operations, zero external tools, and zero\n" +
|
|
32
|
+
" network operations by default; --android does not expose any of those.\n" +
|
|
33
|
+
" Example: my-dev-kit-lab audit --target \"<android-project-path>\" --types security --android --format text,json --fail-on none";
|
|
34
|
+
export async function runAuditCommandFromArgs(argv, options = {}) {
|
|
35
|
+
const context = options.context ?? createLabExecutionContext();
|
|
36
|
+
const toolRoot = context.packageRoot;
|
|
37
|
+
const defaultOutRoot = options.defaultOutRoot ?? toolRoot;
|
|
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 (argv.includes("--help") || argv.includes("-h")) {
|
|
42
|
+
console.log(AUDIT_USAGE);
|
|
43
|
+
return AUDIT_EXIT_CODES.SUCCESS;
|
|
44
|
+
}
|
|
45
|
+
let config;
|
|
46
|
+
try {
|
|
47
|
+
const args = parseAuditArgs(argv);
|
|
48
|
+
config = normalizeAuditConfig(args, defaultOutRoot);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
52
|
+
console.error(`\nERROR: ${msg}`);
|
|
53
|
+
console.error(AUDIT_USAGE);
|
|
54
|
+
return AUDIT_EXIT_CODES.FATAL_ERROR;
|
|
55
|
+
}
|
|
56
|
+
let target;
|
|
57
|
+
try {
|
|
58
|
+
target = resolveAuditTarget(config.targetPathArg, toolRoot);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62
|
+
console.error(`\nERROR: ${msg}`);
|
|
63
|
+
console.error(AUDIT_USAGE);
|
|
64
|
+
return AUDIT_EXIT_CODES.FATAL_ERROR;
|
|
65
|
+
}
|
|
66
|
+
console.log("=".repeat(60));
|
|
67
|
+
console.log("my-dev-kit-lab audit");
|
|
68
|
+
console.log("=".repeat(60));
|
|
69
|
+
console.log(`Tool root : ${toolRoot}`);
|
|
70
|
+
if (!target.isSelf) {
|
|
71
|
+
console.log(`Target : ${target.rootPath}`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(`Mode : self-audit`);
|
|
75
|
+
}
|
|
76
|
+
console.log(`Types : ${config.types.join(", ")}`);
|
|
77
|
+
console.log(`Include : ${config.include.join(", ")}`);
|
|
78
|
+
console.log("");
|
|
79
|
+
let result;
|
|
80
|
+
try {
|
|
81
|
+
result = await runAudit({ config, toolRoot, target });
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
85
|
+
console.error(`\nERROR: audit runtime failure: ${msg}`);
|
|
86
|
+
return AUDIT_EXIT_CODES.FATAL_ERROR;
|
|
87
|
+
}
|
|
88
|
+
const model = buildAuditReportModel(result, { target });
|
|
89
|
+
const { writtenPaths } = writeAuditReports({ model, config, outDir: config.out });
|
|
90
|
+
console.log(`Issues found : ${model.summary.totalIssues}`);
|
|
91
|
+
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}`);
|
|
92
|
+
console.log(`Skipped detectors : ${model.summary.skippedDetectorCount}`);
|
|
93
|
+
if (model.summary.detectorErrorCount > 0) {
|
|
94
|
+
console.log(`Detector errors : ${model.summary.detectorErrorCount}`);
|
|
95
|
+
for (const e of model.detectorErrors) {
|
|
96
|
+
console.log(` [${e.id}] ${e.message}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (model.summary.noDetectorsRegistered && !model.securitySummary.ran) {
|
|
100
|
+
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.`);
|
|
101
|
+
}
|
|
102
|
+
if (model.securitySummary.ran) {
|
|
103
|
+
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})`);
|
|
104
|
+
if (model.securitySummary.reportPaths.text) {
|
|
105
|
+
console.log(` Full report: ${model.securitySummary.reportPaths.text}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (model.androidSecurity.summary.requested) {
|
|
109
|
+
const android = model.androidSecurity.summary;
|
|
110
|
+
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}`);
|
|
111
|
+
if (android.reportPaths.text) {
|
|
112
|
+
console.log(` Full report: ${android.reportPaths.text}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
console.log(`\nInventory: ${model.inventory.totalScannedFileCount} file(s) scanned, ${model.inventory.skippedFileCount} skipped`);
|
|
116
|
+
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}`);
|
|
117
|
+
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}`);
|
|
118
|
+
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})`);
|
|
119
|
+
if (writtenPaths.length > 0) {
|
|
120
|
+
console.log(`\nReports written:`);
|
|
121
|
+
for (const p of writtenPaths) {
|
|
122
|
+
console.log(` ${p}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
console.log(`\nHighest severity: ${model.summary.highestSeverity ?? "(none)"}`);
|
|
126
|
+
console.log(`Verdict: ${model.summary.finalVerdictLabel}`);
|
|
127
|
+
console.log(`Exit reason: ${model.exit.reason}`);
|
|
128
|
+
console.log(model.exit.code === AUDIT_EXIT_CODES.SUCCESS
|
|
129
|
+
? `Exit 0 -- audit completed.`
|
|
130
|
+
: `Exit 1 -- fail-on threshold breached.`);
|
|
131
|
+
return model.exit.code;
|
|
132
|
+
}
|
|
@@ -4,9 +4,11 @@ import { parseAgentId } from "../agents/agentRegistry.js";
|
|
|
4
4
|
import { readBenchmarkProjectProfiles, readEvaluationCases } from "../evaluation/index.js";
|
|
5
5
|
import { contextStrategyComparisonPlugin, resolveExperimentTarget } from "../experiments/index.js";
|
|
6
6
|
import { parsePromptComplexityLevel, parsePromptStrategy } from "../prompts/index.js";
|
|
7
|
+
import { createLabExecutionContext, resolvePackageResource } from "../runtime/index.js";
|
|
8
|
+
const DEFAULT_PROJECT_PROFILES_RESOURCE = "benchmarks/contracts/benchmark-project-profiles.json";
|
|
7
9
|
export function parseRunControlledExperimentArgs(argv) {
|
|
8
10
|
let casesPath = "";
|
|
9
|
-
let projectProfilesPath
|
|
11
|
+
let projectProfilesPath;
|
|
10
12
|
let outDir = "";
|
|
11
13
|
const caseIds = [];
|
|
12
14
|
const benchmarkProjects = [];
|
|
@@ -109,8 +111,10 @@ export function parseRunControlledExperimentArgs(argv) {
|
|
|
109
111
|
includeRealAgents
|
|
110
112
|
};
|
|
111
113
|
}
|
|
112
|
-
export async function runControlledExperimentFromArgs(args, repoRoot = process.cwd()) {
|
|
113
|
-
const projectProfilesPath =
|
|
114
|
+
export async function runControlledExperimentFromArgs(args, repoRoot = process.cwd(), context) {
|
|
115
|
+
const projectProfilesPath = args.projectProfilesPath
|
|
116
|
+
? path.resolve(repoRoot, args.projectProfilesPath)
|
|
117
|
+
: resolvePackageResource(context ?? createLabExecutionContext(), DEFAULT_PROJECT_PROFILES_RESOURCE);
|
|
114
118
|
const casesPath = path.resolve(repoRoot, args.casesPath);
|
|
115
119
|
const projectProfiles = await readBenchmarkProjectProfiles(projectProfilesPath, repoRoot);
|
|
116
120
|
const cases = await readEvaluationCases(casesPath, repoRoot, {
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import { createDefaultExperimentPluginRegistry } from "
|
|
2
|
-
|
|
1
|
+
import { createDefaultExperimentPluginRegistry } from "../experiments/index.js";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// v0.4.6 Batch 4 -- reusable experiment-describe command owner.
|
|
4
|
+
//
|
|
5
|
+
// Extracted from scripts/experiments/describeExperiment.ts so both the npm
|
|
6
|
+
// script and the installed CLI router call the same registry-lookup and
|
|
7
|
+
// description-building path. Read-only: no filesystem writes.
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
export async function runExperimentDescribeCommandFromArgs(argv) {
|
|
3
10
|
try {
|
|
4
11
|
const args = parseDescribeArgs(argv);
|
|
5
12
|
const registry = createDefaultExperimentPluginRegistry();
|
|
@@ -50,7 +57,7 @@ function buildDescription(plugin) {
|
|
|
50
57
|
optionalConfigFields: readConfigFields(plugin, false),
|
|
51
58
|
targetBehavior: describeTargetBehavior(plugin),
|
|
52
59
|
expectedReports: describeExpectedReports(plugin),
|
|
53
|
-
examples: describeExamples(plugin)
|
|
60
|
+
examples: describeExamples(plugin)
|
|
54
61
|
};
|
|
55
62
|
}
|
|
56
63
|
function printDescription(plugin) {
|
|
@@ -95,7 +102,7 @@ function readConfigFields(plugin, required) {
|
|
|
95
102
|
.filter((field) => Boolean(field.required) === required)
|
|
96
103
|
.map((field) => ({
|
|
97
104
|
...field,
|
|
98
|
-
defaultValue: readDefaultValue(plugin.defaultConfig, field.name)
|
|
105
|
+
defaultValue: readDefaultValue(plugin.defaultConfig, field.name)
|
|
99
106
|
}));
|
|
100
107
|
}
|
|
101
108
|
function readSupportedVariants(plugin) {
|
|
@@ -133,11 +140,8 @@ function describeExpectedReports(plugin) {
|
|
|
133
140
|
}
|
|
134
141
|
function describeExamples(plugin) {
|
|
135
142
|
return [
|
|
136
|
-
`
|
|
137
|
-
`
|
|
138
|
-
`
|
|
143
|
+
`my-dev-kit-lab experiment describe --experiment ${plugin.metadata.id}`,
|
|
144
|
+
`my-dev-kit-lab experiment run --experiment ${plugin.metadata.id} --agents fake-agent --complexities short`,
|
|
145
|
+
`my-dev-kit-lab experiment run --experiment ${plugin.metadata.id} --target "Z:\\Users\\newuser\\Projects\\my-dev-kit-v1" --agents fake-agent --complexities short --no-screenshot`
|
|
139
146
|
];
|
|
140
147
|
}
|
|
141
|
-
if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replaceAll("\\", "/"))) {
|
|
142
|
-
process.exitCode = await main(process.argv.slice(2));
|
|
143
|
-
}
|
package/dist/{scripts/experiments/listExperiments.js → src/commands/runExperimentListCommand.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createDefaultExperimentPluginRegistry } from "
|
|
2
|
-
async function
|
|
1
|
+
import { createDefaultExperimentPluginRegistry } from "../experiments/index.js";
|
|
2
|
+
export async function runExperimentListCommandFromArgs(argv) {
|
|
3
3
|
const json = argv.includes("--json");
|
|
4
4
|
const registry = createDefaultExperimentPluginRegistry();
|
|
5
5
|
const plugins = registry.list().map((metadata) => {
|
|
@@ -25,7 +25,7 @@ async function main(argv) {
|
|
|
25
25
|
function toListedExperiment(metadata, plugin) {
|
|
26
26
|
return {
|
|
27
27
|
...metadata,
|
|
28
|
-
supportedVariants: readSupportedVariants(plugin)
|
|
28
|
+
supportedVariants: readSupportedVariants(plugin)
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
function readSupportedVariants(plugin) {
|
|
@@ -39,6 +39,3 @@ function readArrayField(value, key) {
|
|
|
39
39
|
const field = value[key];
|
|
40
40
|
return Array.isArray(field) ? field : [];
|
|
41
41
|
}
|
|
42
|
-
if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replaceAll("\\", "/"))) {
|
|
43
|
-
process.exitCode = await main(process.argv.slice(2));
|
|
44
|
-
}
|
package/dist/{scripts/experiments/runExperiment.js → src/commands/runExperimentRunCommand.js}
RENAMED
|
@@ -1,30 +1,65 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { parseAgentCommandTemplate } from "
|
|
3
|
-
import { parseAgentId } from "
|
|
4
|
-
import { readBenchmarkProjectProfiles, readEvaluationCases } from "
|
|
5
|
-
import { createDefaultExperimentPluginRegistry, runExperiment } from "
|
|
6
|
-
import {
|
|
7
|
-
import { parsePromptComplexityLevel, parsePromptStrategy } from "
|
|
8
|
-
import { writePluginExperimentReports } from "
|
|
9
|
-
|
|
2
|
+
import { parseAgentCommandTemplate } from "../agents/index.js";
|
|
3
|
+
import { parseAgentId } from "../agents/agentRegistry.js";
|
|
4
|
+
import { readBenchmarkProjectProfiles, readEvaluationCases } from "../evaluation/index.js";
|
|
5
|
+
import { contextStrategyComparisonPlugin, createDefaultExperimentPluginRegistry, resolveExperimentTarget, runExperiment } from "../experiments/index.js";
|
|
6
|
+
import { buildDefaultExperimentOutputRoot } from "../experiments/outputPaths.js";
|
|
7
|
+
import { parsePromptComplexityLevel, parsePromptStrategy } from "../prompts/index.js";
|
|
8
|
+
import { writePluginExperimentReports } from "../report/index.js";
|
|
9
|
+
import { createLabExecutionContext, resolvePackageResource } from "../runtime/index.js";
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// v0.4.6 Batch 4 -- reusable experiment-run command owner.
|
|
12
|
+
//
|
|
13
|
+
// Extracted from scripts/experiments/runExperiment.ts. Reuses the existing
|
|
14
|
+
// generic runner (src/experiments/runner.ts) and the registered
|
|
15
|
+
// context-strategy-comparison plugin unchanged. Two things move relative to
|
|
16
|
+
// the source-checkout script:
|
|
17
|
+
//
|
|
18
|
+
// 1. Bundled resource lookup (the default cases/project-profiles files) goes
|
|
19
|
+
// through Batch 1's resolvePackageResource() instead of a
|
|
20
|
+
// process.cwd()-relative path, so it no longer depends on the checkout.
|
|
21
|
+
// 2. The implicit (no --out) output root, for installed execution only, is
|
|
22
|
+
// rooted under workspaceRoot instead of the tool/package root -- computed
|
|
23
|
+
// with the same buildDefaultExperimentOutputRoot() helper the runner
|
|
24
|
+
// itself uses internally, so the plugin/target/run subdirectory shape is
|
|
25
|
+
// unchanged, only the root differs. Explicit --out is pre-resolved
|
|
26
|
+
// against invocationCwd so its resolution base never changes.
|
|
27
|
+
//
|
|
28
|
+
// Self-target fallback (no --target) and relative --target resolution are
|
|
29
|
+
// untouched -- both still go through the shared toolRoot (packageRoot),
|
|
30
|
+
// matching runAuditCommand.ts / runSecurityValidationCommand.ts.
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
const DEFAULT_CASES_RESOURCE = "examples/token-savings-cases.json";
|
|
33
|
+
const DEFAULT_PROJECT_PROFILES_RESOURCE = "benchmarks/contracts/benchmark-project-profiles.json";
|
|
34
|
+
export async function runExperimentRunCommandFromArgs(argv, options = {}) {
|
|
10
35
|
try {
|
|
11
36
|
const args = parseRunExperimentArgs(argv);
|
|
12
|
-
const
|
|
37
|
+
const context = options.context ?? createLabExecutionContext();
|
|
38
|
+
const toolRoot = context.packageRoot;
|
|
13
39
|
const registry = createDefaultExperimentPluginRegistry();
|
|
14
|
-
const inputs = await loadPluginInputs(args, toolRoot);
|
|
40
|
+
const inputs = await loadPluginInputs(args, toolRoot, context);
|
|
41
|
+
const runId = generateExperimentRunId(args.experimentId);
|
|
42
|
+
const outputRoot = resolveOutputRoot(args, {
|
|
43
|
+
toolRoot,
|
|
44
|
+
invocationCwd: context.invocationCwd,
|
|
45
|
+
installedDefaultOutputRoot: options.installedDefaultOutputRoot,
|
|
46
|
+
experimentId: args.experimentId,
|
|
47
|
+
runId
|
|
48
|
+
});
|
|
15
49
|
const result = await runExperiment({
|
|
16
50
|
pluginId: args.experimentId,
|
|
17
51
|
registry,
|
|
18
52
|
targetPath: args.targetPath,
|
|
19
|
-
outputRoot
|
|
53
|
+
outputRoot,
|
|
20
54
|
config: args.config,
|
|
21
55
|
inputs,
|
|
22
56
|
toolRoot,
|
|
57
|
+
runId
|
|
23
58
|
});
|
|
24
59
|
const reports = await writePluginExperimentReports({
|
|
25
60
|
run: result,
|
|
26
61
|
plugin: registry.describe(result.pluginId),
|
|
27
|
-
outputRoot: String(result.metadata?.outputRoot ?? "")
|
|
62
|
+
outputRoot: String(result.metadata?.outputRoot ?? "")
|
|
28
63
|
});
|
|
29
64
|
console.log([
|
|
30
65
|
`Experiment: ${result.pluginId}`,
|
|
@@ -35,7 +70,7 @@ async function main(argv) {
|
|
|
35
70
|
`Target root: ${result.target.targetRoot}`,
|
|
36
71
|
`Output: ${String(result.metadata?.outputRoot ?? "")}`,
|
|
37
72
|
`Report JSON: ${reports.outputPaths.jsonPath}`,
|
|
38
|
-
`Report HTML: ${reports.outputPaths.htmlPath}
|
|
73
|
+
`Report HTML: ${reports.outputPaths.htmlPath}`
|
|
39
74
|
].join("\n"));
|
|
40
75
|
return result.status === "failed" ? 1 : 0;
|
|
41
76
|
}
|
|
@@ -150,11 +185,33 @@ export function parseRunExperimentArgs(argv) {
|
|
|
150
185
|
continueOnFailure,
|
|
151
186
|
requireAgents,
|
|
152
187
|
includeRealAgents,
|
|
153
|
-
commandTemplates: Object.keys(commandTemplates).length > 0 ? commandTemplates : undefined
|
|
154
|
-
})
|
|
188
|
+
commandTemplates: Object.keys(commandTemplates).length > 0 ? commandTemplates : undefined
|
|
189
|
+
})
|
|
155
190
|
};
|
|
156
191
|
}
|
|
157
|
-
|
|
192
|
+
function resolveOutputRoot(args, params) {
|
|
193
|
+
if (args.outDir) {
|
|
194
|
+
// Pre-resolve to an absolute path against invocationCwd so its
|
|
195
|
+
// resolution base never depends on toolRoot/packageRoot.
|
|
196
|
+
return path.resolve(params.invocationCwd, args.outDir);
|
|
197
|
+
}
|
|
198
|
+
if (!params.installedDefaultOutputRoot) {
|
|
199
|
+
// Preserve the runner's own internal toolRoot-relative default.
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
const target = resolveExperimentTarget(args.targetPath, params.toolRoot);
|
|
203
|
+
return buildDefaultExperimentOutputRoot({
|
|
204
|
+
toolRoot: params.installedDefaultOutputRoot,
|
|
205
|
+
pluginId: params.experimentId,
|
|
206
|
+
target,
|
|
207
|
+
runId: params.runId
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function generateExperimentRunId(pluginId) {
|
|
211
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
212
|
+
return `${pluginId}-${timestamp}`;
|
|
213
|
+
}
|
|
214
|
+
async function loadPluginInputs(args, toolRoot, context) {
|
|
158
215
|
if (args.experimentId !== contextStrategyComparisonPlugin.metadata.id) {
|
|
159
216
|
return undefined;
|
|
160
217
|
}
|
|
@@ -162,12 +219,16 @@ async function loadPluginInputs(args, toolRoot) {
|
|
|
162
219
|
if (!validation.valid || !validation.config) {
|
|
163
220
|
throw new Error(`Invalid context strategy comparison config: ${validation.errors.join("; ")}`);
|
|
164
221
|
}
|
|
165
|
-
const projectProfilesPath =
|
|
166
|
-
|
|
222
|
+
const projectProfilesPath = args.config.projectProfilesPath
|
|
223
|
+
? path.resolve(toolRoot, args.config.projectProfilesPath)
|
|
224
|
+
: resolvePackageResource(context, DEFAULT_PROJECT_PROFILES_RESOURCE);
|
|
225
|
+
const casesPath = args.config.casesPath
|
|
226
|
+
? path.resolve(toolRoot, args.config.casesPath)
|
|
227
|
+
: resolvePackageResource(context, DEFAULT_CASES_RESOURCE);
|
|
167
228
|
const projectProfiles = await readBenchmarkProjectProfiles(projectProfilesPath, toolRoot);
|
|
168
229
|
const cases = await readEvaluationCases(casesPath, toolRoot, {
|
|
169
230
|
projectProfiles,
|
|
170
|
-
requireProjectProfileRef: true
|
|
231
|
+
requireProjectProfileRef: true
|
|
171
232
|
});
|
|
172
233
|
return { cases, projectProfiles, env: process.env };
|
|
173
234
|
}
|
|
@@ -194,6 +255,3 @@ function parsePositiveInteger(label, value) {
|
|
|
194
255
|
function withoutUndefined(value) {
|
|
195
256
|
return Object.fromEntries(Object.entries(value).filter(([, entryValue]) => entryValue !== undefined));
|
|
196
257
|
}
|
|
197
|
-
if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replaceAll("\\", "/"))) {
|
|
198
|
-
process.exitCode = await main(process.argv.slice(2));
|
|
199
|
-
}
|
|
@@ -72,7 +72,7 @@ export function parseRunFinalDemoArgs(argv) {
|
|
|
72
72
|
throw new Error("Usage: --cases <path> --out <dir> --kit-command <command>");
|
|
73
73
|
return { casesPath, outDir, kitCommand, agents, strategies, complexities, caseIds, benchmarkProjects, maxRuns, screenshot, includeRealAgents, continueOnFailure, timeoutMs };
|
|
74
74
|
}
|
|
75
|
-
export async function runFinalDemoFromArgs(args, repoRoot = process.cwd()) {
|
|
75
|
+
export async function runFinalDemoFromArgs(args, repoRoot = process.cwd(), context) {
|
|
76
76
|
const rootOut = path.resolve(repoRoot, args.outDir);
|
|
77
77
|
const experimentDir = path.join(rootOut, "controlled-experiment");
|
|
78
78
|
const plotsDir = path.join(rootOut, "plots");
|
|
@@ -81,7 +81,6 @@ export async function runFinalDemoFromArgs(args, repoRoot = process.cwd()) {
|
|
|
81
81
|
const galleryDir = path.join(rootOut, "gallery");
|
|
82
82
|
const experiment = await runControlledExperimentFromArgs({
|
|
83
83
|
casesPath: args.casesPath,
|
|
84
|
-
projectProfilesPath: "benchmarks/contracts/benchmark-project-profiles.json",
|
|
85
84
|
outDir: experimentDir,
|
|
86
85
|
agents: args.agents,
|
|
87
86
|
strategies: args.strategies,
|
|
@@ -92,7 +91,7 @@ export async function runFinalDemoFromArgs(args, repoRoot = process.cwd()) {
|
|
|
92
91
|
includeRealAgents: args.includeRealAgents,
|
|
93
92
|
continueOnFailure: args.continueOnFailure,
|
|
94
93
|
timeoutMs: args.timeoutMs
|
|
95
|
-
}, repoRoot);
|
|
94
|
+
}, repoRoot, context);
|
|
96
95
|
const plots = await runGenerateExperimentPlotsFromArgs({ experimentDir, outDir: plotsDir }, repoRoot);
|
|
97
96
|
const firstProject = experiment.projectProfiles[0]?.rootPath ?? "benchmarks/projects/todo-ts";
|
|
98
97
|
const visualization = await runVisualizationDemosFromArgs({ projectPath: firstProject, kitCommand: args.kitCommand, outDir: visualizationsDir, timeoutMs: args.timeoutMs }, repoRoot);
|