@jevitate/cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/ai-cli.js +40 -30
- package/dist/ai-cli.js.map +1 -1
- package/dist/author-journey-cli.d.ts +4 -0
- package/dist/author-journey-cli.js +109 -0
- package/dist/author-journey-cli.js.map +1 -0
- package/dist/bin.js +58077 -22454
- package/dist/bin.js.map +1 -1
- package/dist/browser-run-options.d.ts +58 -0
- package/dist/browser-run-options.js +106 -0
- package/dist/browser-run-options.js.map +1 -0
- package/dist/build-info.generated.d.ts +2 -0
- package/dist/build-info.generated.js +10 -0
- package/dist/build-info.generated.js.map +1 -0
- package/dist/check-api.d.ts +5 -0
- package/dist/check-api.js +233 -0
- package/dist/check-api.js.map +1 -0
- package/dist/check-budget.d.ts +26 -0
- package/dist/check-budget.js +89 -0
- package/dist/check-budget.js.map +1 -0
- package/dist/check-cli.d.ts +31 -0
- package/dist/check-cli.js +109 -0
- package/dist/check-cli.js.map +1 -0
- package/dist/check-execute.d.ts +25 -0
- package/dist/check-execute.js +385 -0
- package/dist/check-execute.js.map +1 -0
- package/dist/check-plan.d.ts +113 -0
- package/dist/check-plan.js +448 -0
- package/dist/check-plan.js.map +1 -0
- package/dist/check-suite.d.ts +171 -0
- package/dist/check-suite.js +515 -0
- package/dist/check-suite.js.map +1 -0
- package/dist/check-types.d.ts +181 -0
- package/dist/check-types.js +35 -0
- package/dist/check-types.js.map +1 -0
- package/dist/cli-args.d.ts +26 -0
- package/dist/cli-args.js +50 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-output.d.ts +102 -0
- package/dist/cli-output.js +516 -0
- package/dist/cli-output.js.map +1 -0
- package/dist/cli-reference.d.ts +3 -0
- package/dist/cli-reference.js +81 -0
- package/dist/cli-reference.js.map +1 -0
- package/dist/cli-refusal.d.ts +12 -0
- package/dist/cli-refusal.js +52 -0
- package/dist/cli-refusal.js.map +1 -0
- package/dist/cli-shared.d.ts +330 -0
- package/dist/cli-shared.js +492 -0
- package/dist/cli-shared.js.map +1 -0
- package/dist/cli-surface.d.ts +33 -0
- package/dist/cli-surface.js +48 -0
- package/dist/cli-surface.js.map +1 -0
- package/dist/conversation-options.d.ts +15 -0
- package/dist/conversation-options.js +10 -0
- package/dist/conversation-options.js.map +1 -0
- package/dist/credentials-file.d.ts +15 -0
- package/dist/credentials-file.js +56 -0
- package/dist/credentials-file.js.map +1 -0
- package/dist/data-dir.d.ts +1 -1
- package/dist/data-dir.js +1 -1
- package/dist/defect-evidence.d.ts +141 -0
- package/dist/defect-evidence.js +502 -0
- package/dist/defect-evidence.js.map +1 -0
- package/dist/demo-aspect-api.d.ts +209 -0
- package/dist/demo-aspect-api.js +397 -0
- package/dist/demo-aspect-api.js.map +1 -0
- package/dist/demo-aspect-cli.d.ts +3 -0
- package/dist/demo-aspect-cli.js +241 -0
- package/dist/demo-aspect-cli.js.map +1 -0
- package/dist/demo-capture.d.ts +108 -0
- package/dist/demo-capture.js +438 -0
- package/dist/demo-capture.js.map +1 -0
- package/dist/engine.d.ts +35 -0
- package/dist/engine.js +25 -0
- package/dist/engine.js.map +1 -0
- package/dist/environments.d.ts +155 -0
- package/dist/environments.js +364 -0
- package/dist/environments.js.map +1 -0
- package/dist/exit-codes.d.ts +46 -0
- package/dist/exit-codes.js +91 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/explore-adversarial.d.ts +137 -0
- package/dist/explore-adversarial.js +218 -0
- package/dist/explore-adversarial.js.map +1 -0
- package/dist/explore-api.d.ts +7 -187
- package/dist/explore-api.js +7 -301
- package/dist/explore-api.js.map +1 -1
- package/dist/explore-author.d.ts +79 -0
- package/dist/explore-author.js +86 -0
- package/dist/explore-author.js.map +1 -0
- package/dist/explore-cli.d.ts +7 -0
- package/dist/explore-cli.js +963 -0
- package/dist/explore-cli.js.map +1 -0
- package/dist/explore-coverage.d.ts +158 -0
- package/dist/explore-coverage.js +240 -0
- package/dist/explore-coverage.js.map +1 -0
- package/dist/explore-feature.d.ts +127 -0
- package/dist/explore-feature.js +220 -0
- package/dist/explore-feature.js.map +1 -0
- package/dist/explore-goal.d.ts +253 -0
- package/dist/explore-goal.js +374 -0
- package/dist/explore-goal.js.map +1 -0
- package/dist/explore-shared.d.ts +152 -0
- package/dist/explore-shared.js +129 -0
- package/dist/explore-shared.js.map +1 -0
- package/dist/explore-specs.d.ts +53 -0
- package/dist/explore-specs.js +333 -0
- package/dist/explore-specs.js.map +1 -0
- package/dist/findings-filing.d.ts +64 -0
- package/dist/findings-filing.js +108 -0
- package/dist/findings-filing.js.map +1 -0
- package/dist/fixture-auth.d.ts +52 -0
- package/dist/fixture-auth.js +82 -0
- package/dist/fixture-auth.js.map +1 -0
- package/dist/fixture-cli.d.ts +70 -0
- package/dist/fixture-cli.js +178 -0
- package/dist/fixture-cli.js.map +1 -0
- package/dist/github-issue-filer.d.ts +62 -0
- package/dist/github-issue-filer.js +188 -0
- package/dist/github-issue-filer.js.map +1 -0
- package/dist/host-health-run.d.ts +24 -0
- package/dist/host-health-run.js +27 -0
- package/dist/host-health-run.js.map +1 -0
- package/dist/http-5xx-outcome.d.ts +6 -0
- package/dist/http-5xx-outcome.js +39 -0
- package/dist/http-5xx-outcome.js.map +1 -0
- package/dist/inbox-cli.d.ts +7 -0
- package/dist/inbox-cli.js +197 -0
- package/dist/inbox-cli.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init-cli.d.ts +4 -0
- package/dist/init-cli.js +127 -0
- package/dist/init-cli.js.map +1 -0
- package/dist/init-keys.d.ts +19 -2
- package/dist/init-keys.js +15 -4
- package/dist/init-keys.js.map +1 -1
- package/dist/init-next-steps.d.ts +35 -0
- package/dist/init-next-steps.js +79 -0
- package/dist/init-next-steps.js.map +1 -0
- package/dist/invariants-file.d.ts +34 -0
- package/dist/invariants-file.js +68 -0
- package/dist/invariants-file.js.map +1 -0
- package/dist/invariants-validate.d.ts +30 -0
- package/dist/invariants-validate.js +105 -0
- package/dist/invariants-validate.js.map +1 -0
- package/dist/journey-annotate-api.d.ts +76 -0
- package/dist/journey-annotate-api.js +256 -0
- package/dist/journey-annotate-api.js.map +1 -0
- package/dist/journey-annotate-cli.d.ts +9 -0
- package/dist/journey-annotate-cli.js +179 -0
- package/dist/journey-annotate-cli.js.map +1 -0
- package/dist/journey-api.d.ts +79 -2
- package/dist/journey-api.js +136 -19
- package/dist/journey-api.js.map +1 -1
- package/dist/journey-cli.d.ts +4 -0
- package/dist/journey-cli.js +370 -0
- package/dist/journey-cli.js.map +1 -0
- package/dist/journey-demo-api.d.ts +112 -0
- package/dist/journey-demo-api.js +392 -0
- package/dist/journey-demo-api.js.map +1 -0
- package/dist/journey-demo-cli.d.ts +10 -0
- package/dist/journey-demo-cli.js +155 -0
- package/dist/journey-demo-cli.js.map +1 -0
- package/dist/kill-signal.d.ts +193 -0
- package/dist/kill-signal.js +284 -0
- package/dist/kill-signal.js.map +1 -0
- package/dist/launch-armed.d.ts +37 -0
- package/dist/launch-armed.js +31 -0
- package/dist/launch-armed.js.map +1 -0
- package/dist/ledger-api.d.ts +106 -0
- package/dist/ledger-api.js +237 -0
- package/dist/ledger-api.js.map +1 -0
- package/dist/ledger-cli.d.ts +18 -0
- package/dist/ledger-cli.js +107 -0
- package/dist/ledger-cli.js.map +1 -0
- package/dist/load-api.d.ts +29 -11
- package/dist/load-api.js +23 -15
- package/dist/load-api.js.map +1 -1
- package/dist/load-cli.d.ts +4 -0
- package/dist/load-cli.js +97 -0
- package/dist/load-cli.js.map +1 -0
- package/dist/log-correlation.d.ts +147 -0
- package/dist/log-correlation.js +325 -0
- package/dist/log-correlation.js.map +1 -0
- package/dist/log-lines.d.ts +131 -0
- package/dist/log-lines.js +389 -0
- package/dist/log-lines.js.map +1 -0
- package/dist/log-sources.d.ts +71 -0
- package/dist/log-sources.js +235 -0
- package/dist/log-sources.js.map +1 -0
- package/dist/logs-cli.d.ts +3 -0
- package/dist/logs-cli.js +51 -0
- package/dist/logs-cli.js.map +1 -0
- package/dist/logs-retention.d.ts +28 -0
- package/dist/logs-retention.js +84 -0
- package/dist/logs-retention.js.map +1 -0
- package/dist/mcp-api.d.ts +89 -1
- package/dist/mcp-api.js +472 -18
- package/dist/mcp-api.js.map +1 -1
- package/dist/mcp-args.d.ts +38 -0
- package/dist/mcp-args.js +131 -0
- package/dist/mcp-args.js.map +1 -0
- package/dist/mcp-cli-bridge.d.ts +34 -0
- package/dist/mcp-cli-bridge.js +62 -0
- package/dist/mcp-cli-bridge.js.map +1 -0
- package/dist/mcp-cli-runner.d.ts +29 -0
- package/dist/mcp-cli-runner.js +44 -0
- package/dist/mcp-cli-runner.js.map +1 -0
- package/dist/mcp-cli-tools.d.ts +125 -0
- package/dist/mcp-cli-tools.js +680 -0
- package/dist/mcp-cli-tools.js.map +1 -0
- package/dist/mcp-paths.d.ts +28 -0
- package/dist/mcp-paths.js +76 -0
- package/dist/mcp-paths.js.map +1 -0
- package/dist/mission-actors.d.ts +40 -0
- package/dist/mission-actors.js +72 -0
- package/dist/mission-actors.js.map +1 -0
- package/dist/mission-api.d.ts +35 -0
- package/dist/mission-api.js +58 -2
- package/dist/mission-api.js.map +1 -1
- package/dist/mission-cli.d.ts +4 -0
- package/dist/mission-cli.js +247 -0
- package/dist/mission-cli.js.map +1 -0
- package/dist/mission-exit.d.ts +22 -0
- package/dist/mission-exit.js +26 -0
- package/dist/mission-exit.js.map +1 -0
- package/dist/mission-fixtures.d.ts +225 -0
- package/dist/mission-fixtures.js +828 -0
- package/dist/mission-fixtures.js.map +1 -0
- package/dist/mission-journal.d.ts +60 -0
- package/dist/mission-journal.js +115 -0
- package/dist/mission-journal.js.map +1 -0
- package/dist/mission-queue-cli.d.ts +10 -0
- package/dist/mission-queue-cli.js +198 -0
- package/dist/mission-queue-cli.js.map +1 -0
- package/dist/mission-queue-runner.d.ts +126 -0
- package/dist/mission-queue-runner.js +397 -0
- package/dist/mission-queue-runner.js.map +1 -0
- package/dist/multi-run-cli.d.ts +37 -0
- package/dist/multi-run-cli.js +110 -0
- package/dist/multi-run-cli.js.map +1 -0
- package/dist/multi-run.d.ts +339 -0
- package/dist/multi-run.js +619 -0
- package/dist/multi-run.js.map +1 -0
- package/dist/openrouter-call.d.ts +22 -0
- package/dist/openrouter-call.js +63 -0
- package/dist/openrouter-call.js.map +1 -0
- package/dist/profile-cli.d.ts +4 -0
- package/dist/profile-cli.js +57 -0
- package/dist/profile-cli.js.map +1 -0
- package/dist/program.d.ts +3 -75
- package/dist/program.js +119 -1921
- package/dist/program.js.map +1 -1
- package/dist/project-dir.d.ts +96 -0
- package/dist/project-dir.js +220 -0
- package/dist/project-dir.js.map +1 -0
- package/dist/record-api.d.ts +10 -6
- package/dist/record-api.js +39 -28
- package/dist/record-api.js.map +1 -1
- package/dist/record-cli.d.ts +4 -0
- package/dist/record-cli.js +64 -0
- package/dist/record-cli.js.map +1 -0
- package/dist/recording-cli.d.ts +4 -0
- package/dist/recording-cli.js +248 -0
- package/dist/recording-cli.js.map +1 -0
- package/dist/regression-api.d.ts +101 -0
- package/dist/regression-api.js +384 -5
- package/dist/regression-api.js.map +1 -1
- package/dist/regression-cli.d.ts +4 -0
- package/dist/regression-cli.js +232 -0
- package/dist/regression-cli.js.map +1 -0
- package/dist/report-api.d.ts +146 -0
- package/dist/report-api.js +430 -0
- package/dist/report-api.js.map +1 -0
- package/dist/report-cli.d.ts +12 -0
- package/dist/report-cli.js +147 -0
- package/dist/report-cli.js.map +1 -0
- package/dist/result-schema.d.ts +22 -0
- package/dist/result-schema.js +28 -0
- package/dist/result-schema.js.map +1 -0
- package/dist/run-index.d.ts +29 -0
- package/dist/run-index.js +70 -0
- package/dist/run-index.js.map +1 -0
- package/dist/run-screenshots.d.ts +123 -0
- package/dist/run-screenshots.js +229 -0
- package/dist/run-screenshots.js.map +1 -0
- package/dist/runtime-env.d.ts +8 -0
- package/dist/runtime-env.js +22 -0
- package/dist/runtime-env.js.map +1 -0
- package/dist/secret-args.d.ts +23 -0
- package/dist/secret-args.js +45 -0
- package/dist/secret-args.js.map +1 -0
- package/dist/serve-cli.d.ts +4 -0
- package/dist/serve-cli.js +95 -0
- package/dist/serve-cli.js.map +1 -0
- package/dist/server-log-verify.d.ts +34 -0
- package/dist/server-log-verify.js +115 -0
- package/dist/server-log-verify.js.map +1 -0
- package/dist/session-check.d.ts +14 -0
- package/dist/session-check.js +44 -0
- package/dist/session-check.js.map +1 -0
- package/dist/site-cli.d.ts +4 -0
- package/dist/site-cli.js +127 -0
- package/dist/site-cli.js.map +1 -0
- package/dist/site-gate-cli.d.ts +28 -0
- package/dist/site-gate-cli.js +58 -0
- package/dist/site-gate-cli.js.map +1 -0
- package/dist/source-api.js +18 -3
- package/dist/source-api.js.map +1 -1
- package/dist/source-cli.d.ts +4 -0
- package/dist/source-cli.js +284 -0
- package/dist/source-cli.js.map +1 -0
- package/dist/source-run-api.d.ts +27 -1
- package/dist/source-run-api.js +22 -11
- package/dist/source-run-api.js.map +1 -1
- package/dist/storage-state-snapshot.d.ts +50 -0
- package/dist/storage-state-snapshot.js +87 -0
- package/dist/storage-state-snapshot.js.map +1 -0
- package/dist/suite-explore-options.d.ts +289 -0
- package/dist/suite-explore-options.js +140 -0
- package/dist/suite-explore-options.js.map +1 -0
- package/dist/target-config.d.ts +109 -0
- package/dist/target-config.js +216 -0
- package/dist/target-config.js.map +1 -0
- package/dist/transcript-file.d.ts +12 -0
- package/dist/transcript-file.js +23 -0
- package/dist/transcript-file.js.map +1 -0
- package/dist/ui-api.d.ts +3 -0
- package/dist/ui-api.js +7 -1
- package/dist/ui-api.js.map +1 -1
- package/dist/usability-capture.d.ts +43 -0
- package/dist/usability-capture.js +326 -0
- package/dist/usability-capture.js.map +1 -0
- package/dist/usage-config.d.ts +36 -0
- package/dist/usage-config.js +114 -0
- package/dist/usage-config.js.map +1 -0
- package/dist/ux-api.d.ts +3 -75
- package/dist/ux-api.js +3 -220
- package/dist/ux-api.js.map +1 -1
- package/dist/ux-cli.d.ts +4 -0
- package/dist/ux-cli.js +102 -0
- package/dist/ux-cli.js.map +1 -0
- package/dist/ux-config.d.ts +29 -0
- package/dist/ux-config.js +103 -0
- package/dist/ux-config.js.map +1 -0
- package/dist/ux-evidence.d.ts +54 -0
- package/dist/ux-evidence.js +197 -0
- package/dist/ux-evidence.js.map +1 -0
- package/dist/ux-review.d.ts +112 -0
- package/dist/ux-review.js +151 -0
- package/dist/ux-review.js.map +1 -0
- package/dist/ux-usability.d.ts +238 -0
- package/dist/ux-usability.js +494 -0
- package/dist/ux-usability.js.map +1 -0
- package/dist/verify-fix-api.d.ts +173 -0
- package/dist/verify-fix-api.js +454 -0
- package/dist/verify-fix-api.js.map +1 -0
- package/dist/verify-fix-cli.d.ts +4 -0
- package/dist/verify-fix-cli.js +110 -0
- package/dist/verify-fix-cli.js.map +1 -0
- package/package.json +19 -14
- package/skills/jevitate-ci-check/SKILL.md +77 -0
- package/skills/jevitate-demo/SKILL.md +61 -0
- package/skills/jevitate-explore/SKILL.md +88 -87
- package/skills/jevitate-getting-started/SKILL.md +88 -0
- package/skills/jevitate-load-test/SKILL.md +11 -2
- package/skills/jevitate-mission-scope/SKILL.md +19 -11
- package/skills/jevitate-record/SKILL.md +23 -5
- package/skills/jevitate-run-journey/SKILL.md +61 -17
- package/skills/jevitate-sources/SKILL.md +57 -14
- package/skills/jevitate-ux-review/SKILL.md +106 -16
- package/skills/jevitate-verify-fix/SKILL.md +76 -0
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,kGAAkG;AAClG,mGAAmG;AACnG,mGAAmG;AACnG,+DAA+D;AAC/D,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;QAChD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,GAAG,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oGAAoG;AACpG,gGAAgG;AAChG,8FAA8F;AAC9F,mGAAmG;AACnG,6FAA6F;AAC7F,oEAAoE;AACpE,wBAAwB,EAAE,CAAC;AAE3B,iGAAiG;AACjG,kGAAkG;AAClG,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;AACzC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,WAAW;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,6EAA6E;AAC7E,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAClE,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC9E,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC;AAC7C,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { BrowserLaunchOptions, OpenOptions } from "@jevitate/playwright";
|
|
2
|
+
/** The browser options a runner takes: how Chromium is launched, plus how the run is shown (#245). */
|
|
3
|
+
export interface BrowserRunOptions extends BrowserLaunchOptions {
|
|
4
|
+
/** A visible browser window (`--headed` / `JEVITATE_HEADED=1` / a suite item's `headed`). Default: headless. */
|
|
5
|
+
readonly headed?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Record a Playwright video of every browser context the run opens (`--record-video [dir]`).
|
|
8
|
+
* `dir` absent ⇒ next to the run's output. Works headless too.
|
|
9
|
+
*/
|
|
10
|
+
readonly recordVideo?: {
|
|
11
|
+
readonly dir?: string;
|
|
12
|
+
};
|
|
13
|
+
/** `--no-overlay` (false): a headed explore run shows the on-page demo overlay unless this is false. */
|
|
14
|
+
readonly overlay?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** `--slow-mo` when `--headed` is given without one: slow enough for an audience to follow. */
|
|
17
|
+
export declare const HEADED_DEFAULT_SLOW_MO_MS = 250;
|
|
18
|
+
/** The launch part of a session's `OpenOptions` — the ONE place headedness, slowMo and video are resolved. */
|
|
19
|
+
export type SessionLaunchOptions = BrowserLaunchOptions & Pick<OpenOptions, "headless" | "recordVideo">;
|
|
20
|
+
/**
|
|
21
|
+
* `browser` → the launch fields of `BrowserPort.open`: headless unless `headed`; `slowMo` as given,
|
|
22
|
+
* else `HEADED_DEFAULT_SLOW_MO_MS` when headed; `recordVideo` into `videoDir` when the run records
|
|
23
|
+
* (see `runVideoDir`). The demo-only fields (`headed`, `recordVideo`, `overlay`) never reach the port.
|
|
24
|
+
*/
|
|
25
|
+
export declare function sessionLaunchOptions(browser: BrowserRunOptions | undefined, videoDir?: string): SessionLaunchOptions;
|
|
26
|
+
/** The explore config's `demoOverlay` (#245): shown on a headed run unless `--no-overlay`. */
|
|
27
|
+
export declare function demoOverlayOf(browser: BrowserRunOptions | undefined): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Where one run's videos go, or `undefined` when it does not record: a per-run folder named for the
|
|
30
|
+
* run's artifact (`<stem>.videos/`), under `--record-video <dir>` or else beside `artifactPath` —
|
|
31
|
+
* so a run's `videoPaths` are exactly the files in it, never another run's.
|
|
32
|
+
*/
|
|
33
|
+
export declare function runVideoDir(browser: BrowserRunOptions | undefined, artifactPath: string): string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* The video files in a run's video folder, oldest first (absolute paths). Synchronous so a killed
|
|
36
|
+
* run's partial result can list them too. A missing folder (nothing recorded yet) is an empty list.
|
|
37
|
+
*/
|
|
38
|
+
export declare function listVideos(videoDir: string): string[];
|
|
39
|
+
/**
|
|
40
|
+
* #245: a video is finalized only when its browser context closes — so a recording run closes its
|
|
41
|
+
* session(s) BEFORE its result is written, then lists the files. `close` must be idempotent (the
|
|
42
|
+
* runner's own `finally` calls it again; see `closeOnce`). Not recording: nothing closes early, `{}`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function finalizeVideos(videoDir: string | undefined, close: () => Promise<void>): Promise<{
|
|
45
|
+
videoPaths?: string[];
|
|
46
|
+
}>;
|
|
47
|
+
/** Wraps an async teardown so only its first call runs; later calls await the same promise. */
|
|
48
|
+
export declare function closeOnce(close: () => Promise<void>): () => Promise<void>;
|
|
49
|
+
/** Headed without a display (#245): refused before any browser launches, a usage error (exit 64). */
|
|
50
|
+
export declare class HeadedWithoutDisplayError extends Error {
|
|
51
|
+
constructor();
|
|
52
|
+
}
|
|
53
|
+
/** Throws `HeadedWithoutDisplayError` for a headed run on Linux with no X11/Wayland display. */
|
|
54
|
+
export declare function assertHeadedDisplay(headed: boolean, env?: Readonly<Record<string, string | undefined>>, platform?: NodeJS.Platform): void;
|
|
55
|
+
/** `JEVITATE_HEADED=1` (or `true`) turns `--headed` on for every command that takes it. */
|
|
56
|
+
export declare function headedFromEnv(env: Readonly<Record<string, string | undefined>>): boolean;
|
|
57
|
+
/** The one-line warning for a headed run that opens several windows at once (#245: warn, never refuse). */
|
|
58
|
+
export declare function multiWindowWarning(what: string): string;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Demo mode (#245): how a run's browser is SHOWN — a visible window, slowed down, recorded to video,
|
|
3
|
+
* with the on-page overlay — resolved in ONE place. Every runner (every explore strategy, `journey
|
|
4
|
+
* run`, `verify-fix`, regression capture/replay, observers and hang-replay sessions) builds its
|
|
5
|
+
* `BrowserPort.open` options with `sessionLaunchOptions`, never with its own `headless: true`, so a
|
|
6
|
+
* `--headed` run shows every window it opens and a run without the flags is unchanged: headless,
|
|
7
|
+
* no slowMo, no video, no overlay.
|
|
8
|
+
*/
|
|
9
|
+
import { readdirSync, statSync } from "node:fs";
|
|
10
|
+
import { basename, dirname, join } from "node:path";
|
|
11
|
+
/** `--slow-mo` when `--headed` is given without one: slow enough for an audience to follow. */
|
|
12
|
+
export const HEADED_DEFAULT_SLOW_MO_MS = 250;
|
|
13
|
+
/**
|
|
14
|
+
* `browser` → the launch fields of `BrowserPort.open`: headless unless `headed`; `slowMo` as given,
|
|
15
|
+
* else `HEADED_DEFAULT_SLOW_MO_MS` when headed; `recordVideo` into `videoDir` when the run records
|
|
16
|
+
* (see `runVideoDir`). The demo-only fields (`headed`, `recordVideo`, `overlay`) never reach the port.
|
|
17
|
+
*/
|
|
18
|
+
export function sessionLaunchOptions(browser, videoDir) {
|
|
19
|
+
const { headed, recordVideo: _video, overlay: _overlay, slowMo, ...launch } = browser ?? {};
|
|
20
|
+
const effectiveSlowMo = slowMo ?? (headed === true ? HEADED_DEFAULT_SLOW_MO_MS : undefined);
|
|
21
|
+
return {
|
|
22
|
+
...launch,
|
|
23
|
+
headless: headed !== true,
|
|
24
|
+
...(effectiveSlowMo === undefined ? {} : { slowMo: effectiveSlowMo }),
|
|
25
|
+
...(videoDir === undefined ? {} : { recordVideo: { dir: videoDir } }),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** The explore config's `demoOverlay` (#245): shown on a headed run unless `--no-overlay`. */
|
|
29
|
+
export function demoOverlayOf(browser) {
|
|
30
|
+
return browser?.headed === true && browser.overlay !== false;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Where one run's videos go, or `undefined` when it does not record: a per-run folder named for the
|
|
34
|
+
* run's artifact (`<stem>.videos/`), under `--record-video <dir>` or else beside `artifactPath` —
|
|
35
|
+
* so a run's `videoPaths` are exactly the files in it, never another run's.
|
|
36
|
+
*/
|
|
37
|
+
export function runVideoDir(browser, artifactPath) {
|
|
38
|
+
if (browser?.recordVideo === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
const stem = basename(artifactPath).replace(/\.json$/, "");
|
|
41
|
+
return join(browser.recordVideo.dir ?? dirname(artifactPath), `${stem}.videos`);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The video files in a run's video folder, oldest first (absolute paths). Synchronous so a killed
|
|
45
|
+
* run's partial result can list them too. A missing folder (nothing recorded yet) is an empty list.
|
|
46
|
+
*/
|
|
47
|
+
export function listVideos(videoDir) {
|
|
48
|
+
let names;
|
|
49
|
+
try {
|
|
50
|
+
names = readdirSync(videoDir).filter((n) => n.endsWith(".webm"));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
const files = names.map((n) => join(videoDir, n));
|
|
56
|
+
const mtime = (f) => {
|
|
57
|
+
try {
|
|
58
|
+
return statSync(f).mtimeMs;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return files.sort((a, b) => mtime(a) - mtime(b) || a.localeCompare(b));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* #245: a video is finalized only when its browser context closes — so a recording run closes its
|
|
68
|
+
* session(s) BEFORE its result is written, then lists the files. `close` must be idempotent (the
|
|
69
|
+
* runner's own `finally` calls it again; see `closeOnce`). Not recording: nothing closes early, `{}`.
|
|
70
|
+
*/
|
|
71
|
+
export async function finalizeVideos(videoDir, close) {
|
|
72
|
+
if (videoDir === undefined)
|
|
73
|
+
return {};
|
|
74
|
+
await close();
|
|
75
|
+
return { videoPaths: listVideos(videoDir) };
|
|
76
|
+
}
|
|
77
|
+
/** Wraps an async teardown so only its first call runs; later calls await the same promise. */
|
|
78
|
+
export function closeOnce(close) {
|
|
79
|
+
let done;
|
|
80
|
+
return () => (done ??= close());
|
|
81
|
+
}
|
|
82
|
+
/** Headed without a display (#245): refused before any browser launches, a usage error (exit 64). */
|
|
83
|
+
export class HeadedWithoutDisplayError extends Error {
|
|
84
|
+
constructor() {
|
|
85
|
+
super("--headed needs a display, but neither DISPLAY nor WAYLAND_DISPLAY is set (on WSL2 a visible window needs WSLg). " +
|
|
86
|
+
"Run headless and record it instead: --record-video");
|
|
87
|
+
this.name = "HeadedWithoutDisplayError";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Throws `HeadedWithoutDisplayError` for a headed run on Linux with no X11/Wayland display. */
|
|
91
|
+
export function assertHeadedDisplay(headed, env = process.env, platform = process.platform) {
|
|
92
|
+
if (!headed || platform !== "linux")
|
|
93
|
+
return;
|
|
94
|
+
if ((env.DISPLAY ?? "") === "" && (env.WAYLAND_DISPLAY ?? "") === "")
|
|
95
|
+
throw new HeadedWithoutDisplayError();
|
|
96
|
+
}
|
|
97
|
+
/** `JEVITATE_HEADED=1` (or `true`) turns `--headed` on for every command that takes it. */
|
|
98
|
+
export function headedFromEnv(env) {
|
|
99
|
+
const v = env.JEVITATE_HEADED?.trim().toLowerCase();
|
|
100
|
+
return v === "1" || v === "true";
|
|
101
|
+
}
|
|
102
|
+
/** The one-line warning for a headed run that opens several windows at once (#245: warn, never refuse). */
|
|
103
|
+
export function multiWindowWarning(what) {
|
|
104
|
+
return `warning: --headed with ${what} opens several browser windows; each is shown.\n`;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=browser-run-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-run-options.js","sourceRoot":"","sources":["../src/browser-run-options.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/cli/scripts/generate-build-info.mjs at build time.
|
|
2
|
+
// Do not edit by hand — regenerated on every `build`/`bundle` run. Gitignored.
|
|
3
|
+
//
|
|
4
|
+
// The tsc-build counterpart to build.mjs's esbuild `define`: a dev `npm link` install runs
|
|
5
|
+
// this plain `tsc --build` dist (no bundler substitution), so it needs real committed values
|
|
6
|
+
// here instead. See ./engine.ts, which prefers the esbuild-injected value when present and
|
|
7
|
+
// falls back to these.
|
|
8
|
+
export const GENERATED_COMMIT = "09b80b5";
|
|
9
|
+
export const GENERATED_BUILT_AT = "2026-09-29T20:26:11.852Z";
|
|
10
|
+
//# sourceMappingURL=build-info.generated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-info.generated.js","sourceRoot":"","sources":["../src/build-info.generated.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,+EAA+E;AAC/E,EAAE;AACF,2FAA2F;AAC3F,6FAA6F;AAC7F,2FAA2F;AAC3F,uBAAuB;AACvB,MAAM,CAAC,MAAM,gBAAgB,GAAW,SAAS,CAAC;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAAW,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type CheckResult, type RunCheckOptions } from "./check-types.js";
|
|
2
|
+
export { affectedBy } from "./check-plan.js";
|
|
3
|
+
export { BudgetMeter } from "./check-budget.js";
|
|
4
|
+
export { type BudgetReport, CheckAiSetupError, type CheckFinding, type CheckGateways, type CheckItemReport, CheckPreflightError, type CheckResult, type CheckRunners, type ItemKind, type RunCheckOptions } from "./check-types.js";
|
|
5
|
+
export declare function runCheck(opts: RunCheckOptions): Promise<CheckResult>;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { aggregateOf, formatUsageLine } from "@jevitate/ai-core";
|
|
4
|
+
import { consolidate, diffRuns, renderJUnit, renderReportMarkdown, renderSarif } from "@jevitate/findings";
|
|
5
|
+
import { runAdversarialCliMission, runCoverageMission, runExploration, runFeatureCliMission } from "./explore-api.js";
|
|
6
|
+
import { runJourneyProgrammatically } from "./journey-api.js";
|
|
7
|
+
import { runUsabilityMission } from "./ux-api.js";
|
|
8
|
+
import { runVerifyFix } from "./verify-fix-api.js";
|
|
9
|
+
import { currentEngineInfo } from "./engine.js";
|
|
10
|
+
import { loadRunFile, resolveBaseline, scanRuns, summarizeRun } from "./report-api.js";
|
|
11
|
+
import { CheckAiSetupError } from "./check-types.js";
|
|
12
|
+
import { BudgetMeter } from "./check-budget.js";
|
|
13
|
+
import { errorMessage, plan, prepareTarget } from "./check-plan.js";
|
|
14
|
+
import { caseDetail, execute } from "./check-execute.js";
|
|
15
|
+
export { affectedBy } from "./check-plan.js";
|
|
16
|
+
export { BudgetMeter } from "./check-budget.js";
|
|
17
|
+
export { CheckAiSetupError, CheckPreflightError } from "./check-types.js";
|
|
18
|
+
const REAL_RUNNERS = {
|
|
19
|
+
journey: runJourneyProgrammatically,
|
|
20
|
+
goal: runExploration,
|
|
21
|
+
coverage: runCoverageMission,
|
|
22
|
+
adversarial: runAdversarialCliMission,
|
|
23
|
+
feature: runFeatureCliMission,
|
|
24
|
+
usability: runUsabilityMission,
|
|
25
|
+
verifyFix: runVerifyFix,
|
|
26
|
+
};
|
|
27
|
+
export async function runCheck(opts) {
|
|
28
|
+
const nowIso = opts.nowIso ?? (() => new Date().toISOString());
|
|
29
|
+
const startedAt = nowIso();
|
|
30
|
+
const engine = currentEngineInfo();
|
|
31
|
+
const outDir = resolve(opts.outDir);
|
|
32
|
+
const resultsDir = join(outDir, "results");
|
|
33
|
+
const runners = { ...REAL_RUNNERS, ...opts.runners };
|
|
34
|
+
// Preflight — everything validated before the first browser opens.
|
|
35
|
+
const prepared = [];
|
|
36
|
+
for (const t of opts.suite.targets)
|
|
37
|
+
prepared.push(await prepareTarget(t, opts));
|
|
38
|
+
const items = plan(prepared, opts.changedRoutes, opts);
|
|
39
|
+
let gw;
|
|
40
|
+
const gateways = () => {
|
|
41
|
+
if (opts.gateways === undefined)
|
|
42
|
+
return Promise.reject(new CheckAiSetupError("this suite needs a model gateway: pass --real or --fake-ai (or set \"ai\" in the suite)"));
|
|
43
|
+
gw ??= opts.gateways();
|
|
44
|
+
return gw;
|
|
45
|
+
};
|
|
46
|
+
// A missing/unselectable gateway throws here (typed), before any browser opens.
|
|
47
|
+
if (items.some((i) => i.needsAi && i.skipped === undefined))
|
|
48
|
+
await gateways();
|
|
49
|
+
await mkdir(resultsDir, { recursive: true });
|
|
50
|
+
const meter = new BudgetMeter(opts.suite.budget, { ...(opts.now === undefined ? {} : { now: opts.now }), costKnownZero: opts.aiMode === "fake" });
|
|
51
|
+
const usage = async () => (gw === undefined ? undefined : (await gw).usage.snapshot());
|
|
52
|
+
let n = 0;
|
|
53
|
+
const ctx = { opts, runners, resultsDir, gateways, engine, seq: () => String(++n) };
|
|
54
|
+
const now = opts.now ?? Date.now;
|
|
55
|
+
let exceeded;
|
|
56
|
+
const executed = [];
|
|
57
|
+
for (const item of items) {
|
|
58
|
+
if (item.skipped !== undefined) {
|
|
59
|
+
executed.push({ item, ex: undefined, durationMs: 0 });
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const blocked = meter.blocked(await usage());
|
|
63
|
+
if (blocked !== undefined) {
|
|
64
|
+
exceeded ??= blocked;
|
|
65
|
+
executed.push({ item, ex: { status: "error", actions: 0, error: { type: "budget-exceeded", message: `not run: ${blocked}` } }, durationMs: 0 });
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const t0 = now();
|
|
69
|
+
let ex;
|
|
70
|
+
try {
|
|
71
|
+
ex = await execute(item, ctx, meter.remainingActions());
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
ex = { status: "error", actions: 0, error: { type: e instanceof Error ? e.name : "error", message: errorMessage(e) } };
|
|
75
|
+
}
|
|
76
|
+
const over = meter.charge(ex.actions, await usage());
|
|
77
|
+
if (over !== undefined)
|
|
78
|
+
exceeded ??= over;
|
|
79
|
+
executed.push({ item, ex, durationMs: now() - t0 });
|
|
80
|
+
}
|
|
81
|
+
// Findings: the shared identity over every result this check wrote.
|
|
82
|
+
const runs = [];
|
|
83
|
+
const runOf = new Map();
|
|
84
|
+
for (const { ex } of executed) {
|
|
85
|
+
if (ex?.resultPath === undefined)
|
|
86
|
+
continue;
|
|
87
|
+
const run = loadRunFile(ex.resultPath);
|
|
88
|
+
if (run === null)
|
|
89
|
+
continue;
|
|
90
|
+
runs.push(run);
|
|
91
|
+
runOf.set(ex.resultPath, run);
|
|
92
|
+
}
|
|
93
|
+
const defects = consolidate(runs);
|
|
94
|
+
let diff;
|
|
95
|
+
let baselineRuns;
|
|
96
|
+
if (opts.baseline !== undefined) {
|
|
97
|
+
const dirs = opts.baselineDirs ?? [resultsDir];
|
|
98
|
+
baselineRuns = resolveBaseline(opts.baseline, runs, {
|
|
99
|
+
dirs,
|
|
100
|
+
...(opts.baselinesDir === undefined ? {} : { baselinesDir: opts.baselinesDir }),
|
|
101
|
+
pool: scanRuns(dirs),
|
|
102
|
+
});
|
|
103
|
+
diff = diffRuns(baselineRuns, runs);
|
|
104
|
+
}
|
|
105
|
+
const entryOf = new Map(diff?.entries.map((e) => [e.key, e]) ?? []);
|
|
106
|
+
const isGating = (d) => {
|
|
107
|
+
if (d.severity !== "hard" && !opts.suite.gateAdvisory)
|
|
108
|
+
return false;
|
|
109
|
+
if (diff === undefined)
|
|
110
|
+
return true;
|
|
111
|
+
// A finding is matched to its diff entry by any member key (merged cascades).
|
|
112
|
+
const entry = d.keys.map((k) => entryOf.get(k)).find((e) => e !== undefined) ?? entryOf.get(d.key);
|
|
113
|
+
return entry === undefined ? true : !entry.inBaseline;
|
|
114
|
+
};
|
|
115
|
+
const statusOf = (d) => d.keys.map((k) => entryOf.get(k)?.status).find((s) => s !== undefined);
|
|
116
|
+
const gating = defects.filter(isGating);
|
|
117
|
+
const itemReports = executed.map(({ item, ex, durationMs }) => {
|
|
118
|
+
const base = {
|
|
119
|
+
target: item.t.target.name,
|
|
120
|
+
kind: item.kind,
|
|
121
|
+
name: item.name,
|
|
122
|
+
...(item.strategy === undefined ? {} : { strategy: item.strategy }),
|
|
123
|
+
durationMs,
|
|
124
|
+
};
|
|
125
|
+
if (ex === undefined)
|
|
126
|
+
return { ...base, status: "skipped", actions: 0, verdict: "skipped", gating: [] };
|
|
127
|
+
const run = ex.resultPath === undefined ? undefined : runOf.get(ex.resultPath);
|
|
128
|
+
const own = run === undefined ? [] : gating.filter((d) => d.modes.some((m) => m.runs.some((r) => r.path === run.path)));
|
|
129
|
+
const verdict = ex.status === "error" ? "error" : own.length > 0 ? "failed" : "passed";
|
|
130
|
+
return {
|
|
131
|
+
...base,
|
|
132
|
+
status: ex.status,
|
|
133
|
+
actions: ex.actions,
|
|
134
|
+
verdict,
|
|
135
|
+
gating: own.map((d) => d.key),
|
|
136
|
+
...(ex.error === undefined ? {} : { error: ex.error }),
|
|
137
|
+
...(ex.resultPath === undefined ? {} : { resultPath: ex.resultPath }),
|
|
138
|
+
...(run === undefined ? {} : { runId: run.runId }),
|
|
139
|
+
...(ex.outcome === undefined ? {} : { outcome: ex.outcome }),
|
|
140
|
+
...(ex.goalOutcome === undefined ? {} : { goalOutcome: ex.goalOutcome }),
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
const errors = itemReports.filter((i) => i.verdict === "error").length;
|
|
144
|
+
const exitCode = gating.length > 0 ? 1 : errors > 0 || exceeded !== undefined ? 2 : 0;
|
|
145
|
+
const junitPath = resolve(opts.junitPath ?? join(outDir, "junit.xml"));
|
|
146
|
+
const sarifPath = resolve(opts.sarifPath ?? join(outDir, "jevitate.sarif"));
|
|
147
|
+
const jsonPath = resolve(opts.jsonPath ?? join(outDir, "check.json"));
|
|
148
|
+
const reportPath = join(outDir, "report.md");
|
|
149
|
+
const cases = itemReports.map((i) => {
|
|
150
|
+
const own = gating.filter((d) => i.gating.includes(d.key));
|
|
151
|
+
const first = own[0];
|
|
152
|
+
// #250: each gating finding's repro clip and screenshots, attached to the case CI shows.
|
|
153
|
+
const attachments = [
|
|
154
|
+
...new Set(own.flatMap((d) => d.evidence.flatMap((e) => [e.video, e.screenshot]).filter((f) => f !== undefined && /\.(webm|png)$/i.test(f)))),
|
|
155
|
+
];
|
|
156
|
+
return {
|
|
157
|
+
suite: i.target,
|
|
158
|
+
classname: `jevitate.${i.target}.${i.kind}${i.strategy === undefined ? "" : `.${i.strategy}`}`,
|
|
159
|
+
name: i.name,
|
|
160
|
+
timeSec: i.durationMs / 1000,
|
|
161
|
+
status: i.verdict,
|
|
162
|
+
...(i.resultPath === undefined ? {} : { resultPath: i.resultPath }),
|
|
163
|
+
...(attachments.length === 0 ? {} : { attachments }),
|
|
164
|
+
...(i.verdict === "failed" && first !== undefined
|
|
165
|
+
? { type: first.category, message: `${own.length} gating finding(s): ${first.title}`, detail: caseDetail(own) }
|
|
166
|
+
: {}),
|
|
167
|
+
...(i.verdict === "error" && i.error !== undefined ? { type: i.error.type, message: i.error.message } : {}),
|
|
168
|
+
...(i.verdict === "skipped" ? { message: "not affected by --changed-routes" } : {}),
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
if (exceeded !== undefined && !cases.some((c) => c.type === "budget-exceeded")) {
|
|
172
|
+
cases.push({ suite: "budget", classname: "jevitate.budget", name: "total budget", timeSec: 0, status: "error", type: "budget-exceeded", message: exceeded });
|
|
173
|
+
}
|
|
174
|
+
const findings = defects.map((d) => {
|
|
175
|
+
const status = statusOf(d);
|
|
176
|
+
return {
|
|
177
|
+
key: d.key,
|
|
178
|
+
title: d.title,
|
|
179
|
+
category: d.category,
|
|
180
|
+
severity: d.severity,
|
|
181
|
+
identity: d.identity,
|
|
182
|
+
gating: gating.includes(d),
|
|
183
|
+
modes: d.modes,
|
|
184
|
+
...(status === undefined ? {} : { status }),
|
|
185
|
+
...(d.reproduce === undefined ? {} : { reproduce: d.reproduce }),
|
|
186
|
+
};
|
|
187
|
+
});
|
|
188
|
+
const finalUsage = await usage();
|
|
189
|
+
const suiteUsage = finalUsage === undefined ? undefined : aggregateOf(finalUsage, executed.filter((e) => e.ex !== undefined).length);
|
|
190
|
+
const result = {
|
|
191
|
+
kind: "jevitate-check",
|
|
192
|
+
suite: opts.suite.name,
|
|
193
|
+
suitePath: opts.suite.path,
|
|
194
|
+
verdict: exitCode === 0 ? "pass" : "fail",
|
|
195
|
+
exitCode,
|
|
196
|
+
engine,
|
|
197
|
+
...(opts.targetBuild === undefined ? {} : { targetBuild: opts.targetBuild }),
|
|
198
|
+
startedAt,
|
|
199
|
+
budget: meter.report(finalUsage, exceeded),
|
|
200
|
+
...(suiteUsage === undefined ? {} : { usage: suiteUsage }),
|
|
201
|
+
items: itemReports,
|
|
202
|
+
findings,
|
|
203
|
+
summary: {
|
|
204
|
+
items: itemReports.length,
|
|
205
|
+
passed: itemReports.filter((i) => i.verdict === "passed").length,
|
|
206
|
+
failed: itemReports.filter((i) => i.verdict === "failed").length,
|
|
207
|
+
errors,
|
|
208
|
+
skipped: itemReports.filter((i) => i.verdict === "skipped").length,
|
|
209
|
+
gatingFindings: gating.length,
|
|
210
|
+
},
|
|
211
|
+
...(diff === undefined || baselineRuns === undefined ? {} : { diff: { baseline: baselineRuns.map(summarizeRun), summary: diff.summary } }),
|
|
212
|
+
results: runs.map((r) => r.path),
|
|
213
|
+
junitPath,
|
|
214
|
+
sarifPath,
|
|
215
|
+
jsonPath,
|
|
216
|
+
reportPath,
|
|
217
|
+
};
|
|
218
|
+
await writeFile(junitPath, renderJUnit(`jevitate check: ${opts.suite.name}`, cases, startedAt), "utf8");
|
|
219
|
+
const sarif = renderSarif({
|
|
220
|
+
toolVersion: engine.version,
|
|
221
|
+
engineCommit: engine.commit,
|
|
222
|
+
...(opts.targetBuild === undefined ? {} : { targetBuild: opts.targetBuild }),
|
|
223
|
+
suiteUri: opts.suiteUri ?? opts.suite.path,
|
|
224
|
+
automationId: `jevitate-check/${opts.suite.name}/`,
|
|
225
|
+
findings: defects.map((d) => ({ defect: d, gating: gating.includes(d), ...(statusOf(d) === undefined ? {} : { status: statusOf(d) }) })),
|
|
226
|
+
});
|
|
227
|
+
await writeFile(sarifPath, `${JSON.stringify(sarif, null, 2)}\n`, "utf8");
|
|
228
|
+
await writeFile(reportPath, renderReportMarkdown({ title: `jevitate check: ${opts.suite.name} — ${result.verdict}`, runs, defects, ...(diff === undefined ? {} : { diff }) }) +
|
|
229
|
+
(suiteUsage === undefined ? "" : `\n## Model cost\n\n${formatUsageLine(suiteUsage)}\n`), "utf8");
|
|
230
|
+
await writeFile(jsonPath, `${JSON.stringify({ v: 1, ok: true, data: result }, null, 2)}\n`, "utf8");
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=check-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-api.js","sourceRoot":"","sources":["../src/check-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type UsageCounts } from "@jevitate/ai-core";
|
|
2
|
+
import type { SuiteBudget } from "./check-suite.js";
|
|
3
|
+
import { type BudgetReport } from "./check-types.js";
|
|
4
|
+
/** The suite's total budget. Exceeding any limit fails the check (fail closed). */
|
|
5
|
+
export declare class BudgetMeter {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(limits: SuiteBudget, opts?: {
|
|
8
|
+
now?: () => number;
|
|
9
|
+
costKnownZero?: boolean;
|
|
10
|
+
});
|
|
11
|
+
get actions(): number;
|
|
12
|
+
/** Actions left (undefined: no action limit). */
|
|
13
|
+
remainingActions(): number | undefined;
|
|
14
|
+
minutes(): number;
|
|
15
|
+
/**
|
|
16
|
+
* The spend so far: 0 when no model call was made (or the gateways are fakes), the FULL total
|
|
17
|
+
* (Jev + generation, #163) when every call was priced, else undefined — a partial total is not a
|
|
18
|
+
* measurable spend, so a `maxUsd` budget fails closed on it rather than passing on an undercount.
|
|
19
|
+
*/
|
|
20
|
+
usd(usage: UsageCounts | undefined): number | undefined;
|
|
21
|
+
/** Records an item's actions and re-checks every limit. Returns why the budget is now exceeded, if it is. */
|
|
22
|
+
charge(actions: number, usage: UsageCounts | undefined): string | undefined;
|
|
23
|
+
/** Can another item start? Returns why not (the budget is exhausted or already exceeded). */
|
|
24
|
+
blocked(usage: UsageCounts | undefined): string | undefined;
|
|
25
|
+
report(usage: UsageCounts | undefined, exceeded: string | undefined): BudgetReport;
|
|
26
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// ── budget ───────────────────────────────────────────────────────────────────
|
|
2
|
+
/** Why a spend is not measurable: what could not be priced. */
|
|
3
|
+
function unmeasurable(usage) {
|
|
4
|
+
const missing = usage?.missing ?? [];
|
|
5
|
+
return `${usage?.priced === "none" ? "unpriced" : "only partially priced"}${missing.length === 0 ? "" : ` — missing: ${missing.join("; ")}`}`;
|
|
6
|
+
}
|
|
7
|
+
/** The suite's total budget. Exceeding any limit fails the check (fail closed). */
|
|
8
|
+
export class BudgetMeter {
|
|
9
|
+
#limits;
|
|
10
|
+
#now;
|
|
11
|
+
#start;
|
|
12
|
+
#costKnownZero;
|
|
13
|
+
#actions = 0;
|
|
14
|
+
#exceeded;
|
|
15
|
+
constructor(limits, opts = {}) {
|
|
16
|
+
this.#limits = limits;
|
|
17
|
+
this.#now = opts.now ?? Date.now;
|
|
18
|
+
this.#start = this.#now();
|
|
19
|
+
this.#costKnownZero = opts.costKnownZero === true;
|
|
20
|
+
}
|
|
21
|
+
get actions() {
|
|
22
|
+
return this.#actions;
|
|
23
|
+
}
|
|
24
|
+
/** Actions left (undefined: no action limit). */
|
|
25
|
+
remainingActions() {
|
|
26
|
+
return this.#limits.maxActions === undefined ? undefined : this.#limits.maxActions - this.#actions;
|
|
27
|
+
}
|
|
28
|
+
minutes() {
|
|
29
|
+
return (this.#now() - this.#start) / 60_000;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The spend so far: 0 when no model call was made (or the gateways are fakes), the FULL total
|
|
33
|
+
* (Jev + generation, #163) when every call was priced, else undefined — a partial total is not a
|
|
34
|
+
* measurable spend, so a `maxUsd` budget fails closed on it rather than passing on an undercount.
|
|
35
|
+
*/
|
|
36
|
+
usd(usage) {
|
|
37
|
+
if (usage === undefined || usage.judgments + usage.generations === 0)
|
|
38
|
+
return 0;
|
|
39
|
+
if (this.#costKnownZero)
|
|
40
|
+
return usage.totalUsd ?? 0;
|
|
41
|
+
return usage.priced === "full" ? (usage.totalUsd ?? 0) : undefined;
|
|
42
|
+
}
|
|
43
|
+
/** Records an item's actions and re-checks every limit. Returns why the budget is now exceeded, if it is. */
|
|
44
|
+
charge(actions, usage) {
|
|
45
|
+
this.#actions += actions;
|
|
46
|
+
const l = this.#limits;
|
|
47
|
+
if (this.#exceeded === undefined && l.maxActions !== undefined && this.#actions > l.maxActions) {
|
|
48
|
+
this.#exceeded = `action budget exceeded: ${this.#actions} > ${l.maxActions}`;
|
|
49
|
+
}
|
|
50
|
+
if (this.#exceeded === undefined && l.maxMinutes !== undefined && this.minutes() > l.maxMinutes) {
|
|
51
|
+
this.#exceeded = `time budget exceeded: ${this.minutes().toFixed(2)} > ${l.maxMinutes} min`;
|
|
52
|
+
}
|
|
53
|
+
if (this.#exceeded === undefined && l.maxUsd !== undefined) {
|
|
54
|
+
const usd = this.usd(usage);
|
|
55
|
+
if (usd === undefined)
|
|
56
|
+
this.#exceeded = `usd budget set but the model spend is ${unmeasurable(usage)} (spend not measurable)`;
|
|
57
|
+
else if (usd > l.maxUsd)
|
|
58
|
+
this.#exceeded = `usd budget exceeded: $${usd.toFixed(4)} > $${l.maxUsd}`;
|
|
59
|
+
}
|
|
60
|
+
return this.#exceeded;
|
|
61
|
+
}
|
|
62
|
+
/** Can another item start? Returns why not (the budget is exhausted or already exceeded). */
|
|
63
|
+
blocked(usage) {
|
|
64
|
+
if (this.#exceeded !== undefined)
|
|
65
|
+
return this.#exceeded;
|
|
66
|
+
const l = this.#limits;
|
|
67
|
+
if (l.maxActions !== undefined && this.#actions >= l.maxActions)
|
|
68
|
+
return `action budget exhausted: ${this.#actions}/${l.maxActions}`;
|
|
69
|
+
if (l.maxMinutes !== undefined && this.minutes() >= l.maxMinutes)
|
|
70
|
+
return `time budget exhausted: ${l.maxMinutes} min`;
|
|
71
|
+
if (l.maxUsd !== undefined) {
|
|
72
|
+
const usd = this.usd(usage);
|
|
73
|
+
if (usd === undefined)
|
|
74
|
+
return `usd budget set but the model spend is ${unmeasurable(usage)} (spend not measurable)`;
|
|
75
|
+
if (usd >= l.maxUsd)
|
|
76
|
+
return `usd budget exhausted: $${usd.toFixed(4)}/$${l.maxUsd}`;
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
report(usage, exceeded) {
|
|
81
|
+
const usd = this.usd(usage);
|
|
82
|
+
return {
|
|
83
|
+
limits: this.#limits,
|
|
84
|
+
used: { actions: this.#actions, minutes: Number(this.minutes().toFixed(3)), ...(usd === undefined ? {} : { usd }) },
|
|
85
|
+
...(exceeded === undefined ? {} : { exceeded }),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=check-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-budget.js","sourceRoot":"","sources":["../src/check-budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { BrowserLaunchOptions, BrowserPort } from "@jevitate/playwright";
|
|
3
|
+
import { type CheckGateways, type CheckRunners } from "./check-api.js";
|
|
4
|
+
/**
|
|
5
|
+
* `jevitate check --suite <file.json>` (#137). Registered by `program.ts`; its model gateways and
|
|
6
|
+
* browser wiring come in through `CheckCliDeps` so this file never builds a gateway itself.
|
|
7
|
+
*
|
|
8
|
+
* Exit codes (exit-codes.ts): 0 pass · 1 a gating (hard, or new vs `--baseline`) finding · 2 no
|
|
9
|
+
* gating finding but an item errored, the budget was exceeded, or the check itself failed · 64 the
|
|
10
|
+
* suite, preflight, targets file or AI setup was refused (a usage/input error: nothing ran).
|
|
11
|
+
*/
|
|
12
|
+
export interface CheckCliDeps {
|
|
13
|
+
/** Builds the explore gateways for `--real` / `--fake-ai` (program.ts's `buildExploreGateways`). */
|
|
14
|
+
readonly buildGateways: (sel: {
|
|
15
|
+
real: boolean;
|
|
16
|
+
fakeAi: boolean;
|
|
17
|
+
}) => Promise<CheckGateways>;
|
|
18
|
+
readonly journeysDir: string;
|
|
19
|
+
/** The site-policy database (`jevitate site policy set`) Journey items are gated by. */
|
|
20
|
+
readonly sitePolicyDbPath?: string;
|
|
21
|
+
readonly targetsConfigPath?: string;
|
|
22
|
+
/** #247: the environments file a Journey item's `env` names (default: the repo's `.jevitate/environments.json`). */
|
|
23
|
+
readonly environmentsFile?: string;
|
|
24
|
+
readonly browserPortFactory?: () => BrowserPort;
|
|
25
|
+
/** Maps the command's browser launch flags to launch options (program.ts's `browserLaunchFromFlags`). */
|
|
26
|
+
readonly browserLaunch?: (flags: object) => BrowserLaunchOptions | undefined;
|
|
27
|
+
readonly baselinesDir?: string;
|
|
28
|
+
/** Test seam: replace the runners. */
|
|
29
|
+
readonly runners?: Partial<CheckRunners>;
|
|
30
|
+
}
|
|
31
|
+
export declare function registerCheckCommand(program: Command, deps: CheckCliDeps, withLaunchFlags: (cmd: Command) => Command): void;
|