flakelab 0.1.0 → 0.1.2
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 +225 -38
- package/dist/analysis/blob-report.d.ts +15 -0
- package/dist/analysis/blob-report.js +137 -0
- package/dist/analysis/blob-report.js.map +1 -0
- package/dist/analysis/cli.d.ts +7 -0
- package/dist/analysis/cli.js +28 -0
- package/dist/analysis/cli.js.map +1 -0
- package/dist/analysis/schema.d.ts +175 -0
- package/dist/analysis/schema.js +34 -0
- package/dist/analysis/schema.js.map +1 -0
- package/dist/analysis/zip-archive.d.ts +6 -0
- package/dist/analysis/zip-archive.js +193 -0
- package/dist/analysis/zip-archive.js.map +1 -0
- package/dist/artifacts/paths.d.ts +3 -0
- package/dist/artifacts/paths.js +34 -0
- package/dist/artifacts/paths.js.map +1 -0
- package/dist/artifacts/retention.d.ts +1 -0
- package/dist/artifacts/retention.js +80 -0
- package/dist/artifacts/retention.js.map +1 -0
- package/dist/bisect/engine.js +0 -1
- package/dist/bisect/engine.js.map +1 -1
- package/dist/bisect/schema.d.ts +5 -6
- package/dist/bisect/schema.js +1 -2
- package/dist/bisect/schema.js.map +1 -1
- package/dist/bisect/solari-evaluator.js +9 -1
- package/dist/bisect/solari-evaluator.js.map +1 -1
- package/dist/ci/job-summary.d.ts +2 -0
- package/dist/ci/job-summary.js +120 -2
- package/dist/ci/job-summary.js.map +1 -1
- package/dist/ci/select-command.js +1 -1
- package/dist/ci/select-command.js.map +1 -1
- package/dist/ci/summary-command.js +12 -7
- package/dist/ci/summary-command.js.map +1 -1
- package/dist/cli-arguments.d.ts +44 -0
- package/dist/cli-arguments.js +356 -0
- package/dist/cli-arguments.js.map +1 -0
- package/dist/cli-command-help.d.ts +11 -0
- package/dist/cli-command-help.js +211 -0
- package/dist/cli-command-help.js.map +1 -0
- package/dist/cli-help.d.ts +5 -2
- package/dist/cli-help.js +122 -45
- package/dist/cli-help.js.map +1 -1
- package/dist/cli-option-definitions.d.ts +202 -0
- package/dist/cli-option-definitions.js +59 -0
- package/dist/cli-option-definitions.js.map +1 -0
- package/dist/cli.js +100 -100
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze-summary.d.ts +5 -0
- package/dist/commands/analyze-summary.js +89 -0
- package/dist/commands/analyze-summary.js.map +1 -0
- package/dist/commands/analyze.d.ts +6 -0
- package/dist/commands/analyze.js +128 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/bisect.d.ts +2 -2
- package/dist/commands/bisect.js +32 -3
- package/dist/commands/bisect.js.map +1 -1
- package/dist/commands/diagnose.d.ts +3 -2
- package/dist/commands/diagnose.js +355 -23
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/discover.d.ts +18 -2
- package/dist/commands/discover.js +215 -25
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +66 -25
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/investigate.d.ts +3 -2
- package/dist/commands/investigate.js +22 -3
- package/dist/commands/investigate.js.map +1 -1
- package/dist/commands/options.d.ts +123 -16
- package/dist/commands/options.js +24 -2
- package/dist/commands/options.js.map +1 -1
- package/dist/commands/prove.d.ts +2 -2
- package/dist/commands/prove.js +38 -1
- package/dist/commands/prove.js.map +1 -1
- package/dist/commands/repair.d.ts +8 -2
- package/dist/commands/repair.js +32 -9
- package/dist/commands/repair.js.map +1 -1
- package/dist/commands/replay.d.ts +2 -2
- package/dist/commands/replay.js +15 -2
- package/dist/commands/replay.js.map +1 -1
- package/dist/commands/report.d.ts +2 -2
- package/dist/commands/report.js +35 -10
- package/dist/commands/report.js.map +1 -1
- package/dist/commands/scan-summary.d.ts +7 -0
- package/dist/commands/scan-summary.js +175 -0
- package/dist/commands/scan-summary.js.map +1 -0
- package/dist/commands/scan.d.ts +9 -12
- package/dist/commands/scan.js +66 -62
- package/dist/commands/scan.js.map +1 -1
- package/dist/core/plan.js +1 -1
- package/dist/core/plan.js.map +1 -1
- package/dist/diagnosis/checkpoint.d.ts +6 -0
- package/dist/diagnosis/checkpoint.js +46 -0
- package/dist/diagnosis/checkpoint.js.map +1 -0
- package/dist/diagnosis/cli.d.ts +7 -0
- package/dist/diagnosis/cli.js +84 -0
- package/dist/diagnosis/cli.js.map +1 -0
- package/dist/diagnosis/recommendation.d.ts +13 -0
- package/dist/diagnosis/recommendation.js +95 -0
- package/dist/diagnosis/recommendation.js.map +1 -0
- package/dist/diagnosis/run-state.d.ts +52 -0
- package/dist/diagnosis/run-state.js +173 -0
- package/dist/diagnosis/run-state.js.map +1 -0
- package/dist/diagnosis/schema.d.ts +207 -0
- package/dist/diagnosis/schema.js +108 -0
- package/dist/diagnosis/schema.js.map +1 -0
- package/dist/diagnosis/solari-handoff.d.ts +9 -0
- package/dist/diagnosis/solari-handoff.js +40 -0
- package/dist/diagnosis/solari-handoff.js.map +1 -0
- package/dist/diagnosis/summary.d.ts +3 -0
- package/dist/diagnosis/summary.js +115 -0
- package/dist/diagnosis/summary.js.map +1 -0
- package/dist/discovery/auth-cookie.d.ts +19 -0
- package/dist/discovery/auth-cookie.js +26 -0
- package/dist/discovery/auth-cookie.js.map +1 -0
- package/dist/discovery/evaluate.d.ts +35 -2
- package/dist/discovery/evaluate.js +136 -30
- package/dist/discovery/evaluate.js.map +1 -1
- package/dist/discovery/event-loop.d.ts +25 -0
- package/dist/discovery/event-loop.js +84 -0
- package/dist/discovery/event-loop.js.map +1 -0
- package/dist/discovery/minimize.d.ts +61 -1
- package/dist/discovery/minimize.js +179 -7
- package/dist/discovery/minimize.js.map +1 -1
- package/dist/discovery/resource-loading.d.ts +25 -0
- package/dist/discovery/resource-loading.js +84 -0
- package/dist/discovery/resource-loading.js.map +1 -0
- package/dist/discovery/runner-environment.d.ts +26 -0
- package/dist/discovery/runner-environment.js +68 -0
- package/dist/discovery/runner-environment.js.map +1 -0
- package/dist/discovery/startup-event.d.ts +25 -0
- package/dist/discovery/startup-event.js +84 -0
- package/dist/discovery/startup-event.js.map +1 -0
- package/dist/discovery/storage-state.d.ts +26 -0
- package/dist/discovery/storage-state.js +86 -0
- package/dist/discovery/storage-state.js.map +1 -0
- package/dist/discovery/temporal-environment.d.ts +31 -0
- package/dist/discovery/temporal-environment.js +43 -0
- package/dist/discovery/temporal-environment.js.map +1 -0
- package/dist/discovery/visual-environment.d.ts +28 -0
- package/dist/discovery/visual-environment.js +42 -0
- package/dist/discovery/visual-environment.js.map +1 -0
- package/dist/domain/schema.d.ts +840 -20
- package/dist/domain/schema.js +216 -6
- package/dist/domain/schema.js.map +1 -1
- package/dist/faults/browser-context.d.ts +16 -0
- package/dist/faults/browser-context.js +60 -0
- package/dist/faults/browser-context.js.map +1 -0
- package/dist/faults/cookie-header.d.ts +5 -0
- package/dist/faults/cookie-header.js +25 -0
- package/dist/faults/cookie-header.js.map +1 -0
- package/dist/faults/document-bootstrap.d.ts +5 -0
- package/dist/faults/document-bootstrap.js +141 -0
- package/dist/faults/document-bootstrap.js.map +1 -0
- package/dist/faults/install.d.ts +1 -1
- package/dist/faults/install.js +199 -6
- package/dist/faults/install.js.map +1 -1
- package/dist/faults/pattern.d.ts +1 -0
- package/dist/faults/pattern.js +24 -0
- package/dist/faults/pattern.js.map +1 -0
- package/dist/investigator/agent.js +39 -17
- package/dist/investigator/agent.js.map +1 -1
- package/dist/investigator/ledger.d.ts +1 -1
- package/dist/investigator/ledger.js +2 -2
- package/dist/investigator/ledger.js.map +1 -1
- package/dist/investigator/safe-source.d.ts +1 -0
- package/dist/investigator/safe-source.js +12 -3
- package/dist/investigator/safe-source.js.map +1 -1
- package/dist/investigator/schema.d.ts +293 -2
- package/dist/investigator/schema.js +100 -2
- package/dist/investigator/schema.js.map +1 -1
- package/dist/proof/cli.d.ts +7 -0
- package/dist/proof/cli.js +108 -0
- package/dist/proof/cli.js.map +1 -0
- package/dist/proof/preflight.d.ts +4 -0
- package/dist/proof/preflight.js +9 -0
- package/dist/proof/preflight.js.map +1 -0
- package/dist/repair/generator.d.ts +12 -1
- package/dist/repair/generator.js +30 -6
- package/dist/repair/generator.js.map +1 -1
- package/dist/repair/remote-proof-runner.js +6 -10
- package/dist/repair/remote-proof-runner.js.map +1 -1
- package/dist/repair/schema.d.ts +77 -2
- package/dist/repair/schema.js +23 -2
- package/dist/repair/schema.js.map +1 -1
- package/dist/repair/solari-validator.d.ts +2 -0
- package/dist/repair/solari-validator.js +4 -6
- package/dist/repair/solari-validator.js.map +1 -1
- package/dist/repair/summary.d.ts +10 -0
- package/dist/repair/summary.js +58 -0
- package/dist/repair/summary.js.map +1 -0
- package/dist/repair/validator.d.ts +1 -0
- package/dist/repair/validator.js +53 -12
- package/dist/repair/validator.js.map +1 -1
- package/dist/report/bundle.js +16 -37
- package/dist/report/bundle.js.map +1 -1
- package/dist/report/model.js +131 -12
- package/dist/report/model.js.map +1 -1
- package/dist/report/open.d.ts +9 -0
- package/dist/report/open.js +23 -0
- package/dist/report/open.js.map +1 -1
- package/dist/report/report-client.css +2 -0
- package/dist/report/report-client.js +58 -0
- package/dist/report/schema.d.ts +115 -5
- package/dist/report/schema.js +24 -5
- package/dist/report/schema.js.map +1 -1
- package/dist/reproducer/schema.d.ts +89 -4
- package/dist/reproducer/schema.js +3 -4
- package/dist/reproducer/schema.js.map +1 -1
- package/dist/runner/execution-fault.d.ts +10 -0
- package/dist/runner/execution-fault.js +24 -0
- package/dist/runner/execution-fault.js.map +1 -0
- package/dist/runner/fault-proxy.d.ts +7 -0
- package/dist/runner/fault-proxy.js +366 -0
- package/dist/runner/fault-proxy.js.map +1 -0
- package/dist/runner/local.js +2 -2
- package/dist/runner/local.js.map +1 -1
- package/dist/runner/native-scan.d.ts +25 -0
- package/dist/runner/native-scan.js +306 -0
- package/dist/runner/native-scan.js.map +1 -0
- package/dist/runner/playwright-executor.d.ts +3 -0
- package/dist/runner/playwright-executor.js +125 -66
- package/dist/runner/playwright-executor.js.map +1 -1
- package/dist/runner/process-tree.d.ts +7 -0
- package/dist/runner/process-tree.js +62 -0
- package/dist/runner/process-tree.js.map +1 -0
- package/dist/runner/project-bridge.d.ts +7 -0
- package/dist/runner/project-bridge.js +83 -0
- package/dist/runner/project-bridge.js.map +1 -0
- package/dist/runner/trial-reporter.d.ts +7 -0
- package/dist/runner/trial-reporter.js +47 -0
- package/dist/runner/trial-reporter.js.map +1 -0
- package/dist/scan/failure-clusters.d.ts +24 -0
- package/dist/scan/failure-clusters.js +74 -0
- package/dist/scan/failure-clusters.js.map +1 -0
- package/dist/scan/schema.d.ts +170 -0
- package/dist/scan/schema.js +71 -0
- package/dist/scan/schema.js.map +1 -0
- package/dist/solari/executor.d.ts +5 -1
- package/dist/solari/executor.js +25 -17
- package/dist/solari/executor.js.map +1 -1
- package/dist/solari/run-demo.d.ts +13 -1
- package/dist/solari/run-demo.js +35 -16
- package/dist/solari/run-demo.js.map +1 -1
- package/dist/solari/usage.d.ts +8 -2
- package/dist/solari/usage.js +14 -4
- package/dist/solari/usage.js.map +1 -1
- package/dist/ui/boundary.d.ts +17 -0
- package/dist/ui/boundary.js +18 -0
- package/dist/ui/boundary.js.map +1 -0
- package/dist/ui/console.d.ts +4 -0
- package/dist/ui/console.js +11 -0
- package/dist/ui/console.js.map +1 -0
- package/dist/ui/document.d.ts +40 -0
- package/dist/ui/document.js +120 -0
- package/dist/ui/document.js.map +1 -0
- package/dist/ui/format.d.ts +8 -0
- package/dist/ui/format.js +32 -0
- package/dist/ui/format.js.map +1 -0
- package/dist/ui/progress.d.ts +17 -1
- package/dist/ui/progress.js +51 -8
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/status.d.ts +7 -0
- package/dist/ui/status.js +36 -0
- package/dist/ui/status.js.map +1 -0
- package/dist/ui/style.d.ts +8 -0
- package/dist/ui/style.js +22 -0
- package/dist/ui/style.js.map +1 -0
- package/dist/ui/text.d.ts +17 -0
- package/dist/ui/text.js +123 -0
- package/dist/ui/text.js.map +1 -0
- package/dist/ui/theme.d.ts +23 -0
- package/dist/ui/theme.js +77 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/trial-progress.d.ts +13 -0
- package/dist/ui/trial-progress.js +42 -0
- package/dist/ui/trial-progress.js.map +1 -0
- package/package.json +14 -19
- package/dist/faults/network-delay.d.ts +0 -5
- package/dist/faults/network-delay.js +0 -34
- package/dist/faults/network-delay.js.map +0 -1
- package/dist/faults/request-failure.d.ts +0 -5
- package/dist/faults/request-failure.js +0 -24
- package/dist/faults/request-failure.js.map +0 -1
- package/dist/playwright.d.ts +0 -3
- package/dist/playwright.js +0 -21
- package/dist/playwright.js.map +0 -1
- package/dist/report/browser-entry.d.ts +0 -2
- package/dist/report/browser-entry.js +0 -15
- package/dist/report/browser-entry.js.map +0 -1
- package/dist/report/components/artifacts.d.ts +0 -4
- package/dist/report/components/artifacts.js +0 -6
- package/dist/report/components/artifacts.js.map +0 -1
- package/dist/report/components/experiments.d.ts +0 -4
- package/dist/report/components/experiments.js +0 -7
- package/dist/report/components/experiments.js.map +0 -1
- package/dist/report/components/hypotheses.d.ts +0 -4
- package/dist/report/components/hypotheses.js +0 -26
- package/dist/report/components/hypotheses.js.map +0 -1
- package/dist/report/components/indicators.d.ts +0 -32
- package/dist/report/components/indicators.js +0 -42
- package/dist/report/components/indicators.js.map +0 -1
- package/dist/report/components/layout.d.ts +0 -29
- package/dist/report/components/layout.js +0 -20
- package/dist/report/components/layout.js.map +0 -1
- package/dist/report/components/proof.d.ts +0 -4
- package/dist/report/components/proof.js +0 -34
- package/dist/report/components/proof.js.map +0 -1
- package/dist/report/components/reproduction.d.ts +0 -4
- package/dist/report/components/reproduction.js +0 -19
- package/dist/report/components/reproduction.js.map +0 -1
- package/dist/report/components/summary.d.ts +0 -4
- package/dist/report/components/summary.js +0 -12
- package/dist/report/components/summary.js.map +0 -1
- package/dist/report/components/verdict.d.ts +0 -4
- package/dist/report/components/verdict.js +0 -27
- package/dist/report/components/verdict.js.map +0 -1
- package/dist/report/report-app.d.ts +0 -6
- package/dist/report/report-app.js +0 -16
- package/dist/report/report-app.js.map +0 -1
- package/dist/report/report-details.css +0 -182
- package/dist/report/report.css +0 -404
package/dist/ui/progress.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
import type { StatusTone } from "./status.js";
|
|
2
|
+
import type { TerminalTheme } from "./theme.js";
|
|
3
|
+
export type ProgressWriter = (chunk: string) => void;
|
|
4
|
+
export interface ProgressOptions {
|
|
5
|
+
theme?: TerminalTheme;
|
|
6
|
+
write?: ProgressWriter;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Line-oriented stage progress on stderr. It never emits cursor movement,
|
|
10
|
+
* carriage returns, or erase sequences, so a redirected or CI log is identical
|
|
11
|
+
* to what an interactive terminal shows apart from color.
|
|
12
|
+
*/
|
|
1
13
|
export declare class ProgressReporter {
|
|
2
14
|
#private;
|
|
3
|
-
|
|
15
|
+
constructor(options?: ProgressOptions);
|
|
16
|
+
start(label: string, detail?: string): void;
|
|
17
|
+
/** A subordinate observation inside the running stage. */
|
|
18
|
+
step(text: string, tone?: StatusTone): void;
|
|
4
19
|
done(detail?: string): void;
|
|
20
|
+
fail(detail?: string): void;
|
|
5
21
|
}
|
package/dist/ui/progress.js
CHANGED
|
@@ -1,16 +1,59 @@
|
|
|
1
|
+
import { formatDuration } from "./format.js";
|
|
2
|
+
import { statusMark } from "./status.js";
|
|
3
|
+
import { paint } from "./style.js";
|
|
4
|
+
import { sanitizeLine, truncate } from "./text.js";
|
|
5
|
+
import { stderrTheme } from "./theme.js";
|
|
6
|
+
const MAXIMUM_DETAIL_LENGTH = 200;
|
|
7
|
+
function defaultWriter(chunk) {
|
|
8
|
+
process.stderr.write(chunk);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Line-oriented stage progress on stderr. It never emits cursor movement,
|
|
12
|
+
* carriage returns, or erase sequences, so a redirected or CI log is identical
|
|
13
|
+
* to what an interactive terminal shows apart from color.
|
|
14
|
+
*/
|
|
1
15
|
export class ProgressReporter {
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
16
|
+
#label;
|
|
17
|
+
#startedAt = 0;
|
|
18
|
+
#theme;
|
|
19
|
+
#write;
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.#theme = options.theme ?? stderrTheme();
|
|
22
|
+
this.#write = options.write ?? defaultWriter;
|
|
23
|
+
}
|
|
24
|
+
start(label, detail) {
|
|
25
|
+
this.#label = sanitizeLine(label);
|
|
26
|
+
this.#startedAt = Date.now();
|
|
27
|
+
this.#line("running", this.#label, detail);
|
|
28
|
+
}
|
|
29
|
+
/** A subordinate observation inside the running stage. */
|
|
30
|
+
step(text, tone = "muted") {
|
|
31
|
+
this.#write(` ${statusMark(this.#theme, tone)} ${this.#detail(text)}\n`);
|
|
6
32
|
}
|
|
7
33
|
done(detail) {
|
|
8
|
-
|
|
34
|
+
this.#close("success", detail);
|
|
35
|
+
}
|
|
36
|
+
fail(detail) {
|
|
37
|
+
this.#close("failure", detail);
|
|
38
|
+
}
|
|
39
|
+
#close(tone, detail) {
|
|
40
|
+
const label = this.#label;
|
|
41
|
+
if (!label) {
|
|
9
42
|
return;
|
|
10
43
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
44
|
+
this.#label = undefined;
|
|
45
|
+
this.#line(tone, label, detail, formatDuration(Date.now() - this.#startedAt));
|
|
46
|
+
}
|
|
47
|
+
#line(tone, label, ...details) {
|
|
48
|
+
const separator = this.#theme.unicode ? " · " : " | ";
|
|
49
|
+
const suffix = details
|
|
50
|
+
.filter((detail) => detail !== undefined && detail !== "")
|
|
51
|
+
.map((detail) => this.#detail(detail));
|
|
52
|
+
const text = [paint(this.#theme, "bold", label), ...suffix].join(separator);
|
|
53
|
+
this.#write(`${statusMark(this.#theme, tone)} ${text}\n`);
|
|
54
|
+
}
|
|
55
|
+
#detail(value) {
|
|
56
|
+
return paint(this.#theme, "dim", truncate(sanitizeLine(value), MAXIMUM_DETAIL_LENGTH));
|
|
14
57
|
}
|
|
15
58
|
}
|
|
16
59
|
//# sourceMappingURL=progress.js.map
|
package/dist/ui/progress.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/ui/progress.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAgB;IAC3B,
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/ui/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { StyleName } from "./style.js";
|
|
2
|
+
import type { TerminalTheme } from "./theme.js";
|
|
3
|
+
/** The one status vocabulary shared by every FlakeLab command. */
|
|
4
|
+
export type StatusTone = "failure" | "inconclusive" | "muted" | "running" | "success" | "warning";
|
|
5
|
+
export declare function toneStyle(tone: StatusTone): StyleName;
|
|
6
|
+
/** A colored symbol. Callers always print a text label beside it. */
|
|
7
|
+
export declare function statusMark(theme: TerminalTheme, tone: StatusTone): string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { paint } from "./style.js";
|
|
2
|
+
const UNICODE_SYMBOLS = {
|
|
3
|
+
failure: "✗",
|
|
4
|
+
inconclusive: "?",
|
|
5
|
+
muted: "·",
|
|
6
|
+
running: "›",
|
|
7
|
+
success: "✓",
|
|
8
|
+
warning: "!",
|
|
9
|
+
};
|
|
10
|
+
const ASCII_SYMBOLS = {
|
|
11
|
+
failure: "x",
|
|
12
|
+
inconclusive: "?",
|
|
13
|
+
muted: "-",
|
|
14
|
+
running: ">",
|
|
15
|
+
success: "+",
|
|
16
|
+
warning: "!",
|
|
17
|
+
};
|
|
18
|
+
const TONE_STYLES = {
|
|
19
|
+
failure: "red",
|
|
20
|
+
inconclusive: "blue",
|
|
21
|
+
muted: "dim",
|
|
22
|
+
running: "cyan",
|
|
23
|
+
success: "green",
|
|
24
|
+
warning: "yellow",
|
|
25
|
+
};
|
|
26
|
+
export function toneStyle(tone) {
|
|
27
|
+
return TONE_STYLES[tone];
|
|
28
|
+
}
|
|
29
|
+
function statusSymbol(theme, tone) {
|
|
30
|
+
return theme.unicode ? UNICODE_SYMBOLS[tone] : ASCII_SYMBOLS[tone];
|
|
31
|
+
}
|
|
32
|
+
/** A colored symbol. Callers always print a text label beside it. */
|
|
33
|
+
export function statusMark(theme, tone) {
|
|
34
|
+
return paint(theme, toneStyle(tone), statusSymbol(theme, tone));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/ui/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAYlC,MAAM,eAAe,GAA+B;IAClD,OAAO,EAAE,GAAG;IACZ,YAAY,EAAE,GAAG;IACjB,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;CACb,CAAA;AAED,MAAM,aAAa,GAA+B;IAChD,OAAO,EAAE,GAAG;IACZ,YAAY,EAAE,GAAG;IACjB,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;CACb,CAAA;AAED,MAAM,WAAW,GAAkC;IACjD,OAAO,EAAE,KAAK;IACd,YAAY,EAAE,MAAM;IACpB,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,QAAQ;CAClB,CAAA;AAED,MAAM,UAAU,SAAS,CAAC,IAAgB;IACxC,OAAO,WAAW,CAAC,IAAI,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,YAAY,CAAC,KAAoB,EAAE,IAAgB;IAC1D,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;AACpE,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,UAAU,CAAC,KAAoB,EAAE,IAAgB;IAC/D,OAAO,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;AACjE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TerminalTheme } from "./theme.js";
|
|
2
|
+
export type StyleName = "blue" | "bold" | "cyan" | "dim" | "green" | "red" | "yellow";
|
|
3
|
+
/**
|
|
4
|
+
* Applies one SGR style. Only the four-bit palette is used so the output stays
|
|
5
|
+
* legible in Windows consoles and in terminals with custom themes. Cursor and
|
|
6
|
+
* erase sequences are deliberately absent: redirected output stays plain text.
|
|
7
|
+
*/
|
|
8
|
+
export declare function paint(theme: TerminalTheme, name: StyleName, value: string): string;
|
package/dist/ui/style.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const CODES = {
|
|
2
|
+
blue: [34, 39],
|
|
3
|
+
bold: [1, 22],
|
|
4
|
+
cyan: [36, 39],
|
|
5
|
+
dim: [2, 22],
|
|
6
|
+
green: [32, 39],
|
|
7
|
+
red: [31, 39],
|
|
8
|
+
yellow: [33, 39],
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Applies one SGR style. Only the four-bit palette is used so the output stays
|
|
12
|
+
* legible in Windows consoles and in terminals with custom themes. Cursor and
|
|
13
|
+
* erase sequences are deliberately absent: redirected output stays plain text.
|
|
14
|
+
*/
|
|
15
|
+
export function paint(theme, name, value) {
|
|
16
|
+
if (!theme.color || value === "") {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
const [open, close] = CODES[name];
|
|
20
|
+
return `\u001B[${open}m${value}\u001B[${close}m`;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/ui/style.ts"],"names":[],"mappings":"AAIA,MAAM,KAAK,GAAiD;IAC1D,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACd,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;IACb,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACd,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;IACZ,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACf,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;IACb,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;CACjB,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,KAAoB,EAAE,IAAe,EAAE,KAAa;IACxE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACjC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,OAAO,UAAU,IAAI,IAAI,KAAK,UAAU,KAAK,GAAG,CAAA;AAClD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Removes ANSI select-graphic-rendition and other CSI sequences. */
|
|
2
|
+
export declare function stripAnsi(value: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Makes an untrusted value safe to print: escape sequences, cursor controls, and
|
|
5
|
+
* invisible reordering characters cannot survive. Newlines are preserved.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sanitizeText(value: string): string;
|
|
8
|
+
/** Collapses an untrusted value into one safe, single-line string. */
|
|
9
|
+
export declare function sanitizeLine(value: string): string;
|
|
10
|
+
export declare function displayWidth(value: string): number;
|
|
11
|
+
export declare function padRight(value: string, width: number): string;
|
|
12
|
+
export declare function truncate(value: string, maximum: number): string;
|
|
13
|
+
/**
|
|
14
|
+
* Wraps on word boundaries only. A long path or identifier is never broken, so
|
|
15
|
+
* every printed value stays selectable and copyable.
|
|
16
|
+
*/
|
|
17
|
+
export declare function wrapText(value: string, width: number): string[];
|
package/dist/ui/text.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const ESCAPE = 0x1b;
|
|
2
|
+
const TAB = 0x09;
|
|
3
|
+
const LINE_FEED = 0x0a;
|
|
4
|
+
/**
|
|
5
|
+
* Zero-width, bidirectional-override, and byte-order characters. They carry no
|
|
6
|
+
* information in a terminal report but can reorder or hide rendered text.
|
|
7
|
+
*/
|
|
8
|
+
const INVISIBLE_CODE_POINTS = new Set([
|
|
9
|
+
0x200b, 0x200c, 0x200d, 0x200e, 0x200f,
|
|
10
|
+
0x202a, 0x202b, 0x202c, 0x202d, 0x202e,
|
|
11
|
+
0x2060, 0x2061, 0x2062, 0x2063, 0x2064,
|
|
12
|
+
0x2066, 0x2067, 0x2068, 0x2069,
|
|
13
|
+
0xfeff,
|
|
14
|
+
]);
|
|
15
|
+
function unsafeCodePoint(code) {
|
|
16
|
+
return code < 0x20 || (code >= 0x7f && code <= 0x9f) || INVISIBLE_CODE_POINTS.has(code);
|
|
17
|
+
}
|
|
18
|
+
function alphabetic(character) {
|
|
19
|
+
if (character === undefined) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const code = character.codePointAt(0) ?? 0;
|
|
23
|
+
return (code >= 0x41 && code <= 0x5a) || (code >= 0x61 && code <= 0x7a);
|
|
24
|
+
}
|
|
25
|
+
function escapeSequenceEnd(value, start) {
|
|
26
|
+
let index = start + 1;
|
|
27
|
+
if (value[index] !== "[") {
|
|
28
|
+
return index;
|
|
29
|
+
}
|
|
30
|
+
index += 1;
|
|
31
|
+
while (index < value.length && !alphabetic(value[index])) {
|
|
32
|
+
index += 1;
|
|
33
|
+
}
|
|
34
|
+
return index + 1;
|
|
35
|
+
}
|
|
36
|
+
/** Removes ANSI select-graphic-rendition and other CSI sequences. */
|
|
37
|
+
export function stripAnsi(value) {
|
|
38
|
+
let result = "";
|
|
39
|
+
let index = 0;
|
|
40
|
+
while (index < value.length) {
|
|
41
|
+
if (value.codePointAt(index) === ESCAPE) {
|
|
42
|
+
index = escapeSequenceEnd(value, index);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
result += value[index];
|
|
46
|
+
index += 1;
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Makes an untrusted value safe to print: escape sequences, cursor controls, and
|
|
52
|
+
* invisible reordering characters cannot survive. Newlines are preserved.
|
|
53
|
+
*/
|
|
54
|
+
export function sanitizeText(value) {
|
|
55
|
+
let result = "";
|
|
56
|
+
for (const character of value) {
|
|
57
|
+
const code = character.codePointAt(0) ?? 0;
|
|
58
|
+
if (code === TAB) {
|
|
59
|
+
result += " ";
|
|
60
|
+
}
|
|
61
|
+
else if (code === LINE_FEED) {
|
|
62
|
+
result += "\n";
|
|
63
|
+
}
|
|
64
|
+
else if (!unsafeCodePoint(code)) {
|
|
65
|
+
result += character;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
/** Collapses an untrusted value into one safe, single-line string. */
|
|
71
|
+
export function sanitizeLine(value) {
|
|
72
|
+
return sanitizeText(value)
|
|
73
|
+
.split("\n")
|
|
74
|
+
.join(" ")
|
|
75
|
+
.split(" ")
|
|
76
|
+
.filter((part) => part.length > 0)
|
|
77
|
+
.join(" ");
|
|
78
|
+
}
|
|
79
|
+
export function displayWidth(value) {
|
|
80
|
+
return [...stripAnsi(value)].length;
|
|
81
|
+
}
|
|
82
|
+
export function padRight(value, width) {
|
|
83
|
+
const padding = width - displayWidth(value);
|
|
84
|
+
return padding > 0 ? `${value}${" ".repeat(padding)}` : value;
|
|
85
|
+
}
|
|
86
|
+
export function truncate(value, maximum) {
|
|
87
|
+
const characters = [...value];
|
|
88
|
+
if (characters.length <= maximum || maximum < 2) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
return `${characters.slice(0, maximum - 1).join("")}…`;
|
|
92
|
+
}
|
|
93
|
+
function wrapParagraph(paragraph, limit) {
|
|
94
|
+
const words = paragraph.split(" ").filter((word) => word.length > 0);
|
|
95
|
+
if (words.length === 0) {
|
|
96
|
+
return [""];
|
|
97
|
+
}
|
|
98
|
+
const lines = [];
|
|
99
|
+
let current = "";
|
|
100
|
+
for (const word of words) {
|
|
101
|
+
if (current === "") {
|
|
102
|
+
current = word;
|
|
103
|
+
}
|
|
104
|
+
else if (displayWidth(current) + 1 + displayWidth(word) <= limit) {
|
|
105
|
+
current = `${current} ${word}`;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
lines.push(current);
|
|
109
|
+
current = word;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
lines.push(current);
|
|
113
|
+
return lines;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Wraps on word boundaries only. A long path or identifier is never broken, so
|
|
117
|
+
* every printed value stays selectable and copyable.
|
|
118
|
+
*/
|
|
119
|
+
export function wrapText(value, width) {
|
|
120
|
+
const limit = Math.max(width, 16);
|
|
121
|
+
return value.split("\n").flatMap((paragraph) => wrapParagraph(paragraph, limit));
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/ui/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface TerminalTheme {
|
|
2
|
+
readonly color: boolean;
|
|
3
|
+
readonly unicode: boolean;
|
|
4
|
+
readonly width: number;
|
|
5
|
+
}
|
|
6
|
+
export interface TerminalContext {
|
|
7
|
+
columns?: number;
|
|
8
|
+
env: NodeJS.ProcessEnv;
|
|
9
|
+
isTTY: boolean;
|
|
10
|
+
platform: NodeJS.Platform;
|
|
11
|
+
}
|
|
12
|
+
/** Plain, deterministic rendering: the contract for redirected output and tests. */
|
|
13
|
+
export declare const PLAIN_THEME: TerminalTheme;
|
|
14
|
+
/**
|
|
15
|
+
* Honors NO_COLOR (any non-empty value disables), then FORCE_COLOR, then a dumb
|
|
16
|
+
* terminal, then CI, and finally whether the stream is an interactive terminal.
|
|
17
|
+
*/
|
|
18
|
+
export declare function colorEnabled(context: TerminalContext): boolean;
|
|
19
|
+
export declare function terminalWidth(context: TerminalContext): number;
|
|
20
|
+
export declare function createTheme(context: TerminalContext): TerminalTheme;
|
|
21
|
+
export declare function streamTheme(stream: NodeJS.WriteStream, env?: NodeJS.ProcessEnv): TerminalTheme;
|
|
22
|
+
export declare function stdoutTheme(): TerminalTheme;
|
|
23
|
+
export declare function stderrTheme(): TerminalTheme;
|
package/dist/ui/theme.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const DEFAULT_WIDTH = 80;
|
|
2
|
+
const MINIMUM_WIDTH = 40;
|
|
3
|
+
const MAXIMUM_WIDTH = 100;
|
|
4
|
+
/** Plain, deterministic rendering: the contract for redirected output and tests. */
|
|
5
|
+
export const PLAIN_THEME = {
|
|
6
|
+
color: false,
|
|
7
|
+
unicode: true,
|
|
8
|
+
width: DEFAULT_WIDTH,
|
|
9
|
+
};
|
|
10
|
+
function enabledFlag(value) {
|
|
11
|
+
return value !== "" && value !== "0" && value !== "false";
|
|
12
|
+
}
|
|
13
|
+
function present(value) {
|
|
14
|
+
return value !== undefined && value !== "";
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Honors NO_COLOR (any non-empty value disables), then FORCE_COLOR, then a dumb
|
|
18
|
+
* terminal, then CI, and finally whether the stream is an interactive terminal.
|
|
19
|
+
*/
|
|
20
|
+
export function colorEnabled(context) {
|
|
21
|
+
const { env } = context;
|
|
22
|
+
if (present(env.NO_COLOR)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (env.FORCE_COLOR !== undefined) {
|
|
26
|
+
return enabledFlag(env.FORCE_COLOR);
|
|
27
|
+
}
|
|
28
|
+
if (env.TERM === "dumb") {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (present(env.CI)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return context.isTTY;
|
|
35
|
+
}
|
|
36
|
+
function unicodeEnabled(context) {
|
|
37
|
+
if (context.platform !== "win32") {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const { env } = context;
|
|
41
|
+
return env.WT_SESSION !== undefined
|
|
42
|
+
|| env.TERM_PROGRAM === "vscode"
|
|
43
|
+
|| env.ConEmuANSI === "ON"
|
|
44
|
+
|| env.TERM !== undefined;
|
|
45
|
+
}
|
|
46
|
+
export function terminalWidth(context) {
|
|
47
|
+
const columns = context.columns;
|
|
48
|
+
if (columns === undefined || !Number.isFinite(columns) || columns <= 0) {
|
|
49
|
+
return DEFAULT_WIDTH;
|
|
50
|
+
}
|
|
51
|
+
return Math.min(Math.max(Math.trunc(columns), MINIMUM_WIDTH), MAXIMUM_WIDTH);
|
|
52
|
+
}
|
|
53
|
+
export function createTheme(context) {
|
|
54
|
+
return {
|
|
55
|
+
color: colorEnabled(context),
|
|
56
|
+
unicode: unicodeEnabled(context),
|
|
57
|
+
width: terminalWidth(context),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function streamContext(stream, env = process.env) {
|
|
61
|
+
return {
|
|
62
|
+
...(stream.columns ? { columns: stream.columns } : {}),
|
|
63
|
+
env,
|
|
64
|
+
isTTY: Boolean(stream.isTTY),
|
|
65
|
+
platform: process.platform,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function streamTheme(stream, env = process.env) {
|
|
69
|
+
return createTheme(streamContext(stream, env));
|
|
70
|
+
}
|
|
71
|
+
export function stdoutTheme() {
|
|
72
|
+
return streamTheme(process.stdout);
|
|
73
|
+
}
|
|
74
|
+
export function stderrTheme() {
|
|
75
|
+
return streamTheme(process.stderr);
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/ui/theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ProgressReporter } from "./progress.js";
|
|
2
|
+
/**
|
|
3
|
+
* Trial-level progress for long causal searches. One line per completed trial
|
|
4
|
+
* carries the running count, the outcome, the trial duration, the pass/fail
|
|
5
|
+
* split so far, and how much of the elapsed-time budget is spent. Individual
|
|
6
|
+
* fault installations, browser launches, and retries stay silent.
|
|
7
|
+
*/
|
|
8
|
+
export declare class TrialProgress {
|
|
9
|
+
#private;
|
|
10
|
+
constructor(reporter: ProgressReporter, budgetSeconds: number);
|
|
11
|
+
get completed(): number;
|
|
12
|
+
trial(status: string, durationMs: number): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { formatDuration, formatSeconds } from "./format.js";
|
|
2
|
+
/**
|
|
3
|
+
* Trial-level progress for long causal searches. One line per completed trial
|
|
4
|
+
* carries the running count, the outcome, the trial duration, the pass/fail
|
|
5
|
+
* split so far, and how much of the elapsed-time budget is spent. Individual
|
|
6
|
+
* fault installations, browser launches, and retries stay silent.
|
|
7
|
+
*/
|
|
8
|
+
export class TrialProgress {
|
|
9
|
+
#errored = 0;
|
|
10
|
+
#failed = 0;
|
|
11
|
+
#passed = 0;
|
|
12
|
+
#budgetSeconds;
|
|
13
|
+
#reporter;
|
|
14
|
+
#startedAt = Date.now();
|
|
15
|
+
constructor(reporter, budgetSeconds) {
|
|
16
|
+
this.#budgetSeconds = budgetSeconds;
|
|
17
|
+
this.#reporter = reporter;
|
|
18
|
+
}
|
|
19
|
+
get completed() {
|
|
20
|
+
return this.#passed + this.#failed + this.#errored;
|
|
21
|
+
}
|
|
22
|
+
trial(status, durationMs) {
|
|
23
|
+
this.#count(status);
|
|
24
|
+
const errors = this.#errored > 0 ? ` / ${this.#errored} errored` : "";
|
|
25
|
+
this.#reporter.step(`trial ${this.completed} · ${status} · ${formatDuration(durationMs)}`
|
|
26
|
+
+ ` · ${this.#passed} passed / ${this.#failed} failed${errors}`
|
|
27
|
+
+ ` · ${formatDuration(Date.now() - this.#startedAt)} of`
|
|
28
|
+
+ ` ${formatSeconds(this.#budgetSeconds)}`);
|
|
29
|
+
}
|
|
30
|
+
#count(status) {
|
|
31
|
+
if (status === "failed") {
|
|
32
|
+
this.#failed += 1;
|
|
33
|
+
}
|
|
34
|
+
else if (status === "passed") {
|
|
35
|
+
this.#passed += 1;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
this.#errored += 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=trial-progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trial-progress.js","sourceRoot":"","sources":["../../src/ui/trial-progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG3D;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IACxB,QAAQ,GAAG,CAAC,CAAA;IACZ,OAAO,GAAG,CAAC,CAAA;IACX,OAAO,GAAG,CAAC,CAAA;IACF,cAAc,CAAQ;IACtB,SAAS,CAAkB;IAC3B,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAEhC,YAAY,QAA0B,EAAE,aAAqB;QAC3D,IAAI,CAAC,cAAc,GAAG,aAAa,CAAA;QACnC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAA;IAC3B,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAA;IACpD,CAAC;IAED,KAAK,CAAC,MAAc,EAAE,UAAkB;QACtC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;QACrE,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,SAAS,IAAI,CAAC,SAAS,MAAM,MAAM,MAAM,cAAc,CAAC,UAAU,CAAC,EAAE;cACnE,MAAM,IAAI,CAAC,OAAO,aAAa,IAAI,CAAC,OAAO,UAAU,MAAM,EAAE;cAC7D,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK;cACvD,IAAI,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAC3C,CAAA;IACH,CAAC;IAED,MAAM,CAAC,MAAc;QACnB,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;QACnB,CAAC;aAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;QACnB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flakelab",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Find, reproduce, and prove fixes for flaky Playwright tests.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,12 +16,6 @@
|
|
|
16
16
|
"bin": {
|
|
17
17
|
"flakelab": "./bin/flakelab.mjs"
|
|
18
18
|
},
|
|
19
|
-
"exports": {
|
|
20
|
-
"./playwright": {
|
|
21
|
-
"types": "./dist/playwright.d.ts",
|
|
22
|
-
"import": "./dist/playwright.js"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
19
|
"files": [
|
|
26
20
|
"dist",
|
|
27
21
|
"bin",
|
|
@@ -32,44 +26,45 @@
|
|
|
32
26
|
},
|
|
33
27
|
"dependencies": {
|
|
34
28
|
"@ai-sdk/groq": "^4.0.35",
|
|
35
|
-
"@fontsource-variable/geist-mono": "^5.3.0",
|
|
36
29
|
"@solarisdk/browser": "^0.1.2",
|
|
37
30
|
"@solarisdk/sandbox": "^0.1.2",
|
|
38
31
|
"ai": "^7.0.87",
|
|
39
32
|
"diff": "^9.0.0",
|
|
40
33
|
"dotenv": "^17.2.2",
|
|
41
|
-
"react": "^19.2.8",
|
|
42
|
-
"react-dom": "^19.2.8",
|
|
43
|
-
"recharts": "^3.10.1",
|
|
44
34
|
"undici": "^7.29.0",
|
|
45
|
-
"vite": "^8.2.2",
|
|
46
35
|
"yaml": "^2.9.0",
|
|
47
36
|
"zod": "^4.5.4"
|
|
48
37
|
},
|
|
49
38
|
"peerDependencies": {
|
|
50
|
-
"@playwright/test": "
|
|
39
|
+
"@playwright/test": "1.62.1"
|
|
51
40
|
},
|
|
52
41
|
"devDependencies": {
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
42
|
+
"@eslint/js": "^10.0.1",
|
|
43
|
+
"@fontsource-variable/geist-mono": "^5.3.0",
|
|
44
|
+
"@playwright/test": "1.62.1",
|
|
55
45
|
"@types/node": "^22.18.1",
|
|
56
46
|
"@types/react": "^19.2.18",
|
|
57
47
|
"@types/react-dom": "^19.2.5",
|
|
58
48
|
"eslint": "^10.9.1",
|
|
59
49
|
"eslint-plugin-sonarjs": "^4.2.0",
|
|
50
|
+
"react": "^19.2.8",
|
|
51
|
+
"react-dom": "^19.2.8",
|
|
52
|
+
"recharts": "^3.10.1",
|
|
60
53
|
"tsx": "^4.20.5",
|
|
61
54
|
"typescript": "^5.9.2",
|
|
62
|
-
"typescript-eslint": "^8.69.0"
|
|
55
|
+
"typescript-eslint": "^8.69.0",
|
|
56
|
+
"vite": "^8.2.2"
|
|
63
57
|
},
|
|
64
58
|
"scripts": {
|
|
65
|
-
"build": "node scripts/clean-build.mjs && tsc -p tsconfig.build.json && node scripts/
|
|
59
|
+
"build": "node scripts/clean-build.mjs && tsc -p tsconfig.build.json && node scripts/build-report-client.mjs",
|
|
60
|
+
"build:report-client": "node scripts/build-report-client.mjs",
|
|
66
61
|
"ci:select": "tsx src/ci/select-command.ts",
|
|
67
62
|
"ci:summary": "tsx src/ci/summary-command.ts",
|
|
68
63
|
"flakelab": "tsx src/cli.ts",
|
|
69
64
|
"lint": "eslint . --max-warnings=0",
|
|
70
65
|
"lint:fix": "eslint . --fix --max-warnings=0",
|
|
71
|
-
"test": "playwright test --pass-with-no-tests",
|
|
72
|
-
"test:headed": "playwright test --headed",
|
|
66
|
+
"test": "pnpm build:report-client && playwright test --pass-with-no-tests",
|
|
67
|
+
"test:headed": "pnpm build:report-client && playwright test --headed",
|
|
73
68
|
"typecheck": "tsc --noEmit",
|
|
74
69
|
"quality": "pnpm typecheck && pnpm lint && pnpm test",
|
|
75
70
|
"verify:solari-parallel": "tsx src/verify-solari-parallel.ts",
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { Page } from "@playwright/test";
|
|
2
|
-
import type { NetworkDelayFault } from "../domain/schema.js";
|
|
3
|
-
export type RemoveNetworkDelay = () => Promise<void>;
|
|
4
|
-
export declare function installNetworkDelay(page: Page, fault: NetworkDelayFault): Promise<RemoveNetworkDelay>;
|
|
5
|
-
export declare function readNetworkDelayFromEnvironment(): NetworkDelayFault | undefined;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
-
import { networkDelayFaultSchema } from "../domain/schema.js";
|
|
3
|
-
async function continueRoute(route) {
|
|
4
|
-
try {
|
|
5
|
-
await route.continue();
|
|
6
|
-
}
|
|
7
|
-
catch (error) {
|
|
8
|
-
const releasedDuringCleanup = error instanceof Error && error.message.includes("Route is already handled");
|
|
9
|
-
if (!releasedDuringCleanup) {
|
|
10
|
-
throw error;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export async function installNetworkDelay(page, fault) {
|
|
15
|
-
const validatedFault = networkDelayFaultSchema.parse(fault);
|
|
16
|
-
const handler = async (route) => {
|
|
17
|
-
await delay(validatedFault.delayMs);
|
|
18
|
-
await continueRoute(route);
|
|
19
|
-
};
|
|
20
|
-
await page.route(validatedFault.pattern, handler);
|
|
21
|
-
return async () => page.unroute(validatedFault.pattern, handler);
|
|
22
|
-
}
|
|
23
|
-
export function readNetworkDelayFromEnvironment() {
|
|
24
|
-
if (process.env.FLAKELAB_FAULT_KIND === "request-failure") {
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
const delayMs = Number(process.env.FLAKELAB_NETWORK_DELAY_MS ?? "0");
|
|
28
|
-
const pattern = process.env.FLAKELAB_NETWORK_PATTERN?.trim();
|
|
29
|
-
if (!pattern || delayMs <= 0) {
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
return networkDelayFaultSchema.parse({ kind: "network-delay", pattern, delayMs });
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=network-delay.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"network-delay.js","sourceRoot":"","sources":["../../src/faults/network-delay.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAE1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAI7D,KAAK,UAAU,aAAa,CAAC,KAAY;IACvC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAA;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,qBAAqB,GACzB,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAA;QAC9E,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC3B,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAU,EACV,KAAwB;IAExB,MAAM,cAAc,GAAG,uBAAuB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3D,MAAM,OAAO,GAAG,KAAK,EAAE,KAAY,EAAiB,EAAE;QACpD,MAAM,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;QACnC,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;IAC5B,CAAC,CAAA;IAED,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACjD,OAAO,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,+BAA+B;IAC7C,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,iBAAiB,EAAE,CAAC;QAC1D,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,GAAG,CAAC,CAAA;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,CAAA;IAC5D,IAAI,CAAC,OAAO,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,uBAAuB,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;AACnF,CAAC"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { Page } from "@playwright/test";
|
|
2
|
-
import type { RequestFailureFault } from "../domain/schema.js";
|
|
3
|
-
export type RemoveRequestFailure = () => Promise<void>;
|
|
4
|
-
export declare function installRequestFailure(page: Page, fault: RequestFailureFault): Promise<RemoveRequestFailure>;
|
|
5
|
-
export declare function readRequestFailureFromEnvironment(): RequestFailureFault | undefined;
|