@jevitate/cli 0.11.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/approval-provenance.d.ts +6 -0
- package/dist/approval-provenance.js +9 -1
- package/dist/approval-provenance.js.map +1 -1
- package/dist/author-journey-cli.js +2 -1
- package/dist/author-journey-cli.js.map +1 -1
- package/dist/bin.js +25396 -23850
- package/dist/build-info.generated.js +2 -2
- package/dist/demo-aspect-cli.js +2 -1
- package/dist/demo-aspect-cli.js.map +1 -1
- 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 -1346
- package/dist/explore-cli.js.map +1 -1
- package/dist/explore-goal.js +4 -3
- package/dist/explore-goal.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-api.d.ts +12 -3
- package/dist/journey-api.js +34 -12
- package/dist/journey-api.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 +2 -2
- package/dist/journey-cli.js +21 -878
- package/dist/journey-cli.js.map +1 -1
- package/dist/journey-labels-migrate-api.d.ts +100 -0
- package/dist/journey-labels-migrate-api.js +194 -0
- package/dist/journey-labels-migrate-api.js.map +1 -0
- package/dist/journey-lint-sarif.js +4 -0
- package/dist/journey-lint-sarif.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 +9 -2
- package/dist/journey-review.js +183 -144
- 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 +14 -5
- 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/regression-api.js +6 -4
- package/dist/regression-api.js.map +1 -1
- package/dist/review-render-options.d.ts +17 -0
- package/dist/review-render-options.js +17 -0
- package/dist/review-render-options.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 -586
- package/dist/ux-usability.js.map +1 -1
- package/dist/verify-fix-api.js +2 -0
- package/dist/verify-fix-api.js.map +1 -1
- package/package.json +11 -11
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { isMissionResultId, isQueuedMissionId, missionResultFileName, missionStatus, parseResultOutcome } from "@jevitate/mcp-facade";
|
|
2
|
+
import { FsMissionQueueStore } from "@jevitate/missions";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { access, readFile } from "node:fs/promises";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { stampRunMetadata, withRunMetadata } from "../run-metadata.js";
|
|
7
|
+
import { browserRunFromFlags, emulationFromFlags } from "../cli-shared.js";
|
|
8
|
+
import { parseScreenshotsArg } from "../run-screenshots.js";
|
|
9
|
+
import { McpArgError, argErrorBody, optBool, optInt, optNamedSessions, optPath, optExtensions, optRecordVideo, optScreenshots, optString, optStringArray, optViewport } from "../mcp-args.js";
|
|
10
|
+
import { resourcePreflight } from "../resource-preflight.js";
|
|
11
|
+
import { jsonResult, errorResult, governanceArgs, goalOutcomeOf, defectStatusOf, resultField, tagsArg } from "./shared.js";
|
|
12
|
+
/** `verify_fix` and `get_mission_result`: reading and re-checking a mission result by id. */
|
|
13
|
+
export function findingTools(ctx) {
|
|
14
|
+
const { deps, pathRoots, verifyFixImpl } = ctx;
|
|
15
|
+
// get_mission_result: reads a persisted typed mission result by ID only (the artifact stem the
|
|
16
|
+
// CLI wrote) — never a caller-supplied path. The status carries the CLI exit code, and a run that
|
|
17
|
+
// itself broke (inconclusive/crashed) is an MCP error result, so it can never read as a pass.
|
|
18
|
+
//
|
|
19
|
+
// The id is either a result stem (`explore-<stamp>`, `usability-<stamp>.recording`, …) or a
|
|
20
|
+
// `queue_exploration` missionId (#117): the latter resolves through the mission's queue record —
|
|
21
|
+
// `queued`/`running` is reported as such (not an error, not a result), `failed` as an error, and
|
|
22
|
+
// `done` reads the result its drain wrote. Both shapes are closed regexes; nothing caller-shaped
|
|
23
|
+
// ever reaches a path.
|
|
24
|
+
const resolveResultId = async (id, tool) => {
|
|
25
|
+
if (isMissionResultId(id))
|
|
26
|
+
return { resultId: id };
|
|
27
|
+
if (!isQueuedMissionId(id)) {
|
|
28
|
+
return {
|
|
29
|
+
response: errorResult({
|
|
30
|
+
error: "invalid_args",
|
|
31
|
+
message: `${tool} requires a mission result 'id' (explore-|coverage-|exploratory-|adversarial-|feature-|usability-<stamp>) or a queue_exploration missionId`,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (!deps.missionQueueDir) {
|
|
36
|
+
return { response: errorResult({ error: "not_configured", message: `${tool} requires missionQueueDir to resolve a missionId` }) };
|
|
37
|
+
}
|
|
38
|
+
let mission;
|
|
39
|
+
try {
|
|
40
|
+
mission = await new FsMissionQueueStore(deps.missionQueueDir).get(id);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { response: errorResult({ error: "corrupt_mission", id }) };
|
|
44
|
+
}
|
|
45
|
+
if (mission === null)
|
|
46
|
+
return { response: errorResult({ error: "not_found", id }) };
|
|
47
|
+
if (mission.status === "queued" || mission.status === "running") {
|
|
48
|
+
// Not finished: neither a pass nor a failure — the agent polls again later.
|
|
49
|
+
const pending = {
|
|
50
|
+
id,
|
|
51
|
+
missionId: id,
|
|
52
|
+
status: mission.status,
|
|
53
|
+
pending: true,
|
|
54
|
+
enqueuedAtIso: mission.enqueuedAtIso,
|
|
55
|
+
...(mission.startedAtIso === undefined ? {} : { startedAtIso: mission.startedAtIso }),
|
|
56
|
+
};
|
|
57
|
+
return { response: jsonResult(pending), pending };
|
|
58
|
+
}
|
|
59
|
+
if (mission.status === "failed") {
|
|
60
|
+
return { response: errorResult({ id, missionId: id, status: "failed", isError: true, error: mission.error ?? "mission failed" }) };
|
|
61
|
+
}
|
|
62
|
+
if (!isMissionResultId(mission.resultId))
|
|
63
|
+
return { response: errorResult({ error: "corrupt_mission", id }) };
|
|
64
|
+
return { resultId: mission.resultId, missionId: id };
|
|
65
|
+
};
|
|
66
|
+
/** The dirs a result may live in: recordings, and (usability reviews) the UX reports dir. */
|
|
67
|
+
const resultPathsFor = (resultId) => {
|
|
68
|
+
const file = missionResultFileName(resultId);
|
|
69
|
+
const dirs = deps.resultDirsFor?.(resultId) ?? [deps.recordingsDir, ...(resultId.startsWith("usability-") ? [deps.uxReportsDir] : [])];
|
|
70
|
+
return dirs.filter((d) => d !== undefined).map((d) => join(d, file));
|
|
71
|
+
};
|
|
72
|
+
const getMissionResult = async (args) => {
|
|
73
|
+
if (!deps.recordingsDir) {
|
|
74
|
+
return errorResult({ error: "not_configured", message: "get_mission_result requires recordingsDir" });
|
|
75
|
+
}
|
|
76
|
+
const ref = await resolveResultId(args.id, "get_mission_result");
|
|
77
|
+
if ("response" in ref)
|
|
78
|
+
return ref.response;
|
|
79
|
+
const ids = { id: args.id, ...(ref.missionId === undefined ? {} : { missionId: ref.missionId, resultId: ref.resultId }) };
|
|
80
|
+
let raw;
|
|
81
|
+
for (const path of resultPathsFor(ref.resultId)) {
|
|
82
|
+
try {
|
|
83
|
+
raw = await readFile(path, "utf8");
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Try the next candidate dir.
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (raw === undefined) {
|
|
91
|
+
return errorResult({ error: "not_found", ...ids });
|
|
92
|
+
}
|
|
93
|
+
let parsed;
|
|
94
|
+
try {
|
|
95
|
+
parsed = JSON.parse(raw);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return errorResult({ error: "corrupt_result", ...ids });
|
|
99
|
+
}
|
|
100
|
+
// #217: `missionOutcome` is canonical; a goal run's own ending rides beside it as `goalOutcome`.
|
|
101
|
+
const parsedOutcome = parsed !== null && typeof parsed === "object" && "missionOutcome" in parsed
|
|
102
|
+
? parseResultOutcome(parsed.missionOutcome, goalOutcomeOf(parsed), defectStatusOf(parsed))
|
|
103
|
+
: null;
|
|
104
|
+
if (parsedOutcome === null) {
|
|
105
|
+
return errorResult({ error: "corrupt_result", ...ids });
|
|
106
|
+
}
|
|
107
|
+
// #423: the two orthogonal verdicts beside the status — did the goal get reached (goalOutcome +
|
|
108
|
+
// goalReason) and did the app break (defectOutcome, counted by kind) — read from the structured
|
|
109
|
+
// result, never from its `reason` prose.
|
|
110
|
+
const goalReason = resultField(parsed, "goalReason");
|
|
111
|
+
const defectOutcome = resultField(parsed, "defectOutcome");
|
|
112
|
+
const status = {
|
|
113
|
+
...missionStatus(parsedOutcome.outcome),
|
|
114
|
+
...(parsedOutcome.goalOutcome === undefined ? {} : { goalOutcome: parsedOutcome.goalOutcome }),
|
|
115
|
+
...(typeof goalReason === "string" ? { goalReason } : {}),
|
|
116
|
+
...(defectOutcome !== null && typeof defectOutcome === "object" ? { defectOutcome } : {}),
|
|
117
|
+
};
|
|
118
|
+
const result = parsed.result ?? null;
|
|
119
|
+
// An adversarial run's coverage is surfaced next to the status: an `inconclusive` run says what
|
|
120
|
+
// it did and did not exercise, so an agent can tell "found nothing" from "tried nothing".
|
|
121
|
+
const coverage = result !== null && typeof result === "object" && "coverage" in result ? result.coverage : undefined;
|
|
122
|
+
const body = { ...ids, ...status, ...(coverage === undefined ? {} : { coverage }), result };
|
|
123
|
+
return status.isError ? errorResult(body) : jsonResult(body);
|
|
124
|
+
};
|
|
125
|
+
/** #255: verify_fix's CLI-parity replay options, validated like `verify-fix`'s flags (typed, before any browser). */
|
|
126
|
+
const verifyFixOptions = (args) => {
|
|
127
|
+
const storageState = optPath(args, "storageState", pathRoots, { session: true });
|
|
128
|
+
if (storageState !== undefined && !existsSync(storageState))
|
|
129
|
+
throw new McpArgError(`storage state not found: ${storageState}`);
|
|
130
|
+
const replays = optInt(args, "replays", 1);
|
|
131
|
+
const invariantFiles = (optStringArray(args, "invariants") ?? []).map((f, i) => optPath({ [`invariants[${i}]`]: f }, `invariants[${i}]`, pathRoots));
|
|
132
|
+
const fixtures = optPath(args, "fixtures", pathRoots);
|
|
133
|
+
const fixtureIdentity = optNamedSessions(args, "fixtureIdentity", pathRoots);
|
|
134
|
+
const allowEmulationOverride = optBool(args, "allowEmulationOverride");
|
|
135
|
+
const headed = optBool(args, "headed");
|
|
136
|
+
const slowMo = optInt(args, "slowMo", 0);
|
|
137
|
+
const recordVideo = optRecordVideo(args, pathRoots);
|
|
138
|
+
const shots = optScreenshots(args, pathRoots);
|
|
139
|
+
const viewport = optViewport(args);
|
|
140
|
+
const device = optString(args, "device");
|
|
141
|
+
const geolocation = optString(args, "geolocation");
|
|
142
|
+
const extension = optExtensions(args, pathRoots);
|
|
143
|
+
const governance = governanceArgs(args);
|
|
144
|
+
const actionDeltas = optBool(args, "actionDeltas");
|
|
145
|
+
// #484: replaying under another allow list widens what the replay may reach — explicit only (never
|
|
146
|
+
// defaulted), and the report carries allowlistOverride. An MCP caller never names origins: only
|
|
147
|
+
// `env` (an operator-configured environment) can override the stored list; `--allow` is CLI-only.
|
|
148
|
+
if (args["allow"] !== undefined)
|
|
149
|
+
throw new McpArgError("'allow' is not an MCP argument: a replay reaches only operator-configured origins — pass 'env' (an environment in environments.json), or run `jevitate verify-fix --allow` yourself");
|
|
150
|
+
const env = optString(args, "env");
|
|
151
|
+
try {
|
|
152
|
+
const browser = browserRunFromFlags({ browserArg: [], ...governance, ...(extension === undefined ? {} : { extension }), ...(headed === undefined ? {} : { headed }), ...(slowMo === undefined ? {} : { slowMo }), ...(recordVideo === undefined ? {} : { recordVideo }) });
|
|
153
|
+
const screenshots = parseScreenshotsArg(shots);
|
|
154
|
+
const emulation = emulationFromFlags({ ...(viewport === undefined ? {} : { viewport }), ...(device === undefined ? {} : { device }), ...(geolocation === undefined ? {} : { geolocation }) });
|
|
155
|
+
return {
|
|
156
|
+
...(storageState === undefined ? {} : { storageState }),
|
|
157
|
+
...(replays === undefined ? {} : { replays }),
|
|
158
|
+
...(invariantFiles.length === 0 ? {} : { invariantFiles }),
|
|
159
|
+
...(fixtures === undefined && fixtureIdentity === undefined
|
|
160
|
+
? {}
|
|
161
|
+
: { fixtureFlags: { ...(fixtures === undefined ? {} : { fixtures }), ...(fixtureIdentity === undefined ? {} : { fixtureIdentity }) } }),
|
|
162
|
+
...(allowEmulationOverride === undefined ? {} : { allowEmulationOverride }),
|
|
163
|
+
...(browser === undefined ? {} : { browser }),
|
|
164
|
+
...(screenshots === undefined ? {} : { screenshots }),
|
|
165
|
+
...(emulation === undefined ? {} : { emulation }),
|
|
166
|
+
...(actionDeltas === true ? { actionDeltas: true } : {}),
|
|
167
|
+
...(env === undefined ? {} : { env, ...(deps.environmentsFile === undefined ? {} : { environmentsFile: deps.environmentsFile }) }),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
throw new McpArgError(err instanceof Error ? err.message : String(err));
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const verifyFixTool = async (args) => {
|
|
175
|
+
if (!deps.recordingsDir) {
|
|
176
|
+
return errorResult({ error: "not_configured", message: "verify_fix requires recordingsDir" });
|
|
177
|
+
}
|
|
178
|
+
if (!(isMissionResultId(args.id) || isQueuedMissionId(args.id)) ||
|
|
179
|
+
typeof args.fingerprint !== "string" ||
|
|
180
|
+
!/^[0-9a-f]{16}$/.test(args.fingerprint)) {
|
|
181
|
+
return errorResult({ error: "invalid_args", message: "verify_fix requires a mission result 'id' (or missionId) and a 16-hex 'fingerprint'" });
|
|
182
|
+
}
|
|
183
|
+
const tagged = tagsArg(args);
|
|
184
|
+
if ("error" in tagged)
|
|
185
|
+
return errorResult(tagged.error);
|
|
186
|
+
let options;
|
|
187
|
+
try {
|
|
188
|
+
options = verifyFixOptions(args);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
const body = argErrorBody(err);
|
|
192
|
+
if (body === undefined)
|
|
193
|
+
throw err;
|
|
194
|
+
return errorResult(body);
|
|
195
|
+
}
|
|
196
|
+
// #205: the same pre-run checks as `jevitate verify-fix` (orphan sweep, starved-host refusal).
|
|
197
|
+
const starved = await resourcePreflight({});
|
|
198
|
+
if (starved !== null)
|
|
199
|
+
return errorResult({ error: "refused", code: starved.error?.code, message: starved.error?.message });
|
|
200
|
+
const ref = await resolveResultId(args.id, "verify_fix");
|
|
201
|
+
if ("response" in ref) {
|
|
202
|
+
// A mission still queued/running has nothing to verify yet: never a pass.
|
|
203
|
+
return ref.pending === undefined ? ref.response : errorResult({ error: "not_ready", ...ref.pending });
|
|
204
|
+
}
|
|
205
|
+
// The first candidate that exists (usability results may sit in the UX reports dir).
|
|
206
|
+
const candidates = resultPathsFor(ref.resultId);
|
|
207
|
+
let resultPath = candidates[0];
|
|
208
|
+
for (const path of candidates) {
|
|
209
|
+
try {
|
|
210
|
+
await access(path);
|
|
211
|
+
resultPath = path;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Try the next candidate dir.
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const fingerprint = args.fingerprint;
|
|
220
|
+
const report = await withRunMetadata({ tags: tagged.tags }, () => verifyFixImpl({ ...options, resultPath, fingerprint }));
|
|
221
|
+
const body = stampRunMetadata({
|
|
222
|
+
id: args.id,
|
|
223
|
+
...(ref.missionId === undefined ? {} : { missionId: ref.missionId, resultId: ref.resultId }),
|
|
224
|
+
status: report.verdict,
|
|
225
|
+
...report,
|
|
226
|
+
}, { tags: tagged.tags });
|
|
227
|
+
// Neither is a pass: `inconclusive` proved nothing either way, `intermittent` (#74) means the
|
|
228
|
+
// signal fired on SOME but not all fresh-context replays — never trustworthy as "fixed".
|
|
229
|
+
return report.verdict === "inconclusive" || report.verdict === "intermittent" ? errorResult(body) : jsonResult(body);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
return errorResult({ error: "verify_fix_refused", message: err instanceof Error ? err.message : String(err) });
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
return {
|
|
236
|
+
verify_fix: {
|
|
237
|
+
description: "Replay a finding's reproduction (by mission result id — or a finished queue_exploration missionId — + fingerprint) N times in fresh browsers (default 3) — `jevitate verify-fix`. status: fixed (signal absent on every replay) | still-reproduces | intermittent (fired on some but not all replays — never a pass) | inconclusive (replay could not reach the step — never a pass). " +
|
|
238
|
+
"#255 (same as the CLI flags): 'replays' (>= 1); 'recordVideo' (true or a directory: the before/after evidence pair — `evidence.before` is the run's own clip, `evidence.after` a captioned replay — plus videoPaths); 'screenshots'; 'headed'/'slowMo'; " +
|
|
239
|
+
"'storageState' (a path inside the project or ~/.jevitate, never a repo's .jevitate/; overrides the mission's session); 'viewport' {width,height} or 'device' (refused when it differs from the finding's recorded emulation unless 'allowEmulationOverride'); 'geolocation' '<lat>,<lng>[,<accuracy m>]' (#329); " +
|
|
240
|
+
"'invariants' (invariant file paths re-checking a declared-invariant defect); 'fixtures' (a fixtures file overriding the mission's saved one); 'fixtureIdentity' (#243: 'name=<storageState path>' entries re-binding a fixture step's auth.identity; default: the identities the mission recorded); 'extension' (#256: unpacked extension directories — refused unless the same build the finding was recorded with); 'actionDeltas' (#303, opt-in: the defect step's replayed delta vs the recorded one, as evidence on each attempt); '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); #484 'env' (a named environment in environments.json: replay under its CURRENT allow list instead of the one stored with the result, e.g. to prove a localhost → 127.0.0.1 config fix; explicit only, never defaulted) — the result then carries allowlistOverride (source, origins, recorded, added, removed); raw origins are CLI-only (`jevitate verify-fix --allow`), never an MCP argument. Operator-only settings (shell hooks, cmd: log sources, re-sending paid/destructive hang writes) come from targets.json, never an argument.",
|
|
241
|
+
inputSchema: {
|
|
242
|
+
type: "object",
|
|
243
|
+
properties: {
|
|
244
|
+
id: { type: "string" },
|
|
245
|
+
fingerprint: { type: "string" },
|
|
246
|
+
replays: { type: "integer", minimum: 1 },
|
|
247
|
+
actionDeltas: { type: "boolean" },
|
|
248
|
+
recordVideo: { type: ["boolean", "string"] },
|
|
249
|
+
screenshots: { type: ["boolean", "string"] },
|
|
250
|
+
headed: { type: "boolean" },
|
|
251
|
+
slowMo: { type: "integer", minimum: 0 },
|
|
252
|
+
storageState: { type: "string" },
|
|
253
|
+
viewport: { type: "object", properties: { width: { type: "integer" }, height: { type: "integer" } }, required: ["width", "height"] },
|
|
254
|
+
device: { type: "string" },
|
|
255
|
+
geolocation: { type: "string" },
|
|
256
|
+
allowEmulationOverride: { type: "boolean" },
|
|
257
|
+
invariants: { type: "array", items: { type: "string" } },
|
|
258
|
+
fixtures: { type: "string" },
|
|
259
|
+
fixtureIdentity: { type: "array", items: { type: "string" } },
|
|
260
|
+
extension: { type: "array", items: { type: "string" } },
|
|
261
|
+
maxBrowsers: { type: "integer", minimum: 1 },
|
|
262
|
+
maxBrowserMemory: { type: "integer", minimum: 1 },
|
|
263
|
+
tags: { type: "object", additionalProperties: { type: "string" } },
|
|
264
|
+
env: { type: "string" },
|
|
265
|
+
},
|
|
266
|
+
required: ["id", "fingerprint"],
|
|
267
|
+
},
|
|
268
|
+
handler: verifyFixTool,
|
|
269
|
+
},
|
|
270
|
+
get_mission_result: {
|
|
271
|
+
description: "Read a mission's TYPED result by id: a result stem (explore-|coverage-|exploratory-|adversarial-|feature-|usability-<stamp>, e.g. adversarial-2026-09-23T00-00-00-000Z) or a queue_exploration missionId. A queued mission reports status queued | running (pending: true — poll again; `jevitate mission run` drains the queue) or failed (an error: it could not run). A finished one: status is clean | defects-found | hang | intermittent | inconclusive | crashed, with the matching CLI exit code. A broken run (inconclusive/crashed) is returned as an error result — never a pass. An adversarial result carries `coverage` (target controls exercised/total, forms submitted, strategies applied vs found nothing, out-of-scope steps): a run below its coverage thresholds is inconclusive, never clean.",
|
|
272
|
+
inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
|
|
273
|
+
handler: getMissionResult,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings.js","sourceRoot":"","sources":["../../src/mcp-tools/findings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { facadeListIncoming, facadeGetCommand, facadeGetThread, facadeQueueAction, facadeQueueRetrieval, facadeApproveAction, facadeCancelCommand, facadeGetSiteHealth } from "@jevitate/mcp-facade";
|
|
2
|
+
import { FsInboxStore } from "@jevitate/inbox";
|
|
3
|
+
import { currentEngineInfo } from "../engine.js";
|
|
4
|
+
import { jsonResult, errorResult } from "./shared.js";
|
|
5
|
+
/** The 8 inbox / command-queue tools. */
|
|
6
|
+
export function inboxTools(ctx) {
|
|
7
|
+
const { deps } = ctx;
|
|
8
|
+
// The 8 inbox tools: the store is built lazily inside this closure (mirrors
|
|
9
|
+
// `queueExploration` above) so constructing the tool set never touches
|
|
10
|
+
// disk. A missing `inboxDir` is a config error (a refusal), never a silent
|
|
11
|
+
// success — `inboxHandler` below catches it (and any store-layer throw,
|
|
12
|
+
// e.g. `getForAgent`/`get`'s fail-closed throw on corrupt/tampered data)
|
|
13
|
+
// and converts it to a typed `internal` error, never lets it fabricate a
|
|
14
|
+
// success or leak an unhandled rejection out of the handler.
|
|
15
|
+
const inboxStore = () => {
|
|
16
|
+
if (!deps.inboxDir) {
|
|
17
|
+
throw new Error("inbox tools require inboxDir to be configured");
|
|
18
|
+
}
|
|
19
|
+
return new FsInboxStore(deps.inboxDir, deps.engine ?? currentEngineInfo());
|
|
20
|
+
};
|
|
21
|
+
function inboxHandler(fn) {
|
|
22
|
+
return async (args) => {
|
|
23
|
+
try {
|
|
24
|
+
return jsonResult(await fn(inboxStore(), args));
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
return errorResult({ error: "internal", message: err instanceof Error ? err.message : String(err) });
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const idInputSchema = {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: { id: { type: "string" } },
|
|
34
|
+
required: ["id"],
|
|
35
|
+
};
|
|
36
|
+
const queueCommonProperties = {
|
|
37
|
+
run: { type: "string" },
|
|
38
|
+
journey: { type: "string" },
|
|
39
|
+
step: { type: "string" },
|
|
40
|
+
reason: { type: "string" },
|
|
41
|
+
agent: { type: "string" },
|
|
42
|
+
targetUrl: { type: "string" },
|
|
43
|
+
hasScreenshot: { type: "boolean" },
|
|
44
|
+
findings: {
|
|
45
|
+
type: "array",
|
|
46
|
+
items: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
id: { type: "string" },
|
|
50
|
+
title: { type: "string" },
|
|
51
|
+
severity: { type: "string", enum: ["low", "med", "high"] },
|
|
52
|
+
evidence: { type: "string" },
|
|
53
|
+
},
|
|
54
|
+
required: ["id", "title", "severity"],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const queueCommonRequired = ["run", "journey", "step", "reason", "agent"];
|
|
59
|
+
return {
|
|
60
|
+
list_incoming: {
|
|
61
|
+
description: "List pending inbox items (HITL commands awaiting a human) as InboxSummary projections.",
|
|
62
|
+
inputSchema: { type: "object", properties: {} },
|
|
63
|
+
handler: inboxHandler((store) => facadeListIncoming(store)),
|
|
64
|
+
},
|
|
65
|
+
get_command: {
|
|
66
|
+
description: "Agent poll for one inbox item by id (burn-after-read: consumes any human-provided secret input exactly once). Returns not_found for an unknown id.",
|
|
67
|
+
inputSchema: idInputSchema,
|
|
68
|
+
handler: inboxHandler((store, args) => facadeGetCommand(store, args)),
|
|
69
|
+
},
|
|
70
|
+
get_thread: {
|
|
71
|
+
description: "Get the conversation thread (agent/human messages) for one inbox item by id. Never returns secret input.",
|
|
72
|
+
inputSchema: idInputSchema,
|
|
73
|
+
handler: inboxHandler((store, args) => facadeGetThread(store, args)),
|
|
74
|
+
},
|
|
75
|
+
queue_action: {
|
|
76
|
+
description: "Enqueue a HITL inbox item requiring a human decision — kind defaults to 'approval' ('handback'/'review' also accepted). Never resolves anything; only queues.",
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: "object",
|
|
79
|
+
properties: { ...queueCommonProperties, kind: { type: "string", enum: ["approval", "handback", "review"] } },
|
|
80
|
+
required: queueCommonRequired,
|
|
81
|
+
},
|
|
82
|
+
handler: inboxHandler((store, args) => facadeQueueAction(store, args)),
|
|
83
|
+
},
|
|
84
|
+
queue_retrieval: {
|
|
85
|
+
description: "Enqueue a HITL 'handback' inbox item requesting the human retrieve/provide something back to the agent. Never resolves anything; only queues.",
|
|
86
|
+
inputSchema: { type: "object", properties: queueCommonProperties, required: queueCommonRequired },
|
|
87
|
+
handler: inboxHandler((store, args) => facadeQueueRetrieval(store, args)),
|
|
88
|
+
},
|
|
89
|
+
approve_action: {
|
|
90
|
+
description: "SM1: an agent can NEVER approve an inbox item over MCP — always refuses with human_approval_required. Approval is only permitted from the local jevitate UI.",
|
|
91
|
+
inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
|
|
92
|
+
handler: async () => errorResult(facadeApproveAction()),
|
|
93
|
+
},
|
|
94
|
+
cancel_command: {
|
|
95
|
+
description: "SM1: an agent can NEVER cancel an inbox item over MCP — always refuses with human_approval_required. Cancellation is only permitted from the local jevitate UI.",
|
|
96
|
+
inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
|
|
97
|
+
handler: async () => errorResult(facadeCancelCommand()),
|
|
98
|
+
},
|
|
99
|
+
get_site_health: {
|
|
100
|
+
description: "Report inbox store health: ok, pending count, age of the oldest pending item, and store version.",
|
|
101
|
+
inputSchema: { type: "object", properties: {} },
|
|
102
|
+
handler: inboxHandler((store) => facadeGetSiteHealth(store)),
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=inbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/mcp-tools/inbox.ts"],"names":[],"mappings":"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"}
|