@jevitate/cli 0.12.0 → 0.13.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/dist/bin.js +48283 -47589
- package/dist/build-info.generated.js +2 -2
- package/dist/explore-cli/adversarial-strategy.d.ts +3 -0
- package/dist/explore-cli/adversarial-strategy.js +99 -0
- package/dist/explore-cli/adversarial-strategy.js.map +1 -0
- package/dist/explore-cli/coverage-strategy.d.ts +3 -0
- package/dist/explore-cli/coverage-strategy.js +95 -0
- package/dist/explore-cli/coverage-strategy.js.map +1 -0
- package/dist/explore-cli/feature-strategy.d.ts +3 -0
- package/dist/explore-cli/feature-strategy.js +59 -0
- package/dist/explore-cli/feature-strategy.js.map +1 -0
- package/dist/explore-cli/goal-strategy.d.ts +3 -0
- package/dist/explore-cli/goal-strategy.js +184 -0
- package/dist/explore-cli/goal-strategy.js.map +1 -0
- package/dist/explore-cli/options.d.ts +3 -0
- package/dist/explore-cli/options.js +155 -0
- package/dist/explore-cli/options.js.map +1 -0
- package/dist/explore-cli/run.d.ts +7 -0
- package/dist/explore-cli/run.js +682 -0
- package/dist/explore-cli/run.js.map +1 -0
- package/dist/explore-cli/shared.d.ts +158 -0
- package/dist/explore-cli/shared.js +20 -0
- package/dist/explore-cli/shared.js.map +1 -0
- package/dist/explore-cli/usability-strategy.d.ts +3 -0
- package/dist/explore-cli/usability-strategy.js +136 -0
- package/dist/explore-cli/usability-strategy.js.map +1 -0
- package/dist/explore-cli.d.ts +2 -2
- package/dist/explore-cli.js +2 -1347
- package/dist/explore-cli.js.map +1 -1
- package/dist/journey-anchor-api.d.ts +10 -9
- package/dist/journey-anchor-api.js +12 -22
- package/dist/journey-anchor-api.js.map +1 -1
- package/dist/journey-anchor-cli.d.ts +1 -1
- package/dist/journey-anchor-cli.js +10 -6
- package/dist/journey-anchor-cli.js.map +1 -1
- package/dist/journey-cli/anchors.d.ts +4 -0
- package/dist/journey-cli/anchors.js +48 -0
- package/dist/journey-cli/anchors.js.map +1 -0
- package/dist/journey-cli/find.d.ts +4 -0
- package/dist/journey-cli/find.js +44 -0
- package/dist/journey-cli/find.js.map +1 -0
- package/dist/journey-cli/lint.d.ts +4 -0
- package/dist/journey-cli/lint.js +76 -0
- package/dist/journey-cli/lint.js.map +1 -0
- package/dist/journey-cli/list.d.ts +4 -0
- package/dist/journey-cli/list.js +48 -0
- package/dist/journey-cli/list.js.map +1 -0
- package/dist/journey-cli/migrate.d.ts +4 -0
- package/dist/journey-cli/migrate.js +101 -0
- package/dist/journey-cli/migrate.js.map +1 -0
- package/dist/journey-cli/promote.d.ts +4 -0
- package/dist/journey-cli/promote.js +181 -0
- package/dist/journey-cli/promote.js.map +1 -0
- package/dist/journey-cli/publish.d.ts +4 -0
- package/dist/journey-cli/publish.js +70 -0
- package/dist/journey-cli/publish.js.map +1 -0
- package/dist/journey-cli/review.d.ts +4 -0
- package/dist/journey-cli/review.js +103 -0
- package/dist/journey-cli/review.js.map +1 -0
- package/dist/journey-cli/run.d.ts +4 -0
- package/dist/journey-cli/run.js +244 -0
- package/dist/journey-cli/run.js.map +1 -0
- package/dist/journey-cli/shared.d.ts +9 -0
- package/dist/journey-cli/shared.js +12 -0
- package/dist/journey-cli/shared.js.map +1 -0
- package/dist/journey-cli/verify.d.ts +4 -0
- package/dist/journey-cli/verify.js +125 -0
- package/dist/journey-cli/verify.js.map +1 -0
- package/dist/journey-cli.d.ts +3 -2
- package/dist/journey-cli.js +21 -949
- package/dist/journey-cli.js.map +1 -1
- package/dist/journey-review/render.d.ts +43 -0
- package/dist/journey-review/render.js +461 -0
- package/dist/journey-review/render.js.map +1 -0
- package/dist/journey-review.d.ts +1 -4
- package/dist/journey-review.js +16 -391
- package/dist/journey-review.js.map +1 -1
- package/dist/log-sources.js +17 -1
- package/dist/log-sources.js.map +1 -1
- package/dist/mcp-api.js +16 -821
- package/dist/mcp-api.js.map +1 -1
- package/dist/mcp-cli-tools.js +12 -4
- package/dist/mcp-cli-tools.js.map +1 -1
- package/dist/mcp-tools/cli.d.ts +3 -0
- package/dist/mcp-tools/cli.js +20 -0
- package/dist/mcp-tools/cli.js.map +1 -0
- package/dist/mcp-tools/explore.d.ts +3 -0
- package/dist/mcp-tools/explore.js +141 -0
- package/dist/mcp-tools/explore.js.map +1 -0
- package/dist/mcp-tools/findings.d.ts +3 -0
- package/dist/mcp-tools/findings.js +277 -0
- package/dist/mcp-tools/findings.js.map +1 -0
- package/dist/mcp-tools/inbox.d.ts +3 -0
- package/dist/mcp-tools/inbox.js +106 -0
- package/dist/mcp-tools/inbox.js.map +1 -0
- package/dist/mcp-tools/journey.d.ts +3 -0
- package/dist/mcp-tools/journey.js +260 -0
- package/dist/mcp-tools/journey.js.map +1 -0
- package/dist/mcp-tools/shared.d.ts +39 -0
- package/dist/mcp-tools/shared.js +69 -0
- package/dist/mcp-tools/shared.js.map +1 -0
- package/dist/sweep-api.d.ts +9 -0
- package/dist/sweep-api.js +70 -2
- package/dist/sweep-api.js.map +1 -1
- package/dist/sweep-cli.d.ts +2 -0
- package/dist/sweep-cli.js +22 -5
- package/dist/sweep-cli.js.map +1 -1
- package/dist/ux-usability/analysis.d.ts +14 -0
- package/dist/ux-usability/analysis.js +106 -0
- package/dist/ux-usability/analysis.js.map +1 -0
- package/dist/ux-usability/done-adjudication.d.ts +15 -0
- package/dist/ux-usability/done-adjudication.js +56 -0
- package/dist/ux-usability/done-adjudication.js.map +1 -0
- package/dist/ux-usability/hang.d.ts +5 -0
- package/dist/ux-usability/hang.js +41 -0
- package/dist/ux-usability/hang.js.map +1 -0
- package/dist/ux-usability/loop.d.ts +15 -0
- package/dist/ux-usability/loop.js +104 -0
- package/dist/ux-usability/loop.js.map +1 -0
- package/dist/ux-usability/observe.d.ts +7 -0
- package/dist/ux-usability/observe.js +89 -0
- package/dist/ux-usability/observe.js.map +1 -0
- package/dist/ux-usability/result.d.ts +11 -0
- package/dist/ux-usability/result.js +113 -0
- package/dist/ux-usability/result.js.map +1 -0
- package/dist/ux-usability/setup.d.ts +75 -0
- package/dist/ux-usability/setup.js +203 -0
- package/dist/ux-usability/setup.js.map +1 -0
- package/dist/ux-usability/teardown.d.ts +3 -0
- package/dist/ux-usability/teardown.js +13 -0
- package/dist/ux-usability/teardown.js.map +1 -0
- package/dist/ux-usability.d.ts +14 -17
- package/dist/ux-usability.js +15 -589
- package/dist/ux-usability.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { SiteGateRefusedError } from "@jevitate/runtime";
|
|
2
|
+
import { findCapabilities } from "@jevitate/mcp-facade";
|
|
3
|
+
import { FsJourneyStore, JourneyRegistry } from "@jevitate/journey";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { ParamValidationError } from "@jevitate/journey";
|
|
6
|
+
import { safeRunPolicy as defaultRunPolicy } from "@jevitate/domain";
|
|
7
|
+
import { stampRunMetadata, withRunMetadata } from "../run-metadata.js";
|
|
8
|
+
import { JourneyRequiresAuthError, UnknownJourneyError } from "../journey-api.js";
|
|
9
|
+
import { ExtensionMismatchError } from "../browser-run-options.js";
|
|
10
|
+
import { browserRunFromFlags, emulationFromFlags } from "../cli-shared.js";
|
|
11
|
+
import { environmentFromFlags, isEnvironmentError } from "../environments.js";
|
|
12
|
+
import { buildMissionFixtures, checkSetupRefs } from "../fixture-cli.js";
|
|
13
|
+
import { FixtureSetupError, FixtureSpecError, UnboundSetupRefError } from "../mission-fixtures.js";
|
|
14
|
+
import { parseScreenshotsArg } from "../run-screenshots.js";
|
|
15
|
+
import { makeEvidenceSelfHealer } from "../self-heal-adapter.js";
|
|
16
|
+
import { JourneyHealArgsError, MCP_HEAL_NAMES, journeyHealBudget, readJourneyChangeScope, validateJourneyHeal } from "../journey-heal.js";
|
|
17
|
+
import { ChangesArgsError, ChangesInputError } from "../change-context.js";
|
|
18
|
+
import { MAX_STEP_RESPONSE_TIMEOUT_MS } from "../journey-network-checks.js";
|
|
19
|
+
import { McpArgError, argErrorBody, optBool, optEnum, optInt, optNamedSessions, optPath, optExtensions, optRecordVideo, optScreenshots, optString, optStringArray, optStringMap, optViewport } from "../mcp-args.js";
|
|
20
|
+
import { resourcePreflight } from "../resource-preflight.js";
|
|
21
|
+
import { jsonResult, errorResult, governanceArgs, withJourneyExitCode, SetupRequired, redactCredentials, tagsArg } from "./shared.js";
|
|
22
|
+
/** `find_capabilities` and `run_journey`: the promoted-Journey tools. */
|
|
23
|
+
export function journeyTools(ctx) {
|
|
24
|
+
const { deps, pathRoots, credentialStore, runJourney } = ctx;
|
|
25
|
+
const findCaps = deps.findCapabilities ??
|
|
26
|
+
((query) => findCapabilities(new JourneyRegistry(new FsJourneyStore(deps.journeysDir)), query));
|
|
27
|
+
/**
|
|
28
|
+
* #255: `run_journey`'s CLI-parity options, resolved exactly as `journey run` resolves its flags
|
|
29
|
+
* (the same helpers: environmentFromFlags, browserRunFromFlags, parseScreenshotsArg,
|
|
30
|
+
* emulationFromFlags, buildMissionFixtures) — every refusal typed, before any browser opens.
|
|
31
|
+
*/
|
|
32
|
+
const resolveJourneyRun = async (args) => {
|
|
33
|
+
// Params keep their historical leniency for a non-object (treated as none); a non-string VALUE is refused.
|
|
34
|
+
const params = args.params && typeof args.params === "object" && !Array.isArray(args.params) ? (optStringMap(args, "params") ?? {}) : {};
|
|
35
|
+
const envName = optString(args, "env");
|
|
36
|
+
const baseUrl = optString(args, "baseUrl");
|
|
37
|
+
const environment = environmentFromFlags({ ...(envName === undefined ? {} : { env: envName }), ...(baseUrl === undefined ? {} : { baseUrl }) }, { ...(deps.environmentsFile === undefined ? {} : { environmentsFile: deps.environmentsFile }), ...(deps.targetsConfigPath === undefined ? {} : { targetsFile: deps.targetsConfigPath }) });
|
|
38
|
+
// --storage-state wins; else the environment's own session (~/.jevitate/targets.json[<origin>]).
|
|
39
|
+
const storageState = optPath(args, "storageState", pathRoots, { session: true }) ?? environment?.storageState;
|
|
40
|
+
if (args.storageState !== undefined && storageState !== undefined && !existsSync(storageState))
|
|
41
|
+
throw new McpArgError(`storage state not found: ${storageState}`);
|
|
42
|
+
const headed = optBool(args, "headed");
|
|
43
|
+
const slowMo = optInt(args, "slowMo", 0);
|
|
44
|
+
const recordVideo = optRecordVideo(args, pathRoots);
|
|
45
|
+
const extension = optExtensions(args, pathRoots);
|
|
46
|
+
const governance = governanceArgs(args);
|
|
47
|
+
let browser;
|
|
48
|
+
let screenshots;
|
|
49
|
+
let emulation;
|
|
50
|
+
try {
|
|
51
|
+
browser = browserRunFromFlags({ browserArg: [], ...governance, ...(extension === undefined ? {} : { extension }), ...(headed === undefined ? {} : { headed }), ...(slowMo === undefined ? {} : { slowMo }), ...(recordVideo === undefined ? {} : { recordVideo }) });
|
|
52
|
+
screenshots = parseScreenshotsArg(optScreenshots(args, pathRoots));
|
|
53
|
+
const viewport = optViewport(args);
|
|
54
|
+
const device = optString(args, "device");
|
|
55
|
+
const geolocation = optString(args, "geolocation");
|
|
56
|
+
emulation = emulationFromFlags({ ...(viewport === undefined ? {} : { viewport }), ...(device === undefined ? {} : { device }), ...(geolocation === undefined ? {} : { geolocation }) });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
if (err instanceof McpArgError || argErrorBody(err) !== undefined)
|
|
60
|
+
throw err;
|
|
61
|
+
throw new McpArgError(err instanceof Error ? err.message : String(err));
|
|
62
|
+
}
|
|
63
|
+
const fixturesFile = optPath(args, "fixtures", pathRoots);
|
|
64
|
+
const fixtureIdentity = optNamedSessions(args, "fixtureIdentity", pathRoots);
|
|
65
|
+
// The environment's hooks apply as on the CLI; they need --allow-shell-hooks, which MCP never sets.
|
|
66
|
+
const fixtureFlags = {
|
|
67
|
+
...(fixturesFile === undefined ? {} : { fixtures: fixturesFile }),
|
|
68
|
+
...(fixtureIdentity === undefined ? {} : { fixtureIdentity }),
|
|
69
|
+
...(environment?.hooks?.before === undefined ? {} : { before: environment.hooks.before }),
|
|
70
|
+
...(environment?.hooks?.after === undefined ? {} : { after: environment.hooks.after }),
|
|
71
|
+
};
|
|
72
|
+
const fixtures = (site) => {
|
|
73
|
+
const fx = buildMissionFixtures(fixtureFlags, {
|
|
74
|
+
allowlist: environment === undefined ? [site] : environment.allowedOrigins,
|
|
75
|
+
baseUrl: site,
|
|
76
|
+
...(storageState !== undefined ? { storageState } : {}),
|
|
77
|
+
...(environment?.fixtures === undefined ? {} : { targetFixtures: environment.fixtures }),
|
|
78
|
+
});
|
|
79
|
+
checkSetupRefs({ "--param": Object.values(params) }, fx);
|
|
80
|
+
return fx;
|
|
81
|
+
};
|
|
82
|
+
const selfHeal = optEnum(args, "selfHeal", ["fail-closed", "hybrid", "full"]) ?? "fail-closed";
|
|
83
|
+
const real = optBool(args, "real") ?? false;
|
|
84
|
+
const fakeAi = optBool(args, "fakeAi") ?? false;
|
|
85
|
+
// #429: the Jev provider for self-heal judgments (typesafe | openrouter), as `--jev-provider`.
|
|
86
|
+
const jevProvider = optEnum(args, "jevProvider", ["typesafe", "openrouter"]);
|
|
87
|
+
// #453 Q1: the same refusals as `journey run` — a heal needs a change context, the change and
|
|
88
|
+
// budget arguments need a heal — before any gateway, Journey lookup or browser.
|
|
89
|
+
const changes = optString(args, "changes");
|
|
90
|
+
const healMaxAttempts = optInt(args, "healMaxAttempts", 1);
|
|
91
|
+
const healMaxModelCalls = optInt(args, "healMaxModelCalls", 1);
|
|
92
|
+
const healMaxMs = optInt(args, "healMaxMs", 1);
|
|
93
|
+
const healMaxRunAttempts = optInt(args, "healMaxRunAttempts", 1);
|
|
94
|
+
const healMaxRunMs = optInt(args, "healMaxRunMs", 1);
|
|
95
|
+
const stepResponseTimeoutMs = optInt(args, "stepResponseTimeoutMs", 1);
|
|
96
|
+
if (stepResponseTimeoutMs !== undefined && stepResponseTimeoutMs > MAX_STEP_RESPONSE_TIMEOUT_MS) {
|
|
97
|
+
throw new McpArgError(`'stepResponseTimeoutMs' must be an integer from 1 to ${MAX_STEP_RESPONSE_TIMEOUT_MS}`);
|
|
98
|
+
}
|
|
99
|
+
const healRequest = {
|
|
100
|
+
selfHeal,
|
|
101
|
+
...(changes === undefined ? {} : { changes }),
|
|
102
|
+
changeNotes: optStringArray(args, "changeNote") ?? [],
|
|
103
|
+
...(healMaxAttempts === undefined ? {} : { maxAttempts: healMaxAttempts }),
|
|
104
|
+
...(healMaxModelCalls === undefined ? {} : { maxModelCalls: healMaxModelCalls }),
|
|
105
|
+
...(healMaxMs === undefined ? {} : { maxMs: healMaxMs }),
|
|
106
|
+
...(healMaxRunAttempts === undefined ? {} : { maxRunAttempts: healMaxRunAttempts }),
|
|
107
|
+
...(healMaxRunMs === undefined ? {} : { maxRunMs: healMaxRunMs }),
|
|
108
|
+
};
|
|
109
|
+
validateJourneyHeal(healRequest, MCP_HEAL_NAMES);
|
|
110
|
+
const healScope = selfHeal === "fail-closed" ? undefined : await readJourneyChangeScope(healRequest, deps.journeysDir);
|
|
111
|
+
let selfHealer;
|
|
112
|
+
let policy = defaultRunPolicy();
|
|
113
|
+
let usage;
|
|
114
|
+
if (selfHeal !== "fail-closed") {
|
|
115
|
+
if (deps.selfHealGateways === undefined)
|
|
116
|
+
throw new SetupRequired("run_journey selfHeal needs the model gateways, which this server was not given");
|
|
117
|
+
// #453: the healer is evidence-only — its model is an advisory ranker; judgment never decides a heal.
|
|
118
|
+
let gen;
|
|
119
|
+
try {
|
|
120
|
+
({ gen, usage } = await deps.selfHealGateways({ real, fakeAi, ...(jevProvider === undefined ? {} : { jevProvider }) }));
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
throw new SetupRequired(redactCredentials(err instanceof Error ? err.message : String(err), credentialStore));
|
|
124
|
+
}
|
|
125
|
+
selfHealer = makeEvidenceSelfHealer(gen, usage === undefined ? {} : { usage });
|
|
126
|
+
policy = { ...policy, selfHeal: { mode: selfHeal, budget: journeyHealBudget(healRequest) } };
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
params,
|
|
130
|
+
...(storageState === undefined ? {} : { storageState }),
|
|
131
|
+
options: {
|
|
132
|
+
policy,
|
|
133
|
+
fixtures,
|
|
134
|
+
...(selfHealer === undefined ? {} : { selfHealer }),
|
|
135
|
+
...(healScope === undefined ? {} : { heal: { scope: healScope } }),
|
|
136
|
+
...(environment === undefined ? {} : { environment }),
|
|
137
|
+
...(browser === undefined ? {} : { browser }),
|
|
138
|
+
...(emulation === undefined ? {} : { emulation }),
|
|
139
|
+
...(screenshots === undefined ? {} : { screenshots }),
|
|
140
|
+
...(optBool(args, "actionDeltas") === true ? { actionDeltas: true } : {}),
|
|
141
|
+
...(stepResponseTimeoutMs === undefined ? {} : { stepResponseTimeoutMs }),
|
|
142
|
+
},
|
|
143
|
+
...(usage === undefined ? {} : { usage }),
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
find_capabilities: {
|
|
148
|
+
description: "Find promoted Journeys (capabilities) whose metadata matches a query.",
|
|
149
|
+
inputSchema: { type: "object", properties: { query: { type: "string" } }, required: ["query"] },
|
|
150
|
+
handler: async (args) => jsonResult(await findCaps(typeof args.query === "string" ? args.query : "")),
|
|
151
|
+
},
|
|
152
|
+
run_journey: {
|
|
153
|
+
description: "Run a PUBLISHED Journey by id with string params (fail-closed policy) — `jevitate journey run`. Never accepts inline steps. " +
|
|
154
|
+
"Optional 'storageState': a PATH (on the machine running this MCP server; inside the project or ~/.jevitate, never a repo's .jevitate/) to a Playwright storageState " +
|
|
155
|
+
"JSON file, for a Journey authored behind a login (#118) — the file's contents are read only by the " +
|
|
156
|
+
"server's own browser, never returned or logged. A Journey that declares metadata.requiresAuth refuses " +
|
|
157
|
+
"with a clear error when no storageState is given. #255 (same as the CLI flags): 'env' (a named environment in .jevitate/environments.json; its session from ~/.jevitate/targets.json) and/or 'baseUrl'; " +
|
|
158
|
+
"'headed' (needs a display) and 'slowMo'; 'recordVideo' (true, or a directory) → videoPaths; 'screenshots' (true | screens | steps | mode:<dir> | <dir>) → screenshotPaths; " +
|
|
159
|
+
"'viewport' {width,height} or 'device' (mutually exclusive); 'geolocation' '<lat>,<lng>[,<accuracy m>]' (#329); 'fixtures' (a fixtures JSON path: setup before, restore after; 'fixtureIdentity' (#243) 'name=<storageState path>' entries name who a step with auth.identity authenticates as; an environment's shell hooks are never run over MCP — they refuse as the CLI does without --allow-shell-hooks); " +
|
|
160
|
+
"'extension' (#256: unpacked extension directories inside the project or ~/.jevitate; a Journey recorded with extensions needs the same build); 'selfHeal' fail-closed (default) | hybrid | full with 'real' or 'fakeAi' (a write step never self-heals; 'jevProvider' typesafe | openrouter picks the Jev key with real, #429) — #453: a heal mode needs a change context, 'changes' (a git range such as HEAD~1..HEAD, read-only) and/or 'changeNote' (strings), else it is refused; only a break that change explains is retargeted, one-for-one, and the run ends healed-pending-review (exitCode 5: a proposed revision a person accepts, never a pass); budgets 'healMaxAttempts'/'healMaxModelCalls'/'healMaxMs' (per broken step) and 'healMaxRunAttempts'/'healMaxRunMs' (per run), each >= 1; the result's 'exitCode' is the CLI's (0 ok, 5 pending review, 1 failed); 'actionDeltas' (#303, opt-in: each replayed step's action delta, compared with the recorded one → actionDeltas); 'stepResponseTimeoutMs' (#486, 1..300000, default 15000: how long a step's responseStatus check waits for a request sent but not yet answered, e.g. a cold start — a late 2xx is an advisory slowSteps finding; a step's own responseTimeoutMs overrides it); 'maxBrowsers'/'maxBrowserMemory' (#205: machine-wide browser cap, browser memory ceiling in MiB); 'tags' (#426: {key: value} run metadata, returned on the result — never a secret). A site-policy refusal is {error: throttled, retryAfter}.",
|
|
161
|
+
inputSchema: {
|
|
162
|
+
type: "object",
|
|
163
|
+
properties: {
|
|
164
|
+
id: { type: "string" },
|
|
165
|
+
params: { type: "object", additionalProperties: { type: "string" } },
|
|
166
|
+
storageState: { type: "string" },
|
|
167
|
+
env: { type: "string" },
|
|
168
|
+
baseUrl: { type: "string" },
|
|
169
|
+
headed: { type: "boolean" },
|
|
170
|
+
slowMo: { type: "integer", minimum: 0 },
|
|
171
|
+
recordVideo: { type: ["boolean", "string"] },
|
|
172
|
+
screenshots: { type: ["boolean", "string"] },
|
|
173
|
+
viewport: { type: "object", properties: { width: { type: "integer" }, height: { type: "integer" } }, required: ["width", "height"] },
|
|
174
|
+
device: { type: "string" },
|
|
175
|
+
geolocation: { type: "string" },
|
|
176
|
+
fixtures: { type: "string" },
|
|
177
|
+
fixtureIdentity: { type: "array", items: { type: "string" } },
|
|
178
|
+
selfHeal: { type: "string", enum: ["fail-closed", "hybrid", "full"] },
|
|
179
|
+
changes: { type: "string" },
|
|
180
|
+
changeNote: { type: "array", items: { type: "string" } },
|
|
181
|
+
healMaxAttempts: { type: "integer", minimum: 1 },
|
|
182
|
+
healMaxModelCalls: { type: "integer", minimum: 1 },
|
|
183
|
+
healMaxMs: { type: "integer", minimum: 1 },
|
|
184
|
+
healMaxRunAttempts: { type: "integer", minimum: 1 },
|
|
185
|
+
healMaxRunMs: { type: "integer", minimum: 1 },
|
|
186
|
+
real: { type: "boolean" },
|
|
187
|
+
fakeAi: { type: "boolean" },
|
|
188
|
+
jevProvider: { type: "string", enum: ["typesafe", "openrouter"] },
|
|
189
|
+
extension: { type: "array", items: { type: "string" } },
|
|
190
|
+
maxBrowsers: { type: "integer", minimum: 1 },
|
|
191
|
+
maxBrowserMemory: { type: "integer", minimum: 1 },
|
|
192
|
+
actionDeltas: { type: "boolean" },
|
|
193
|
+
stepResponseTimeoutMs: { type: "integer", minimum: 1, maximum: MAX_STEP_RESPONSE_TIMEOUT_MS },
|
|
194
|
+
tags: { type: "object", additionalProperties: { type: "string" } },
|
|
195
|
+
},
|
|
196
|
+
required: ["id"],
|
|
197
|
+
},
|
|
198
|
+
handler: async (args) => {
|
|
199
|
+
if (typeof args.id !== "string" || args.id.length === 0) {
|
|
200
|
+
return errorResult({ error: "invalid_args", message: "run_journey requires a non-empty string 'id'" });
|
|
201
|
+
}
|
|
202
|
+
const tagged = tagsArg(args);
|
|
203
|
+
if ("error" in tagged)
|
|
204
|
+
return errorResult(tagged.error);
|
|
205
|
+
// Invariant #5: only id + params (+ a storageState PATH and the run options below) are
|
|
206
|
+
// threaded through — any inline `steps`/`recording` in the arguments is deliberately ignored.
|
|
207
|
+
let resolved;
|
|
208
|
+
try {
|
|
209
|
+
resolved = await resolveJourneyRun(args);
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
const body = argErrorBody(err) ?? (isEnvironmentError(err) ? { error: "invalid_args", code: err.code, message: err.message } : undefined);
|
|
213
|
+
if (body !== undefined)
|
|
214
|
+
return errorResult(body);
|
|
215
|
+
if (err instanceof JourneyHealArgsError || err instanceof ChangesArgsError || err instanceof ChangesInputError) {
|
|
216
|
+
return errorResult({ error: "invalid_args", code: err.code, message: err.message });
|
|
217
|
+
}
|
|
218
|
+
if (err instanceof SetupRequired)
|
|
219
|
+
return errorResult({ error: "setup_required", message: err.message });
|
|
220
|
+
throw err;
|
|
221
|
+
}
|
|
222
|
+
// #205: the same pre-run checks as `jevitate journey run` (orphan sweep, starved-host refusal).
|
|
223
|
+
const starved = await resourcePreflight({});
|
|
224
|
+
if (starved !== null)
|
|
225
|
+
return errorResult({ error: "refused", code: starved.error?.code, message: starved.error?.message });
|
|
226
|
+
try {
|
|
227
|
+
const id = args.id;
|
|
228
|
+
const result = await withRunMetadata({ tags: tagged.tags }, () => runJourney(id, resolved.params, resolved.storageState, resolved.options));
|
|
229
|
+
// #163: a self-healing run's model usage lands on its result, as on the CLI. #426: so do its tags.
|
|
230
|
+
const withUsage = resolved.usage === undefined || result === null || typeof result !== "object" ? result : { ...result, usage: resolved.usage.snapshot() };
|
|
231
|
+
// #453: the CLI's exit code for the outcome — 0 ok, 5 healed-pending-review (a proposed revision, never a pass), 1 otherwise.
|
|
232
|
+
return jsonResult(stampRunMetadata(withJourneyExitCode(withUsage), { tags: tagged.tags }));
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
// A site-policy refusal (throttle, budget, quiet hours) is an answer the agent acts on — when to retry.
|
|
236
|
+
if (err instanceof SiteGateRefusedError) {
|
|
237
|
+
return errorResult({ error: "throttled", reason: err.reason, retryAfter: err.retryAfter, message: err.message });
|
|
238
|
+
}
|
|
239
|
+
if (err instanceof UnknownJourneyError)
|
|
240
|
+
return errorResult({ error: "not_found", id: args.id, message: err.message });
|
|
241
|
+
if (err instanceof JourneyRequiresAuthError)
|
|
242
|
+
return errorResult({ error: "invalid_args", code: "E_JOURNEY_REQUIRES_AUTH", message: err.message });
|
|
243
|
+
if (err instanceof ExtensionMismatchError)
|
|
244
|
+
return errorResult({ error: "invalid_args", code: err.code, message: err.message });
|
|
245
|
+
if (err instanceof ParamValidationError)
|
|
246
|
+
return errorResult({ error: "invalid_args", code: "E_INVALID_PARAMS", message: err.message });
|
|
247
|
+
if (isEnvironmentError(err) || err instanceof FixtureSpecError || err instanceof UnboundSetupRefError) {
|
|
248
|
+
return errorResult({ error: "invalid_args", code: err.code, message: err.message });
|
|
249
|
+
}
|
|
250
|
+
// Never run on unknown state: inconclusive (exit 2) — proves nothing, so an error result.
|
|
251
|
+
if (err instanceof FixtureSetupError) {
|
|
252
|
+
return errorResult({ outcome: "inconclusive", reason: err.message, failure: { kind: "configuration", message: err.message }, attribution: "configuration", exitCode: 2 });
|
|
253
|
+
}
|
|
254
|
+
throw err;
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=journey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journey.js","sourceRoot":"","sources":["../../src/mcp-tools/journey.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type CredentialStore } from "@jevitate/ai-core";
|
|
2
|
+
import { type GovernanceFlags } from "../resource-preflight.js";
|
|
3
|
+
import type { McpApiDeps, McpTool, McpToolResult } from "../mcp-api.js";
|
|
4
|
+
/** The dependencies a tool group closes over (built once by `buildMcpTools`). */
|
|
5
|
+
export interface McpToolCtx {
|
|
6
|
+
readonly deps: McpApiDeps;
|
|
7
|
+
readonly pathRoots: readonly string[];
|
|
8
|
+
readonly credentialStore: CredentialStore;
|
|
9
|
+
readonly runJourney: NonNullable<McpApiDeps["runJourney"]>;
|
|
10
|
+
readonly verifyFixImpl: NonNullable<McpApiDeps["verifyFix"]>;
|
|
11
|
+
}
|
|
12
|
+
/** One group's tool descriptors, keyed by tool name (the name is added by `buildMcpTools`). */
|
|
13
|
+
export type McpToolGroup = Record<string, Omit<McpTool, "name">>;
|
|
14
|
+
/** #205: a native tool's `maxBrowsers` / `maxBrowserMemory` (MiB) arguments, typed like the CLI flags. */
|
|
15
|
+
export declare function governanceArgs(args: Record<string, unknown>): GovernanceFlags;
|
|
16
|
+
/** #453: a Journey run result with the CLI's exit code for its outcome (anything else unchanged). */
|
|
17
|
+
export declare function withJourneyExitCode(result: unknown): unknown;
|
|
18
|
+
export declare function jsonResult(value: unknown): McpToolResult;
|
|
19
|
+
export declare function errorResult(value: unknown): McpToolResult;
|
|
20
|
+
/** Strips any known credential VALUE from a diagnostic string so a provider
|
|
21
|
+
* SDK error (which can echo request internals verbatim) never surfaces a key
|
|
22
|
+
* through the MCP result. The message returned to the caller is generic and
|
|
23
|
+
* key-free; this is belt-and-braces on top of the gateway's outbound guard. */
|
|
24
|
+
/** #217: a persisted goal result's own ending (`result.goalOutcome`), when present. */
|
|
25
|
+
export declare function goalOutcomeOf(file: object): unknown;
|
|
26
|
+
/** #423: a persisted result's `defectOutcome.status` (`none`/`defects`), when present. */
|
|
27
|
+
export declare function defectStatusOf(file: object): unknown;
|
|
28
|
+
/** One field of a persisted result's `result` object, else undefined. */
|
|
29
|
+
export declare function resultField(file: object, key: string): unknown;
|
|
30
|
+
/** A model-backed option was asked for without usable gateways/keys (typed `setup_required`). */
|
|
31
|
+
export declare class SetupRequired extends Error {
|
|
32
|
+
}
|
|
33
|
+
export declare function redactCredentials(message: string, store: CredentialStore): string;
|
|
34
|
+
/** #426: the run tools' `tags` object — validated like `--tag` (an invalid one is invalid_args, never dropped). */
|
|
35
|
+
export declare const tagsArg: (args: Record<string, unknown>) => {
|
|
36
|
+
tags: Record<string, string>;
|
|
37
|
+
} | {
|
|
38
|
+
error: Record<string, unknown>;
|
|
39
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ALL_CREDENTIAL_KEYS } from "@jevitate/ai-core";
|
|
2
|
+
import { RunTagError, JOURNEY_RUN_OUTCOMES, journeyExitCode, validateRunTags } from "@jevitate/domain";
|
|
3
|
+
import { optInt } from "../mcp-args.js";
|
|
4
|
+
/** #205: a native tool's `maxBrowsers` / `maxBrowserMemory` (MiB) arguments, typed like the CLI flags. */
|
|
5
|
+
export function governanceArgs(args) {
|
|
6
|
+
const maxBrowsers = optInt(args, "maxBrowsers", 1);
|
|
7
|
+
const maxBrowserMemory = optInt(args, "maxBrowserMemory", 1);
|
|
8
|
+
return { ...(maxBrowsers === undefined ? {} : { maxBrowsers }), ...(maxBrowserMemory === undefined ? {} : { maxBrowserMemory }) };
|
|
9
|
+
}
|
|
10
|
+
/** #453: a Journey run result with the CLI's exit code for its outcome (anything else unchanged). */
|
|
11
|
+
export function withJourneyExitCode(result) {
|
|
12
|
+
if (result === null || typeof result !== "object")
|
|
13
|
+
return result;
|
|
14
|
+
const outcome = result.outcome;
|
|
15
|
+
if (typeof outcome !== "string" || !JOURNEY_RUN_OUTCOMES.includes(outcome))
|
|
16
|
+
return result;
|
|
17
|
+
return { ...result, exitCode: journeyExitCode(outcome) };
|
|
18
|
+
}
|
|
19
|
+
export function jsonResult(value) {
|
|
20
|
+
return { content: [{ type: "text", text: JSON.stringify(value) }] };
|
|
21
|
+
}
|
|
22
|
+
export function errorResult(value) {
|
|
23
|
+
return { content: [{ type: "text", text: JSON.stringify(value) }], isError: true };
|
|
24
|
+
}
|
|
25
|
+
/** Strips any known credential VALUE from a diagnostic string so a provider
|
|
26
|
+
* SDK error (which can echo request internals verbatim) never surfaces a key
|
|
27
|
+
* through the MCP result. The message returned to the caller is generic and
|
|
28
|
+
* key-free; this is belt-and-braces on top of the gateway's outbound guard. */
|
|
29
|
+
/** #217: a persisted goal result's own ending (`result.goalOutcome`), when present. */
|
|
30
|
+
export function goalOutcomeOf(file) {
|
|
31
|
+
const result = file.result;
|
|
32
|
+
return result !== null && typeof result === "object" && "goalOutcome" in result ? result.goalOutcome : undefined;
|
|
33
|
+
}
|
|
34
|
+
/** #423: a persisted result's `defectOutcome.status` (`none`/`defects`), when present. */
|
|
35
|
+
export function defectStatusOf(file) {
|
|
36
|
+
const outcome = resultField(file, "defectOutcome");
|
|
37
|
+
return outcome !== null && typeof outcome === "object" && "status" in outcome ? outcome.status : undefined;
|
|
38
|
+
}
|
|
39
|
+
/** One field of a persisted result's `result` object, else undefined. */
|
|
40
|
+
export function resultField(file, key) {
|
|
41
|
+
const result = file.result;
|
|
42
|
+
return result !== null && typeof result === "object" && key in result ? result[key] : undefined;
|
|
43
|
+
}
|
|
44
|
+
/** A model-backed option was asked for without usable gateways/keys (typed `setup_required`). */
|
|
45
|
+
export class SetupRequired extends Error {
|
|
46
|
+
}
|
|
47
|
+
export function redactCredentials(message, store) {
|
|
48
|
+
let out = message;
|
|
49
|
+
for (const key of ALL_CREDENTIAL_KEYS) {
|
|
50
|
+
const value = store.read(key);
|
|
51
|
+
if (value)
|
|
52
|
+
out = out.split(value).join("***REDACTED***");
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
/** #426: the run tools' `tags` object — validated like `--tag` (an invalid one is invalid_args, never dropped). */
|
|
57
|
+
export const tagsArg = (args) => {
|
|
58
|
+
if (args.tags === undefined)
|
|
59
|
+
return { tags: {} };
|
|
60
|
+
try {
|
|
61
|
+
return { tags: validateRunTags(args.tags, "tags") };
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (!(err instanceof RunTagError))
|
|
65
|
+
throw err;
|
|
66
|
+
return { error: { error: "invalid_args", code: err.code, message: err.message } };
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/mcp-tools/shared.ts"],"names":[],"mappings":"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"}
|
package/dist/sweep-api.d.ts
CHANGED
|
@@ -37,6 +37,13 @@ export declare const MAX_SWEEP_CONCURRENCY = 16;
|
|
|
37
37
|
export declare const MAX_SWEEP_TARGETS = 1000;
|
|
38
38
|
/** The target option name → its typed explore argument (the allowed set). */
|
|
39
39
|
export declare function sweepTargetOptions(): Readonly<Record<string, CliParam>>;
|
|
40
|
+
/**
|
|
41
|
+
* #513: a sweep fixture, checked synchronously against the project root exactly like every upload
|
|
42
|
+
* fixture (#498): inside the root (after realpath), an existing file, not sensitive. Returns the absolute
|
|
43
|
+
* path (a relative one resolves against the working directory, as `explore --fixture` does).
|
|
44
|
+
* Throws `FixturePathError`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function confineSweepFixture(raw: string, root: string | undefined): string;
|
|
40
47
|
export interface SweepPersona {
|
|
41
48
|
readonly name: string;
|
|
42
49
|
/** Absolute, confined path of the persona's storage state (its contents are never read). */
|
|
@@ -64,6 +71,8 @@ export interface LoadSweepTargetsOptions {
|
|
|
64
71
|
/** Extra roots a persona storage state may live in (default: the project and `~/.jevitate`). */
|
|
65
72
|
readonly roots?: readonly string[];
|
|
66
73
|
readonly env?: NodeJS.ProcessEnv;
|
|
74
|
+
/** The project root a target's `options.fixture` is confined to (default: the folder holding `.jevitate/`). */
|
|
75
|
+
readonly projectRoot?: string;
|
|
67
76
|
}
|
|
68
77
|
/**
|
|
69
78
|
* Loads and validates a targets file (`.tsv`: a header row then one target per line; `.json`: an
|
package/dist/sweep-api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
3
3
|
import { MISSION_EXIT_CODES, RunTagError, clock, combineOutcomes, validateRunTags, } from "@jevitate/domain";
|
|
4
4
|
import { currentEngineInfo } from "./engine.js";
|
|
@@ -10,6 +10,8 @@ import { confineMcpPath, defaultMcpPathRoots } from "./mcp-paths.js";
|
|
|
10
10
|
import { EXPLORE_STRATEGIES } from "./cli-shared.js";
|
|
11
11
|
import { STARVED_LOAD_PER_CORE, hostProbe, validateAllowControlPatterns, validateDenyPatterns } from "@jevitate/explore";
|
|
12
12
|
import { parseAuthCheck } from "./persona-login.js";
|
|
13
|
+
import { journeyFixtureBaseDir } from "./journey-api.js";
|
|
14
|
+
import { FixturePathError, fixtureEscapesRoot, fixtureNoRoot, fixtureNotFound, fixtureOutsideProject, fixtureRootRefusal, fixtureSensitive, fixtureSensitiveReason, fixtureUnsafeRoot, } from "@jevitate/recording";
|
|
13
15
|
/**
|
|
14
16
|
* `jevitate sweep` (#425): one release check over many targets (features/routes) × personas, run
|
|
15
17
|
* with bounded concurrency, resumable, with ONE aggregated `sweep.result.json`.
|
|
@@ -96,8 +98,48 @@ export function sweepTargetOptions() {
|
|
|
96
98
|
continue;
|
|
97
99
|
out[name] = p;
|
|
98
100
|
}
|
|
101
|
+
// `fixture` is a path kind on MCP (so excluded above), but the CLI's `explore --fixture` is confined to
|
|
102
|
+
// the project root (#498) and the sweep re-checks it when the spec loads: a target may set it (#513).
|
|
103
|
+
out.fixture = { kind: "string", flag: "--fixture" };
|
|
99
104
|
return out;
|
|
100
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* #513: a sweep fixture, checked synchronously against the project root exactly like every upload
|
|
108
|
+
* fixture (#498): inside the root (after realpath), an existing file, not sensitive. Returns the absolute
|
|
109
|
+
* path (a relative one resolves against the working directory, as `explore --fixture` does).
|
|
110
|
+
* Throws `FixturePathError`.
|
|
111
|
+
*/
|
|
112
|
+
export function confineSweepFixture(raw, root) {
|
|
113
|
+
if (root === undefined)
|
|
114
|
+
throw fixtureNoRoot(raw);
|
|
115
|
+
const unsafe = fixtureRootRefusal(root);
|
|
116
|
+
if (unsafe !== null)
|
|
117
|
+
throw fixtureUnsafeRoot(raw, root, unsafe);
|
|
118
|
+
const absolute = resolve(raw);
|
|
119
|
+
const { escapes, real } = fixtureEscapesRoot(absolute, root);
|
|
120
|
+
if (escapes)
|
|
121
|
+
throw fixtureOutsideProject(real === absolute ? absolute : `${absolute} (→ ${real})`, root);
|
|
122
|
+
let isFile = false;
|
|
123
|
+
try {
|
|
124
|
+
isFile = statSync(real).isFile();
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// not there
|
|
128
|
+
}
|
|
129
|
+
if (!isFile)
|
|
130
|
+
throw fixtureNotFound(absolute, root);
|
|
131
|
+
let realRoot = resolve(root);
|
|
132
|
+
try {
|
|
133
|
+
realRoot = realpathSync(root);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// keep the lexical root
|
|
137
|
+
}
|
|
138
|
+
const sensitive = fixtureSensitiveReason(real, realRoot) ?? fixtureSensitiveReason(absolute, resolve(root));
|
|
139
|
+
if (sensitive !== null)
|
|
140
|
+
throw fixtureSensitive(absolute, root, sensitive);
|
|
141
|
+
return absolute;
|
|
142
|
+
}
|
|
101
143
|
function isRecord(v) {
|
|
102
144
|
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
103
145
|
}
|
|
@@ -302,10 +344,23 @@ const OPTION_SPEC = (params) => ({
|
|
|
302
344
|
description: "",
|
|
303
345
|
command: { path: "explore", params, omitted: {} },
|
|
304
346
|
});
|
|
347
|
+
/**
|
|
348
|
+
* Browser launch settings are per-sweep, never per-target: a run's browser is launched the same way
|
|
349
|
+
* for every target. Set them with the `sweep` command's own flag; a target's option is refused.
|
|
350
|
+
*/
|
|
351
|
+
const BROWSER_TARGET_OPTIONS = {
|
|
352
|
+
browserArg: "--browser-arg",
|
|
353
|
+
browserExecutable: "--browser-executable",
|
|
354
|
+
browserChannel: "--browser-channel",
|
|
355
|
+
};
|
|
305
356
|
/** A target's options as explore flags (typed and closed: an unknown option or a wrong type is a problem). */
|
|
306
357
|
function optionArgvOf(options, where, problems) {
|
|
307
358
|
const allowed = sweepTargetOptions();
|
|
308
|
-
const
|
|
359
|
+
for (const [key, flag] of Object.entries(BROWSER_TARGET_OPTIONS)) {
|
|
360
|
+
if (options[key] !== undefined)
|
|
361
|
+
problems.push(`${where}: ${key} is not a per-target option — a sweep launches every run's browser the same way: pass ${flag} to \`jevitate sweep\``);
|
|
362
|
+
}
|
|
363
|
+
const unknown = Object.keys(options).filter((k) => allowed[k] === undefined && BROWSER_TARGET_OPTIONS[k] === undefined);
|
|
309
364
|
if (unknown.length > 0) {
|
|
310
365
|
problems.push(`${where}: unknown or not-allowed explore option(s) ${unknown.join(", ")} (a target may set: ${Object.keys(allowed).sort().join(", ")}; ` +
|
|
311
366
|
"url/route, persona, strategy, goal and tags are their own fields)");
|
|
@@ -450,6 +505,19 @@ export function loadSweepTargets(path, opts = {}) {
|
|
|
450
505
|
if ((effectiveStrategy === "goal" || effectiveStrategy === "usability") && typeof goal !== "string" && options.feature === undefined) {
|
|
451
506
|
problems.push(`${where}: strategy ${effectiveStrategy} needs a goal${effectiveStrategy === "goal" ? " (or options.feature for a feature run)" : ""}`);
|
|
452
507
|
}
|
|
508
|
+
if (typeof options.fixture === "string") {
|
|
509
|
+
try {
|
|
510
|
+
options.fixture = confineSweepFixture(options.fixture, opts.projectRoot ?? journeyFixtureBaseDir());
|
|
511
|
+
}
|
|
512
|
+
catch (err) {
|
|
513
|
+
if (!(err instanceof FixturePathError))
|
|
514
|
+
throw err;
|
|
515
|
+
problems.push(`${where}: options.fixture ${JSON.stringify(options.fixture)} refused (${err.code}): ${err.message}`);
|
|
516
|
+
delete options.fixture;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
else if (options.fixture !== undefined)
|
|
520
|
+
problems.push(`${where}: options.fixture must be a file path`);
|
|
453
521
|
const optionArgv = optionArgvOf(options, where, problems);
|
|
454
522
|
validateRunShaping(options, effectiveStrategy, where, problems);
|
|
455
523
|
let tags = { ...defaultTags };
|