@jevitate/cli 0.2.0 → 0.4.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/ai-cli.d.ts +31 -11
- package/dist/ai-cli.js +100 -67
- package/dist/ai-cli.js.map +1 -1
- package/dist/author-journey-cli.js +3 -1
- package/dist/author-journey-cli.js.map +1 -1
- package/dist/bin.js +48715 -40027
- package/dist/browser-run-options.d.ts +32 -1
- package/dist/browser-run-options.js +69 -0
- package/dist/browser-run-options.js.map +1 -1
- package/dist/build-info.generated.js +2 -2
- package/dist/campaign-api.d.ts +153 -0
- package/dist/campaign-api.js +447 -0
- package/dist/campaign-api.js.map +1 -0
- package/dist/campaign-cli.d.ts +8 -0
- package/dist/campaign-cli.js +109 -0
- package/dist/campaign-cli.js.map +1 -0
- package/dist/check-api.js +3 -2
- package/dist/check-api.js.map +1 -1
- package/dist/check-budget.js +2 -1
- package/dist/check-budget.js.map +1 -1
- package/dist/check-execute.d.ts +4 -0
- package/dist/check-execute.js +46 -10
- package/dist/check-execute.js.map +1 -1
- package/dist/check-plan.d.ts +5 -0
- package/dist/check-plan.js +77 -4
- package/dist/check-plan.js.map +1 -1
- package/dist/check-suite.d.ts +14 -1
- package/dist/check-suite.js +26 -1
- package/dist/check-suite.js.map +1 -1
- package/dist/cli-output.d.ts +4 -0
- package/dist/cli-output.js +52 -5
- package/dist/cli-output.js.map +1 -1
- package/dist/cli-shared.d.ts +13 -3
- package/dist/cli-shared.js +52 -7
- package/dist/cli-shared.js.map +1 -1
- package/dist/defect-evidence.d.ts +3 -2
- package/dist/defect-evidence.js +12 -8
- package/dist/defect-evidence.js.map +1 -1
- package/dist/demo-aspect-api.js +2 -1
- package/dist/demo-aspect-api.js.map +1 -1
- package/dist/demo-aspect-cli.js +3 -1
- package/dist/demo-aspect-cli.js.map +1 -1
- package/dist/demo-capture.d.ts +37 -3
- package/dist/demo-capture.js +119 -20
- package/dist/demo-capture.js.map +1 -1
- package/dist/explore-adversarial.d.ts +11 -4
- package/dist/explore-adversarial.js +22 -13
- package/dist/explore-adversarial.js.map +1 -1
- package/dist/explore-cli.js +282 -31
- package/dist/explore-cli.js.map +1 -1
- package/dist/explore-coverage.d.ts +17 -2
- package/dist/explore-coverage.js +20 -14
- package/dist/explore-coverage.js.map +1 -1
- package/dist/explore-feature.d.ts +0 -2
- package/dist/explore-feature.js +7 -9
- package/dist/explore-feature.js.map +1 -1
- package/dist/explore-goal.d.ts +25 -7
- package/dist/explore-goal.js +62 -19
- package/dist/explore-goal.js.map +1 -1
- package/dist/explore-shared.d.ts +53 -3
- package/dist/explore-shared.js +48 -1
- package/dist/explore-shared.js.map +1 -1
- package/dist/fixture-auth.d.ts +13 -2
- package/dist/fixture-auth.js +19 -6
- package/dist/fixture-auth.js.map +1 -1
- package/dist/fixture-cli.d.ts +29 -0
- package/dist/fixture-cli.js +121 -7
- package/dist/fixture-cli.js.map +1 -1
- package/dist/github-issue-filer.js +2 -1
- package/dist/github-issue-filer.js.map +1 -1
- package/dist/host-health-run.d.ts +2 -1
- package/dist/host-health-run.js +8 -2
- package/dist/host-health-run.js.map +1 -1
- package/dist/init-cli.js +34 -5
- package/dist/init-cli.js.map +1 -1
- package/dist/init-keys.d.ts +11 -0
- package/dist/init-keys.js +5 -2
- package/dist/init-keys.js.map +1 -1
- package/dist/journey-annotate-api.js +17 -4
- package/dist/journey-annotate-api.js.map +1 -1
- package/dist/journey-annotate-cli.js +3 -1
- package/dist/journey-annotate-cli.js.map +1 -1
- package/dist/journey-api.d.ts +26 -1
- package/dist/journey-api.js +51 -25
- package/dist/journey-api.js.map +1 -1
- package/dist/journey-cli.d.ts +1 -1
- package/dist/journey-cli.js +44 -3
- package/dist/journey-cli.js.map +1 -1
- package/dist/journey-demo-api.d.ts +2 -0
- package/dist/journey-demo-api.js +23 -10
- package/dist/journey-demo-api.js.map +1 -1
- package/dist/journey-demo-cli.js +5 -2
- package/dist/journey-demo-cli.js.map +1 -1
- package/dist/journey-prefix.d.ts +194 -0
- package/dist/journey-prefix.js +279 -0
- package/dist/journey-prefix.js.map +1 -0
- package/dist/key-report.d.ts +49 -0
- package/dist/key-report.js +101 -0
- package/dist/key-report.js.map +1 -0
- package/dist/kill-signal.js +0 -1
- package/dist/kill-signal.js.map +1 -1
- package/dist/ledger-api.js +3 -1
- package/dist/ledger-api.js.map +1 -1
- package/dist/log-correlation.d.ts +63 -1
- package/dist/log-correlation.js +125 -16
- package/dist/log-correlation.js.map +1 -1
- package/dist/log-sources.js +6 -5
- package/dist/log-sources.js.map +1 -1
- package/dist/log-trace.d.ts +80 -0
- package/dist/log-trace.js +210 -0
- package/dist/log-trace.js.map +1 -0
- package/dist/logs-cli.js +60 -1
- package/dist/logs-cli.js.map +1 -1
- package/dist/logs-retention.js +2 -1
- package/dist/logs-retention.js.map +1 -1
- package/dist/masked-input.d.ts +22 -0
- package/dist/masked-input.js +99 -0
- package/dist/masked-input.js.map +1 -0
- package/dist/mcp-api.d.ts +3 -1
- package/dist/mcp-api.js +49 -7
- package/dist/mcp-api.js.map +1 -1
- package/dist/mcp-args.d.ts +12 -0
- package/dist/mcp-args.js +33 -0
- package/dist/mcp-args.js.map +1 -1
- package/dist/mcp-cli-tools.d.ts +6 -1
- package/dist/mcp-cli-tools.js +103 -16
- package/dist/mcp-cli-tools.js.map +1 -1
- package/dist/mission-api.js +2 -1
- package/dist/mission-api.js.map +1 -1
- package/dist/mission-cli.js +3 -1
- package/dist/mission-cli.js.map +1 -1
- package/dist/mission-fixtures.d.ts +10 -1
- package/dist/mission-fixtures.js +49 -15
- package/dist/mission-fixtures.js.map +1 -1
- package/dist/mission-queue-runner.d.ts +2 -0
- package/dist/mission-queue-runner.js +18 -5
- package/dist/mission-queue-runner.js.map +1 -1
- package/dist/multi-run-cli.js +7 -1
- package/dist/multi-run-cli.js.map +1 -1
- package/dist/openrouter-call.js +3 -2
- package/dist/openrouter-call.js.map +1 -1
- package/dist/program.js +4 -0
- package/dist/program.js.map +1 -1
- package/dist/project-dir.js +3 -2
- package/dist/project-dir.js.map +1 -1
- package/dist/record-api.d.ts +3 -1
- package/dist/record-api.js +5 -2
- package/dist/record-api.js.map +1 -1
- package/dist/record-cli.js +14 -2
- package/dist/record-cli.js.map +1 -1
- package/dist/regression-api.d.ts +6 -0
- package/dist/regression-api.js +4 -2
- package/dist/regression-api.js.map +1 -1
- package/dist/regression-cli.js +56 -4
- package/dist/regression-cli.js.map +1 -1
- package/dist/report-api.js +2 -1
- package/dist/report-api.js.map +1 -1
- package/dist/resource-preflight.d.ts +87 -0
- package/dist/resource-preflight.js +160 -0
- package/dist/resource-preflight.js.map +1 -0
- package/dist/result-schema.d.ts +1 -1
- package/dist/result-schema.js +1 -1
- package/dist/run-key-preflight.d.ts +42 -0
- package/dist/run-key-preflight.js +82 -0
- package/dist/run-key-preflight.js.map +1 -0
- package/dist/run-screenshots.js +11 -5
- package/dist/run-screenshots.js.map +1 -1
- package/dist/runtime-env.js +3 -2
- package/dist/runtime-env.js.map +1 -1
- package/dist/server-log-verify.d.ts +2 -0
- package/dist/server-log-verify.js +8 -3
- package/dist/server-log-verify.js.map +1 -1
- package/dist/signal-triage.d.ts +147 -0
- package/dist/signal-triage.js +281 -0
- package/dist/signal-triage.js.map +1 -0
- package/dist/site-gate-cli.js +2 -1
- package/dist/site-gate-cli.js.map +1 -1
- package/dist/source-api.js +2 -1
- package/dist/source-api.js.map +1 -1
- package/dist/suite-explore-options.d.ts +36 -0
- package/dist/suite-explore-options.js +23 -0
- package/dist/suite-explore-options.js.map +1 -1
- package/dist/target-config.d.ts +12 -0
- package/dist/target-config.js +15 -0
- package/dist/target-config.js.map +1 -1
- package/dist/type-fixture-file.d.ts +9 -0
- package/dist/type-fixture-file.js +48 -0
- package/dist/type-fixture-file.js.map +1 -0
- package/dist/ui-api.js +4 -3
- package/dist/ui-api.js.map +1 -1
- package/dist/usability-capture.js +4 -3
- package/dist/usability-capture.js.map +1 -1
- package/dist/usage-config.d.ts +1 -1
- package/dist/usage-config.js +1 -1
- package/dist/ux-claim-probe.d.ts +45 -0
- package/dist/ux-claim-probe.js +386 -0
- package/dist/ux-claim-probe.js.map +1 -0
- package/dist/ux-cli.js +8 -1
- package/dist/ux-cli.js.map +1 -1
- package/dist/ux-product.d.ts +14 -0
- package/dist/ux-product.js +39 -0
- package/dist/ux-product.js.map +1 -0
- package/dist/ux-review.d.ts +4 -0
- package/dist/ux-review.js +27 -7
- package/dist/ux-review.js.map +1 -1
- package/dist/ux-usability.d.ts +34 -9
- package/dist/ux-usability.js +102 -16
- package/dist/ux-usability.js.map +1 -1
- package/dist/verify-fix-api.d.ts +21 -0
- package/dist/verify-fix-api.js +85 -33
- package/dist/verify-fix-api.js.map +1 -1
- package/dist/verify-fix-cli.js +7 -2
- package/dist/verify-fix-cli.js.map +1 -1
- package/package.json +11 -11
- package/skills/jevitate-explore/SKILL.md +13 -0
- package/skills/jevitate-getting-started/SKILL.md +2 -1
- package/skills/jevitate-test-campaign/SKILL.md +206 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { redactUrl } from "@jevitate/ai-core";
|
|
2
|
+
import { LogSpecError } from "./log-lines.js";
|
|
3
|
+
import { clock } from "@jevitate/domain";
|
|
4
|
+
/**
|
|
5
|
+
* Request ↔ backend-log correlation by TRACE / CORRELATION ID (#204), instead of by time window.
|
|
6
|
+
*
|
|
7
|
+
* The browser side (`RequestIdLedger`) records, for every request the run's page sends, the ids it
|
|
8
|
+
* carries: W3C `traceparent` (its trace-id), `x-request-id`, `x-correlation-id`, `request-id`,
|
|
9
|
+
* `x-amzn-trace-id` (its `Root`), `x-b3-traceid`, `x-cloud-trace-context` (its trace) — on the
|
|
10
|
+
* REQUEST (a frontend with OpenTelemetry) or the RESPONSE (a server-generated request id) — plus
|
|
11
|
+
* any operator-named header (`--log-correlation-header`). The log side (`lineIds`) finds those
|
|
12
|
+
* ids in a backend log line: any whitespace/punctuation-delimited token equal to a recorded id
|
|
13
|
+
* (exact — never a prefix or a substring of a longer token).
|
|
14
|
+
*
|
|
15
|
+
* `ServerLogRuntime` then attaches a line that carries a run's id to EXACTLY that request (method,
|
|
16
|
+
* URL, status) and to the step that sent it — whatever time the line landed — and falls back to the
|
|
17
|
+
* time window only for lines with no id. Once ids demonstrably correlate (at least one line matched
|
|
18
|
+
* a run's id), a line carrying a DIFFERENT id (`foreignIds`: a `trace_id=`/`request_id=` key, a
|
|
19
|
+
* `traceparent`, or an operator `--log-id-pattern`) belongs to other work — another user, a
|
|
20
|
+
* background job — and is never attributed to this run.
|
|
21
|
+
*
|
|
22
|
+
* Ids are not secrets, but every URL is redacted and every attached line is redacted with the run's
|
|
23
|
+
* secrets, as before.
|
|
24
|
+
*/
|
|
25
|
+
/** Headers whose value identifies a request across the browser and the backend (lower-case). */
|
|
26
|
+
export const DEFAULT_CORRELATION_HEADERS = [
|
|
27
|
+
"traceparent",
|
|
28
|
+
"x-request-id",
|
|
29
|
+
"x-correlation-id",
|
|
30
|
+
"request-id",
|
|
31
|
+
"x-amzn-trace-id",
|
|
32
|
+
"x-b3-traceid",
|
|
33
|
+
"x-cloud-trace-context",
|
|
34
|
+
];
|
|
35
|
+
/** An id shorter than this would match unrelated tokens (a "1", a "200"): never used. */
|
|
36
|
+
const MIN_ID_CHARS = 8;
|
|
37
|
+
const MAX_ID_CHARS = 128;
|
|
38
|
+
const ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
39
|
+
const TRACEPARENT = /^[0-9a-f]{2}-([0-9a-f]{32})-[0-9a-f]{16}-[0-9a-f]{2}$/i;
|
|
40
|
+
const HEADER_NAME = /^[A-Za-z0-9!#$%&'*+.^_`|~-]{1,64}$/;
|
|
41
|
+
/** Most requests the ledger keeps (the oldest are dropped past it). */
|
|
42
|
+
const MAX_REQUESTS = 5_000;
|
|
43
|
+
/** Normalizes an id for comparison (hex trace ids are case-insensitive in practice). */
|
|
44
|
+
const norm = (id) => id.toLowerCase();
|
|
45
|
+
function usable(id) {
|
|
46
|
+
const v = id.trim();
|
|
47
|
+
if (v.length < MIN_ID_CHARS || v.length > MAX_ID_CHARS || !ID_SHAPE.test(v))
|
|
48
|
+
return null;
|
|
49
|
+
// An all-zero trace id is the W3C "invalid" value: it identifies nothing.
|
|
50
|
+
if (/^0+$/.test(v.replace(/[-:.]/g, "")))
|
|
51
|
+
return null;
|
|
52
|
+
return v;
|
|
53
|
+
}
|
|
54
|
+
/** The correlation id(s) a header value carries. */
|
|
55
|
+
export function idsFromHeader(name, value) {
|
|
56
|
+
const n = name.toLowerCase();
|
|
57
|
+
const v = value.trim();
|
|
58
|
+
let candidates;
|
|
59
|
+
if (n === "traceparent") {
|
|
60
|
+
const m = TRACEPARENT.exec(v);
|
|
61
|
+
candidates = m === null ? [] : [m[1]];
|
|
62
|
+
}
|
|
63
|
+
else if (n === "x-amzn-trace-id") {
|
|
64
|
+
const root = /(?:^|;)\s*Root=([^;]+)/i.exec(v);
|
|
65
|
+
candidates = root === null ? [] : [root[1]];
|
|
66
|
+
}
|
|
67
|
+
else if (n === "x-cloud-trace-context") {
|
|
68
|
+
candidates = [v.split("/")[0] ?? ""];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
candidates = v.split(",").map((s) => s.trim());
|
|
72
|
+
}
|
|
73
|
+
return candidates.map(usable).filter((x) => x !== null);
|
|
74
|
+
}
|
|
75
|
+
/** Validates `--log-correlation-header` names (fails closed on the first bad one). */
|
|
76
|
+
export function parseCorrelationHeaders(raw) {
|
|
77
|
+
return raw.map((h) => {
|
|
78
|
+
const v = h.trim().toLowerCase();
|
|
79
|
+
if (!HEADER_NAME.test(v))
|
|
80
|
+
throw new LogSpecError(`--log-correlation-header: not a header name: ${JSON.stringify(h)}`);
|
|
81
|
+
return v;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Parses `--log-id-pattern` values: `/regex/flags` whose first capture group (or whole match) is a
|
|
86
|
+
* correlation id in a log line of the operator's own format. Bounded and compiled once.
|
|
87
|
+
*/
|
|
88
|
+
export function parseLogIdPatterns(raw) {
|
|
89
|
+
return raw.map((p) => {
|
|
90
|
+
const m = /^\/(.+)\/([a-z]*)$/s.exec(p);
|
|
91
|
+
if (m === null)
|
|
92
|
+
throw new LogSpecError(`--log-id-pattern must be /regex/flags, got ${JSON.stringify(p)}`);
|
|
93
|
+
if (m[1].length > 500)
|
|
94
|
+
throw new LogSpecError("--log-id-pattern is too long (max 500 chars)");
|
|
95
|
+
try {
|
|
96
|
+
const flags = m[2].replace(/[gy]/g, "");
|
|
97
|
+
return new RegExp(m[1], `${flags}g`);
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
throw new LogSpecError(`--log-id-pattern: invalid regex ${JSON.stringify(p)}: ${e instanceof Error ? e.message : String(e)}`);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/** Records every request a run's page sends with its correlation ids (#204). */
|
|
105
|
+
export class RequestIdLedger {
|
|
106
|
+
#headers;
|
|
107
|
+
#now;
|
|
108
|
+
#byRequest = new WeakMap();
|
|
109
|
+
#byId = new Map();
|
|
110
|
+
#requests = [];
|
|
111
|
+
constructor(opts = {}) {
|
|
112
|
+
this.#headers = new Set([...DEFAULT_CORRELATION_HEADERS, ...(opts.headers ?? []).map((h) => h.toLowerCase())]);
|
|
113
|
+
this.#now = opts.now ?? clock.now;
|
|
114
|
+
}
|
|
115
|
+
/** Starts listening on a page (call before its first navigation). */
|
|
116
|
+
observe(page) {
|
|
117
|
+
page.on("request", (r) => {
|
|
118
|
+
let rec;
|
|
119
|
+
let headers;
|
|
120
|
+
try {
|
|
121
|
+
rec = { method: r.method().toUpperCase(), url: redactUrl(r.url()), status: null, startedAtMs: this.#now(), ids: [] };
|
|
122
|
+
headers = r.headers();
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return; // a request whose page is already gone: nothing to correlate
|
|
126
|
+
}
|
|
127
|
+
this.#byRequest.set(r, rec);
|
|
128
|
+
this.#requests.push(rec);
|
|
129
|
+
if (this.#requests.length > MAX_REQUESTS) {
|
|
130
|
+
const old = this.#requests.shift();
|
|
131
|
+
for (const id of old?.ids ?? [])
|
|
132
|
+
if (this.#byId.get(norm(id)) === old)
|
|
133
|
+
this.#byId.delete(norm(id));
|
|
134
|
+
}
|
|
135
|
+
this.#addIds(rec, headers);
|
|
136
|
+
});
|
|
137
|
+
page.on("response", (res) => {
|
|
138
|
+
try {
|
|
139
|
+
const rec = this.#byRequest.get(res.request());
|
|
140
|
+
if (rec === undefined)
|
|
141
|
+
return;
|
|
142
|
+
rec.status = res.status();
|
|
143
|
+
this.#addIds(rec, res.headers());
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// a response whose page is already gone: nothing more to learn
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
#addIds(rec, headers) {
|
|
151
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
152
|
+
if (!this.#headers.has(name.toLowerCase()))
|
|
153
|
+
continue;
|
|
154
|
+
for (const id of idsFromHeader(name, value)) {
|
|
155
|
+
if (rec.ids.includes(id))
|
|
156
|
+
continue;
|
|
157
|
+
rec.ids.push(id);
|
|
158
|
+
// The same id on two requests (a trace spanning several calls): the first sender owns it.
|
|
159
|
+
if (!this.#byId.has(norm(id)))
|
|
160
|
+
this.#byId.set(norm(id), rec);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** How many requests carried at least one id. */
|
|
165
|
+
get requestsWithIds() {
|
|
166
|
+
return this.#requests.filter((r) => r.ids.length > 0).length;
|
|
167
|
+
}
|
|
168
|
+
/** The request a log line belongs to (by an id it carries), or undefined. */
|
|
169
|
+
requestFor(raw) {
|
|
170
|
+
if (this.#byId.size === 0)
|
|
171
|
+
return undefined;
|
|
172
|
+
for (const token of tokens(raw)) {
|
|
173
|
+
const hit = this.#byId.get(norm(token));
|
|
174
|
+
if (hit !== undefined)
|
|
175
|
+
return { request: hit, id: token };
|
|
176
|
+
const tp = TRACEPARENT.exec(token);
|
|
177
|
+
if (tp !== null) {
|
|
178
|
+
const t = this.#byId.get(norm(tp[1]));
|
|
179
|
+
if (t !== undefined)
|
|
180
|
+
return { request: t, id: tp[1] };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/** The tokens of a log line an id can be (delimited by anything an id cannot contain). */
|
|
187
|
+
function tokens(raw) {
|
|
188
|
+
return raw.split(/[^A-Za-z0-9._:-]+/).filter((t) => t.length >= MIN_ID_CHARS && t.length <= 200);
|
|
189
|
+
}
|
|
190
|
+
/** Built-in id keys: `trace_id=…`, `"traceId": "…"`, `request-id: …`, `correlationId=…`, `x-request-id=…`. */
|
|
191
|
+
const KEYED_ID = /(?:^|[^A-Za-z0-9])(?:x-)?(?:trace|request|req|correlation|corr)[_.-]?id["']?\s*[:=]\s*["']?([A-Za-z0-9][A-Za-z0-9._:-]{7,127})/gi;
|
|
192
|
+
const TRACEPARENT_IN_TEXT = /\b[0-9a-f]{2}-([0-9a-f]{32})-[0-9a-f]{16}-[0-9a-f]{2}\b/gi;
|
|
193
|
+
/**
|
|
194
|
+
* The correlation ids a log line DECLARES (#204): a keyed id (`trace_id=`, `"requestId":`, …), a
|
|
195
|
+
* `traceparent`, or an operator `--log-id-pattern` match. Used to tell another request's line
|
|
196
|
+
* (foreign) from one with no id at all (time-window fallback).
|
|
197
|
+
*/
|
|
198
|
+
export function declaredIds(raw, patterns = []) {
|
|
199
|
+
const out = new Set();
|
|
200
|
+
for (const re of [KEYED_ID, TRACEPARENT_IN_TEXT, ...patterns]) {
|
|
201
|
+
re.lastIndex = 0;
|
|
202
|
+
for (const m of raw.matchAll(re)) {
|
|
203
|
+
const id = usable(m[1] ?? m[0]);
|
|
204
|
+
if (id !== null)
|
|
205
|
+
out.add(id);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return [...out];
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=log-trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-trace.js","sourceRoot":"","sources":["../src/log-trace.ts"],"names":[],"mappings":"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"}
|
package/dist/logs-cli.js
CHANGED
|
@@ -2,7 +2,11 @@ import { ok, fail } from "./envelope.js";
|
|
|
2
2
|
import { LogsConfigError, loadLogsRetention, pruneLogs } from "./logs-retention.js";
|
|
3
3
|
import { logsRoot } from "./project-dir.js";
|
|
4
4
|
import { resolveDataDir } from "./data-dir.js";
|
|
5
|
-
import {
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { buildExploreGateways, emitJson } from "./cli-shared.js";
|
|
7
|
+
import { LITERAL_SECRET_WARNING, SecretArgError, resolveSecretArgs } from "./secret-args.js";
|
|
8
|
+
import { signalsPathFor, triageRunResult } from "./signal-triage.js";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
6
10
|
/** The commands that write run output under `.jevitate/logs` — pruned before, when auto-prune is on. */
|
|
7
11
|
const LOG_WRITING_COMMANDS = new Set(["explore", "explore-author-journey", "record", "ux", "check", "run", "verify-fix", "capture"]);
|
|
8
12
|
export function registerLogsCommands(program, deps) {
|
|
@@ -47,5 +51,60 @@ export function registerLogsCommands(program, deps) {
|
|
|
47
51
|
emitJson(program, fail("E_LOGS_PRUNE", err instanceof Error ? err.message : String(err)));
|
|
48
52
|
}
|
|
49
53
|
});
|
|
54
|
+
logs
|
|
55
|
+
.command("triage")
|
|
56
|
+
.description("#313: re-triage a finished run's signals (<run>.signals.jsonl, written by explore --log-triage): attach to each defect only the lines that relate to it " +
|
|
57
|
+
"(defects[].relatedLogs) — the lines correlated to its request, then, with --real, the window lines Jev scores relevant (else its error/warning lines). Rewrites the result")
|
|
58
|
+
.requiredOption("--result <path>", "the run's <run>.result.json (its <run>.signals.jsonl must sit next to it)")
|
|
59
|
+
.option("--secret <value|env:VAR>", "a value to keep out of the judgment payload (repeatable; env:VAR reads it from the environment)", (v, prev) => [...prev, v], [])
|
|
60
|
+
.option("--threshold <p>", "Jev relevance probability at or above which a line is kept (default 0.5)", (v) => Number(v))
|
|
61
|
+
.option("--real", "score relevance with the live Jev gateway (requires keys; log text goes to the judgment model, redacted)", false)
|
|
62
|
+
.option("--fake-ai", "no model: keep the correlated lines and the window's error/warning lines (code only)", false)
|
|
63
|
+
.option("--json", "emit a JSON envelope")
|
|
64
|
+
.action(async function () {
|
|
65
|
+
const o = this.opts();
|
|
66
|
+
const emit = (envelope) => emitJson(program, envelope);
|
|
67
|
+
if (o.real === true && o.fakeAi === true)
|
|
68
|
+
return emit(fail("E_LOGS_ARGS", "--real and --fake-ai are mutually exclusive — pass one, not both"));
|
|
69
|
+
if (o.threshold !== undefined && !(o.threshold >= 0 && o.threshold <= 1))
|
|
70
|
+
return emit(fail("E_LOGS_ARGS", "--threshold must be a probability in 0..1"));
|
|
71
|
+
if (!existsSync(signalsPathFor(o.result))) {
|
|
72
|
+
return emit(fail("E_LOGS_ARGS", `no signals next to ${o.result} (${signalsPathFor(o.result)}): run explore with --log-source and --log-triage first`));
|
|
73
|
+
}
|
|
74
|
+
let secrets;
|
|
75
|
+
try {
|
|
76
|
+
const resolved = resolveSecretArgs(o.secret, process.env, "--secret");
|
|
77
|
+
if (resolved.literals > 0)
|
|
78
|
+
program.configureOutput().writeErr?.(LITERAL_SECRET_WARNING);
|
|
79
|
+
secrets = resolved.secrets;
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
if (err instanceof SecretArgError)
|
|
83
|
+
return emit(fail("E_LOGS_ARGS", err.message));
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const file = JSON.parse(readFileSync(o.result, "utf8"));
|
|
88
|
+
if (typeof file.result !== "object" || file.result === null)
|
|
89
|
+
return emit(fail("E_LOGS_ARGS", `${o.result} is not a jevitate run result`));
|
|
90
|
+
const judge = o.real === true ? (await buildExploreGateways(deps, { real: true, fakeAi: false })).judge : undefined;
|
|
91
|
+
const updated = await triageRunResult(file.result, o.result, {
|
|
92
|
+
secrets,
|
|
93
|
+
...(judge === undefined ? {} : { judge }),
|
|
94
|
+
...(o.threshold === undefined ? {} : { threshold: o.threshold }),
|
|
95
|
+
});
|
|
96
|
+
const defects = (Array.isArray(updated.defects) ? updated.defects : []);
|
|
97
|
+
const data = { resultPath: o.result, signals: updated.signals, defects: defects.map((d) => ({ fingerprint: d.fingerprint, relatedLogs: d.relatedLogs ?? [] })) };
|
|
98
|
+
if (o.json === true)
|
|
99
|
+
emit(ok(data));
|
|
100
|
+
else {
|
|
101
|
+
const s = updated.signals;
|
|
102
|
+
program.configureOutput().writeOut?.(`triaged ${defects.length} defect(s) over ${s.entries} signal(s) (${s.triage.mode}): kept ${s.triage.kept} of ${s.triage.candidates} candidate line(s), ${s.triage.jevCalls} Jev call(s)\nresult ${o.result}\n`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
emit(fail("E_LOGS_TRIAGE", err instanceof Error ? err.message : String(err)));
|
|
107
|
+
}
|
|
108
|
+
});
|
|
50
109
|
}
|
|
51
110
|
//# sourceMappingURL=logs-cli.js.map
|
package/dist/logs-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-cli.js","sourceRoot":"","sources":["../src/logs-cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAgB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"logs-cli.js","sourceRoot":"","sources":["../src/logs-cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAgB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,wGAAwG;AACxG,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,wBAAwB,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAErI,MAAM,UAAU,oBAAoB,CAAC,OAAgB,EAAE,IAAa;IAClE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,cAAc,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAC5E,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC1C,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBAAE,OAAO;YACrD,4FAA4F;YAC5F,2FAA2F;YAC3F,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAChD,IAAI,CAAC;gBACH,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxG,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,8DAA8D,CAAC,CAAC;IACjH,IAAI;SACD,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,2IAA2I,CAAC;SACxJ,MAAM,CAAC,aAAa,EAAE,mFAAmF,CAAC;SAC1G,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC;SACnE,MAAM,CAAC,QAAQ,EAAE,sBAAsB,CAAC;SACxC,MAAM,CAAC;QACN,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAsD,CAAC;QAC1E,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI,QAAQ,EAAE,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACpI,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACjE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;gBAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;;gBAC5C,OAAO,CAAC,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,MAAM,CAAC,QAAQ,SAAS,SAAS,CAAC,OAAO,kBAAkB,SAAS,CAAC,UAAU,KAAK,CAAC,CAAC;QAC7N,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,eAAe;gBAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;;gBAC9E,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACjG,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CACV,0JAA0J;QACxJ,4KAA4K,CAC/K;SACA,cAAc,CAAC,iBAAiB,EAAE,2EAA2E,CAAC;SAC9G,MAAM,CAAC,0BAA0B,EAAE,iGAAiG,EAAE,CAAC,CAAS,EAAE,IAAc,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,EAAc,CAAC;SAClM,MAAM,CAAC,iBAAiB,EAAE,0EAA0E,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SAC/H,MAAM,CAAC,QAAQ,EAAE,0GAA0G,EAAE,KAAK,CAAC;SACnI,MAAM,CAAC,WAAW,EAAE,sFAAsF,EAAE,KAAK,CAAC;SAClH,MAAM,CAAC,QAAQ,EAAE,sBAAsB,CAAC;SACxC,MAAM,CAAC,KAAK;QACX,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAA8G,CAAC;QAClI,MAAM,IAAI,GAAG,CAAC,QAAwC,EAAQ,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,kEAAkE,CAAC,CAAC,CAAC;QAC/I,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,2CAA2C,CAAC,CAAC,CAAC;QACxJ,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC,CAAC;QACzJ,CAAC;QACD,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YACtE,IAAI,QAAQ,CAAC,QAAQ,GAAG,CAAC;gBAAE,OAAO,CAAC,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,sBAAsB,CAAC,CAAC;YACxF,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,cAAc;gBAAE,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACjF,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAyC,CAAC;YAChG,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,MAAM,+BAA+B,CAAC,CAAC,CAAC;YAC1I,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;YACpH,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;gBAC3D,OAAO;gBACP,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;gBACzC,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;aACjE,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAA6D,CAAC;YACpI,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;YACjK,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;gBAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;iBAC/B,CAAC;gBACJ,MAAM,CAAC,GAAG,OAAO,CAAC,OAA4G,CAAC;gBAC/H,OAAO,CAAC,eAAe,EAAE,CAAC,QAAQ,EAAE,CAAC,WAAW,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,UAAU,uBAAuB,CAAC,CAAC,MAAM,CAAC,QAAQ,0BAA0B,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;YAC1P,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChF,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/logs-retention.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
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
|
+
import { clock } from "@jevitate/domain";
|
|
4
5
|
export const DEFAULT_LOGS_RETENTION = { ttlDays: 14, keepLatest: 50 };
|
|
5
6
|
export class LogsConfigError extends Error {
|
|
6
7
|
code = "E_LOGS_CONFIG";
|
|
@@ -65,7 +66,7 @@ function runsIn(root) {
|
|
|
65
66
|
}
|
|
66
67
|
/** Applies `retention` to the logs under `root`. `dryRun` reports what would go, deleting nothing. */
|
|
67
68
|
export function pruneLogs(root, retention, opts = {}) {
|
|
68
|
-
const nowMs = opts.nowMs ??
|
|
69
|
+
const nowMs = opts.nowMs ?? clock.now();
|
|
69
70
|
const { runs, dateDirs } = runsIn(root);
|
|
70
71
|
const newestFirst = [...runs].sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
71
72
|
const cutoff = nowMs - retention.ttlDays * 86_400_000;
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"logs-retention.js","sourceRoot":"","sources":["../src/logs-retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #269 — masked key entry. The previous prompt muted readline's echo by hooking its private
|
|
3
|
+
* `_writeToOutput`, but readline's line refresh still moved the cursor and cleared the screen below
|
|
4
|
+
* it on every keystroke: the instructions printed before the prompt vanished as soon as the user
|
|
5
|
+
* typed ("flash off too fast to read"), and nothing showed that input was being received.
|
|
6
|
+
*
|
|
7
|
+
* This reader never clears anything: the instructions stay on their own line, and each typed (or
|
|
8
|
+
* pasted) character is echoed as `•` — never the character itself. Backspace erases one mark,
|
|
9
|
+
* Ctrl-U erases all, Enter finishes, Ctrl-C / Ctrl-D (on an empty entry) cancel. Without a TTY
|
|
10
|
+
* (piped input) it reads one line and echoes nothing. The value is only ever returned to the
|
|
11
|
+
* caller; it is never written to `output`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const MASK_CHAR = "\u2022";
|
|
14
|
+
export interface MaskedInput extends NodeJS.ReadableStream {
|
|
15
|
+
readonly isTTY?: boolean;
|
|
16
|
+
setRawMode?(mode: boolean): unknown;
|
|
17
|
+
}
|
|
18
|
+
/** Key entry was cancelled (Ctrl-C, Ctrl-D, or the input ended): nothing was entered. */
|
|
19
|
+
export declare class KeyEntryCancelledError extends Error {
|
|
20
|
+
constructor();
|
|
21
|
+
}
|
|
22
|
+
export declare function readMaskedLine(input: MaskedInput, output: NodeJS.WritableStream, message: string): Promise<string>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #269 — masked key entry. The previous prompt muted readline's echo by hooking its private
|
|
3
|
+
* `_writeToOutput`, but readline's line refresh still moved the cursor and cleared the screen below
|
|
4
|
+
* it on every keystroke: the instructions printed before the prompt vanished as soon as the user
|
|
5
|
+
* typed ("flash off too fast to read"), and nothing showed that input was being received.
|
|
6
|
+
*
|
|
7
|
+
* This reader never clears anything: the instructions stay on their own line, and each typed (or
|
|
8
|
+
* pasted) character is echoed as `•` — never the character itself. Backspace erases one mark,
|
|
9
|
+
* Ctrl-U erases all, Enter finishes, Ctrl-C / Ctrl-D (on an empty entry) cancel. Without a TTY
|
|
10
|
+
* (piped input) it reads one line and echoes nothing. The value is only ever returned to the
|
|
11
|
+
* caller; it is never written to `output`.
|
|
12
|
+
*/
|
|
13
|
+
export const MASK_CHAR = "•";
|
|
14
|
+
/** Key entry was cancelled (Ctrl-C, Ctrl-D, or the input ended): nothing was entered. */
|
|
15
|
+
export class KeyEntryCancelledError extends Error {
|
|
16
|
+
constructor() {
|
|
17
|
+
super("key entry cancelled — nothing was stored");
|
|
18
|
+
this.name = "KeyEntryCancelledError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function readMaskedLine(input, output, message) {
|
|
22
|
+
const raw = input.isTTY === true && typeof input.setRawMode === "function";
|
|
23
|
+
output.write(`${message}\n> `);
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
let value = "";
|
|
26
|
+
let done = false;
|
|
27
|
+
const finish = (err) => {
|
|
28
|
+
if (done)
|
|
29
|
+
return;
|
|
30
|
+
done = true;
|
|
31
|
+
input.removeListener("data", onData);
|
|
32
|
+
input.removeListener("end", onEnd);
|
|
33
|
+
if (raw)
|
|
34
|
+
input.setRawMode?.(false);
|
|
35
|
+
input.pause();
|
|
36
|
+
output.write("\n");
|
|
37
|
+
if (err === null)
|
|
38
|
+
resolve(value);
|
|
39
|
+
else
|
|
40
|
+
reject(err);
|
|
41
|
+
};
|
|
42
|
+
const onEnd = () => {
|
|
43
|
+
// Piped input that ends without a newline still delivers what it held; an empty one is a cancel.
|
|
44
|
+
if (value.length > 0)
|
|
45
|
+
finish(null);
|
|
46
|
+
else
|
|
47
|
+
finish(new KeyEntryCancelledError());
|
|
48
|
+
};
|
|
49
|
+
const onData = (chunk) => {
|
|
50
|
+
const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
51
|
+
// An escape sequence (arrow keys, function keys) is navigation, never part of a key.
|
|
52
|
+
if (raw && text.startsWith("\u001b"))
|
|
53
|
+
return;
|
|
54
|
+
for (const ch of text) {
|
|
55
|
+
if (ch === "\r" || ch === "\n") {
|
|
56
|
+
finish(null);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!raw) {
|
|
60
|
+
value += ch;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (ch === "\u0003") {
|
|
64
|
+
finish(new KeyEntryCancelledError());
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (ch === "\u0004") {
|
|
68
|
+
if (value.length === 0)
|
|
69
|
+
finish(new KeyEntryCancelledError());
|
|
70
|
+
else
|
|
71
|
+
finish(null);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (ch === "\u007f" || ch === "\b") {
|
|
75
|
+
if (value.length > 0) {
|
|
76
|
+
value = [...value].slice(0, -1).join("");
|
|
77
|
+
output.write("\b \b");
|
|
78
|
+
}
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (ch === "\u0015") {
|
|
82
|
+
output.write("\b \b".repeat([...value].length));
|
|
83
|
+
value = "";
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (ch < " ")
|
|
87
|
+
continue; // other control characters
|
|
88
|
+
value += ch;
|
|
89
|
+
output.write(MASK_CHAR);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
if (raw)
|
|
93
|
+
input.setRawMode?.(true);
|
|
94
|
+
input.on("data", onData);
|
|
95
|
+
input.on("end", onEnd);
|
|
96
|
+
input.resume();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=masked-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masked-input.js","sourceRoot":"","sources":["../src/masked-input.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-api.d.ts
CHANGED
|
@@ -51,13 +51,15 @@ export interface McpJourneyRunOptions {
|
|
|
51
51
|
readonly emulation?: EmulationSpec;
|
|
52
52
|
readonly screenshots?: ScreenshotsSpec;
|
|
53
53
|
readonly fixtures?: (site: string) => MissionFixtures | undefined;
|
|
54
|
+
/** #303: record and compare each replayed step's action delta (`--action-deltas`). */
|
|
55
|
+
readonly actionDeltas?: boolean;
|
|
54
56
|
}
|
|
55
57
|
/**
|
|
56
58
|
* #255: what `verify_fix` hands the runner — the finding (resolved result path + fingerprint) and
|
|
57
59
|
* the CLI-parity replay options. Operator-only settings (shell hooks, `cmd:` log sources, re-sending
|
|
58
60
|
* paid/destructive hang writes, redaction literals) are never MCP arguments: targets.json decides.
|
|
59
61
|
*/
|
|
60
|
-
export type McpVerifyFixArgs = Pick<RunVerifyFixOptions, "resultPath" | "fingerprint"> & Partial<Pick<RunVerifyFixOptions, "storageState" | "browser" | "replays" | "invariantFiles" | "fixtureFlags" | "emulation" | "allowEmulationOverride" | "screenshots">>;
|
|
62
|
+
export type McpVerifyFixArgs = Pick<RunVerifyFixOptions, "resultPath" | "fingerprint"> & Partial<Pick<RunVerifyFixOptions, "storageState" | "browser" | "replays" | "invariantFiles" | "fixtureFlags" | "emulation" | "allowEmulationOverride" | "screenshots" | "actionDeltas">>;
|
|
61
63
|
export interface McpApiDeps {
|
|
62
64
|
/** Journeys store directory (`~/.jevitate/journeys` in production). */
|
|
63
65
|
journeysDir: string;
|