@keboola/validate-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # @keboola/validate-ui
2
+
3
+ Closed-loop validation for agent-generated Keboola UI. It boots a rendered
4
+ module in a headless browser, drives it, and returns a **machine-readable
5
+ verdict** across four axes so an agent can see and fix its own output before a
6
+ human looks:
7
+
8
+ - **runtime-health** — white-screens, console/page errors, failed requests
9
+ - **a11y** — axe-core violations mapped to WCAG
10
+ - **visual-brand** — baseline diff + the alt-brand fitness function (chrome must
11
+ re-skin under an alternate brand) + layout overflow (asserting categorical
12
+ colors stay fixed is future work)
13
+ - **brief-conformance** — a VLM judge on "did it build what the brief asked,
14
+ and are the empty/loading/error states present?"
15
+
16
+ Static gates (`tsc`, `oxlint`, `brand-audit`) prove code compiles and is
17
+ brand-safe. This proves the UI actually works and looks right.
18
+
19
+ ## Install
20
+
21
+ Public on npm. Outside the monorepo:
22
+
23
+ ```bash
24
+ pnpm add -D @keboola/validate-ui
25
+ pnpm exec playwright install chromium
26
+ ```
27
+
28
+ ## CLI
29
+
30
+ ```bash
31
+ # Validate a running URL
32
+ validate-ui --url http://localhost:5173 --brief "Users list with empty state"
33
+
34
+ # Serve a built SPA dir and validate a route
35
+ validate-ui --serve apps/boilerplate/dist --route /tokens --json
36
+ ```
37
+
38
+ Exit code is `0` when every axis passes, `1` otherwise.
39
+
40
+ ## Programmatic
41
+
42
+ ```ts
43
+ import { validate } from '@keboola/validate-ui';
44
+
45
+ const verdict = await validate({
46
+ url: 'http://localhost:5173/tokens',
47
+ brief: 'A paginated tokens list with search and an empty state',
48
+ });
49
+
50
+ if (!verdict.pass) {
51
+ for (const axis of verdict.verdicts.filter((a) => !a.pass)) {
52
+ console.error(axis.axis, axis.findings);
53
+ }
54
+ }
55
+ ```
56
+
57
+ `capture()` and `capturePage()` expose the render/capture primitive; `runAxes()`
58
+ and the individual axes are exported for custom pipelines.
59
+
60
+ ## brief-conformance VLM backend
61
+
62
+ The **brief-conformance** axis judges the screenshot + DOM with a Claude vision
63
+ model. It picks a backend from the environment, and skips gracefully (a minor
64
+ finding, no failure) when none is configured:
65
+
66
+ - **Keboola LLM path** (preferred for internal/team use, no dedicated API key
67
+ needed) — set `VALIDATE_UI_LLM_BASE_URL` to the Keboola-hosted Claude proxy
68
+ and `VALIDATE_UI_LLM_TOKEN` to your Keboola token. This points the Anthropic
69
+ SDK at the proxy (`baseURL`) and authenticates with the token (`x-api-key`),
70
+ the same routing `kai-agent` uses. The SDK-native `ANTHROPIC_BASE_URL` +
71
+ `ANTHROPIC_API_KEY` pair — the exact vars `kai-agent` injects to route the
72
+ proxy — is also accepted; `VALIDATE_UI_LLM_TOKEN` and `KBC_TOKEN` are
73
+ Keboola-convention aliases for the token. Token precedence:
74
+ `VALIDATE_UI_LLM_TOKEN` → `KBC_TOKEN` → `ANTHROPIC_API_KEY`; base-URL
75
+ precedence: `VALIDATE_UI_LLM_BASE_URL` → `ANTHROPIC_BASE_URL`.
76
+ - **Raw key path** — set `ANTHROPIC_API_KEY` with no proxy base URL for a direct
77
+ Anthropic API call.
78
+
79
+ When both a proxy base URL and a raw key are set, the Keboola LLM path wins.
80
+ Override the model with `VALIDATE_UI_MODEL` (default `claude-sonnet-4-6`).