@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,247 @@
|
|
|
1
|
+
import { MissingCredentialError } from "@jevitate/ai-core";
|
|
2
|
+
import { ok, fail } from "./envelope.js";
|
|
3
|
+
import { logsDirFor } from "./project-dir.js";
|
|
4
|
+
import { addMissionTarget, listMissionTargets, promoteMissionTarget, missionTargetContext, missionTargetAuth, updateMissionTargetAuth, withMissionTargetAuthFlags, UnknownMissionTargetError, } from "./mission-api.js";
|
|
5
|
+
import { FsMissionQueueStore } from "@jevitate/missions";
|
|
6
|
+
import { drainMissionQueue, needsModel, realQueuedMissionExecutor } from "./mission-queue-runner.js";
|
|
7
|
+
import { loadTargetsFile } from "./target-config.js";
|
|
8
|
+
import { withEngine } from "./engine.js";
|
|
9
|
+
import { EXIT_CODES } from "./exit-codes.js";
|
|
10
|
+
import { positiveIntArg } from "./cli-args.js";
|
|
11
|
+
import { resolveDataDir } from "./data-dir.js";
|
|
12
|
+
import { registerMissionQueueCommands } from "./mission-queue-cli.js";
|
|
13
|
+
import { resolveMissionTargetsDir, withBrowserLaunchFlags, browserLaunchFromFlags, emitJson, GatewaySelectionError, buildExploreGateways, } from "./cli-shared.js";
|
|
14
|
+
/** Registers `jevitate mission`: `target add|update|list|promote`, `run` (drains the mission queue), `queue` and `result` (#254). */
|
|
15
|
+
export function registerMissionCommands(program, deps) {
|
|
16
|
+
// Additive: `mission target` — register/list/promote exploration mission
|
|
17
|
+
// targets (Ticket #21). Wires the real fs-backed `@jevitate/missions`
|
|
18
|
+
// store/registry (the SAME store `queue_exploration` resolves promoted
|
|
19
|
+
// targets from). SECURITY: `add` registers UNPROMOTED — the promoted-only
|
|
20
|
+
// gate stays intact, so a registered target is not resolvable by
|
|
21
|
+
// `queue_exploration` until a separate `promote` flips it.
|
|
22
|
+
const mission = program.command("mission").description("manage exploration mission targets and drain the mission queue");
|
|
23
|
+
const missionTarget = mission.command("target");
|
|
24
|
+
const missionTargetAdd = missionTarget
|
|
25
|
+
.command("add <id>")
|
|
26
|
+
.description("register an exploration mission target (UNPROMOTED — not usable by queue_exploration until promoted)")
|
|
27
|
+
.option("--name <name>", "human-readable target name")
|
|
28
|
+
.option("--authorized-origin <origin>", "the target's app origin (a bare http(s) origin); --base-url must be on it")
|
|
29
|
+
.option("--api-origin <origin>", "a further origin the app talks to, e.g. its API on another origin (repeatable) — the queued-mission analogue of a second `explore --allow`", (v, prev) => [...prev, v], [])
|
|
30
|
+
.option("--base-url <url>", "the base URL a mission starts navigation from")
|
|
31
|
+
.option("--description <text>", "optional human-readable description");
|
|
32
|
+
withMissionTargetAuthFlags(missionTargetAdd)
|
|
33
|
+
.option("--dir <path>", "mission targets directory (default: ~/.jevitate/missions/targets)")
|
|
34
|
+
.option("--json", "emit a JSON envelope")
|
|
35
|
+
.action(async function (id) {
|
|
36
|
+
const { name, authorizedOrigin, apiOrigin, baseUrl, description, dir, json, ...authFlags } = this.opts();
|
|
37
|
+
// Validate in-action + fail envelope (not commander's hard-exiting
|
|
38
|
+
// `.requiredOption`), matching this CLI's convention.
|
|
39
|
+
if (!name || !authorizedOrigin || !baseUrl) {
|
|
40
|
+
emitJson(program, fail("E_MISSION_TARGET_ARGS", "--name, --authorized-origin and --base-url are all required"));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const ctx = missionTargetContext(resolveMissionTargetsDir(deps, dir));
|
|
45
|
+
const auth = missionTargetAuth(authFlags);
|
|
46
|
+
const target = await addMissionTarget(ctx, {
|
|
47
|
+
id,
|
|
48
|
+
name,
|
|
49
|
+
authorizedOrigin,
|
|
50
|
+
apiOrigins: apiOrigin,
|
|
51
|
+
baseUrl,
|
|
52
|
+
...(description === undefined ? {} : { description }),
|
|
53
|
+
...(auth === undefined ? {} : { auth }),
|
|
54
|
+
});
|
|
55
|
+
const envelope = ok(target);
|
|
56
|
+
if (json) {
|
|
57
|
+
emitJson(program, envelope);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
program.configureOutput().writeOut?.(`registered mission target '${target.id}' (unpromoted — run 'jevitate mission target promote ${target.id}' to make it resolvable)\n`);
|
|
61
|
+
process.exitCode = 0;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
emitJson(program, fail("E_MISSION_TARGET_ADD", String(err instanceof Error ? err.message : err)));
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
withMissionTargetAuthFlags(missionTarget
|
|
69
|
+
.command("update <id>")
|
|
70
|
+
.description("set a registered target's operator-declared auth for queued missions (#175); keeps its promotion state")
|
|
71
|
+
.option("--clear-auth", "drop the target's storage state, save-back and secret fields first"))
|
|
72
|
+
.option("--dir <path>", "mission targets directory (default: ~/.jevitate/missions/targets)")
|
|
73
|
+
.option("--json", "emit a JSON envelope")
|
|
74
|
+
.action(async function (id) {
|
|
75
|
+
const { dir, json, clearAuth, ...authFlags } = this.opts();
|
|
76
|
+
const auth = missionTargetAuth(authFlags);
|
|
77
|
+
if (auth === undefined && clearAuth !== true) {
|
|
78
|
+
emitJson(program, fail("E_MISSION_TARGET_ARGS", "nothing to update: pass --storage-state, --save-storage-state, --secret-field or --clear-auth"));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const ctx = missionTargetContext(resolveMissionTargetsDir(deps, dir));
|
|
83
|
+
const target = await updateMissionTargetAuth(ctx, id, { ...(auth ?? {}), ...(clearAuth === true ? { clear: true } : {}) });
|
|
84
|
+
if (json) {
|
|
85
|
+
emitJson(program, ok(target));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
program.configureOutput().writeOut?.(`updated mission target '${target.id}'\n`);
|
|
89
|
+
process.exitCode = 0;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
if (err instanceof UnknownMissionTargetError) {
|
|
94
|
+
emitJson(program, fail("E_UNKNOWN_MISSION_TARGET", err.message));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
emitJson(program, fail("E_MISSION_TARGET_UPDATE", String(err instanceof Error ? err.message : err)));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
missionTarget
|
|
101
|
+
.command("list")
|
|
102
|
+
.description("list ALL mission targets (promoted and unpromoted) — a local/dev-facing listing")
|
|
103
|
+
.option("--dir <path>", "mission targets directory (default: ~/.jevitate/missions/targets)")
|
|
104
|
+
.option("--json", "emit a JSON envelope")
|
|
105
|
+
.action(async function () {
|
|
106
|
+
const { dir, json } = this.opts();
|
|
107
|
+
try {
|
|
108
|
+
const ctx = missionTargetContext(resolveMissionTargetsDir(deps, dir));
|
|
109
|
+
const targets = await listMissionTargets(ctx);
|
|
110
|
+
const envelope = ok(targets);
|
|
111
|
+
if (json) {
|
|
112
|
+
emitJson(program, envelope);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const out = program.configureOutput().writeOut;
|
|
116
|
+
for (const t of targets) {
|
|
117
|
+
const origins = [t.authorizedOrigin, ...(t.apiOrigins ?? [])].join(",");
|
|
118
|
+
out?.(`${t.id}\t${t.name}\t${origins}${t.promoted ? "" : " (unpromoted)"}\n`);
|
|
119
|
+
}
|
|
120
|
+
process.exitCode = 0;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
emitJson(program, fail("E_MISSION_TARGET_LIST", String(err instanceof Error ? err.message : err)));
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
missionTarget
|
|
128
|
+
.command("promote <id>")
|
|
129
|
+
.description("promote a registered target so queue_exploration can resolve it")
|
|
130
|
+
.option("--dir <path>", "mission targets directory (default: ~/.jevitate/missions/targets)")
|
|
131
|
+
.option("--json", "emit a JSON envelope")
|
|
132
|
+
.action(async function (id) {
|
|
133
|
+
const { dir, json } = this.opts();
|
|
134
|
+
try {
|
|
135
|
+
const ctx = missionTargetContext(resolveMissionTargetsDir(deps, dir));
|
|
136
|
+
const target = await promoteMissionTarget(ctx, id);
|
|
137
|
+
const envelope = ok(target);
|
|
138
|
+
if (json) {
|
|
139
|
+
emitJson(program, envelope);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
program.configureOutput().writeOut?.(`promoted mission target '${target.id}'\n`);
|
|
143
|
+
process.exitCode = 0;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
if (err instanceof UnknownMissionTargetError) {
|
|
148
|
+
emitJson(program, fail("E_UNKNOWN_MISSION_TARGET", err.message));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
emitJson(program, fail("E_MISSION_TARGET_PROMOTE", String(err instanceof Error ? err.message : err)));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
// `mission run` (#117) — drains the queue `queue_exploration` (MCP) fills: each queued mission runs
|
|
156
|
+
// through its strategy's CLI runner, its typed result lands in the recordings dir `jevitate mcp`
|
|
157
|
+
// reads, and its queue record moves queued → running → done (resultId) | failed, so
|
|
158
|
+
// `get_mission_result {id: missionId}` resolves it. `--once` (default) drains what is queued now
|
|
159
|
+
// and exits; `--watch` keeps polling.
|
|
160
|
+
withBrowserLaunchFlags(mission
|
|
161
|
+
.command("run")
|
|
162
|
+
.description("run queued missions (queue_exploration) through their strategy's runner; get_mission_result {id: missionId} then reads the result"))
|
|
163
|
+
.option("--once", "drain the missions queued now, then exit (default)")
|
|
164
|
+
.option("--watch", "keep draining: poll the queue every --interval ms until interrupted")
|
|
165
|
+
.option("--interval <ms>", "--watch poll interval in ms (default 5000)", positiveIntArg, 5000)
|
|
166
|
+
.option("--dir <path>", "mission queue directory (default: ~/.jevitate/missions/queue)")
|
|
167
|
+
.option("--targets-dir <path>", "mission targets directory (default: ~/.jevitate/missions/targets)")
|
|
168
|
+
.option("--out <dir>", "where results are written (default: .jevitate/logs/<date> in the project, else ~/.jevitate/logs/<date> — where `jevitate mcp` reads them)")
|
|
169
|
+
.option("--real", "use live Jev + OpenRouter gateways for model-driven missions (requires keys)", false)
|
|
170
|
+
.option("--fake-ai", "use deterministic fake gateways (pipeline smoke only)", false)
|
|
171
|
+
.option("--json", "emit a JSON envelope")
|
|
172
|
+
.action(async function () {
|
|
173
|
+
const o = this.opts();
|
|
174
|
+
if (o.once && o.watch) {
|
|
175
|
+
emitJson(program, fail("E_MISSION_RUN_ARGS", "--once and --watch are mutually exclusive"));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const intervalMs = Number(o.interval);
|
|
179
|
+
if (!Number.isInteger(intervalMs) || intervalMs <= 0) {
|
|
180
|
+
emitJson(program, fail("E_MISSION_RUN_ARGS", `--interval must be a positive integer (got ${JSON.stringify(o.interval)})`));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// Model-driven missions need a gateway selection; without one they stay queued (reported as
|
|
184
|
+
// skipped), never run against a silently-substituted fake. Feature missions are model-free.
|
|
185
|
+
let gatewayRefusal;
|
|
186
|
+
try {
|
|
187
|
+
await buildExploreGateways(deps, { real: o.real ?? false, fakeAi: o.fakeAi ?? false });
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
if (!(err instanceof MissingCredentialError || err instanceof GatewaySelectionError))
|
|
191
|
+
throw err;
|
|
192
|
+
gatewayRefusal = err.message;
|
|
193
|
+
}
|
|
194
|
+
const queue = new FsMissionQueueStore(o.dir ?? deps.missions?.queueDir ?? resolveDataDir(["missions", "queue"]));
|
|
195
|
+
const targets = missionTargetContext(resolveMissionTargetsDir(deps, o.targetsDir)).registry;
|
|
196
|
+
// #142 follow-up: ~/.jevitate/targets.json's per-origin logSources/logDefect/allowLogCmd — a
|
|
197
|
+
// queued mission never carries its own (never an MCP argument); this is the operator's only
|
|
198
|
+
// way to declare one for a mission drained here.
|
|
199
|
+
const targetConfigs = loadTargetsFile(deps.explore?.targetsConfigPath);
|
|
200
|
+
const execute = deps.missions?.execute ??
|
|
201
|
+
realQueuedMissionExecutor({
|
|
202
|
+
outDir: o.out ?? logsDirFor(),
|
|
203
|
+
gateways: () => buildExploreGateways(deps, { real: o.real ?? false, fakeAi: o.fakeAi ?? false }),
|
|
204
|
+
...(deps.explore?.browserPortFactory === undefined ? {} : { browserPortFactory: deps.explore.browserPortFactory }),
|
|
205
|
+
...(browserLaunchFromFlags(o) === undefined ? {} : { browser: browserLaunchFromFlags(o) }),
|
|
206
|
+
targets: targetConfigs,
|
|
207
|
+
});
|
|
208
|
+
const drainOnce = () => drainMissionQueue({
|
|
209
|
+
queue,
|
|
210
|
+
targets,
|
|
211
|
+
execute,
|
|
212
|
+
accepts: (m) => (gatewayRefusal !== undefined && needsModel(m) ? `needs a model gateway: ${gatewayRefusal}` : true),
|
|
213
|
+
});
|
|
214
|
+
const emit = (report) => {
|
|
215
|
+
const data = withEngine(report);
|
|
216
|
+
if (o.json) {
|
|
217
|
+
emitJson(program, ok(data));
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
program.configureOutput().writeOut?.(`${JSON.stringify(data)}\n`);
|
|
221
|
+
}
|
|
222
|
+
// Every claimed mission ran (whatever its own outcome); 2 only when one could not run at all —
|
|
223
|
+
// it proves nothing, so never 1 (defects) — exit-codes.ts.
|
|
224
|
+
process.exitCode = report.ran.some((m) => m.status === "failed") ? EXIT_CODES.inconclusive : EXIT_CODES.ok;
|
|
225
|
+
};
|
|
226
|
+
try {
|
|
227
|
+
if (!o.watch) {
|
|
228
|
+
emit(await drainOnce());
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// --watch: one envelope per pass that ran something; interrupted by SIGINT/SIGTERM (the kill
|
|
232
|
+
// switch still writes a killed mission's partial result).
|
|
233
|
+
for (;;) {
|
|
234
|
+
const report = await drainOnce();
|
|
235
|
+
if (report.ran.length > 0)
|
|
236
|
+
emit(report);
|
|
237
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
emitJson(program, fail("E_MISSION_RUN", String(err instanceof Error ? err.message : err)));
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
// #254: `mission queue` / `mission result` — MCP queue_exploration / get_mission_result from the CLI.
|
|
245
|
+
registerMissionQueueCommands(program, mission, deps);
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=mission-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-cli.js","sourceRoot":"","sources":["../src/mission-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type MissionOutcome } from "@jevitate/domain";
|
|
2
|
+
import type { GoalBasedOutcome } from "@jevitate/explore";
|
|
3
|
+
/**
|
|
4
|
+
* Exit codes for mission runs (documented in the CLI README / `explore --help`):
|
|
5
|
+
*
|
|
6
|
+
* - `0` clean (goal: succeeded)
|
|
7
|
+
* - `1` defects found (goal: the success assertion did not hold — the existing convention)
|
|
8
|
+
* - `2` inconclusive or crashed — the run itself broke, so it proves nothing
|
|
9
|
+
* - `3` hang — the app under test hung and it reproduced on replay
|
|
10
|
+
* - `4` intermittent — a hang that did not reproduce on every replay
|
|
11
|
+
*
|
|
12
|
+
* Codes 0 and 1 keep their pre-existing meaning; 2–4 are new and never overlap a finding with a
|
|
13
|
+
* broken run.
|
|
14
|
+
*/
|
|
15
|
+
export declare function missionExitCode(outcome: MissionOutcome): number;
|
|
16
|
+
/**
|
|
17
|
+
* The goal mission's own outcome → exit code. The mapping itself lives in ONE place —
|
|
18
|
+
* `outcomeExitCode`/`GOAL_OUTCOME_FOLD` in `@jevitate/domain` (`mission-outcome.ts`) — so the CLI,
|
|
19
|
+
* MCP and the result schema can never disagree: `succeeded` 0 · `failed`/`exhausted`/`blocked`/
|
|
20
|
+
* `defects-found` 1 · `inconclusive`/`crashed` 2 · `hang` 3 · `intermittent` 4.
|
|
21
|
+
*/
|
|
22
|
+
export declare function goalExitCode(outcome: GoalBasedOutcome): number;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MISSION_EXIT_CODES, outcomeExitCode } from "@jevitate/domain";
|
|
2
|
+
/**
|
|
3
|
+
* Exit codes for mission runs (documented in the CLI README / `explore --help`):
|
|
4
|
+
*
|
|
5
|
+
* - `0` clean (goal: succeeded)
|
|
6
|
+
* - `1` defects found (goal: the success assertion did not hold — the existing convention)
|
|
7
|
+
* - `2` inconclusive or crashed — the run itself broke, so it proves nothing
|
|
8
|
+
* - `3` hang — the app under test hung and it reproduced on replay
|
|
9
|
+
* - `4` intermittent — a hang that did not reproduce on every replay
|
|
10
|
+
*
|
|
11
|
+
* Codes 0 and 1 keep their pre-existing meaning; 2–4 are new and never overlap a finding with a
|
|
12
|
+
* broken run.
|
|
13
|
+
*/
|
|
14
|
+
export function missionExitCode(outcome) {
|
|
15
|
+
return MISSION_EXIT_CODES[outcome];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The goal mission's own outcome → exit code. The mapping itself lives in ONE place —
|
|
19
|
+
* `outcomeExitCode`/`GOAL_OUTCOME_FOLD` in `@jevitate/domain` (`mission-outcome.ts`) — so the CLI,
|
|
20
|
+
* MCP and the result schema can never disagree: `succeeded` 0 · `failed`/`exhausted`/`blocked`/
|
|
21
|
+
* `defects-found` 1 · `inconclusive`/`crashed` 2 · `hang` 3 · `intermittent` 4.
|
|
22
|
+
*/
|
|
23
|
+
export function goalExitCode(outcome) {
|
|
24
|
+
return outcomeExitCode(outcome);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=mission-exit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-exit.js","sourceRoot":"","sources":["../src/mission-exit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAuB,MAAM,kBAAkB,CAAC;AAG5F;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,OAAuB;IACrD,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAAyB;IACpD,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { type AuthSources, type RequestAuth } from "./fixture-auth.js";
|
|
2
|
+
/**
|
|
3
|
+
* Mission fixtures (#140 declarative app setup, #144 setup/restore around missions and replays) —
|
|
4
|
+
* ONE capability: put the app into a known state before a mission, bind what that setup created
|
|
5
|
+
* (an item id, an invite URL) into the run as `${setup.<name>}`, restore the state afterwards, and
|
|
6
|
+
* do the same around EVERY replay (hang reproduction, `verify-fix`, regression capture) so a replay
|
|
7
|
+
* starts from the state the finding was made in, not whatever earlier runs left behind.
|
|
8
|
+
*
|
|
9
|
+
* Two step kinds, both operator-declared:
|
|
10
|
+
*
|
|
11
|
+
* - HTTP steps, from a fixtures JSON file (`--fixtures`, or `fixtures` in `~/.jevitate/targets.json`).
|
|
12
|
+
* Only to an `--allow`-listed http(s) origin; authenticated like the page is (`fixture-auth.ts`:
|
|
13
|
+
* a storageState localStorage bearer, its cookies, or a `--secret-field` binding). A file can
|
|
14
|
+
* never declare a command. A step's json/body/headers may use `${secretField.<VAR>}` (#166) —
|
|
15
|
+
* the run's `--secret-field` value bound to env `<VAR>`, so a login step can authenticate; it
|
|
16
|
+
* is put on the wire only (never in a URL, the step log, the result or the Recording).
|
|
17
|
+
* - Shell hooks, from the operator's own CLI flags only (`--before <cmd>` / `--after <cmd>`, and
|
|
18
|
+
* only with `--allow-shell-hooks`). Never model-chosen, never read from a file a run wrote. Exit
|
|
19
|
+
* codes are recorded; stdout is never persisted (it may carry `{vars, secret}`), stderr only
|
|
20
|
+
* redacted and clipped.
|
|
21
|
+
*
|
|
22
|
+
* Fail closed: a setup that fails, times out, or leaves a `${setup.x}` reference unresolved ends
|
|
23
|
+
* the run `inconclusive` (`fixture setup failed: …`, a configuration error) — a mission never runs
|
|
24
|
+
* on unknown state. Secret outputs join the run's redaction set and may only be used inside the
|
|
25
|
+
* fixture's own requests, never in text a model sees.
|
|
26
|
+
*/
|
|
27
|
+
export declare const SETUP_REF: RegExp;
|
|
28
|
+
/**
|
|
29
|
+
* `${secretField.<VAR>}` (#166): a run's `--secret-field` value (bound to env `<VAR>`), allowed only
|
|
30
|
+
* in a step's `json`/`body`/`headers` — so a login step can authenticate. Substituted into the
|
|
31
|
+
* outgoing request only: never into a URL, the step log, the result or the Recording.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SECRET_FIELD_REF: RegExp;
|
|
34
|
+
export interface FixtureHttpStep {
|
|
35
|
+
readonly name?: string;
|
|
36
|
+
readonly method: string;
|
|
37
|
+
/** Absolute, or relative to the mission's start URL. May reference `${setup.<name>}` (not in its origin). */
|
|
38
|
+
readonly url: string;
|
|
39
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
40
|
+
readonly json?: unknown;
|
|
41
|
+
readonly body?: string;
|
|
42
|
+
readonly auth?: RequestAuth;
|
|
43
|
+
/** Accepted statuses. Default: any 2xx. */
|
|
44
|
+
readonly expectStatus?: readonly number[];
|
|
45
|
+
/** Output name → `$.json.path` (JSONPath-lite) or `header:<name>`. */
|
|
46
|
+
readonly outputs?: Readonly<Record<string, string>>;
|
|
47
|
+
/** Output names that are credentials: redacted everywhere, never substituted into model-visible text. */
|
|
48
|
+
readonly secretOutputs?: readonly string[];
|
|
49
|
+
readonly timeoutMs?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface FixtureSpec {
|
|
52
|
+
readonly name?: string;
|
|
53
|
+
readonly setup: readonly FixtureHttpStep[];
|
|
54
|
+
readonly restore: readonly FixtureHttpStep[];
|
|
55
|
+
}
|
|
56
|
+
/** The operator's own shell hooks (CLI flags; never from a file or a model). */
|
|
57
|
+
export interface ShellHooks {
|
|
58
|
+
readonly before?: string;
|
|
59
|
+
readonly after?: string;
|
|
60
|
+
readonly timeoutMs?: number;
|
|
61
|
+
}
|
|
62
|
+
export declare class FixtureSpecError extends Error {
|
|
63
|
+
readonly code: "E_FIXTURE_SPEC";
|
|
64
|
+
constructor(message: string);
|
|
65
|
+
}
|
|
66
|
+
/** Setup failed: the run must end `inconclusive` (a configuration error) without touching the app. */
|
|
67
|
+
export declare class FixtureSetupError extends Error {
|
|
68
|
+
readonly code: "E_FIXTURE_SETUP";
|
|
69
|
+
constructor(detail: string);
|
|
70
|
+
}
|
|
71
|
+
export interface FixtureBounds {
|
|
72
|
+
readonly allowlist: readonly string[];
|
|
73
|
+
/** What a relative step URL resolves against (the mission's start URL). */
|
|
74
|
+
readonly baseUrl: string;
|
|
75
|
+
}
|
|
76
|
+
/** Every `${setup.x}` name referenced in `text`. */
|
|
77
|
+
export declare function referencedNames(text: string): string[];
|
|
78
|
+
/**
|
|
79
|
+
* Every `--secret-field` env variable a spec needs (#166): the `auth: {from: "secretField"}` names
|
|
80
|
+
* and every `${secretField.<VAR>}` in a step's json/body/headers.
|
|
81
|
+
*/
|
|
82
|
+
export declare function secretFieldNames(spec: FixtureSpec | undefined): string[];
|
|
83
|
+
/**
|
|
84
|
+
* Validates a fixtures spec (fail closed, before any browser or request). `openRefs` allows
|
|
85
|
+
* references a `--before` hook may bind at run time (unknown statically; still checked when used).
|
|
86
|
+
*/
|
|
87
|
+
export declare function parseFixtureSpec(raw: unknown, bounds: FixtureBounds, opts?: {
|
|
88
|
+
openRefs?: boolean;
|
|
89
|
+
}): FixtureSpec;
|
|
90
|
+
/** Reads and validates a fixtures JSON file. */
|
|
91
|
+
export declare function loadFixtureFile(path: string, bounds: FixtureBounds, opts?: {
|
|
92
|
+
openRefs?: boolean;
|
|
93
|
+
}): FixtureSpec;
|
|
94
|
+
/** `$`, `.key`, `[0]`, `["key"]` — the JSONPath-lite output selectors. */
|
|
95
|
+
type PathSeg = string | number;
|
|
96
|
+
export declare function parseJsonPath(path: string, where?: string): PathSeg[];
|
|
97
|
+
/** The scalar at `path` in `doc`, as a string; `undefined` when absent or not a scalar. */
|
|
98
|
+
export declare function selectJsonPath(doc: unknown, path: string): string | undefined;
|
|
99
|
+
/** A setup's bound outputs: values, and which of them are secrets. */
|
|
100
|
+
export interface FixtureBindings {
|
|
101
|
+
readonly values: Readonly<Record<string, string>>;
|
|
102
|
+
readonly secretNames: ReadonlySet<string>;
|
|
103
|
+
}
|
|
104
|
+
export declare class UnboundSetupRefError extends Error {
|
|
105
|
+
readonly code: "E_FIXTURE_REF";
|
|
106
|
+
constructor(message: string);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Substitutes every `${setup.x}` in `text`. An unknown name throws (never a hollow run); a SECRET
|
|
110
|
+
* output throws unless `allowSecret` — goal/URL/success text is model- or artifact-visible.
|
|
111
|
+
*/
|
|
112
|
+
export declare function substituteSetupRefs(text: string, b: FixtureBindings, opts?: {
|
|
113
|
+
allowSecret?: boolean;
|
|
114
|
+
where?: string;
|
|
115
|
+
}): string;
|
|
116
|
+
/** One step of setup/restore, as recorded in the result (redacted; never headers or bodies). */
|
|
117
|
+
export interface FixtureStepLog {
|
|
118
|
+
readonly phase: "setup" | "restore";
|
|
119
|
+
readonly kind: "http" | "shell";
|
|
120
|
+
readonly name: string;
|
|
121
|
+
readonly ok: boolean;
|
|
122
|
+
readonly durationMs: number;
|
|
123
|
+
readonly method?: string;
|
|
124
|
+
readonly url?: string;
|
|
125
|
+
readonly status?: number;
|
|
126
|
+
readonly exitCode?: number | null;
|
|
127
|
+
readonly detail?: string;
|
|
128
|
+
/** A shell hook's stderr, redacted and clipped (stdout is never persisted). */
|
|
129
|
+
readonly stderr?: string;
|
|
130
|
+
}
|
|
131
|
+
/** What the result/Recording carries: identity + non-secret outputs; secrets by NAME only. */
|
|
132
|
+
export interface FixtureRecord {
|
|
133
|
+
/** Hash of the spec (+ hook commands) and the bound outputs (secret outputs by name only). */
|
|
134
|
+
readonly identity: string;
|
|
135
|
+
/** Hash of the spec (+ hook commands) alone: equal across runs of the same fixture. */
|
|
136
|
+
readonly specHash: string;
|
|
137
|
+
readonly outputs: Readonly<Record<string, string>>;
|
|
138
|
+
readonly secretOutputs: readonly string[];
|
|
139
|
+
/** Setup/restore cycles run (1 for the mission + one per replay). */
|
|
140
|
+
readonly cycles: number;
|
|
141
|
+
readonly log: readonly FixtureStepLog[];
|
|
142
|
+
}
|
|
143
|
+
/** What a mission result persists so `verify-fix`/regression capture restore the SAME state. */
|
|
144
|
+
export interface PersistedFixtures {
|
|
145
|
+
readonly identity: string;
|
|
146
|
+
readonly specHash: string;
|
|
147
|
+
readonly spec?: FixtureSpec;
|
|
148
|
+
/** sha256 of each operator hook command — the commands themselves are re-supplied, never replayed from a file. */
|
|
149
|
+
readonly hooks?: {
|
|
150
|
+
readonly before?: string;
|
|
151
|
+
readonly after?: string;
|
|
152
|
+
};
|
|
153
|
+
readonly outputs: Readonly<Record<string, string>>;
|
|
154
|
+
readonly secretOutputs: readonly string[];
|
|
155
|
+
}
|
|
156
|
+
export declare function hookHash(cmd: string): string;
|
|
157
|
+
export interface FixtureRunOptions extends FixtureBounds {
|
|
158
|
+
readonly spec?: FixtureSpec;
|
|
159
|
+
readonly hooks?: ShellHooks;
|
|
160
|
+
/** Required to run `hooks` at all (CLI `--allow-shell-hooks`). */
|
|
161
|
+
readonly allowShellHooks?: boolean;
|
|
162
|
+
readonly auth: AuthSources;
|
|
163
|
+
/** The run's own secrets: redacted from everything a fixture logs. */
|
|
164
|
+
readonly secrets?: readonly string[];
|
|
165
|
+
/** Testing seam. */
|
|
166
|
+
readonly fetchImpl?: typeof fetch;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* One mission's fixture lifecycle. `setup()` before the mission, `restore()` after it (every exit
|
|
170
|
+
* path), and `reset()` (restore the active state, then set up again) before each replay.
|
|
171
|
+
*/
|
|
172
|
+
export declare class MissionFixtures {
|
|
173
|
+
#private;
|
|
174
|
+
constructor(opts: FixtureRunOptions);
|
|
175
|
+
hookHashes(): PersistedFixtures["hooks"] | undefined;
|
|
176
|
+
get specHash(): string;
|
|
177
|
+
/** The output names the spec declares; `null` when a `--before` hook may bind more at run time. */
|
|
178
|
+
declaredOutputs(): Set<string> | null;
|
|
179
|
+
/** The output names the spec declares secret. */
|
|
180
|
+
declaredSecretOutputs(): Set<string>;
|
|
181
|
+
bindings(): FixtureBindings;
|
|
182
|
+
/** Non-secret outputs (what a replay's recorded values are rebound to). */
|
|
183
|
+
publicOutputs(): Record<string, string>;
|
|
184
|
+
/** Secret output values: the caller adds them to the run's redaction set. */
|
|
185
|
+
secrets(): string[];
|
|
186
|
+
identity(): string;
|
|
187
|
+
record(): FixtureRecord;
|
|
188
|
+
persisted(): PersistedFixtures;
|
|
189
|
+
/** Sets up the fixture. Throws `FixtureSetupError`; the caller still calls `restore()`. */
|
|
190
|
+
setup(): Promise<void>;
|
|
191
|
+
/** Restores the state the last `setup()` created. Never throws: every step is logged. */
|
|
192
|
+
restore(): Promise<void>;
|
|
193
|
+
/** Before a replay: restore whatever is active, then set up afresh. Throws `FixtureSetupError`. */
|
|
194
|
+
reset(): Promise<void>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* A replay session re-uses the Recording of the ORIGINAL run, whose navigations carry the values
|
|
198
|
+
* that run's setup bound (e.g. `/items/<old id>`). After a fresh setup, the same navigation must go
|
|
199
|
+
* to the NEW value: this rewrites each recorded value to its current one in every `page.goto` of the
|
|
200
|
+
* replay's own page (non-secret outputs of 4+ characters only — shorter ones are too ambiguous to
|
|
201
|
+
* rewrite blindly).
|
|
202
|
+
*/
|
|
203
|
+
export declare function rebindReplayNavigation(page: {
|
|
204
|
+
goto: (url: string, ...rest: never[]) => Promise<unknown>;
|
|
205
|
+
}, recorded: Readonly<Record<string, string>>, current: Readonly<Record<string, string>>): void;
|
|
206
|
+
/** The fixture identity carried on a Recording (non-secret outputs only). */
|
|
207
|
+
export declare function recordingFixture(r: FixtureRecord): {
|
|
208
|
+
identity: string;
|
|
209
|
+
specHash: string;
|
|
210
|
+
outputs: Record<string, string>;
|
|
211
|
+
};
|
|
212
|
+
/** What a mission result carries: the record (log, identity, outputs) plus what a replay needs to restore the same state. */
|
|
213
|
+
export type MissionFixtureResult = FixtureRecord & Pick<PersistedFixtures, "spec" | "hooks">;
|
|
214
|
+
/**
|
|
215
|
+
* Wraps a replay-session opener (hang reproduction, `verify-fix`, regression capture) so EVERY
|
|
216
|
+
* replay starts from the fixture's state: restore whatever is active, set up afresh (a failure
|
|
217
|
+
* throws, so the replay is "could not open a session" — inconclusive, never evidence), then rebind
|
|
218
|
+
* the Recording's values (`recorded`, from the run the Recording came from) to the new outputs.
|
|
219
|
+
*/
|
|
220
|
+
export declare function fixtureReplayOpener<S extends {
|
|
221
|
+
readonly page: {
|
|
222
|
+
goto: (url: string, ...rest: never[]) => Promise<unknown>;
|
|
223
|
+
};
|
|
224
|
+
}>(open: () => Promise<S>, fx: MissionFixtures, recorded: Readonly<Record<string, string>>): () => Promise<S>;
|
|
225
|
+
export {};
|