@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
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { type GoalOutcome, type MissionOutcome } from "@jevitate/domain";
|
|
2
|
+
import { type UsageAggregate, type UsageCounts } from "@jevitate/ai-core";
|
|
3
|
+
import { type EngineInfo } from "./engine.js";
|
|
4
|
+
/**
|
|
5
|
+
* Multi-run orchestration over the existing explore strategies (#141 repeat-and-vote, #143 persona
|
|
6
|
+
* matrix). One orchestrator runs the SAME mission N times — once per persona (storageState) and
|
|
7
|
+
* `--repeat` times within each — strictly SEQUENTIALLY (never concurrently: conversational and
|
|
8
|
+
* stateful missions share server-side state), each run in a fresh browser context (every run is a
|
|
9
|
+
* separate mission, which opens its own context). It then aggregates the runs with code only:
|
|
10
|
+
*
|
|
11
|
+
* - repeat-and-vote (#141): a finding is kept when it recurs in ≥ k of N runs; the rest are
|
|
12
|
+
* reported as `flaky` (seen, not counted). The overall outcome is the agreed one (the most
|
|
13
|
+
* common per-run outcome, when it was reached by ≥ k runs), else `intermittent`.
|
|
14
|
+
* - persona matrix (#143): per-persona outcome, findings, requests (method + templated path →
|
|
15
|
+
* status) and visible controls, plus an ADVISORY diff: requests one persona made that another
|
|
16
|
+
* did not, status differences for the same request (a 401/403 against a 2xx is a candidate RBAC
|
|
17
|
+
* finding), controls visible to one persona only, and each persona's outcome.
|
|
18
|
+
*
|
|
19
|
+
* Storage-state CONTENTS are never read, logged or copied here — only their paths travel.
|
|
20
|
+
*/
|
|
21
|
+
export declare class MultiRunArgsError extends Error {
|
|
22
|
+
readonly code: "E_EXPLORE_ARGS";
|
|
23
|
+
constructor(message: string);
|
|
24
|
+
}
|
|
25
|
+
export interface Persona {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
/** Absolute path of the persona's Playwright storageState file (its contents are never read). */
|
|
28
|
+
readonly storageState: string;
|
|
29
|
+
}
|
|
30
|
+
export interface MultiRunPlan {
|
|
31
|
+
/** Runs per persona (or per mission, without personas). */
|
|
32
|
+
readonly repeat: number;
|
|
33
|
+
/** A finding (and the outcome) counts when seen in at least this many of `repeat` runs. */
|
|
34
|
+
readonly minAgreement: number;
|
|
35
|
+
/** The persona matrix; `null` for a plain `--repeat`. */
|
|
36
|
+
readonly personas: readonly Persona[] | null;
|
|
37
|
+
}
|
|
38
|
+
/** Upper bound on `--repeat`: each run is a whole mission, run one after another. */
|
|
39
|
+
export declare const MAX_REPEAT = 20;
|
|
40
|
+
/** `--persona <name>=<storageState>`: the path is resolved against the working directory. */
|
|
41
|
+
export declare function parsePersonaSpec(spec: string, cwd?: string): Persona;
|
|
42
|
+
/**
|
|
43
|
+
* `--actor <name>=<storageState>` (#147): the same `<name>=<storageState>` shape and checks as a
|
|
44
|
+
* persona (the file must exist; its contents are never read here).
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseActorSpec(spec: string, cwd?: string): Persona;
|
|
47
|
+
/**
|
|
48
|
+
* `--personas <file>`: JSON, either `{"admin": "admin.json", "sales": "sales.json"}` or
|
|
49
|
+
* `{"personas": [{"name": "admin", "storageState": "admin.json"}]}` (a bare array also works).
|
|
50
|
+
* Relative paths resolve against the personas file's own directory.
|
|
51
|
+
*/
|
|
52
|
+
export declare function loadPersonasFile(path: string): Persona[];
|
|
53
|
+
export interface MultiRunFlags {
|
|
54
|
+
readonly repeat?: string;
|
|
55
|
+
readonly minAgreement?: string;
|
|
56
|
+
readonly persona: readonly string[];
|
|
57
|
+
readonly personas?: string;
|
|
58
|
+
readonly storageState?: string;
|
|
59
|
+
readonly saveStorageState?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Whether the flags ask for a multi-run at all. */
|
|
62
|
+
export declare function wantsMultiRun(f: MultiRunFlags): boolean;
|
|
63
|
+
/** Validates the multi-run flags (before any browser opens). Default k = a strict majority of N. */
|
|
64
|
+
export declare function resolveMultiRunPlan(f: MultiRunFlags, cwd?: string): MultiRunPlan;
|
|
65
|
+
/** One finding as a run reported it, reduced to what cross-run matching needs. */
|
|
66
|
+
export interface RunFinding {
|
|
67
|
+
/** defect / invariant / hang / advisory / coverage-defect / ux (plus the defect's own kind). */
|
|
68
|
+
readonly kind: string;
|
|
69
|
+
/** The engine's own stable fingerprint, when the finding has one. */
|
|
70
|
+
readonly fingerprint?: string;
|
|
71
|
+
/** Templated route it was (first) seen on. */
|
|
72
|
+
readonly route: string;
|
|
73
|
+
readonly title: string;
|
|
74
|
+
/** For a UX finding: its rubric item and implicated controls (a UX finding has no fingerprint). */
|
|
75
|
+
readonly rubricItemId?: string;
|
|
76
|
+
readonly controls?: readonly string[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* THE cross-run finding identity (#141). Kept deliberately small and self-contained so it can be
|
|
80
|
+
* swapped for the shared finding-identity model of `jevitate report`/`diff`/`check` (#137–#139):
|
|
81
|
+
* the engine's own fingerprint (defect / hang / invariant / signal) plus the templated route; a UX
|
|
82
|
+
* finding (no fingerprint) is its rubric item + route + implicated controls.
|
|
83
|
+
*/
|
|
84
|
+
export declare function findingIdentity(f: RunFinding): string;
|
|
85
|
+
/** Every finding a run's result carries, whatever its strategy. */
|
|
86
|
+
export declare function extractRunFindings(data: unknown): RunFinding[];
|
|
87
|
+
/**
|
|
88
|
+
* #226: a run's canonical verdict (the #217 contract): its own `missionOutcome`; else a goal run's
|
|
89
|
+
* ending folded (`GOAL_OUTCOME_FOLD`), or another strategy's `outcome` when it already is one; else
|
|
90
|
+
* `crashed` — a run that says nothing readable proves nothing.
|
|
91
|
+
*/
|
|
92
|
+
export declare function runMissionOutcomeOf(strategy: string, data: unknown): MissionOutcome;
|
|
93
|
+
/** `METHOD /templated/path` → the distinct response statuses seen (assets excluded; pending dropped). */
|
|
94
|
+
export declare function extractRequests(data: unknown): Record<string, number[]>;
|
|
95
|
+
/** Every control identity the run's transcript saw (see `TranscriptEntry.controls`). */
|
|
96
|
+
export declare function extractControls(transcript: unknown): string[];
|
|
97
|
+
/** What one run contributed. */
|
|
98
|
+
export interface RunSummary {
|
|
99
|
+
/** 1-based, within its persona. */
|
|
100
|
+
readonly index: number;
|
|
101
|
+
/** False when the run could not start or broke outside the mission (its envelope was an error). */
|
|
102
|
+
readonly ok: boolean;
|
|
103
|
+
/** The run's own ending: a goal run's `goalOutcome`, else its canonical outcome. */
|
|
104
|
+
readonly outcome: string;
|
|
105
|
+
/** #226: the run's canonical verdict (#217) — what the vote counts. */
|
|
106
|
+
readonly missionOutcome: MissionOutcome;
|
|
107
|
+
/** #226: a goal run's own ending (#217), beside `missionOutcome`. */
|
|
108
|
+
readonly goalOutcome?: GoalOutcome;
|
|
109
|
+
readonly exitCode: number;
|
|
110
|
+
readonly findings: readonly RunFinding[];
|
|
111
|
+
readonly requests: Readonly<Record<string, readonly number[]>>;
|
|
112
|
+
readonly controls: readonly string[];
|
|
113
|
+
/** The run's own persisted result (or report), when it wrote one. */
|
|
114
|
+
readonly resultPath?: string;
|
|
115
|
+
/** The run's envelope, as written next to its artifacts. */
|
|
116
|
+
readonly envelopePath?: string;
|
|
117
|
+
readonly error?: {
|
|
118
|
+
readonly code: string;
|
|
119
|
+
readonly message: string;
|
|
120
|
+
};
|
|
121
|
+
/** #220: why the run ended the way it did, when its result says (a crash's failure, a stop reason). */
|
|
122
|
+
readonly reason?: string;
|
|
123
|
+
/** The run's model usage (#163), as its envelope reported it. */
|
|
124
|
+
readonly usage?: UsageCounts;
|
|
125
|
+
/** #213: the run's `failure.kind` (or its crash's), when it had one. */
|
|
126
|
+
readonly failureKind?: string;
|
|
127
|
+
/** #226: a find-out run's answer (`{text, evidence}`), as its result carried it. */
|
|
128
|
+
readonly answer?: unknown;
|
|
129
|
+
/** #213: why the run's storage-state session (a persona's) was not honoured, when it was not. */
|
|
130
|
+
readonly sessionLost?: string;
|
|
131
|
+
}
|
|
132
|
+
export interface AggregatedFinding {
|
|
133
|
+
readonly id: string;
|
|
134
|
+
readonly kind: string;
|
|
135
|
+
readonly fingerprint?: string;
|
|
136
|
+
readonly route: string;
|
|
137
|
+
readonly title: string;
|
|
138
|
+
/** `seen/N`, e.g. `2/3`. */
|
|
139
|
+
readonly stability: string;
|
|
140
|
+
readonly seen: number;
|
|
141
|
+
readonly of: number;
|
|
142
|
+
/** Which runs (1-based) saw it. */
|
|
143
|
+
readonly runs: number[];
|
|
144
|
+
/** `agreed`: seen in ≥ k runs (counted). `flaky`: seen in fewer — reported, never counted. */
|
|
145
|
+
readonly status: "agreed" | "flaky";
|
|
146
|
+
}
|
|
147
|
+
export interface CellResult {
|
|
148
|
+
readonly persona: string | null;
|
|
149
|
+
readonly storageStatePath?: string;
|
|
150
|
+
/**
|
|
151
|
+
* The agreed outcome; else `intermittent` when the finished runs reached different VERDICTS — or
|
|
152
|
+
* `inconclusive` (#220) when they did not agree because a run broke (crashed/inconclusive: a lost
|
|
153
|
+
* browser proves nothing about the app) or runs are still missing. `reason` then says which.
|
|
154
|
+
*/
|
|
155
|
+
readonly outcome: string;
|
|
156
|
+
/**
|
|
157
|
+
* #226: the canonical verdict (#217) the runs agreed on — voted over each run's `missionOutcome`, so
|
|
158
|
+
* goal runs that failed in different ways (exhausted, blocked) still agree they found a defect.
|
|
159
|
+
*/
|
|
160
|
+
readonly missionOutcome: MissionOutcome;
|
|
161
|
+
/** #226: goal runs only — the goal ending ≥ k runs agreed on, else the canonical outcome (#217). */
|
|
162
|
+
readonly goalOutcome?: GoalOutcome;
|
|
163
|
+
/** #220: why the outcome is `inconclusive` (which runs broke, or how many are missing). */
|
|
164
|
+
readonly reason?: string;
|
|
165
|
+
/** The exit code of `missionOutcome`. */
|
|
166
|
+
readonly exitCode: number;
|
|
167
|
+
/** How many runs ended in each (own) outcome. */
|
|
168
|
+
readonly outcomes: Readonly<Record<string, number>>;
|
|
169
|
+
readonly runs: readonly RunSummary[];
|
|
170
|
+
/** Agreed findings (≥ k runs), most stable first. */
|
|
171
|
+
readonly findings: AggregatedFinding[];
|
|
172
|
+
/** Findings seen in fewer than k runs. */
|
|
173
|
+
readonly flaky: AggregatedFinding[];
|
|
174
|
+
/** Requests seen in ≥ k runs → every status seen for them. */
|
|
175
|
+
readonly requests: Record<string, number[]>;
|
|
176
|
+
/** Controls seen in ≥ k runs. */
|
|
177
|
+
readonly controls: string[];
|
|
178
|
+
/**
|
|
179
|
+
* #213: set when every run ended without observing the app (a starved host, an unreachable or
|
|
180
|
+
* unresponsive target) — why. Such a persona is left out of the persona diff: its missing requests
|
|
181
|
+
* and controls are the environment, never an access difference.
|
|
182
|
+
*/
|
|
183
|
+
readonly notObserved?: string;
|
|
184
|
+
/**
|
|
185
|
+
* #213: the persona's session was not honoured in some run (its first page was a sign-in page) —
|
|
186
|
+
* what it tested was not this persona. Which runs, and why.
|
|
187
|
+
*/
|
|
188
|
+
readonly sessionLost?: string;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Votes one persona's (or the mission's) runs: findings, outcome, requests and controls. `planned`
|
|
192
|
+
* is how many runs the plan has (default: the runs given) — fewer finished never reads `intermittent`.
|
|
193
|
+
*/
|
|
194
|
+
export declare function voteRuns(runs: readonly RunSummary[], k: number, persona?: Persona | null, planned?: number): CellResult;
|
|
195
|
+
export interface PersonaPresenceDiff {
|
|
196
|
+
/** The request (`METHOD /templated/path`) or control (`role "name"`). */
|
|
197
|
+
readonly item: string;
|
|
198
|
+
/** Personas that made / saw it. */
|
|
199
|
+
readonly presentFor: string[];
|
|
200
|
+
/** Personas that did not. */
|
|
201
|
+
readonly absentFor: string[];
|
|
202
|
+
}
|
|
203
|
+
export interface PersonaStatusDiff {
|
|
204
|
+
readonly request: string;
|
|
205
|
+
/** Persona → the statuses its runs got for this same request. */
|
|
206
|
+
readonly statuses: Record<string, number[]>;
|
|
207
|
+
}
|
|
208
|
+
export interface RbacCandidate {
|
|
209
|
+
readonly request: string;
|
|
210
|
+
/** Personas refused (401/403) and the status they got. */
|
|
211
|
+
readonly denied: Record<string, number[]>;
|
|
212
|
+
/** Personas the same request succeeded (2xx) for. */
|
|
213
|
+
readonly allowed: string[];
|
|
214
|
+
readonly title: string;
|
|
215
|
+
}
|
|
216
|
+
export interface PersonaDiff {
|
|
217
|
+
/** Always true: the diff is code-computed evidence for a person to judge, never a verdict. */
|
|
218
|
+
readonly advisory: true;
|
|
219
|
+
readonly requestsOnlyIn: PersonaPresenceDiff[];
|
|
220
|
+
readonly statusDiffs: PersonaStatusDiff[];
|
|
221
|
+
readonly controlsOnlyIn: PersonaPresenceDiff[];
|
|
222
|
+
/** Persona → its agreed canonical outcome (`missionOutcome`, #226). */
|
|
223
|
+
readonly outcomes: Record<string, string>;
|
|
224
|
+
/** True when not every persona reached the same outcome. */
|
|
225
|
+
readonly outcomeDiffers: boolean;
|
|
226
|
+
/** A 401/403 for one persona where another got a 2xx on the same request. */
|
|
227
|
+
readonly rbacCandidates: RbacCandidate[];
|
|
228
|
+
/** #213: personas left out of the comparison because their runs never observed the app — and why. */
|
|
229
|
+
readonly notCompared: Array<{
|
|
230
|
+
readonly persona: string;
|
|
231
|
+
readonly reason: string;
|
|
232
|
+
}>;
|
|
233
|
+
/**
|
|
234
|
+
* #213: persona → why its session was lost (its first page was a sign-in page). Every other
|
|
235
|
+
* difference for that persona is then an access difference of whoever the run was, not the persona.
|
|
236
|
+
*/
|
|
237
|
+
readonly sessionLost?: Record<string, string>;
|
|
238
|
+
}
|
|
239
|
+
/** The persona matrix's diff section (#143): pure, over the per-persona (voted) cells. */
|
|
240
|
+
export declare function diffPersonas(cells: readonly CellResult[]): PersonaDiff;
|
|
241
|
+
/** A run's JSON envelope, exactly as `jevitate explore --json` emits it. */
|
|
242
|
+
export type RunEnvelope = {
|
|
243
|
+
readonly ok: true;
|
|
244
|
+
readonly data: unknown;
|
|
245
|
+
} | {
|
|
246
|
+
readonly ok: false;
|
|
247
|
+
readonly error: {
|
|
248
|
+
readonly code: string;
|
|
249
|
+
readonly message: string;
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
export interface RunOnceArgs {
|
|
253
|
+
/** Persona storage state to start from (`undefined`: the mission's own `--storage-state`, if any). */
|
|
254
|
+
readonly storageState?: string;
|
|
255
|
+
/** Where this run writes its artifacts. */
|
|
256
|
+
readonly outDir: string;
|
|
257
|
+
}
|
|
258
|
+
export type RunOnce = (args: RunOnceArgs) => Promise<RunEnvelope>;
|
|
259
|
+
export interface MultiRunResult {
|
|
260
|
+
readonly kind: "multi-run";
|
|
261
|
+
readonly strategy: string;
|
|
262
|
+
readonly repeat: number;
|
|
263
|
+
readonly minAgreement: number;
|
|
264
|
+
/**
|
|
265
|
+
* Without personas: the agreed outcome. With personas: every persona's, when they agree; else
|
|
266
|
+
* `mixed`. While runs are pending (`complete: false`, or a killed multi-run) it is `inconclusive` (#220).
|
|
267
|
+
*/
|
|
268
|
+
readonly outcome: string;
|
|
269
|
+
/**
|
|
270
|
+
* #226: the canonical verdict (#217), like every mission result's: without personas, the agreed
|
|
271
|
+
* `missionOutcome`; with personas, the shared one when they agree, else the most severe persona's
|
|
272
|
+
* (`combineOutcomes`: a broken persona run dominates, a confirmed hang beats a defect). While runs
|
|
273
|
+
* are pending (`complete: false`, or a killed multi-run) it is `inconclusive`.
|
|
274
|
+
*/
|
|
275
|
+
readonly missionOutcome: MissionOutcome;
|
|
276
|
+
/** #226: `--goal` multi-runs only — the goal ending the runs agreed on, else the canonical outcome (#217). */
|
|
277
|
+
readonly goalOutcome?: GoalOutcome;
|
|
278
|
+
/** #220: why the outcome is `inconclusive` (runs pending or interrupted, or a run broke). */
|
|
279
|
+
readonly reason?: string;
|
|
280
|
+
/** #220: the multi-run was stopped by this signal; the run in flight is recorded as interrupted. */
|
|
281
|
+
readonly interrupted?: {
|
|
282
|
+
readonly signal: string;
|
|
283
|
+
};
|
|
284
|
+
/** The exit code of `missionOutcome` (130/143 for a killed multi-run). */
|
|
285
|
+
readonly exitCode: number;
|
|
286
|
+
/** #226: the build that produced the aggregate (`{version, commit, builtAt}`), like every result. */
|
|
287
|
+
readonly engine: EngineInfo;
|
|
288
|
+
/** Agreed findings (with personas: each tagged by persona). */
|
|
289
|
+
readonly findings: Array<AggregatedFinding & {
|
|
290
|
+
readonly persona?: string;
|
|
291
|
+
}>;
|
|
292
|
+
/** Flaky findings (seen in fewer than k runs) — reported, not counted. */
|
|
293
|
+
readonly flaky: Array<AggregatedFinding & {
|
|
294
|
+
readonly persona?: string;
|
|
295
|
+
}>;
|
|
296
|
+
/** One cell per persona (a single, persona-less cell without personas). */
|
|
297
|
+
readonly cells: CellResult[];
|
|
298
|
+
/** The persona matrix's diff (present only with personas). */
|
|
299
|
+
readonly diff?: PersonaDiff;
|
|
300
|
+
/** The aggregate result file (`multi-run.result.json` in the multi-run directory). */
|
|
301
|
+
readonly resultPath: string;
|
|
302
|
+
/** False while runs are still pending (the file is rewritten after every run). */
|
|
303
|
+
readonly complete: boolean;
|
|
304
|
+
/**
|
|
305
|
+
* Model usage summed over every run so far (#163): equals the sum of the runs' own `usage`. A run
|
|
306
|
+
* whose envelope carried none (it crashed outside the mission) makes the total `partial`.
|
|
307
|
+
*/
|
|
308
|
+
readonly usage: UsageAggregate;
|
|
309
|
+
}
|
|
310
|
+
/** A run a signal interrupted (#220): the killed mission's partial result, when one was armed. */
|
|
311
|
+
export interface InterruptedRun {
|
|
312
|
+
readonly signal: string;
|
|
313
|
+
readonly exitCode: number;
|
|
314
|
+
/** The killed mission's partial result (absent when the signal landed before it was armed). */
|
|
315
|
+
readonly partial?: Record<string, unknown>;
|
|
316
|
+
}
|
|
317
|
+
export interface RunMultiRunOptions {
|
|
318
|
+
readonly plan: MultiRunPlan;
|
|
319
|
+
readonly strategy: string;
|
|
320
|
+
/** The multi-run directory: `<persona>/run-<i>/` per run plus `multi-run.result.json`. */
|
|
321
|
+
readonly outDir: string;
|
|
322
|
+
readonly runOnce: RunOnce;
|
|
323
|
+
/**
|
|
324
|
+
* #220: armed for the whole multi-run. `onKill` must be called SYNCHRONOUSLY on a kill signal: it
|
|
325
|
+
* records the run in flight as interrupted, rewrites the aggregate (incomplete, `inconclusive`)
|
|
326
|
+
* and returns it. Returns the disarm function.
|
|
327
|
+
*/
|
|
328
|
+
readonly armKill?: (onKill: (interrupted: InterruptedRun) => MultiRunResult) => () => void;
|
|
329
|
+
}
|
|
330
|
+
/** Summarizes one run's envelope (the only IO: its transcript file when the result omits it). */
|
|
331
|
+
export declare function summarizeRun(strategy: string, index: number, envelope: RunEnvelope, envelopePath?: string): RunSummary;
|
|
332
|
+
/** Folds the voted cells into the aggregate (pure). */
|
|
333
|
+
export declare function aggregateCells(strategy: string, plan: MultiRunPlan, cells: CellResult[], resultPath: string, complete: boolean, engine?: EngineInfo): MultiRunResult;
|
|
334
|
+
/**
|
|
335
|
+
* Runs the plan SEQUENTIALLY — persona by persona, `repeat` runs each, one at a time (never
|
|
336
|
+
* concurrently) — writing each run's envelope next to its artifacts and rewriting the aggregate
|
|
337
|
+
* after every run (so a killed multi-run still leaves the runs it finished, marked incomplete).
|
|
338
|
+
*/
|
|
339
|
+
export declare function runMultiRun(opts: RunMultiRunOptions): Promise<MultiRunResult>;
|