@plune-ai/cairn 0.2.1
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/LICENSE +674 -0
- package/README.md +181 -0
- package/dist/agent/graph.d.ts +538 -0
- package/dist/agent/graph.d.ts.map +1 -0
- package/dist/agent/graph.js +0 -0
- package/dist/agent/graph.js.map +1 -0
- package/dist/agent/index.d.ts +83 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +407 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/analyze/index.d.ts +22 -0
- package/dist/analyze/index.d.ts.map +1 -0
- package/dist/analyze/index.js +39 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/artifacts/index.d.ts +29 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +68 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/report.d.ts +21 -0
- package/dist/artifacts/report.d.ts.map +1 -0
- package/dist/artifacts/report.js +56 -0
- package/dist/artifacts/report.js.map +1 -0
- package/dist/artifacts/testcase-md.d.ts +37 -0
- package/dist/artifacts/testcase-md.d.ts.map +1 -0
- package/dist/artifacts/testcase-md.js +91 -0
- package/dist/artifacts/testcase-md.js.map +1 -0
- package/dist/browser/backends/playwright-cli.d.ts +23 -0
- package/dist/browser/backends/playwright-cli.d.ts.map +1 -0
- package/dist/browser/backends/playwright-cli.js +85 -0
- package/dist/browser/backends/playwright-cli.js.map +1 -0
- package/dist/browser/backends/playwright-lib.d.ts +32 -0
- package/dist/browser/backends/playwright-lib.d.ts.map +1 -0
- package/dist/browser/backends/playwright-lib.js +157 -0
- package/dist/browser/backends/playwright-lib.js.map +1 -0
- package/dist/browser/gateway.d.ts +33 -0
- package/dist/browser/gateway.d.ts.map +1 -0
- package/dist/browser/gateway.js +2 -0
- package/dist/browser/gateway.js.map +1 -0
- package/dist/browser/index.d.ts +15 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +59 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/types.d.ts +99 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +6 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/checklist/index.d.ts +24 -0
- package/dist/checklist/index.d.ts.map +1 -0
- package/dist/checklist/index.js +65 -0
- package/dist/checklist/index.js.map +1 -0
- package/dist/cli/branding.d.ts +14 -0
- package/dist/cli/branding.d.ts.map +1 -0
- package/dist/cli/branding.js +14 -0
- package/dist/cli/branding.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +322 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/lex-bot.d.ts +3 -0
- package/dist/cli/lex-bot.d.ts.map +1 -0
- package/dist/cli/lex-bot.js +11 -0
- package/dist/cli/lex-bot.js.map +1 -0
- package/dist/codegen/index.d.ts +36 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +63 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/schema.d.ts +14 -0
- package/dist/codegen/schema.d.ts.map +1 -0
- package/dist/codegen/schema.js +9 -0
- package/dist/codegen/schema.js.map +1 -0
- package/dist/config/env.d.ts +18 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +42 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/index.d.ts +11 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +74 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/profiles.d.ts +7 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +28 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/config/schema.d.ts +91 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +20 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/design/index.d.ts +36 -0
- package/dist/design/index.d.ts.map +1 -0
- package/dist/design/index.js +35 -0
- package/dist/design/index.js.map +1 -0
- package/dist/design/schema.d.ts +109 -0
- package/dist/design/schema.d.ts.map +1 -0
- package/dist/design/schema.js +35 -0
- package/dist/design/schema.js.map +1 -0
- package/dist/eval/collect.d.ts +18 -0
- package/dist/eval/collect.d.ts.map +1 -0
- package/dist/eval/collect.js +53 -0
- package/dist/eval/collect.js.map +1 -0
- package/dist/eval/experiment.d.ts +49 -0
- package/dist/eval/experiment.d.ts.map +1 -0
- package/dist/eval/experiment.js +66 -0
- package/dist/eval/experiment.js.map +1 -0
- package/dist/eval/judge.d.ts +30 -0
- package/dist/eval/judge.d.ts.map +1 -0
- package/dist/eval/judge.js +47 -0
- package/dist/eval/judge.js.map +1 -0
- package/dist/eval/pilot.d.ts +21 -0
- package/dist/eval/pilot.d.ts.map +1 -0
- package/dist/eval/pilot.js +24 -0
- package/dist/eval/pilot.js.map +1 -0
- package/dist/eval/scorers.d.ts +23 -0
- package/dist/eval/scorers.d.ts.map +1 -0
- package/dist/eval/scorers.js +38 -0
- package/dist/eval/scorers.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/index.d.ts +7 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +39 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/llm/factory.d.ts +31 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +48 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/index.d.ts +5 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +3 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/structured.d.ts +30 -0
- package/dist/llm/structured.d.ts.map +1 -0
- package/dist/llm/structured.js +58 -0
- package/dist/llm/structured.js.map +1 -0
- package/dist/llm/vision.d.ts +16 -0
- package/dist/llm/vision.d.ts.map +1 -0
- package/dist/llm/vision.js +4 -0
- package/dist/llm/vision.js.map +1 -0
- package/dist/observe/index.d.ts +21 -0
- package/dist/observe/index.d.ts.map +1 -0
- package/dist/observe/index.js +18 -0
- package/dist/observe/index.js.map +1 -0
- package/dist/observe/parse-aria.d.ts +8 -0
- package/dist/observe/parse-aria.d.ts.map +1 -0
- package/dist/observe/parse-aria.js +71 -0
- package/dist/observe/parse-aria.js.map +1 -0
- package/dist/probe/index.d.ts +19 -0
- package/dist/probe/index.d.ts.map +1 -0
- package/dist/probe/index.js +38 -0
- package/dist/probe/index.js.map +1 -0
- package/dist/promote/index.d.ts +6 -0
- package/dist/promote/index.d.ts.map +1 -0
- package/dist/promote/index.js +4 -0
- package/dist/promote/index.js.map +1 -0
- package/dist/promote/promote-case.d.ts +12 -0
- package/dist/promote/promote-case.d.ts.map +1 -0
- package/dist/promote/promote-case.js +103 -0
- package/dist/promote/promote-case.js.map +1 -0
- package/dist/promote/selectors.d.ts +29 -0
- package/dist/promote/selectors.d.ts.map +1 -0
- package/dist/promote/selectors.js +58 -0
- package/dist/promote/selectors.js.map +1 -0
- package/dist/prompts/index.d.ts +32 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +55 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/local/identify-elements.d.ts +6 -0
- package/dist/prompts/local/identify-elements.d.ts.map +1 -0
- package/dist/prompts/local/identify-elements.js +21 -0
- package/dist/prompts/local/identify-elements.js.map +1 -0
- package/dist/prompts/local/index.d.ts +3 -0
- package/dist/prompts/local/index.d.ts.map +1 -0
- package/dist/prompts/local/index.js +18 -0
- package/dist/prompts/local/index.js.map +1 -0
- package/dist/prompts/local/judge-checklist-coverage.d.ts +3 -0
- package/dist/prompts/local/judge-checklist-coverage.d.ts.map +1 -0
- package/dist/prompts/local/judge-checklist-coverage.js +11 -0
- package/dist/prompts/local/judge-checklist-coverage.js.map +1 -0
- package/dist/prompts/local/judge-test-cases.d.ts +3 -0
- package/dist/prompts/local/judge-test-cases.d.ts.map +1 -0
- package/dist/prompts/local/judge-test-cases.js +11 -0
- package/dist/prompts/local/judge-test-cases.js.map +1 -0
- package/dist/prompts/local/pilot-review.d.ts +3 -0
- package/dist/prompts/local/pilot-review.d.ts.map +1 -0
- package/dist/prompts/local/pilot-review.js +13 -0
- package/dist/prompts/local/pilot-review.js.map +1 -0
- package/dist/prompts/local/qa-manual-test-designer.d.ts +7 -0
- package/dist/prompts/local/qa-manual-test-designer.d.ts.map +1 -0
- package/dist/prompts/local/qa-manual-test-designer.js +13 -0
- package/dist/prompts/local/qa-manual-test-designer.js.map +1 -0
- package/dist/prompts/local/qa-playwright-ts-writer.d.ts +6 -0
- package/dist/prompts/local/qa-playwright-ts-writer.d.ts.map +1 -0
- package/dist/prompts/local/qa-playwright-ts-writer.js +40 -0
- package/dist/prompts/local/qa-playwright-ts-writer.js.map +1 -0
- package/dist/prompts/local/qa-testcase-from-ui.d.ts +6 -0
- package/dist/prompts/local/qa-testcase-from-ui.d.ts.map +1 -0
- package/dist/prompts/local/qa-testcase-from-ui.js +52 -0
- package/dist/prompts/local/qa-testcase-from-ui.js.map +1 -0
- package/dist/session/index.d.ts +27 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +74 -0
- package/dist/session/index.js.map +1 -0
- package/dist/telemetry/index.d.ts +21 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +26 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/tui/App.d.ts +6 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +61 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/components/error-boundary.d.ts +17 -0
- package/dist/tui/components/error-boundary.d.ts.map +1 -0
- package/dist/tui/components/error-boundary.js +20 -0
- package/dist/tui/components/error-boundary.js.map +1 -0
- package/dist/tui/components/field.d.ts +10 -0
- package/dist/tui/components/field.d.ts.map +1 -0
- package/dist/tui/components/field.js +8 -0
- package/dist/tui/components/field.js.map +1 -0
- package/dist/tui/components/help.d.ts +5 -0
- package/dist/tui/components/help.d.ts.map +1 -0
- package/dist/tui/components/help.js +7 -0
- package/dist/tui/components/help.js.map +1 -0
- package/dist/tui/components/log-pane.d.ts +6 -0
- package/dist/tui/components/log-pane.d.ts.map +1 -0
- package/dist/tui/components/log-pane.js +10 -0
- package/dist/tui/components/log-pane.js.map +1 -0
- package/dist/tui/components/node-checklist.d.ts +6 -0
- package/dist/tui/components/node-checklist.d.ts.map +1 -0
- package/dist/tui/components/node-checklist.js +9 -0
- package/dist/tui/components/node-checklist.js.map +1 -0
- package/dist/tui/components/pilot-badge.d.ts +6 -0
- package/dist/tui/components/pilot-badge.d.ts.map +1 -0
- package/dist/tui/components/pilot-badge.js +12 -0
- package/dist/tui/components/pilot-badge.js.map +1 -0
- package/dist/tui/components/scores-table.d.ts +6 -0
- package/dist/tui/components/scores-table.d.ts.map +1 -0
- package/dist/tui/components/scores-table.js +9 -0
- package/dist/tui/components/scores-table.js.map +1 -0
- package/dist/tui/components/scrollable-text.d.ts +6 -0
- package/dist/tui/components/scrollable-text.d.ts.map +1 -0
- package/dist/tui/components/scrollable-text.js +22 -0
- package/dist/tui/components/scrollable-text.js.map +1 -0
- package/dist/tui/components/session-picker.d.ts +5 -0
- package/dist/tui/components/session-picker.d.ts.map +1 -0
- package/dist/tui/components/session-picker.js +16 -0
- package/dist/tui/components/session-picker.js.map +1 -0
- package/dist/tui/components/test-case-list.d.ts +7 -0
- package/dist/tui/components/test-case-list.d.ts.map +1 -0
- package/dist/tui/components/test-case-list.js +10 -0
- package/dist/tui/components/test-case-list.js.map +1 -0
- package/dist/tui/hooks/use-run-artifacts.d.ts +14 -0
- package/dist/tui/hooks/use-run-artifacts.d.ts.map +1 -0
- package/dist/tui/hooks/use-run-artifacts.js +37 -0
- package/dist/tui/hooks/use-run-artifacts.js.map +1 -0
- package/dist/tui/hooks/use-runner.d.ts +25 -0
- package/dist/tui/hooks/use-runner.d.ts.map +1 -0
- package/dist/tui/hooks/use-runner.js +116 -0
- package/dist/tui/hooks/use-runner.js.map +1 -0
- package/dist/tui/hooks/use-runs.d.ts +14 -0
- package/dist/tui/hooks/use-runs.d.ts.map +1 -0
- package/dist/tui/hooks/use-runs.js +57 -0
- package/dist/tui/hooks/use-runs.js.map +1 -0
- package/dist/tui/hooks/use-sessions.d.ts +10 -0
- package/dist/tui/hooks/use-sessions.d.ts.map +1 -0
- package/dist/tui/hooks/use-sessions.js +32 -0
- package/dist/tui/hooks/use-sessions.js.map +1 -0
- package/dist/tui/hooks/use-stdout-dimensions.d.ts +3 -0
- package/dist/tui/hooks/use-stdout-dimensions.d.ts.map +1 -0
- package/dist/tui/hooks/use-stdout-dimensions.js +18 -0
- package/dist/tui/hooks/use-stdout-dimensions.js.map +1 -0
- package/dist/tui/index.d.ts +7 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +13 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/router-context.d.ts +12 -0
- package/dist/tui/router-context.d.ts.map +1 -0
- package/dist/tui/router-context.js +14 -0
- package/dist/tui/router-context.js.map +1 -0
- package/dist/tui/router.d.ts +44 -0
- package/dist/tui/router.d.ts.map +1 -0
- package/dist/tui/router.js +22 -0
- package/dist/tui/router.js.map +1 -0
- package/dist/tui/screens/form-screen.d.ts +7 -0
- package/dist/tui/screens/form-screen.d.ts.map +1 -0
- package/dist/tui/screens/form-screen.js +104 -0
- package/dist/tui/screens/form-screen.js.map +1 -0
- package/dist/tui/screens/launcher-screen.d.ts +2 -0
- package/dist/tui/screens/launcher-screen.d.ts.map +1 -0
- package/dist/tui/screens/launcher-screen.js +28 -0
- package/dist/tui/screens/launcher-screen.js.map +1 -0
- package/dist/tui/screens/run-dashboard-screen.d.ts +7 -0
- package/dist/tui/screens/run-dashboard-screen.d.ts.map +1 -0
- package/dist/tui/screens/run-dashboard-screen.js +32 -0
- package/dist/tui/screens/run-dashboard-screen.js.map +1 -0
- package/dist/tui/screens/run-detail-screen.d.ts +5 -0
- package/dist/tui/screens/run-detail-screen.d.ts.map +1 -0
- package/dist/tui/screens/run-detail-screen.js +67 -0
- package/dist/tui/screens/run-detail-screen.js.map +1 -0
- package/dist/tui/screens/runs-list-screen.d.ts +2 -0
- package/dist/tui/screens/runs-list-screen.d.ts.map +1 -0
- package/dist/tui/screens/runs-list-screen.js +22 -0
- package/dist/tui/screens/runs-list-screen.js.map +1 -0
- package/dist/tui/screens/summary-screen.d.ts +6 -0
- package/dist/tui/screens/summary-screen.d.ts.map +1 -0
- package/dist/tui/screens/summary-screen.js +53 -0
- package/dist/tui/screens/summary-screen.js.map +1 -0
- package/dist/tui/theme.d.ts +31 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +70 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/types.d.ts +38 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +2 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/validate/index.d.ts +30 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +39 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/runner.d.ts +15 -0
- package/dist/validate/runner.d.ts.map +1 -0
- package/dist/validate/runner.js +74 -0
- package/dist/validate/runner.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useStdout } from "ink";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
/** Current terminal [columns, rows], updated on resize — used to size scroll viewports. */
|
|
4
|
+
export function useStdoutDimensions() {
|
|
5
|
+
const { stdout } = useStdout();
|
|
6
|
+
const [size, setSize] = useState([stdout.columns ?? 80, stdout.rows ?? 24]);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (typeof stdout?.on !== "function")
|
|
9
|
+
return; // headless/test stdout has no resize events
|
|
10
|
+
const onResize = () => setSize([stdout.columns ?? 80, stdout.rows ?? 24]);
|
|
11
|
+
stdout.on("resize", onResize);
|
|
12
|
+
return () => {
|
|
13
|
+
stdout.off?.("resize", onResize);
|
|
14
|
+
};
|
|
15
|
+
}, [stdout]);
|
|
16
|
+
return size;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=use-stdout-dimensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-stdout-dimensions.js","sourceRoot":"","sources":["../../../src/tui/hooks/use-stdout-dimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,2FAA2F;AAC3F,MAAM,UAAU,mBAAmB;IACjC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAmB,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IAE9F,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,EAAE,EAAE,KAAK,UAAU;YAAE,OAAO,CAAC,4CAA4C;QAC1F,MAAM,QAAQ,GAAG,GAAS,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QAChF,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI entry point. Lazily imported by the CLI dispatch when `cairn` runs with
|
|
3
|
+
* no arguments in a TTY — this keeps React/Ink out of every non-TUI code path
|
|
4
|
+
* (other CLI commands and library embedders never load them).
|
|
5
|
+
*/
|
|
6
|
+
export declare function mountTui(): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TUI entry point. Lazily imported by the CLI dispatch when `cairn` runs with
|
|
3
|
+
* no arguments in a TTY — this keeps React/Ink out of every non-TUI code path
|
|
4
|
+
* (other CLI commands and library embedders never load them).
|
|
5
|
+
*/
|
|
6
|
+
export async function mountTui() {
|
|
7
|
+
const React = (await import("react")).default;
|
|
8
|
+
const { render } = await import("ink");
|
|
9
|
+
const { App } = await import("./App.js");
|
|
10
|
+
const { waitUntilExit } = render(React.createElement(App), { exitOnCtrlC: true });
|
|
11
|
+
await waitUntilExit();
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAClF,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Screen } from "./router.js";
|
|
2
|
+
export interface RouterApi {
|
|
3
|
+
navigate: (screen: Screen) => void;
|
|
4
|
+
back: () => void;
|
|
5
|
+
replace: (screen: Screen) => void;
|
|
6
|
+
canGoBack: boolean;
|
|
7
|
+
/** Screens with a focused text input set this true so global `q`/esc don't steal keys. */
|
|
8
|
+
setInTextField: (v: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const RouterProvider: import("react").Provider<RouterApi | null>;
|
|
11
|
+
export declare function useRouter(): RouterApi;
|
|
12
|
+
//# sourceMappingURL=router-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../../src/tui/router-context.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,0FAA0F;IAC1F,cAAc,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC;AAID,eAAO,MAAM,cAAc,4CAAyB,CAAC;AAErD,wBAAgB,SAAS,IAAI,SAAS,CAIrC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React context exposing navigation to any screen without prop-drilling.
|
|
3
|
+
* The reducer itself lives in router.ts (pure); this only wires it into React.
|
|
4
|
+
*/
|
|
5
|
+
import { createContext, useContext } from "react";
|
|
6
|
+
const RouterContext = createContext(null);
|
|
7
|
+
export const RouterProvider = RouterContext.Provider;
|
|
8
|
+
export function useRouter() {
|
|
9
|
+
const ctx = useContext(RouterContext);
|
|
10
|
+
if (!ctx)
|
|
11
|
+
throw new Error("useRouter must be used within a RouterProvider");
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=router-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-context.js","sourceRoot":"","sources":["../../src/tui/router-context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAYlD,MAAM,aAAa,GAAG,aAAa,CAAmB,IAAI,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC;AAErD,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAC5E,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure screen router for the TUI: a stack of screens with go/back/replace.
|
|
3
|
+
* Kept free of React so it is trivially unit-testable (router.test.ts).
|
|
4
|
+
*/
|
|
5
|
+
import type { Command, FormValues, AnyResult } from "./types.js";
|
|
6
|
+
export type Screen = {
|
|
7
|
+
name: "launcher";
|
|
8
|
+
} | {
|
|
9
|
+
name: "form";
|
|
10
|
+
command: Command;
|
|
11
|
+
initial?: Partial<FormValues>;
|
|
12
|
+
} | {
|
|
13
|
+
name: "dashboard";
|
|
14
|
+
command: Command;
|
|
15
|
+
values: FormValues;
|
|
16
|
+
} | {
|
|
17
|
+
name: "summary";
|
|
18
|
+
command: Command;
|
|
19
|
+
result: AnyResult;
|
|
20
|
+
} | {
|
|
21
|
+
name: "runsList";
|
|
22
|
+
} | {
|
|
23
|
+
name: "runDetail";
|
|
24
|
+
runDir: string;
|
|
25
|
+
};
|
|
26
|
+
export interface RouterState {
|
|
27
|
+
stack: Screen[];
|
|
28
|
+
}
|
|
29
|
+
export type RouterAction = {
|
|
30
|
+
type: "go";
|
|
31
|
+
screen: Screen;
|
|
32
|
+
} | {
|
|
33
|
+
type: "back";
|
|
34
|
+
} | {
|
|
35
|
+
type: "replace";
|
|
36
|
+
screen: Screen;
|
|
37
|
+
};
|
|
38
|
+
export declare const initialRouter: RouterState;
|
|
39
|
+
export declare function routerReducer(state: RouterState, action: RouterAction): RouterState;
|
|
40
|
+
/** The visible (top-of-stack) screen. The stack is never empty (seeded with launcher). */
|
|
41
|
+
export declare function currentScreen(state: RouterState): Screen;
|
|
42
|
+
/** Whether back navigation is possible (i.e. not at the root). */
|
|
43
|
+
export declare function canGoBack(state: RouterState): boolean;
|
|
44
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/tui/router.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,MAAM,GACd;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,eAAO,MAAM,aAAa,EAAE,WAA+C,CAAC;AAE5E,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,WAAW,CAUnF;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAGxD;AAED,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAErD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const initialRouter = { stack: [{ name: "launcher" }] };
|
|
2
|
+
export function routerReducer(state, action) {
|
|
3
|
+
switch (action.type) {
|
|
4
|
+
case "go":
|
|
5
|
+
return { stack: [...state.stack, action.screen] };
|
|
6
|
+
case "back":
|
|
7
|
+
// Never pop the root screen.
|
|
8
|
+
return state.stack.length > 1 ? { stack: state.stack.slice(0, -1) } : state;
|
|
9
|
+
case "replace":
|
|
10
|
+
return { stack: [...state.stack.slice(0, -1), action.screen] };
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** The visible (top-of-stack) screen. The stack is never empty (seeded with launcher). */
|
|
14
|
+
export function currentScreen(state) {
|
|
15
|
+
const top = state.stack[state.stack.length - 1];
|
|
16
|
+
return top ?? { name: "launcher" };
|
|
17
|
+
}
|
|
18
|
+
/** Whether back navigation is possible (i.e. not at the root). */
|
|
19
|
+
export function canGoBack(state) {
|
|
20
|
+
return state.stack.length > 1;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/tui/router.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,MAAM,aAAa,GAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AAE5E,MAAM,UAAU,aAAa,CAAC,KAAkB,EAAE,MAAoB;IACpE,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,IAAI;YACP,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,KAAK,MAAM;YACT,6BAA6B;YAC7B,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC9E,KAAK,SAAS;YACZ,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IACnE,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,aAAa,CAAC,KAAkB;IAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,OAAO,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AACrC,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Command, FormValues } from "../types.js";
|
|
2
|
+
/** Sequential wizard: one field per step, ⏎ advances, last step runs the command. */
|
|
3
|
+
export declare function FormScreen({ command, initial }: {
|
|
4
|
+
command: Command;
|
|
5
|
+
initial?: Partial<FormValues>;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=form-screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/form-screen.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAiB,MAAM,aAAa,CAAC;AA6BtE,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,+BAsHnG"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Box, Text, useInput } from "ink";
|
|
4
|
+
import SelectInput from "ink-select-input";
|
|
5
|
+
import { useRouter } from "../router-context.js";
|
|
6
|
+
import { Field } from "../components/field.js";
|
|
7
|
+
import { SessionPicker } from "../components/session-picker.js";
|
|
8
|
+
function stepsFor(command) {
|
|
9
|
+
if (command === "automate")
|
|
10
|
+
return ["runDir", "session", "validate", "submit"];
|
|
11
|
+
if (command === "observe")
|
|
12
|
+
return ["url", "session", "headed", "submit"];
|
|
13
|
+
return ["url", "session", "checklist", "style", "headed", "submit"]; // explore / design
|
|
14
|
+
}
|
|
15
|
+
const STYLE_ITEMS = [
|
|
16
|
+
{ label: "all — full coverage", value: "all" },
|
|
17
|
+
{ label: "happy — positive paths", value: "happy" },
|
|
18
|
+
{ label: "negative — error cases", value: "negative" },
|
|
19
|
+
{ label: "coverage — breadth", value: "coverage" },
|
|
20
|
+
];
|
|
21
|
+
const YESNO = [
|
|
22
|
+
{ label: "no", value: "no" },
|
|
23
|
+
{ label: "yes", value: "yes" },
|
|
24
|
+
];
|
|
25
|
+
/** Sequential wizard: one field per step, ⏎ advances, last step runs the command. */
|
|
26
|
+
export function FormScreen({ command, initial }) {
|
|
27
|
+
const { navigate, setInTextField } = useRouter();
|
|
28
|
+
const [values, setValues] = useState({ url: "", style: "all", headed: false, ...initial });
|
|
29
|
+
const [stepIndex, setStepIndex] = useState(0);
|
|
30
|
+
const steps = stepsFor(command);
|
|
31
|
+
const step = steps[stepIndex] ?? "submit";
|
|
32
|
+
const isText = step === "url" || step === "runDir" || step === "checklist";
|
|
33
|
+
// Suppress global q/esc only while a text field owns the keyboard.
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
setInTextField(isText);
|
|
36
|
+
return () => setInTextField(false);
|
|
37
|
+
}, [isText, setInTextField]);
|
|
38
|
+
const advance = () => setStepIndex((i) => Math.min(i + 1, steps.length - 1));
|
|
39
|
+
const set = (k, v) => setValues((s) => ({ ...s, [k]: v }));
|
|
40
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: command }), _jsx(FormSummary, { values: values, command: command }), _jsx(Box, { marginTop: 1, children: renderStep() })] }));
|
|
41
|
+
function renderStep() {
|
|
42
|
+
switch (step) {
|
|
43
|
+
case "url":
|
|
44
|
+
return (_jsx(Field, { label: "URL", value: values.url, onChange: (v) => set("url", v), onSubmit: () => values.url.trim() && advance(), placeholder: "https://app.example.com/page (required)" }));
|
|
45
|
+
case "runDir":
|
|
46
|
+
return (_jsx(Field, { label: "Run dir", value: values.runDir ?? "", onChange: (v) => set("runDir", v), onSubmit: () => (values.runDir ?? "").trim() && advance(), placeholder: "runs/<id> (required)" }));
|
|
47
|
+
case "checklist":
|
|
48
|
+
return (_jsx(Field, { label: "Checklist", value: values.checklist ?? "", onChange: (v) => set("checklist", v), onSubmit: advance, placeholder: "(optional) path to a .md file" }));
|
|
49
|
+
case "session":
|
|
50
|
+
return (_jsx(SessionPicker, { onSelect: (s) => {
|
|
51
|
+
set("session", s);
|
|
52
|
+
advance();
|
|
53
|
+
} }));
|
|
54
|
+
case "style":
|
|
55
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Planning style:" }), _jsx(SelectInput, { items: STYLE_ITEMS, onSelect: (it) => {
|
|
56
|
+
set("style", it.value);
|
|
57
|
+
advance();
|
|
58
|
+
} })] }));
|
|
59
|
+
case "headed":
|
|
60
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Headed (visible) browser?" }), _jsx(SelectInput, { items: YESNO, onSelect: (it) => {
|
|
61
|
+
set("headed", it.value === "yes");
|
|
62
|
+
advance();
|
|
63
|
+
} })] }));
|
|
64
|
+
case "validate":
|
|
65
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "Validate (run the generated tests)?" }), _jsx(SelectInput, { items: YESNO, onSelect: (it) => {
|
|
66
|
+
set("validate", it.value === "yes");
|
|
67
|
+
advance();
|
|
68
|
+
} })] }));
|
|
69
|
+
case "submit":
|
|
70
|
+
return (_jsx(SubmitStep, { command: command, onRun: () => navigate({ name: "dashboard", command, values }) }));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function SubmitStep({ command, onRun }) {
|
|
75
|
+
useInput((_, key) => {
|
|
76
|
+
if (key.return)
|
|
77
|
+
onRun();
|
|
78
|
+
});
|
|
79
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "green", children: ["Ready to run ", command, "."] }), _jsx(Text, { dimColor: true, children: "Press \u23CE to start \u00B7 esc to go back" })] }));
|
|
80
|
+
}
|
|
81
|
+
function FormSummary({ values, command }) {
|
|
82
|
+
const rows = [];
|
|
83
|
+
if (command === "automate") {
|
|
84
|
+
if (values.runDir)
|
|
85
|
+
rows.push(`run dir: ${values.runDir}`);
|
|
86
|
+
if (values.validate !== undefined)
|
|
87
|
+
rows.push(`validate: ${values.validate ? "yes" : "no"}`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
if (values.url)
|
|
91
|
+
rows.push(`url: ${values.url}`);
|
|
92
|
+
if (command !== "observe") {
|
|
93
|
+
if (values.checklist)
|
|
94
|
+
rows.push(`checklist: ${values.checklist}`);
|
|
95
|
+
rows.push(`style: ${values.style}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (values.session)
|
|
99
|
+
rows.push(`session: ${values.session}`);
|
|
100
|
+
if (rows.length === 0)
|
|
101
|
+
return null;
|
|
102
|
+
return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: rows.map((r) => (_jsxs(Text, { dimColor: true, children: ["\u00B7 ", r] }, r))) }));
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=form-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/form-screen.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launcher-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/launcher-screen.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,cAAc,gCA2B7B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useApp } from "ink";
|
|
3
|
+
import SelectInput from "ink-select-input";
|
|
4
|
+
import { useRouter } from "../router-context.js";
|
|
5
|
+
const ITEMS = [
|
|
6
|
+
{ label: "Explore — full pipeline (cases → code → validate → repair)", value: "explore" },
|
|
7
|
+
{ label: "Design — test cases only (.md, no code)", value: "design" },
|
|
8
|
+
{ label: "Automate — generate @playwright/test from existing cases", value: "automate" },
|
|
9
|
+
{ label: "Browse past runs", value: "runs" },
|
|
10
|
+
{ label: "Quit", value: "quit" },
|
|
11
|
+
];
|
|
12
|
+
export function LauncherScreen() {
|
|
13
|
+
const { navigate } = useRouter();
|
|
14
|
+
const { exit } = useApp();
|
|
15
|
+
const onSelect = (item) => {
|
|
16
|
+
if (item.value === "quit") {
|
|
17
|
+
exit();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (item.value === "runs") {
|
|
21
|
+
navigate({ name: "runsList" });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
navigate({ name: "form", command: item.value });
|
|
25
|
+
};
|
|
26
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Cairn" }), _jsx(Text, { dimColor: true, children: "Interactive UI-test generation \u2014 pick a command" }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: ITEMS, onSelect: onSelect }) })] }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=launcher-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launcher-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/launcher-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AACxC,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAQjD,MAAM,KAAK,GAAe;IACxB,EAAE,KAAK,EAAE,4DAA4D,EAAE,KAAK,EAAE,SAAS,EAAE;IACzF,EAAE,KAAK,EAAE,yCAAyC,EAAE,KAAK,EAAE,QAAQ,EAAE;IACrE,EAAE,KAAK,EAAE,0DAA0D,EAAE,KAAK,EAAE,UAAU,EAAE;IACxF,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE;IAC5C,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;CACjC,CAAC;AAEF,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IACjC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAE1B,MAAM,QAAQ,GAAG,CAAC,IAAc,EAAE,EAAE;QAClC,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAgB,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,4BAEhB,EACP,KAAC,IAAI,IAAC,QAAQ,2EAAuD,EACrE,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAI,GAC7C,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Command, FormValues } from "../types.js";
|
|
2
|
+
/** Runs the command and shows a live node checklist + log; routes to summary on success. */
|
|
3
|
+
export declare function RunDashboardScreen({ command, values }: {
|
|
4
|
+
command: Command;
|
|
5
|
+
values: FormValues;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=run-dashboard-screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-dashboard-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/run-dashboard-screen.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAUvD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,+BA6C/F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { useRouter } from "../router-context.js";
|
|
5
|
+
import { useRunner } from "../hooks/use-runner.js";
|
|
6
|
+
import { NodeChecklist } from "../components/node-checklist.js";
|
|
7
|
+
import { LogPane } from "../components/log-pane.js";
|
|
8
|
+
const ERROR_HINTS = {
|
|
9
|
+
session: "Session looks expired/missing — recapture it (npm run session:save).",
|
|
10
|
+
"rate-limit": "Rate-limited (429). The SDK retried; try again shortly.",
|
|
11
|
+
budget: "Call budget exceeded — the run hit the cost guardrail.",
|
|
12
|
+
config: "Check your API key env (ANTHROPIC_API_KEY / OPENROUTER_API_KEY).",
|
|
13
|
+
unknown: "Unexpected error — see the message above.",
|
|
14
|
+
};
|
|
15
|
+
/** Runs the command and shows a live node checklist + log; routes to summary on success. */
|
|
16
|
+
export function RunDashboardScreen({ command, values }) {
|
|
17
|
+
const { replace, setInTextField } = useRouter();
|
|
18
|
+
const { state, start, dispose } = useRunner();
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
setInTextField(false);
|
|
21
|
+
start(command, values);
|
|
22
|
+
return dispose;
|
|
23
|
+
// run once on mount
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (state.phase === "done" && state.result) {
|
|
27
|
+
replace({ name: "summary", command, result: state.result });
|
|
28
|
+
}
|
|
29
|
+
}, [state.phase]);
|
|
30
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: command }), _jsx(Text, { dimColor: true, children: state.phase === "running" ? " running…" : ` ${state.phase}` }), state.liveGreen !== undefined && _jsx(Text, { color: "green", children: ` · ${String(state.liveGreen)}% green` })] }), _jsx(Box, { marginTop: 1, children: _jsx(NodeChecklist, { nodes: state.nodes }) }), _jsx(LogPane, { log: state.log }), state.phase === "error" && state.error && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { color: "red", bold: true, children: ["Failed: ", state.error.kind] }), _jsx(Text, { children: state.error.message }), _jsx(Text, { dimColor: true, children: ERROR_HINTS[state.error.kind] ?? "" }), _jsx(Text, { dimColor: true, children: "esc \u2014 back to the form" })] }))] }));
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=run-dashboard-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-dashboard-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/run-dashboard-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAGpD,MAAM,WAAW,GAA2B;IAC1C,OAAO,EAAE,sEAAsE;IAC/E,YAAY,EAAE,yDAAyD;IACvE,MAAM,EAAE,wDAAwD;IAChE,MAAM,EAAE,kEAAkE;IAC1E,OAAO,EAAE,2CAA2C;CACrD,CAAC;AAEF,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,EAA4C;IAC9F,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,SAAS,EAAE,CAAC;IAChD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvB,OAAO,OAAO,CAAC;QACf,oBAAoB;IACtB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3C,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kBACpB,OAAO,GACH,EACP,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,EAAE,GAAQ,EACpF,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,GAAQ,IAClG,EAEN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAI,GACjC,EAEN,KAAC,OAAO,IAAC,GAAG,EAAE,KAAK,CAAC,GAAG,GAAI,EAE1B,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,IAAI,CACzC,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACtC,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,EAAC,IAAI,+BACX,KAAK,CAAC,KAAK,CAAC,IAAI,IACpB,EACP,KAAC,IAAI,cAAE,KAAK,CAAC,KAAK,CAAC,OAAO,GAAQ,EAClC,KAAC,IAAI,IAAC,QAAQ,kBAAE,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAQ,EAC3D,KAAC,IAAI,IAAC,QAAQ,kDAA8B,IACxC,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-detail-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/run-detail-screen.tsx"],"names":[],"mappings":"AAWA,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,+BA2F7D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, Text, useInput } from "ink";
|
|
4
|
+
import { useRunArtifacts } from "../hooks/use-run-artifacts.js";
|
|
5
|
+
import { useStdoutDimensions } from "../hooks/use-stdout-dimensions.js";
|
|
6
|
+
import { ScrollableText } from "../components/scrollable-text.js";
|
|
7
|
+
import { promoteCase } from "../../promote/index.js";
|
|
8
|
+
const TABS = ["cases", "report", "logs"];
|
|
9
|
+
const TAB_LABELS = { cases: "Cases", report: "Report", logs: "Logs" };
|
|
10
|
+
/** Tabbed artifact viewer. Tabs: 1/2/3 or ←→ · scroll: ↑↓ · cases: n/p · back: esc. */
|
|
11
|
+
export function RunDetailScreen({ runDir }) {
|
|
12
|
+
const arts = useRunArtifacts(runDir);
|
|
13
|
+
const [, rows] = useStdoutDimensions();
|
|
14
|
+
const [tab, setTab] = useState("cases");
|
|
15
|
+
const [caseIdx, setCaseIdx] = useState(0);
|
|
16
|
+
const [note, setNote] = useState("");
|
|
17
|
+
const [promoted, setPromoted] = useState(false);
|
|
18
|
+
// Derive current case here (before useInput) so the key handler can reference it.
|
|
19
|
+
const current = arts.cases[caseIdx];
|
|
20
|
+
useInput((input, key) => {
|
|
21
|
+
if (input === "1")
|
|
22
|
+
setTab("cases");
|
|
23
|
+
else if (input === "2")
|
|
24
|
+
setTab("report");
|
|
25
|
+
else if (input === "3")
|
|
26
|
+
setTab("logs");
|
|
27
|
+
else if (key.leftArrow)
|
|
28
|
+
setTab((t) => TABS[(TABS.indexOf(t) + TABS.length - 1) % TABS.length] ?? "cases");
|
|
29
|
+
else if (key.rightArrow || key.tab)
|
|
30
|
+
setTab((t) => TABS[(TABS.indexOf(t) + 1) % TABS.length] ?? "cases");
|
|
31
|
+
else if (tab === "cases" && input === "n") {
|
|
32
|
+
setCaseIdx((i) => Math.min(i + 1, Math.max(0, arts.cases.length - 1)));
|
|
33
|
+
}
|
|
34
|
+
else if (tab === "cases" && input === "p") {
|
|
35
|
+
setCaseIdx((i) => Math.max(i - 1, 0));
|
|
36
|
+
}
|
|
37
|
+
else if (tab === "cases" && input === "a" && !promoted && current?.name.startsWith("MTC")) {
|
|
38
|
+
const id = current.name.replace(/\.md$/, "");
|
|
39
|
+
void promoteCase(runDir, id, {})
|
|
40
|
+
.then((r) => {
|
|
41
|
+
setPromoted(true);
|
|
42
|
+
setNote(`Promoted ${r.oldId} → ${r.newId}${r.warning ? ` (⚠ ${r.warning})` : ""}`);
|
|
43
|
+
arts.reload();
|
|
44
|
+
})
|
|
45
|
+
.catch((e) => setNote(`Promote failed: ${e instanceof Error ? e.message : String(e)}`));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
if (arts.loading)
|
|
49
|
+
return _jsx(Text, { dimColor: true, children: "loading artifacts\u2026" });
|
|
50
|
+
const viewHeight = Math.max(6, rows - 10);
|
|
51
|
+
let body;
|
|
52
|
+
if (tab === "cases") {
|
|
53
|
+
body = current ? (_jsx(ScrollableText, { text: current.text, height: viewHeight }, caseIdx)) : (_jsx(Text, { dimColor: true, children: "No test cases in this run." }));
|
|
54
|
+
}
|
|
55
|
+
else if (tab === "report") {
|
|
56
|
+
body = _jsx(ScrollableText, { text: arts.report, height: viewHeight });
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
body = _jsx(ScrollableText, { text: arts.log, height: viewHeight });
|
|
60
|
+
}
|
|
61
|
+
const isMtc = tab === "cases" && (current?.name.startsWith("MTC") ?? false);
|
|
62
|
+
const hint = tab === "cases" && arts.cases.length > 1
|
|
63
|
+
? `↑↓ scroll · n/p next·prev case${isMtc ? " · a promote→ATC" : ""} · 1/2/3 or ←→ tab · esc back`
|
|
64
|
+
: `↑↓ scroll${isMtc ? " · a promote→ATC" : ""} · 1/2/3 or ←→ tab · esc back`;
|
|
65
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: TABS.map((t, i) => (_jsx(Box, { marginRight: 1, children: _jsx(Text, { color: t === tab ? "black" : "cyan", backgroundColor: t === tab ? "cyan" : undefined, bold: t === tab, children: ` ${String(i + 1)} ${TAB_LABELS[t]} ` }) }, t))) }), _jsxs(Box, { borderStyle: "round", borderColor: "gray", flexDirection: "column", paddingX: 1, marginTop: 1, children: [tab === "cases" && current ? (_jsxs(Text, { children: [_jsxs(Text, { color: "cyan", children: ["case ", caseIdx + 1, "/", arts.cases.length] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", current.name] }), arts.cases.length > 1 ? (_jsx(Text, { color: "yellow", children: " \u00B7 press n/p for next/prev" })) : null] })) : null, body] }), note ? _jsx(Text, { color: "green", children: note }) : null, _jsx(Text, { dimColor: true, children: hint })] }));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=run-detail-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-detail-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/run-detail-screen.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs-list-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/runs-list-screen.tsx"],"names":[],"mappings":"AAUA,wBAAgB,cAAc,gCAkC7B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import SelectInput from "ink-select-input";
|
|
4
|
+
import { useRouter } from "../router-context.js";
|
|
5
|
+
import { useRuns } from "../hooks/use-runs.js";
|
|
6
|
+
export function RunsListScreen() {
|
|
7
|
+
const { navigate } = useRouter();
|
|
8
|
+
const { runs, loading } = useRuns();
|
|
9
|
+
if (loading)
|
|
10
|
+
return _jsx(Text, { dimColor: true, children: "scanning ./runs\u2026" });
|
|
11
|
+
if (runs.length === 0) {
|
|
12
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "No runs found in ./runs" }), _jsx(Text, { dimColor: true, children: "esc \u2014 back" })] }));
|
|
13
|
+
}
|
|
14
|
+
const items = runs.map((r) => {
|
|
15
|
+
const date = r.date.toISOString().slice(0, 16).replace("T", " ");
|
|
16
|
+
const green = r.greenRatio !== undefined ? `${String(Math.round(r.greenRatio * 100))}% ` : "";
|
|
17
|
+
const pilot = r.pilot ? `${r.pilot} ` : "";
|
|
18
|
+
return { label: `${date} ${r.mode} ${green}${pilot} ${r.url}`, value: r.dir };
|
|
19
|
+
});
|
|
20
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "cyan", bold: true, children: ["Past runs (", runs.length, ")"] }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: items, onSelect: (it) => navigate({ name: "runDetail", runDir: it.value }) }) })] }));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=runs-list-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs-list-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/runs-list-screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAO/C,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;IACjC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAEpC,IAAI,OAAO;QAAE,OAAO,KAAC,IAAI,IAAC,QAAQ,4CAAwB,CAAC;IAC3D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,IAAI,0CAA+B,EACpC,KAAC,IAAI,IAAC,QAAQ,sCAAkB,IAC5B,CACP,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kCACT,IAAI,CAAC,MAAM,SAClB,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,EAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,GACzE,GACE,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary-screen.d.ts","sourceRoot":"","sources":["../../../src/tui/screens/summary-screen.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;AAgClE,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,+BAmDzF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import SelectInput from "ink-select-input";
|
|
4
|
+
import { useRouter } from "../router-context.js";
|
|
5
|
+
import { ScoresTable } from "../components/scores-table.js";
|
|
6
|
+
import { PilotBadge } from "../components/pilot-badge.js";
|
|
7
|
+
import { TestCaseList } from "../components/test-case-list.js";
|
|
8
|
+
/** Rebuild form prefill from a finished run so re-run starts with the same target. */
|
|
9
|
+
function rerunInitial(command, result) {
|
|
10
|
+
if (command === "automate")
|
|
11
|
+
return { runDir: result.runDir };
|
|
12
|
+
const url = "study" in result ? result.study.url : undefined;
|
|
13
|
+
return url ? { url } : {};
|
|
14
|
+
}
|
|
15
|
+
// All numbers come from the typed result — never parsed from progress text.
|
|
16
|
+
function validationOf(r) {
|
|
17
|
+
return "validation" in r ? r.validation : undefined;
|
|
18
|
+
}
|
|
19
|
+
function pilotOf(r) {
|
|
20
|
+
return "pilot" in r ? r.pilot : undefined;
|
|
21
|
+
}
|
|
22
|
+
function testCasesOf(r) {
|
|
23
|
+
return "testCases" in r ? r.testCases : [];
|
|
24
|
+
}
|
|
25
|
+
function scoresOf(r) {
|
|
26
|
+
return "scores" in r ? r.scores : [];
|
|
27
|
+
}
|
|
28
|
+
function specCountOf(r) {
|
|
29
|
+
return "specFiles" in r ? r.specFiles.length : undefined;
|
|
30
|
+
}
|
|
31
|
+
export function SummaryScreen({ command, result }) {
|
|
32
|
+
const { navigate } = useRouter();
|
|
33
|
+
const validation = validationOf(result);
|
|
34
|
+
const pilot = pilotOf(result);
|
|
35
|
+
const cases = testCasesOf(result);
|
|
36
|
+
const scores = scoresOf(result);
|
|
37
|
+
const specs = specCountOf(result);
|
|
38
|
+
const actions = [
|
|
39
|
+
{ label: "View artifacts (cases · report · logs)", value: "artifacts" },
|
|
40
|
+
{ label: "Re-run this command", value: "rerun" },
|
|
41
|
+
{ label: "Back to menu", value: "menu" },
|
|
42
|
+
];
|
|
43
|
+
const onAction = (item) => {
|
|
44
|
+
if (item.value === "artifacts")
|
|
45
|
+
navigate({ name: "runDetail", runDir: result.runDir });
|
|
46
|
+
else if (item.value === "rerun")
|
|
47
|
+
navigate({ name: "form", command, initial: rerunInitial(command, result) });
|
|
48
|
+
else
|
|
49
|
+
navigate({ name: "launcher" });
|
|
50
|
+
};
|
|
51
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "cyan", bold: true, children: [command, " \u2014 done"] }), _jsx(Text, { dimColor: true, children: result.runDir }), validation ? (_jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: validation.greenRatio >= 0.8 ? "green" : "yellow", children: [Math.round(validation.greenRatio * 100), "% green"] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 flaky: ", validation.flakyCount] })] })) : null, specs !== undefined ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: [specs, " spec file(s) generated"] }) })) : null, pilot ? _jsx(PilotBadge, { pilot: pilot }) : null, _jsx(ScoresTable, { scores: scores }), _jsx(TestCaseList, { cases: cases }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: actions, onSelect: onAction }) })] }));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=summary-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary-screen.js","sourceRoot":"","sources":["../../../src/tui/screens/summary-screen.tsx"],"names":[],"mappings":"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"}
|