@jevitate/cli 0.28.0 → 0.29.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 +1 -1
- package/dist/approval-provenance.d.ts +9 -1
- package/dist/approval-provenance.js +12 -4
- package/dist/approval-provenance.js.map +1 -1
- package/dist/author-journey-cli.js +1 -1
- package/dist/author-journey-cli.js.map +1 -1
- package/dist/bin.js +12663 -8284
- package/dist/bin.js.map +1 -1
- package/dist/build-info.generated.js +3 -3
- package/dist/catalog-analysis.js +3 -2
- package/dist/catalog-analysis.js.map +1 -1
- package/dist/catalog-bundle.js +2 -2
- package/dist/catalog-bundle.js.map +1 -1
- package/dist/check-plan.js +12 -0
- package/dist/check-plan.js.map +1 -1
- package/dist/demo-aspect-cli.d.ts +10 -0
- package/dist/demo-aspect-cli.js +4 -1
- package/dist/demo-aspect-cli.js.map +1 -1
- package/dist/engine.d.ts +8 -1
- package/dist/engine.js +16 -2
- package/dist/engine.js.map +1 -1
- package/dist/explore-adversarial.js +4 -0
- package/dist/explore-adversarial.js.map +1 -1
- package/dist/explore-cli/feature-strategy.js +1 -0
- package/dist/explore-cli/feature-strategy.js.map +1 -1
- package/dist/explore-cli/run.js +7 -0
- package/dist/explore-cli/run.js.map +1 -1
- package/dist/explore-feature.d.ts +2 -0
- package/dist/explore-feature.js +15 -8
- package/dist/explore-feature.js.map +1 -1
- package/dist/explore-goal.js +12 -0
- package/dist/explore-goal.js.map +1 -1
- package/dist/explore-specs.js +2 -2
- package/dist/explore-specs.js.map +1 -1
- package/dist/heal-probe-guard.d.ts +7 -3
- package/dist/heal-probe-guard.js +8 -2
- package/dist/heal-probe-guard.js.map +1 -1
- package/dist/http-probe.js +2 -2
- package/dist/http-probe.js.map +1 -1
- package/dist/journey-annotate-api.d.ts +5 -0
- package/dist/journey-annotate-api.js +49 -24
- package/dist/journey-annotate-api.js.map +1 -1
- package/dist/journey-annotate-cli.js +4 -1
- package/dist/journey-annotate-cli.js.map +1 -1
- package/dist/journey-api.d.ts +46 -7
- package/dist/journey-api.js +111 -43
- package/dist/journey-api.js.map +1 -1
- package/dist/journey-chain.d.ts +0 -6
- package/dist/journey-chain.js +36 -5
- package/dist/journey-chain.js.map +1 -1
- package/dist/journey-cli/chain.js +6 -0
- package/dist/journey-cli/chain.js.map +1 -1
- package/dist/journey-cli/lint.js +10 -3
- package/dist/journey-cli/lint.js.map +1 -1
- package/dist/journey-cli/run.js +39 -4
- package/dist/journey-cli/run.js.map +1 -1
- package/dist/journey-cli/verify.d.ts +8 -1
- package/dist/journey-cli/verify.js +111 -14
- package/dist/journey-cli/verify.js.map +1 -1
- package/dist/journey-cli-readiness.js +2 -0
- package/dist/journey-cli-readiness.js.map +1 -1
- package/dist/journey-demo-cli.js +2 -0
- package/dist/journey-demo-cli.js.map +1 -1
- package/dist/journey-network-checks.d.ts +4 -0
- package/dist/journey-network-checks.js +6 -2
- package/dist/journey-network-checks.js.map +1 -1
- package/dist/journey-prefix.d.ts +2 -0
- package/dist/journey-prefix.js +20 -1
- package/dist/journey-prefix.js.map +1 -1
- package/dist/journey-proof-context.d.ts +7 -1
- package/dist/journey-proof-context.js +19 -1
- package/dist/journey-proof-context.js.map +1 -1
- package/dist/journey-proof-waiver-cli.js +6 -3
- package/dist/journey-proof-waiver-cli.js.map +1 -1
- package/dist/journey-readiness.js +4 -0
- package/dist/journey-readiness.js.map +1 -1
- package/dist/journey-review-api.js +23 -0
- package/dist/journey-review-api.js.map +1 -1
- package/dist/journey-review.d.ts +30 -10
- package/dist/journey-review.js +33 -39
- package/dist/journey-review.js.map +1 -1
- package/dist/journey-run-record.d.ts +91 -0
- package/dist/journey-run-record.js +239 -0
- package/dist/journey-run-record.js.map +1 -0
- package/dist/journey-stale-api.d.ts +7 -0
- package/dist/journey-stale-api.js +50 -6
- package/dist/journey-stale-api.js.map +1 -1
- package/dist/journey-verify-checkpoint.d.ts +656 -0
- package/dist/journey-verify-checkpoint.js +923 -0
- package/dist/journey-verify-checkpoint.js.map +1 -0
- package/dist/journey-verify.d.ts +84 -3
- package/dist/journey-verify.js +1387 -110
- package/dist/journey-verify.js.map +1 -1
- package/dist/kill-signal.d.ts +24 -2
- package/dist/kill-signal.js +39 -11
- package/dist/kill-signal.js.map +1 -1
- package/dist/load-api.js +31 -2
- package/dist/load-api.js.map +1 -1
- package/dist/load-cli.js +6 -0
- package/dist/load-cli.js.map +1 -1
- package/dist/logs-retention.js +28 -3
- package/dist/logs-retention.js.map +1 -1
- package/dist/mask-values.d.ts +5 -0
- package/dist/mask-values.js +12 -0
- package/dist/mask-values.js.map +1 -0
- package/dist/mcp-api.d.ts +2 -0
- package/dist/mcp-api.js +19 -3
- package/dist/mcp-api.js.map +1 -1
- package/dist/mcp-cli-runner.d.ts +7 -1
- package/dist/mcp-cli-runner.js +30 -3
- package/dist/mcp-cli-runner.js.map +1 -1
- package/dist/mcp-cli-tools.d.ts +9 -1
- package/dist/mcp-cli-tools.js +29 -4
- package/dist/mcp-cli-tools.js.map +1 -1
- package/dist/mcp-paths.js +11 -0
- package/dist/mcp-paths.js.map +1 -1
- package/dist/mcp-run-guard.d.ts +79 -0
- package/dist/mcp-run-guard.js +371 -0
- package/dist/mcp-run-guard.js.map +1 -0
- package/dist/mcp-tools/cli.js +1 -1
- package/dist/mcp-tools/cli.js.map +1 -1
- package/dist/mcp-tools/findings.js +12 -1
- package/dist/mcp-tools/findings.js.map +1 -1
- package/dist/mcp-tools/journey.js +25 -8
- package/dist/mcp-tools/journey.js.map +1 -1
- package/dist/mission-fixtures.d.ts +3 -1
- package/dist/mission-fixtures.js +23 -6
- package/dist/mission-fixtures.js.map +1 -1
- package/dist/mutation-proof-policy.d.ts +2 -0
- package/dist/mutation-proof-policy.js +2 -2
- package/dist/mutation-proof-policy.js.map +1 -1
- package/dist/program.d.ts +6 -0
- package/dist/program.js +6 -9
- package/dist/program.js.map +1 -1
- package/dist/project-dir.d.ts +5 -1
- package/dist/project-dir.js +54 -5
- package/dist/project-dir.js.map +1 -1
- package/dist/readiness.js +3 -1
- package/dist/readiness.js.map +1 -1
- package/dist/regression-api.d.ts +5 -0
- package/dist/regression-api.js +17 -10
- package/dist/regression-api.js.map +1 -1
- package/dist/regression-cli.js +14 -1
- package/dist/regression-cli.js.map +1 -1
- package/dist/report-api.js +6 -0
- package/dist/report-api.js.map +1 -1
- package/dist/resource-preflight.d.ts +2 -1
- package/dist/resource-preflight.js +2 -1
- package/dist/resource-preflight.js.map +1 -1
- package/dist/secret-params.d.ts +82 -0
- package/dist/secret-params.js +234 -0
- package/dist/secret-params.js.map +1 -0
- package/dist/self-heal-adapter.d.ts +2 -2
- package/dist/self-heal-adapter.js +7 -9
- package/dist/self-heal-adapter.js.map +1 -1
- package/dist/source-cli.js +3 -1
- package/dist/source-cli.js.map +1 -1
- package/dist/source-run-api.d.ts +2 -0
- package/dist/source-run-api.js +21 -2
- package/dist/source-run-api.js.map +1 -1
- package/dist/target-config.d.ts +39 -0
- package/dist/target-config.js +76 -1
- package/dist/target-config.js.map +1 -1
- package/dist/terminal-result.d.ts +181 -0
- package/dist/terminal-result.js +609 -0
- package/dist/terminal-result.js.map +1 -0
- package/dist/usability-capture.js +2 -2
- package/dist/usability-capture.js.map +1 -1
- package/dist/ux-usability/hang.js +2 -0
- package/dist/ux-usability/hang.js.map +1 -1
- package/dist/ux-usability.js +6 -0
- package/dist/ux-usability.js.map +1 -1
- package/dist/verify-fix-api.d.ts +43 -0
- package/dist/verify-fix-api.js +138 -10
- package/dist/verify-fix-api.js.map +1 -1
- package/dist/verify-fix-cli.d.ts +6 -1
- package/dist/verify-fix-cli.js +65 -11
- package/dist/verify-fix-cli.js.map +1 -1
- package/package.json +9 -9
- package/skills/jevitate-run-journey/SKILL.md +23 -3
package/dist/logs-retention.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileSync, readdirSync, rmSync, rmdirSync, statSync } from "node:fs"
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { resolveDataDir } from "./data-dir.js";
|
|
4
4
|
import { clock } from "@jevitate/domain";
|
|
5
|
+
import { isLiveVerifyReceipt } from "./journey-verify-checkpoint.js";
|
|
5
6
|
export const DEFAULT_LOGS_RETENTION = { ttlDays: 14, keepLatest: 50 };
|
|
6
7
|
export class LogsConfigError extends Error {
|
|
7
8
|
code = "E_LOGS_CONFIG";
|
|
@@ -41,6 +42,28 @@ export function loadLogsRetention(path = resolveDataDir(["config.json"])) {
|
|
|
41
42
|
return { ttlDays: int("ttlDays"), keepLatest: int("keepLatest") };
|
|
42
43
|
}
|
|
43
44
|
const RUN_KEY = /^([a-z][a-z-]*-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z)/;
|
|
45
|
+
/** #787: a proof's durable progress: one receipt per Journey, replaced as the proof moves. */
|
|
46
|
+
const VERIFY_PROGRESS_DIR = "verify-progress";
|
|
47
|
+
/**
|
|
48
|
+
* #787: the proof receipts under `logs/verify-progress/`, each its own run. A receipt whose verifier is
|
|
49
|
+
* still live stays, however old (its proof may be mid-way). One that cannot be read is judged by age.
|
|
50
|
+
*/
|
|
51
|
+
function verifyProgressIn(root) {
|
|
52
|
+
const dir = join(root, VERIFY_PROGRESS_DIR);
|
|
53
|
+
let names;
|
|
54
|
+
try {
|
|
55
|
+
names = readdirSync(dir);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
if (typeof e === "object" && e !== null && "code" in e && e.code === "ENOENT")
|
|
59
|
+
return [];
|
|
60
|
+
throw e;
|
|
61
|
+
}
|
|
62
|
+
return names.flatMap((name) => {
|
|
63
|
+
const path = join(dir, name);
|
|
64
|
+
return isLiveVerifyReceipt(path) ? [] : [{ key: `${VERIFY_PROGRESS_DIR}/${name}`, paths: [path], mtimeMs: statSync(path).mtimeMs }];
|
|
65
|
+
});
|
|
66
|
+
}
|
|
44
67
|
function runsIn(root) {
|
|
45
68
|
let dates;
|
|
46
69
|
try {
|
|
@@ -68,9 +91,11 @@ function runsIn(root) {
|
|
|
68
91
|
export function pruneLogs(root, retention, opts = {}) {
|
|
69
92
|
const nowMs = opts.nowMs ?? clock.now();
|
|
70
93
|
const { runs, dateDirs } = runsIn(root);
|
|
71
|
-
const
|
|
94
|
+
const receipts = verifyProgressIn(root);
|
|
72
95
|
const cutoff = nowMs - retention.ttlDays * 86_400_000;
|
|
73
|
-
|
|
96
|
+
// Receipts keep their own `keepLatest`: a project's many proofs never crowd out its runs, or the reverse.
|
|
97
|
+
const expired = (pool) => [...pool].sort((a, b) => b.mtimeMs - a.mtimeMs).slice(retention.keepLatest).filter((r) => r.mtimeMs < cutoff);
|
|
98
|
+
const doomed = [...expired(runs), ...expired(receipts)];
|
|
74
99
|
if (opts.dryRun !== true) {
|
|
75
100
|
for (const r of doomed)
|
|
76
101
|
for (const p of r.paths)
|
|
@@ -80,6 +105,6 @@ export function pruneLogs(root, retention, opts = {}) {
|
|
|
80
105
|
rmdirSync(d);
|
|
81
106
|
}
|
|
82
107
|
}
|
|
83
|
-
return { root, removed: doomed.map((r) => r.key).sort(), keptRuns: runs.length - doomed.length };
|
|
108
|
+
return { root, removed: doomed.map((r) => r.key).sort(), keptRuns: runs.length + receipts.length - doomed.length };
|
|
84
109
|
}
|
|
85
110
|
//# sourceMappingURL=logs-retention.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-retention.js","sourceRoot":"","sources":["../src/logs-retention.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"logs-retention.js","sourceRoot":"","sources":["../src/logs-retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `text` with every value in it replaced, whatever its case, longest value first. A host reaches here
|
|
3
|
+
* lower-cased and in punycode, as `URL` has it, so a value is looked for in that form too.
|
|
4
|
+
*/
|
|
5
|
+
export declare function maskValues(text: string, values: readonly string[], mask: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { domainToASCII } from "node:url";
|
|
2
|
+
/**
|
|
3
|
+
* `text` with every value in it replaced, whatever its case, longest value first. A host reaches here
|
|
4
|
+
* lower-cased and in punycode, as `URL` has it, so a value is looked for in that form too.
|
|
5
|
+
*/
|
|
6
|
+
export function maskValues(text, values, mask) {
|
|
7
|
+
const forms = values.flatMap((v) => (v === "" ? [] : [v, domainToASCII(v)])).filter((f) => f !== "");
|
|
8
|
+
return [...new Set(forms)]
|
|
9
|
+
.sort((a, b) => b.length - a.length)
|
|
10
|
+
.reduce((out, form) => out.split(new RegExp(form.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "giu")).join(mask), text);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=mask-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask-values.js","sourceRoot":"","sources":["../src/mask-values.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,MAAyB,EAAE,IAAY;IAC9E,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACrG,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;SACvB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;SACnC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;AACvH,CAAC"}
|
package/dist/mcp-api.d.ts
CHANGED
|
@@ -96,6 +96,8 @@ export interface McpApiDeps {
|
|
|
96
96
|
environmentsFile?: string;
|
|
97
97
|
/** `~/.jevitate/targets.json` override (environment sessions, verify_fix target config). */
|
|
98
98
|
targetsConfigPath?: string;
|
|
99
|
+
/** #790: test seam for the logs root run records go under (default: the project's `.jevitate/logs`). */
|
|
100
|
+
runRecordLogsRoot?: string;
|
|
99
101
|
/**
|
|
100
102
|
* #255 (`run_journey {selfHeal: hybrid|full}`): builds the self-heal gateways exactly as the CLI's
|
|
101
103
|
* `--real`/`--fake-ai` do (`buildExploreGateways`). Absent: a heal mode is refused (setup_required).
|
package/dist/mcp-api.js
CHANGED
|
@@ -3,9 +3,12 @@ import { withSiteGate } from "./site-gate-cli.js";
|
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
import { ALLOWED_TOOLS, FORBIDDEN_TOOLS } from "@jevitate/mcp-facade";
|
|
6
|
-
import { envCredentialStore } from "@jevitate/ai-core";
|
|
6
|
+
import { ALL_CREDENTIAL_KEYS, envCredentialStore } from "@jevitate/ai-core";
|
|
7
7
|
import { safeRunPolicy as defaultRunPolicy } from "@jevitate/domain";
|
|
8
8
|
import { runJourneyProgrammatically } from "./journey-api.js";
|
|
9
|
+
import { assertMcpRunnable } from "./journey-stale-api.js";
|
|
10
|
+
import { runAsMcpInvocation } from "./approval-provenance.js";
|
|
11
|
+
import { withJourneyRunRecord } from "./journey-run-record.js";
|
|
9
12
|
import { runVerifyFix } from "./verify-fix-api.js";
|
|
10
13
|
import { defaultMcpPathRoots } from "./mcp-paths.js";
|
|
11
14
|
import { currentEngineInfo } from "./engine.js";
|
|
@@ -44,10 +47,16 @@ function assertAllowlisted(name) {
|
|
|
44
47
|
*/
|
|
45
48
|
export function buildMcpTools(deps) {
|
|
46
49
|
const runJourney = deps.runJourney ??
|
|
47
|
-
((id, params, storageState, o) =>
|
|
50
|
+
((id, params, storageState, o) =>
|
|
51
|
+
// #789: an MCP invocation, so the run guard applies (and an approval made here would say `mcp`).
|
|
52
|
+
runAsMcpInvocation(() => withJourneyRunRecord({ channel: "mcp", id, params, logsRoot: deps.runRecordLogsRoot }, (runRecorder) => withSiteGate(deps.sitePolicyDbPath, (siteGate) => runJourneyProgrammatically({
|
|
48
53
|
dir: deps.journeysDir,
|
|
49
54
|
id,
|
|
50
55
|
params,
|
|
56
|
+
runRecorder,
|
|
57
|
+
// #788: only a promoted Journey with a current approval runs over MCP, refused before any browser.
|
|
58
|
+
assertRunnable: (stored) => assertMcpRunnable(stored, deps.journeysDir),
|
|
59
|
+
...(deps.targetsConfigPath === undefined ? {} : { runGuardTargetsFile: deps.targetsConfigPath }),
|
|
51
60
|
policy: o?.policy ?? defaultRunPolicy(),
|
|
52
61
|
...(storageState !== undefined ? { storageState } : {}),
|
|
53
62
|
...(siteGate === undefined ? {} : { siteGate }),
|
|
@@ -60,7 +69,7 @@ export function buildMcpTools(deps) {
|
|
|
60
69
|
...(o?.fixtures === undefined ? {} : { fixtures: o.fixtures }),
|
|
61
70
|
...(o?.actionDeltas === true ? { actionDeltas: true } : {}),
|
|
62
71
|
...(o?.stepResponseTimeoutMs === undefined ? {} : { stepResponseTimeoutMs: o.stepResponseTimeoutMs }),
|
|
63
|
-
})));
|
|
72
|
+
})))));
|
|
64
73
|
const pathRoots = deps.pathRoots ?? defaultMcpPathRoots();
|
|
65
74
|
const credentialStore = deps.credentialStore ?? envCredentialStore();
|
|
66
75
|
// verify_fix: replays a persisted finding by (result id, fingerprint) — never a caller-supplied
|
|
@@ -71,8 +80,15 @@ export function buildMcpTools(deps) {
|
|
|
71
80
|
const verifyFixImpl = deps.verifyFix ??
|
|
72
81
|
((a) => runVerifyFix({
|
|
73
82
|
targets: loadTargetsFile(deps.targetsConfigPath),
|
|
83
|
+
...(deps.targetsConfigPath === undefined ? {} : { runGuardTargetsFile: deps.targetsConfigPath }),
|
|
74
84
|
resultPath: a.resultPath,
|
|
75
85
|
fingerprint: a.fingerprint,
|
|
86
|
+
// #767: the tool's report is persisted too (the terminal layer does nothing inside an MCP
|
|
87
|
+
// call, by design) — the returned `resultPath` names it.
|
|
88
|
+
resultArtifact: true,
|
|
89
|
+
// Masked from the report and its artifact, as the CLI masks `--secret`: a tool call has no such
|
|
90
|
+
// argument, and runVerifyFix adds what it resolves itself (invariant auth tokens, fixture secrets).
|
|
91
|
+
secrets: ALL_CREDENTIAL_KEYS.flatMap((key) => credentialStore.read(key) ?? []),
|
|
76
92
|
...(a.storageState === undefined ? {} : { storageState: a.storageState }),
|
|
77
93
|
...(a.browser === undefined ? {} : { browser: a.browser }),
|
|
78
94
|
...(a.replays === undefined ? {} : { replays: a.replays }),
|
package/dist/mcp-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-api.js","sourceRoot":"","sources":["../src/mcp-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAuB,MAAM,oCAAoC,CAAC;AACxH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAwE,MAAM,sBAAsB,CAAC;AAG5I,OAAO,EAAE,kBAAkB,EAAuE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-api.js","sourceRoot":"","sources":["../src/mcp-api.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-cli-runner.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ import { type Command } from "commander";
|
|
|
17
17
|
* into a typed usage refusal (exit 64).
|
|
18
18
|
* - `process.exitCode` (how every action reports its contract code) is saved, read and restored,
|
|
19
19
|
* and calls are serialised, so one call's code never leaks into another's or into the server's.
|
|
20
|
+
* - #787: a read that must answer while a long call holds the queue (`journey verify --status`) runs
|
|
21
|
+
* beside it. It touches no shared state: only its own refusal sets an exit code, undone at once.
|
|
20
22
|
* - #437: every call runs inside `runAsMcpInvocation`, so an approval it makes (`promote_journey`,
|
|
21
23
|
* `approve_demo`) never prompts and is recorded with provenance channel `mcp`.
|
|
22
24
|
*/
|
|
@@ -25,7 +27,11 @@ export interface CliRunOutcome {
|
|
|
25
27
|
readonly stdout: string;
|
|
26
28
|
/** The command's contract exit code (exit-codes.ts). */
|
|
27
29
|
readonly exitCode: number;
|
|
30
|
+
/** #789: the run guard ended a replay in this call: the tool's answer, however the command handled the error. */
|
|
31
|
+
readonly refusal?: Error;
|
|
28
32
|
}
|
|
29
|
-
export type McpCliRunner = (argv: readonly string[]
|
|
33
|
+
export type McpCliRunner = (argv: readonly string[], options?: {
|
|
34
|
+
readonly unqueued?: boolean;
|
|
35
|
+
}) => Promise<CliRunOutcome>;
|
|
30
36
|
/** A runner over `build()` — called once per invocation, so no program state is shared between calls. */
|
|
31
37
|
export declare function makeInProcessCliRunner(build: () => Command): McpCliRunner;
|
package/dist/mcp-cli-runner.js
CHANGED
|
@@ -18,13 +18,16 @@ export function makeInProcessCliRunner(build) {
|
|
|
18
18
|
}, () => undefined);
|
|
19
19
|
const saved = process.exitCode;
|
|
20
20
|
process.exitCode = undefined;
|
|
21
|
+
const invocation = {};
|
|
21
22
|
try {
|
|
22
23
|
// #437: an approval made inside an MCP tool call is recorded as channel `mcp` (an agent's).
|
|
23
|
-
await runAsMcpInvocation(() => program.parseAsync([...argv], { from: "user" }));
|
|
24
|
+
await runAsMcpInvocation(() => program.parseAsync([...argv], { from: "user" }), invocation);
|
|
24
25
|
const code = process.exitCode;
|
|
25
|
-
return { stdout, exitCode: code === undefined ? 0 : Number(code) };
|
|
26
|
+
return { stdout, exitCode: code === undefined ? 0 : Number(code), ...(invocation.refusal === undefined ? {} : { refusal: invocation.refusal }) };
|
|
26
27
|
}
|
|
27
28
|
catch (err) {
|
|
29
|
+
if (invocation.refusal !== undefined)
|
|
30
|
+
return { stdout, exitCode: EXIT_CODES.inconclusive, refusal: invocation.refusal };
|
|
28
31
|
if (err instanceof CommanderError) {
|
|
29
32
|
const envelope = { v: 1, ok: false, error: { code: "E_CLI_USAGE", message: err.message.replace(/^error: /, "") } };
|
|
30
33
|
return { stdout: `${stdout}${JSON.stringify(envelope)}\n`, exitCode: EXIT_CODES.usage };
|
|
@@ -37,7 +40,31 @@ export function makeInProcessCliRunner(build) {
|
|
|
37
40
|
process.exitCode = saved;
|
|
38
41
|
}
|
|
39
42
|
};
|
|
40
|
-
|
|
43
|
+
// Only file reads and resolved promises, so no call in the queue can run in between. A call's own exit code is never reset: it may hold the queue's.
|
|
44
|
+
const runBeside = async (argv) => {
|
|
45
|
+
let stdout = "";
|
|
46
|
+
const program = build();
|
|
47
|
+
configureTree(program, (s) => {
|
|
48
|
+
stdout += s;
|
|
49
|
+
}, () => undefined);
|
|
50
|
+
const held = process.exitCode;
|
|
51
|
+
try {
|
|
52
|
+
await runAsMcpInvocation(() => program.parseAsync([...argv], { from: "user" }));
|
|
53
|
+
return { stdout, exitCode: process.exitCode === held ? 0 : Number(process.exitCode) };
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const usage = err instanceof CommanderError;
|
|
57
|
+
const envelope = { v: 1, ok: false, error: { code: usage ? "E_CLI_USAGE" : "E_CLI_INTERNAL", message: err instanceof Error ? err.message.replace(/^error: /, "") : String(err) } };
|
|
58
|
+
return { stdout: `${stdout}${JSON.stringify(envelope)}\n`, exitCode: usage ? EXIT_CODES.usage : EXIT_CODES.inconclusive };
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
if (process.exitCode !== held)
|
|
62
|
+
process.exitCode = held;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return (argv, options) => {
|
|
66
|
+
if (options?.unqueued === true)
|
|
67
|
+
return runBeside(argv);
|
|
41
68
|
const next = queue.then(() => runOne(argv));
|
|
42
69
|
queue = next.catch(() => undefined);
|
|
43
70
|
return next;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-cli-runner.js","sourceRoot":"","sources":["../src/mcp-cli-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAgB,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"mcp-cli-runner.js","sourceRoot":"","sources":["../src/mcp-cli-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-cli-tools.d.ts
CHANGED
|
@@ -79,6 +79,11 @@ export interface CliCommandSpec {
|
|
|
79
79
|
readonly params: Readonly<Record<string, CliParam>>;
|
|
80
80
|
/** Every flag of the command that is NOT an MCP argument, with why (checked by the parity guard). */
|
|
81
81
|
readonly omitted: Readonly<Record<string, string>>;
|
|
82
|
+
/**
|
|
83
|
+
* The Journeys a `--param` of this command goes to, so a secret parameter's value is refused before
|
|
84
|
+
* the command runs (secret-params.ts). Every command taking `--param` has one (checked by a guard).
|
|
85
|
+
*/
|
|
86
|
+
readonly paramJourneys?: (args: McpArgs) => readonly unknown[];
|
|
82
87
|
}
|
|
83
88
|
export interface CliToolSpec {
|
|
84
89
|
readonly name: string;
|
|
@@ -86,6 +91,8 @@ export interface CliToolSpec {
|
|
|
86
91
|
/** One command, or several selected by an `action` argument (a family of small commands). */
|
|
87
92
|
readonly command?: CliCommandSpec;
|
|
88
93
|
readonly actions?: Readonly<Record<string, CliCommandSpec>>;
|
|
94
|
+
/** #787: this call only reads, and must answer while a long call of the same server holds the queue. */
|
|
95
|
+
readonly answersWhileBusy?: (args: McpArgs) => boolean;
|
|
89
96
|
}
|
|
90
97
|
export declare const OMIT: {
|
|
91
98
|
readonly json: "always set: the tool returns the command's JSON envelope";
|
|
@@ -93,7 +100,7 @@ export declare const OMIT: {
|
|
|
93
100
|
readonly browserBin: "which browser binary, channel and Chromium switches launch is the operator's setting (the server's own launch), never an MCP argument";
|
|
94
101
|
readonly storeDir: "store and results locations are the server's (the `jevitate mcp` defaults / --dir): an MCP argument never picks which directory is read or written as a store";
|
|
95
102
|
readonly envSecret: "binds an environment variable (or a literal secret) the run types or redacts: a request never chooses which of the operator's variables is read — secret fields come from targets.json (secretFields/personas)";
|
|
96
|
-
readonly mcpOrigins: "#484:
|
|
103
|
+
readonly mcpOrigins: "#484: a request adds no origin to a replay's allowlist by flag: over MCP use 'env' (an environment in environments.json), or verify-fix --allow on the CLI. Where a tool takes 'baseUrl', that argument can still name an origin the configuration doesn't know (docs/safety.md)";
|
|
97
104
|
readonly logCmd: "server-log sources can run commands and read arbitrary files: operator-declared only (targets.json logSources/allowLogCmd)";
|
|
98
105
|
readonly logTriage: "#313: sends the run's recorded log text (redacted) to the judgment model — an operator opt-in for their own logs, never a request's choice";
|
|
99
106
|
readonly hangWrites: "re-sending a paid/destructive write is the operator's call (targets.json safety.hangReplayWrites)";
|
|
@@ -136,4 +143,5 @@ export declare function runCliTool(spec: CliToolSpec, args: McpArgs, deps: {
|
|
|
136
143
|
runCli?: McpCliRunner;
|
|
137
144
|
roots: readonly string[];
|
|
138
145
|
redact: (text: string) => string;
|
|
146
|
+
journeysDir: string;
|
|
139
147
|
}): Promise<CliToolOutcome>;
|
package/dist/mcp-cli-tools.js
CHANGED
|
@@ -3,6 +3,8 @@ import { confineMcpPath, McpPathError } from "./mcp-paths.js";
|
|
|
3
3
|
import { resolve as resolvePath } from "node:path";
|
|
4
4
|
import { homeDataRoot } from "./project-dir.js";
|
|
5
5
|
import { CATALOG_EXPORT_FORMATS } from "./catalog-bundle-api.js";
|
|
6
|
+
import { RunGuardRefusedError, runGuardRefusalBody } from "./mcp-run-guard.js";
|
|
7
|
+
import { secretParamRefusalBody, secretParamsCarried } from "./secret-params.js";
|
|
6
8
|
// ── Why a flag is not an MCP argument ──────────────────────────────────────────────────────────
|
|
7
9
|
export const OMIT = {
|
|
8
10
|
json: "always set: the tool returns the command's JSON envelope",
|
|
@@ -10,7 +12,7 @@ export const OMIT = {
|
|
|
10
12
|
browserBin: "which browser binary, channel and Chromium switches launch is the operator's setting (the server's own launch), never an MCP argument",
|
|
11
13
|
storeDir: "store and results locations are the server's (the `jevitate mcp` defaults / --dir): an MCP argument never picks which directory is read or written as a store",
|
|
12
14
|
envSecret: "binds an environment variable (or a literal secret) the run types or redacts: a request never chooses which of the operator's variables is read — secret fields come from targets.json (secretFields/personas)",
|
|
13
|
-
mcpOrigins: "#484:
|
|
15
|
+
mcpOrigins: "#484: a request adds no origin to a replay's allowlist by flag: over MCP use 'env' (an environment in environments.json), or verify-fix --allow on the CLI. Where a tool takes 'baseUrl', that argument can still name an origin the configuration doesn't know (docs/safety.md)",
|
|
14
16
|
logCmd: "server-log sources can run commands and read arbitrary files: operator-declared only (targets.json logSources/allowLogCmd)",
|
|
15
17
|
logTriage: "#313: sends the run's recorded log text (redacted) to the judgment model — an operator opt-in for their own logs, never a request's choice",
|
|
16
18
|
hangWrites: "re-sending a paid/destructive write is the operator's call (targets.json safety.hangReplayWrites)",
|
|
@@ -231,6 +233,7 @@ export const CLI_TOOL_SPECS = [
|
|
|
231
233
|
"With approve: true, applies the reviewed draft (shows the diff; refused with E_JOURNEY_ANNOTATIONS_STALE if the Journey changed since the draft) — the same proposal/approval semantics as the CLI. Drafting needs real or fakeAi.",
|
|
232
234
|
command: {
|
|
233
235
|
path: "journey annotate",
|
|
236
|
+
paramJourneys: (a) => [a["id"]],
|
|
234
237
|
params: { ...EXTENSION, id: pos(), approve: b("--approve"), params: { kind: "params", flag: "--param" }, storageState: session("--storage-state"), fixtures: path("--fixtures"), fixtureIdentity: FIXTURE_IDENTITY, screenshots: { kind: "screenshots", flag: "--screenshots" }, actionDeltas: b("--action-deltas"), ...ENVIRONMENT, ...EMULATION, ...AI },
|
|
235
238
|
omitted: { ...LOCATION_FLAGS, "--dir": OMIT.storeDir, ...HOOK_FLAGS, ...BROWSER_FLAGS, ...JSON_FLAG },
|
|
236
239
|
},
|
|
@@ -240,6 +243,7 @@ export const CLI_TOOL_SPECS = [
|
|
|
240
243
|
description: "`jevitate journey demo <id>` (#248): replay a Journey as a narrated demo — a WebM video with .vtt subtitles (video: a .webm path) and/or a Markdown step-by-step guide with screenshots (guide: a .md path). A Journey that no longer replays fails (exit 1). Paths inside the project or ~/.jevitate.",
|
|
241
244
|
command: {
|
|
242
245
|
path: "journey demo",
|
|
246
|
+
paramJourneys: (a) => [a["id"]],
|
|
243
247
|
params: {
|
|
244
248
|
id: pos(),
|
|
245
249
|
...EXTENSION,
|
|
@@ -261,14 +265,17 @@ export const CLI_TOOL_SPECS = [
|
|
|
261
265
|
},
|
|
262
266
|
{
|
|
263
267
|
name: "verify_journey",
|
|
264
|
-
description: "`jevitate journey verify <id> --plan|--mutate` (#402): plan previews the exact mutations, assertion pairings, unpaired assertions and minimum replay count without opening a browser; mutate proves each assertion can fail by replaying the Journey
|
|
268
|
+
description: "`jevitate journey verify <id> --plan|--mutate|--status` (#402): plan previews the exact mutations, assertion pairings, unpaired assertions and minimum replay count without opening a browser; mutate proves each assertion can fail by replaying the Journey as recorded, then once per mutation, with independence, control and closing replays around them. Mutations only skip steps, abort the app's own writes or alter checked non-secret inputs; nothing is fabricated. status (#787) reads a proof's durable progress and whether its verifier is live, exited or stale: no browser, no hook, nothing of the app's. resume, with mutate, continues an interrupted proof of the same Journey and configuration, reusing finished pairs after the base replay passes again; any mismatch, a damaged or over-24h checkpoint, or a live verifier is refused by name (data.reason) and never starts over. Set exactly one of plan, mutate or status.",
|
|
265
269
|
command: {
|
|
266
270
|
path: "journey verify",
|
|
271
|
+
paramJourneys: (a) => [a["id"]],
|
|
267
272
|
params: {
|
|
268
273
|
id: pos(),
|
|
269
274
|
...EXTENSION,
|
|
270
275
|
mutate: b("--mutate"),
|
|
271
276
|
plan: b("--plan"),
|
|
277
|
+
status: b("--status"),
|
|
278
|
+
resume: b("--resume"),
|
|
272
279
|
params: { kind: "params", flag: "--param" },
|
|
273
280
|
storageState: session("--storage-state"),
|
|
274
281
|
fixtures: path("--fixtures"),
|
|
@@ -278,12 +285,15 @@ export const CLI_TOOL_SPECS = [
|
|
|
278
285
|
},
|
|
279
286
|
omitted: { ...LOCATION_FLAGS, "--dir": OMIT.storeDir, "--allow": OMIT.mcpOrigins, ...HOOK_FLAGS, ...BROWSER_FLAGS, ...JSON_FLAG },
|
|
280
287
|
},
|
|
288
|
+
// The command takes `status` first and runs no proof, whatever else is set.
|
|
289
|
+
answersWhileBusy: (args) => args["status"] === true,
|
|
281
290
|
},
|
|
282
291
|
{
|
|
283
292
|
name: "journey_readiness",
|
|
284
293
|
description: "`jevitate journey readiness <id> [--with <toId>] --json` (#581): one readiness receipt for a Journey or a linked pair — lint, schema, the #582 handoff, the #583 boundary, strict review, annotations, catalog links/approvals, the recorded mutation proof (fresh only while bound to the current review hash) and promotion, each pass / fail / inconclusive / stale / not-run / awaiting-human. mode: report (default; no browser, sends nothing) | replay (baseline run, or the chain for a pair with requests) | prove (replay plus verify --mutate). replay/prove need env or baseUrl, refuse an environment flagged production and refuse missing params by name, all before any browser. verdict: technically-ready (exit 0) | blocked (1) | inconclusive / incomplete (2); a passing replay never hides an inconclusive proof. Approvals are listed under awaitingHuman and never acted on; the receipt carries no param value, page text or secret.",
|
|
285
294
|
command: {
|
|
286
295
|
path: "journey readiness",
|
|
296
|
+
paramJourneys: (a) => [a["id"], a["with"]],
|
|
287
297
|
params: {
|
|
288
298
|
id: pos(),
|
|
289
299
|
with: s("--with"),
|
|
@@ -318,6 +328,7 @@ export const CLI_TOOL_SPECS = [
|
|
|
318
328
|
description: "`jevitate journey chain --from <discover> --to <reply> --requests <file>` (#580): run a discover Journey once, then a prepare-only reply Journey once per approved request in the JSON Lines file ({commentId, account, replyText}) matched to a discovered record by commentId AND account. Both Journeys must be promoted. #608: params supplies explicit producer (discover) params, validated against the producer's schema before anything runs. Unmatched requests never run; an empty discovery stops the chain (no target is guessed). The result names ids and outcomes only, never record or reply text. Exit 0 only when every request matched and its run was ok.",
|
|
319
329
|
command: {
|
|
320
330
|
path: "journey chain",
|
|
331
|
+
paramJourneys: (a) => [a["from"], a["to"]],
|
|
321
332
|
params: {
|
|
322
333
|
from: s("--from", { required: true }),
|
|
323
334
|
to: s("--to", { required: true }),
|
|
@@ -400,6 +411,7 @@ export const CLI_TOOL_SPECS = [
|
|
|
400
411
|
"For a PROMOTED target prefer queue_exploration (queue + poll). Model-driven strategies need real or fakeAi. Media: recordVideo, screenshots, evidenceVideo. Sessions: storageState, persona/actor entries 'name=<storageState path>'; authCheck (off/auto/urlExcludes:/selector:) ends a run on an expired session as auth-expired (inconclusive), re-signing a persona in once when its personas file declares login parameters.",
|
|
401
412
|
command: {
|
|
402
413
|
path: "explore",
|
|
414
|
+
paramJourneys: (a) => [a["fromJourney"]],
|
|
403
415
|
params: { tags: TAGS, ...EXTENSION,
|
|
404
416
|
url: s("--url"),
|
|
405
417
|
targetId: s("--target"),
|
|
@@ -760,6 +772,7 @@ export const CLI_TOOL_SPECS = [
|
|
|
760
772
|
description: "`jevitate load run <journeyId>`: replay a Journey concurrently (concurrency × iterations) against an authorized origin and report latency/errors.",
|
|
761
773
|
command: {
|
|
762
774
|
path: "load run",
|
|
775
|
+
paramJourneys: (a) => [a["journeyId"]],
|
|
763
776
|
params: {
|
|
764
777
|
tags: TAGS,
|
|
765
778
|
journeyId: pos(),
|
|
@@ -914,6 +927,8 @@ export const CLI_TOOL_SPECS = [
|
|
|
914
927
|
remove: { path: "source remove", params: { name: pos() }, omitted: JSON_FLAG },
|
|
915
928
|
run: {
|
|
916
929
|
path: "source run",
|
|
930
|
+
// The Journey is resolved through the source's run gate: runSourceJourney refuses there.
|
|
931
|
+
paramJourneys: () => [],
|
|
917
932
|
params: { tags: TAGS, ...EXTENSION, name: pos(), journeyId: pos(), params: { kind: "params", flag: "--param" }, storageState: session("--storage-state"), ...EMULATION },
|
|
918
933
|
omitted: { ...BROWSER_FLAGS, ...JSON_FLAG },
|
|
919
934
|
},
|
|
@@ -1174,12 +1189,22 @@ export async function runCliTool(spec, args, deps) {
|
|
|
1174
1189
|
throw err;
|
|
1175
1190
|
return { isError: true, body };
|
|
1176
1191
|
}
|
|
1192
|
+
const paramJourneys = commandFor(spec, args).paramJourneys;
|
|
1193
|
+
if (paramJourneys !== undefined) {
|
|
1194
|
+
const carried = await secretParamsCarried(deps.journeysDir, paramJourneys(args), args["params"]);
|
|
1195
|
+
if (carried.length > 0)
|
|
1196
|
+
return { isError: true, body: secretParamRefusalBody(carried) };
|
|
1197
|
+
}
|
|
1177
1198
|
if (deps.runCli === undefined) {
|
|
1178
1199
|
return { isError: true, body: { error: "not_configured", message: `${spec.name} runs \`jevitate ${commandFor(spec, args).path}\` in process, which this server was not given` } };
|
|
1179
1200
|
}
|
|
1180
|
-
const { stdout: raw, exitCode } = await deps.runCli(argv);
|
|
1201
|
+
const { stdout: raw, exitCode, refusal } = await (spec.answersWhileBusy?.(args) === true ? deps.runCli(argv, { unqueued: true }) : deps.runCli(argv));
|
|
1181
1202
|
const stdout = deps.redact(raw);
|
|
1182
1203
|
let envelope = lastEnvelope(stdout);
|
|
1204
|
+
// #789: a refused replay is the answer, whatever the command made of it. What the command did report before it stays beside it.
|
|
1205
|
+
if (refusal instanceof RunGuardRefusedError) {
|
|
1206
|
+
return { isError: true, body: { ...runGuardRefusalBody(refusal), ...(envelope?.data === undefined || envelope.data === null ? {} : { partial: envelope.data }) } };
|
|
1207
|
+
}
|
|
1183
1208
|
if (envelope === undefined && exitCode === 0) {
|
|
1184
1209
|
// A command without --json (`recording promote`) prints its result as plain JSON.
|
|
1185
1210
|
try {
|
|
@@ -1192,7 +1217,7 @@ export async function runCliTool(spec, args, deps) {
|
|
|
1192
1217
|
if (envelope === undefined)
|
|
1193
1218
|
return { isError: true, body: { error: "internal", message: "the command printed no JSON envelope", exitCode } };
|
|
1194
1219
|
if (!envelope.ok) {
|
|
1195
|
-
return { isError: true, body: { error: exitCode === 64 ? "invalid_args" : "refused", code: envelope.error?.code ?? "E_UNKNOWN", message: envelope.error?.message ?? "refused", exitCode } };
|
|
1220
|
+
return { isError: true, body: { error: exitCode === 64 ? "invalid_args" : "refused", code: envelope.error?.code ?? "E_UNKNOWN", message: envelope.error?.message ?? "refused", exitCode, ...(envelope.data === undefined ? {} : { data: envelope.data }) } };
|
|
1196
1221
|
}
|
|
1197
1222
|
// 0/1/3/4 are answers; 2 (proved nothing) is never a pass.
|
|
1198
1223
|
return { isError: exitCode === 2 || exitCode >= 64, body: { exitCode, data: envelope.data ?? null } };
|